Back to Home

Writing a simple web browser plugin using FireBreath

As previously written on Habré · FireBreath is a framework for developing cross-platform plug-ins using NPAPI [1] technologies and ActiveX Control hosts · which will allow you to use the plugin in ...

Writing a simple web browser plugin using FireBreath

    As already mentioned before on the Habré, FireBreath - is a framework for developing cross-platform plug-ins using NPAPI technology [1], and ActiveX Control hosts, enabling the use of a plugin in the following browsers: Gecko / Firefox, Google Chrome, Apple Safari, Opera, Microsoft Internet Explorer 6, 7, and 8.

    This framework came in handy for the following: the project (web application) used a Java applet to print Pdf files directly to the printer, but due to various problems with Java Policy and permissions, it failed achieve stable operation of the applet + various minor bugs, such as capturing the focus by the applet after loading or browser freeze while printing. Maybe it's just crooked hands. In general, the press either worked or not, and this did not suit anyone.

    As an option, it was decided to try to write a plugin that will get rid of the applet and print files quickly and reliably. Actually, printing now implements the same Java code, rewritten as a jar file. However, the layer that interacts between Java and client code is the browser plugin.

    Now let's write a simple “consider doing nothing” plugin that will write data to a file in the local file system.

    Install Firebreath


    • Download the source code of FireBreath using Git or the archive from the FireBreath website [2]:
      git clone git://github.com/firebreath/FireBreath.git -b firebreath-1.5 firebreath-1.5
    • Go to the folder with the downloaded Firebreath and generate an empty project. To do this, we need installed Python:
      python fbgen.py
      fbgen.py will ask us for some data about the plugin (for example, name and description) and create a folder with the plugin sources in the projects / pluginName folder. Next, the console output when performing these operations:

    alex@alex-laptop:~$ git clone git://github.com/firebreath/FireBreath.git -b firebreath-1.5 firebreath-1.5
    Initialized empty Git repository in /home/alex/firebreath-1.5/.git/
    remote: Counting objects: 16089, done.
    remote: Compressing objects: 100% (4841/4841), done.
    remote: Total 16089 (delta 12322), reused 14495 (delta 11066)
    Receiving objects: 100% (16089/16089), 11.28 MiB | 535 KiB/s, done.
    Resolving deltas: 100% (12322/12322), done.
    alex@alex-laptop:~$ cd firebreath-1.5/
    alex@alex-laptop:~/firebreath-1.5$ python fbgen.py
    Plugin Name []: readFile
    Plugin Identifier [readFile]:
    Plugin Prefix [RFI]:
    Plugin MIME type [application/x-readfile]:
    Plugin Description []:
    Invalid syntax: Description must be one or more characters long!
    Plugin Description []: Read test.txt from ~ folder
    Plugin has no UI [false]:
    Company Name []:
    Invalid syntax: Name must be at least one character, and may not contain carriage returns.
    Company Name []: Takeforce
    Company Identifier [Takeforce]:
    Company Domain [takeforce.com]:
    Done. Files placed in /home/alex/firebreath-1.5/projects/readFile

    • Now we write a code that will write data to a file (for example, /home/alex/log.txt). We will need to make changes to the code of the readFileAPI.cpp and readFileAPI.h files, which, as the name implies, describe and implement the plugin interface:
      Method that will write to the file (forgive my C ++ :)):
      FB::variant readFileAPI::write(const FB::variant& msg)
      {
      	  string message;
      	   if (msg.is_of_type<FB::JSObjectPtr>()) {
              	  message = msg.cast<FB::JSObjectPtr>()->Invoke("ToString", FB::variant_list_of()).convert_cast<std::string > ();
                 } else {
      	          message = msg.convert_cast<std::string > ();
                 }
         	   ofstream myfile;
      	   myfile.open ("/home/alex/log.txt");
      	   myfile << message;
      	   myfile.close();
      	  return msg;
      }

    • We also add the method signature to the .h file, register the method in the class constructor:
      registerMethod("write", make_method(this, &readFileAPI::write)); 


    Plugin assembly


    We will need the following packages to work:
    1. CMake version 2.8
    2. libgtk2.0-dev
    3. Git
    On Ubuntu / Debian, you can install using the command:
    apt-get install cmake libgtk2.0-dev git
    • First you need to prepare the code for the assembly by running prepmake.sh in the FireBreath root folder
    • The build folder is created, go to it and execute the make command.


    Implementation


    As a result, the npreadFile.so file appears in the build / bin / readFile folder, which you need to copy ~ / .mozilla / plugins, where chrome and firefox can find it. After that, you can launch the browser and open the file build / projects / readFile / gen / FBControl.htm. The
    page will say that the plugin has loaded successfully and now you can try it in the console - write:
    plugin().write('Hello');
    And we look at our file /home/alex/log.txt, which appeared "Hello."

    findings


    If you need to do something on the client with browser rights, which could not be done in other ways, or perform some heavy operations, and at the same time, you are happy that you need to install software on the client computer, that is, it makes sense to look aside FireBreath

    I checked that the plugin created in FireBreath works in Google Chome, Mozilla Firefox and IE8 versions. It is stated the same way that it works in Opera, Safari and IE6-7, but I have not tested it.

    References:


    1) en.wikipedia.org/wiki/NPAPI
    2) www.firebreath.org

    Read Next