├── wercker.yml ├── chromeExtension ├── custom.css ├── icon.png ├── images │ ├── verify.png │ └── sprite_black2.png ├── binaries │ ├── Windows │ │ ├── libgpgme-11.dll │ │ ├── libgpg-error-0.dll │ │ └── npwebpgPlugin-v0.5.9.dll │ ├── Ubuntu │ │ ├── npwebpgPlugin-v0.5.9_32.so │ │ └── npwebpgPlugin-v0.5.9_64.so │ └── Mac │ │ └── npwebpgPlugin-v0.5.9.plugin │ │ └── Contents │ │ ├── MacOS │ │ └── webpgPlugin │ │ ├── Resources │ │ └── English.lproj │ │ │ ├── Localized.rsrc │ │ │ └── InfoPlist.strings │ │ └── Info.plist ├── background.html ├── jquery-ui-content.hack.js ├── manifest.json ├── popup.js ├── options.js ├── options.html ├── jquery.client.js ├── general.html ├── popup.html ├── background.js ├── jquery-ui-1.8.13.custom.min.js ├── jquery.ui.widget.js └── content_script.js ├── gmailGPG ├── generic │ ├── Mac │ │ ├── bundle_template │ │ │ ├── InfoPlist.strings │ │ │ ├── Localized.r │ │ │ └── Info.plist │ │ └── projectDef.cmake │ ├── X11 │ │ └── projectDef.cmake │ ├── CMakeLists.txt │ ├── gmailGPGAPI.h │ ├── Factory.cpp │ ├── gmailGPG.h │ ├── PluginConfig.cmake │ ├── Win │ │ ├── projectDef.cmake │ │ └── WiX │ │ │ └── gmailGPGInstaller.wxs │ ├── gmailGPG.cpp │ ├── t-support.h │ ├── gmailGPGAPI.cpp │ └── b64.c └── windows │ ├── Mac │ ├── bundle_template │ │ ├── InfoPlist.strings │ │ ├── Localized.r │ │ └── Info.plist │ └── projectDef.cmake │ ├── X11 │ └── projectDef.cmake │ ├── CMakeLists.txt │ ├── gmailGPGAPI.h │ ├── Factory.cpp │ ├── gmailGPG.h │ ├── PluginConfig.cmake │ ├── Win │ ├── projectDef.cmake │ └── WiX │ │ └── gmailGPGInstaller.wxs │ ├── gmailGPG.cpp │ └── gmailGPGAPI.cpp ├── changelog.md └── README.md /wercker.yml: -------------------------------------------------------------------------------- 1 | box: wercker/default 2 | -------------------------------------------------------------------------------- /chromeExtension/custom.css: -------------------------------------------------------------------------------- 1 | .ui-dialog-titlebar {font-size: 1em; font-weight: bold;} 2 | -------------------------------------------------------------------------------- /chromeExtension/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/icon.png -------------------------------------------------------------------------------- /chromeExtension/images/verify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/images/verify.png -------------------------------------------------------------------------------- /chromeExtension/images/sprite_black2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/images/sprite_black2.png -------------------------------------------------------------------------------- /chromeExtension/binaries/Windows/libgpgme-11.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/binaries/Windows/libgpgme-11.dll -------------------------------------------------------------------------------- /chromeExtension/binaries/Windows/libgpg-error-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/binaries/Windows/libgpg-error-0.dll -------------------------------------------------------------------------------- /chromeExtension/binaries/Windows/npwebpgPlugin-v0.5.9.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/binaries/Windows/npwebpgPlugin-v0.5.9.dll -------------------------------------------------------------------------------- /chromeExtension/binaries/Ubuntu/npwebpgPlugin-v0.5.9_32.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/binaries/Ubuntu/npwebpgPlugin-v0.5.9_32.so -------------------------------------------------------------------------------- /chromeExtension/binaries/Ubuntu/npwebpgPlugin-v0.5.9_64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/binaries/Ubuntu/npwebpgPlugin-v0.5.9_64.so -------------------------------------------------------------------------------- /gmailGPG/generic/Mac/bundle_template/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | CFBundleName = "${PLUGIN_NAME}.plugin"; 4 | NSHumanReadableCopyright = "${FBSTRING_LegalCopyright}"; 5 | -------------------------------------------------------------------------------- /gmailGPG/windows/Mac/bundle_template/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | CFBundleName = "${PLUGIN_NAME}.plugin"; 4 | NSHumanReadableCopyright = "${FBSTRING_LegalCopyright}"; 5 | -------------------------------------------------------------------------------- /chromeExtension/binaries/Mac/npwebpgPlugin-v0.5.9.plugin/Contents/MacOS/webpgPlugin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/binaries/Mac/npwebpgPlugin-v0.5.9.plugin/Contents/MacOS/webpgPlugin -------------------------------------------------------------------------------- /chromeExtension/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /chromeExtension/binaries/Mac/npwebpgPlugin-v0.5.9.plugin/Contents/Resources/English.lproj/Localized.rsrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RC1140/cr-gpg/HEAD/chromeExtension/binaries/Mac/npwebpgPlugin-v0.5.9.plugin/Contents/Resources/English.lproj/Localized.rsrc -------------------------------------------------------------------------------- /chromeExtension/binaries/Mac/npwebpgPlugin-v0.5.9.plugin/Contents/Resources/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | CFBundleName = "npwebpgPlugin-v0.5.9.plugin"; 4 | NSHumanReadableCopyright = "Copyright 2012 CURE|THE|ITCH"; 5 | -------------------------------------------------------------------------------- /gmailGPG/generic/Mac/bundle_template/Localized.r: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | resource 'STR#' (126) 4 | { { 5 | "${FBSTRING_LegalCopyright}", 6 | "${FBSTRING_ProductName}" 7 | } }; 8 | 9 | resource 'STR#' (127) 10 | { { 11 | "", 12 | } }; 13 | 14 | resource 'STR#' (128) 15 | { { 16 | @foreach (FBSTRING_MIMEType CUR_MIMETYPE FBSTRING_FileExtents CUR_EXTENT) 17 | "${CUR_MIMETYPE}", 18 | "${CUR_EXTENT}", 19 | @endforeach 20 | } }; 21 | -------------------------------------------------------------------------------- /gmailGPG/windows/Mac/bundle_template/Localized.r: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | resource 'STR#' (126) 4 | { { 5 | "${FBSTRING_LegalCopyright}", 6 | "${FBSTRING_ProductName}" 7 | } }; 8 | 9 | resource 'STR#' (127) 10 | { { 11 | "", 12 | } }; 13 | 14 | resource 'STR#' (128) 15 | { { 16 | @foreach (FBSTRING_MIMEType CUR_MIMETYPE FBSTRING_FileExtents CUR_EXTENT) 17 | "${CUR_MIMETYPE}", 18 | "${CUR_EXTENT}", 19 | @endforeach 20 | } }; 21 | -------------------------------------------------------------------------------- /chromeExtension/jquery-ui-content.hack.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | function fixcsspath(rules, folder) { 3 | var path_prefix = chrome.extension.getURL(''); 4 | var lookfor = 'url('; 5 | var ss = document.styleSheets; 6 | 7 | for (var j = 0; j < rules.length; j++) { 8 | var b = rules[j].style['background-image']; 9 | var s; 10 | if (b && (s = b.indexOf(lookfor)) >= 0) { 11 | s = s + lookfor.length; 12 | rules[j].style['background-image'] = b.replace(b.substr(s, b.indexOf(folder) - s), path_prefix); 13 | } 14 | } 15 | }; 16 | 17 | var ss = document.styleSheets; 18 | 19 | for (var i = 0; i < ss.length; i++) { 20 | var rules = ss[i].rules || ss[i].cssRules; 21 | if (rules[0].selectorText != "#chrome-extention-relative-paths") continue; 22 | fixcsspath(ss[i].rules, '/images/'); 23 | } 24 | }); -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | ### Changed in 0.8.3 : 2 | - Fixed popup loading issue when self sign was enabled. 3 | 4 | ### Changed in 0.8.2 : 5 | - Fixed a number of security issues reported by both Gynvael Coldwind (http://gynvael.coldwind.pl/) and Krzysztof Kotowicz (http://blog.kotowicz.net/) 6 | - Added multi language support , thanks to the patch from (@Crepuscule https://github.com/RC1140/cr-gpg/issues/20) 7 | - Fixed an issue when adding multiple recipients , thanks to the patch from (@luisgmuniz https://github.com/RC1140/cr-gpg/issues/23) 8 | - Added dynamic key selection for decryption based on the currently logged in email address. 9 | - Complete change of backend from using command line calls to using libgpgme. 10 | - Tiny optimizations 11 | 12 | ### Change updated in 0.7.4 : 13 | - Restriced the sites that the extension is enabled for to only mail.google.com/* 14 | - Added the chrome auto update information to the manifest so that new changes are deployed easily 15 | 16 | -------------------------------------------------------------------------------- /gmailGPG/windows/X11/projectDef.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # Auto-generated X11 project definition file for the 3 | # gmailGPG project 4 | #\**********************************************************/ 5 | 6 | # X11 template platform definition CMake file 7 | # Included from ../CMakeLists.txt 8 | 9 | # remember that the current source dir is the project root; this file is in X11/ 10 | file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 11 | X11/[^.]*.cpp 12 | X11/[^.]*.h 13 | X11/[^.]*.cmake 14 | ) 15 | 16 | SOURCE_GROUP(X11 FILES ${PLATFORM}) 17 | 18 | # use this to add preprocessor definitions 19 | add_definitions( 20 | ) 21 | 22 | set (SOURCES 23 | ${SOURCES} 24 | ${PLATFORM} 25 | ) 26 | 27 | add_x11_plugin(${PROJECT_NAME} SOURCES) 28 | 29 | # add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing! 30 | target_link_libraries(${PROJECT_NAME} 31 | ${PLUGIN_INTERNAL_DEPS} 32 | ) 33 | -------------------------------------------------------------------------------- /gmailGPG/generic/X11/projectDef.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # Auto-generated X11 project definition file for the 3 | # gmailGPG project 4 | #\**********************************************************/ 5 | 6 | # X11 template platform definition CMake file 7 | # Included from ../CMakeLists.txt 8 | 9 | # remember that the current source dir is the project root; this file is in X11/ 10 | file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 11 | X11/[^.]*.cpp 12 | X11/[^.]*.h 13 | X11/[^.]*.cmake 14 | ) 15 | 16 | SOURCE_GROUP(X11 FILES ${PLATFORM}) 17 | 18 | # use this to add preprocessor definitions 19 | add_definitions( 20 | ) 21 | 22 | set (SOURCES 23 | ${SOURCES} 24 | ${PLATFORM} 25 | ) 26 | 27 | add_x11_plugin(${PROJECT_NAME} SOURCES) 28 | 29 | # add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing! 30 | target_link_libraries(${PROJECT_NAME} 31 | ${PLUGIN_INTERNAL_DEPS} 32 | -lgpgme 33 | -lgpg-error 34 | ) 35 | -------------------------------------------------------------------------------- /gmailGPG/generic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # 3 | # Auto-generated CMakeLists.txt for the gmailGPG project 4 | # 5 | #\**********************************************************/ 6 | 7 | # Written to work with cmake 2.6 8 | cmake_minimum_required (VERSION 2.6) 9 | set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 10 | 11 | Project(${PLUGIN_NAME}) 12 | 13 | file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 14 | [^.]*.cpp 15 | [^.]*.h 16 | [^.]*.cmake 17 | ) 18 | 19 | include_directories(${PLUGIN_INCLUDE_DIRS}) 20 | 21 | # Generated files are stored in ${GENERATED} by the project configuration 22 | SET_SOURCE_FILES_PROPERTIES( 23 | ${GENERATED} 24 | PROPERTIES 25 | GENERATED 1 26 | ) 27 | 28 | SOURCE_GROUP(Generated FILES 29 | ${GENERATED} 30 | ) 31 | 32 | SET( SOURCES 33 | ${GENERAL} 34 | ${GENERATED} 35 | ) 36 | 37 | # This will include Win/projectDef.cmake, X11/projectDef.cmake, Mac/projectDef 38 | # depending on the platform 39 | include_platform() 40 | -------------------------------------------------------------------------------- /gmailGPG/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # 3 | # Auto-generated CMakeLists.txt for the gmailGPG project 4 | # 5 | #\**********************************************************/ 6 | 7 | # Written to work with cmake 2.6 8 | cmake_minimum_required (VERSION 2.6) 9 | set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 10 | 11 | Project(${PLUGIN_NAME}) 12 | 13 | file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 14 | [^.]*.cpp 15 | [^.]*.h 16 | [^.]*.cmake 17 | ) 18 | 19 | include_directories(${PLUGIN_INCLUDE_DIRS}) 20 | 21 | # Generated files are stored in ${GENERATED} by the project configuration 22 | SET_SOURCE_FILES_PROPERTIES( 23 | ${GENERATED} 24 | PROPERTIES 25 | GENERATED 1 26 | ) 27 | 28 | SOURCE_GROUP(Generated FILES 29 | ${GENERATED} 30 | ) 31 | 32 | SET( SOURCES 33 | ${GENERAL} 34 | ${GENERATED} 35 | ) 36 | 37 | # This will include Win/projectDef.cmake, X11/projectDef.cmake, Mac/projectDef 38 | # depending on the platform 39 | include_platform() 40 | -------------------------------------------------------------------------------- /gmailGPG/generic/Mac/projectDef.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # Auto-generated Mac project definition file for the 3 | # gmailGPG project 4 | #\**********************************************************/ 5 | 6 | # Mac template platform definition CMake file 7 | # Included from ../CMakeLists.txt 8 | 9 | # remember that the current source dir is the project root; this file is in Mac/ 10 | file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 11 | Mac/[^.]*.cpp 12 | Mac/[^.]*.h 13 | Mac/[^.]*.cmake 14 | ) 15 | 16 | # use this to add preprocessor definitions 17 | add_definitions( 18 | 19 | ) 20 | 21 | 22 | SOURCE_GROUP(Mac FILES ${PLATFORM}) 23 | 24 | set (SOURCES 25 | ${SOURCES} 26 | ${PLATFORM} 27 | ) 28 | 29 | set(PLIST "Mac/bundle_template/Info.plist") 30 | set(STRINGS "Mac/bundle_template/InfoPlist.strings") 31 | set(LOCALIZED "Mac/bundle_template/Localized.r") 32 | 33 | add_mac_plugin(${PROJECT_NAME} ${PLIST} ${STRINGS} ${LOCALIZED} SOURCES) 34 | 35 | # add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing! 36 | target_link_libraries(${PROJECT_NAME} 37 | ${PLUGIN_INTERNAL_DEPS} 38 | ) 39 | -------------------------------------------------------------------------------- /gmailGPG/windows/Mac/projectDef.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # Auto-generated Mac project definition file for the 3 | # gmailGPG project 4 | #\**********************************************************/ 5 | 6 | # Mac template platform definition CMake file 7 | # Included from ../CMakeLists.txt 8 | 9 | # remember that the current source dir is the project root; this file is in Mac/ 10 | file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 11 | Mac/[^.]*.cpp 12 | Mac/[^.]*.h 13 | Mac/[^.]*.cmake 14 | ) 15 | 16 | # use this to add preprocessor definitions 17 | add_definitions( 18 | 19 | ) 20 | 21 | 22 | SOURCE_GROUP(Mac FILES ${PLATFORM}) 23 | 24 | set (SOURCES 25 | ${SOURCES} 26 | ${PLATFORM} 27 | ) 28 | 29 | set(PLIST "Mac/bundle_template/Info.plist") 30 | set(STRINGS "Mac/bundle_template/InfoPlist.strings") 31 | set(LOCALIZED "Mac/bundle_template/Localized.r") 32 | 33 | add_mac_plugin(${PROJECT_NAME} ${PLIST} ${STRINGS} ${LOCALIZED} SOURCES) 34 | 35 | # add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing! 36 | target_link_libraries(${PROJECT_NAME} 37 | ${PLUGIN_INTERNAL_DEPS} 38 | ) 39 | -------------------------------------------------------------------------------- /chromeExtension/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Cr-gpg", 3 | "manifest_version": 2, 4 | "version": "0.8.4", 5 | "description": "Chrome-gpg. Quick hack that bridges gmail to your locally installed gpg.", 6 | "icons":{"128":"icon.png"}, 7 | "offline_enabled" : true, 8 | "update_url": "https://github.com/downloads/RC1140/cr-gpg/updates.xml", 9 | "browser_action": { 10 | "default_title": "The chrome gpg encryption plugin", 11 | "default_icon": "icon.png", 12 | "default_popup": "popup.html" 13 | }, 14 | "options_page": "options.html", 15 | "plugins": [ 16 | {"path": "binaries/Windows/npwebpgPlugin-v0.5.9.dll"}, 17 | {"path": "binaries/Mac/npwebpgPlugin-v0.5.9.plugin"}, 18 | {"path": "binaries/Ubuntu/npwebpgPlugin-v0.5.9_32.so"}, 19 | {"path": "binaries/Ubuntu/npwebpgPlugin-v0.5.9_64.so"} 20 | ], 21 | "content_scripts": [ 22 | { 23 | "matches": ["http://mail.google.com/*", "https://mail.google.com/*"], 24 | "css": ["jquery-ui-1.8.11.thinkst.css","custom.css"], 25 | "js": ["jquery-1.7.1.min.js","jquery-ui-1.8.13.custom.js","content_script.js","popup.js","jquery.client.js"] 26 | } 27 | ], 28 | "permissions": [ 29 | "tabs", 30 | "https://mail.google.com/*" 31 | ], 32 | "background": { 33 | "page": "background.html" 34 | }, 35 | "web_accessible_resources": [ 36 | "images/verify.png", 37 | "images/sprite_black2.png" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /gmailGPG/generic/gmailGPGAPI.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "JSAPIAuto.h" 6 | #include "BrowserHost.h" 7 | #include "gmailGPG.h" 8 | 9 | #ifndef H_gmailGPGAPI 10 | #define H_gmailGPGAPI 11 | 12 | class gmailGPGAPI : public FB::JSAPIAuto 13 | { 14 | public: 15 | gmailGPGAPI(const gmailGPGPtr& plugin, const FB::BrowserHostPtr& host); 16 | virtual ~gmailGPGAPI(); 17 | 18 | gmailGPGPtr getPlugin(); 19 | 20 | std::string get_appPath(); 21 | void set_appPath(const std::string& val); 22 | std::string get_tempPath(); 23 | void set_tempPath(const std::string& val); 24 | 25 | std::string get_version(); 26 | 27 | std::string readAndRemoveErrorFile(std::string); 28 | std::string readTempFile(const std::string ); 29 | std::string readFileClean(std::string fileName); 30 | FB::variant encryptMessage(const FB::variant& recipients,const FB::variant& msg); 31 | FB::variant decryptMessage(const FB::variant& msg); 32 | FB::variant importKey(const FB::variant& pubKey); 33 | FB::variant listKeys(const std::string& domain,int secret_only); 34 | FB::variant listPrivateKeys(); 35 | FB::variant clearSignMessage(const FB::variant& message); 36 | FB::variant verifyMessage(const FB::variant& message); 37 | FB::variant verifyMessageWithDetachedFile(const FB::variant& message,const FB::variant& sig); 38 | 39 | FB_JSAPI_EVENT(fired, 3, (const FB::variant&, bool, int)); 40 | FB_JSAPI_EVENT(echo, 2, (const FB::variant&, const int)); 41 | FB_JSAPI_EVENT(notify, 0, ()); 42 | 43 | private: 44 | gmailGPGWeakPtr m_plugin; 45 | FB::BrowserHostPtr m_host; 46 | 47 | std::string m_testString; 48 | std::string m_appPath; 49 | std::string m_tempPath; 50 | }; 51 | 52 | #endif // H_gmailGPGAPI 53 | 54 | -------------------------------------------------------------------------------- /gmailGPG/windows/gmailGPGAPI.h: -------------------------------------------------------------------------------- 1 | /**********************************************************\ 2 | 3 | Auto-generated gmailGPGAPI.h 4 | 5 | \**********************************************************/ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "JSAPIAuto.h" 11 | #include "BrowserHost.h" 12 | #include "gmailGPG.h" 13 | 14 | #ifndef H_gmailGPGAPI 15 | #define H_gmailGPGAPI 16 | 17 | class gmailGPGAPI : public FB::JSAPIAuto 18 | { 19 | public: 20 | gmailGPGAPI(const gmailGPGPtr& plugin, const FB::BrowserHostPtr& host); 21 | virtual ~gmailGPGAPI(); 22 | 23 | gmailGPGPtr getPlugin(); 24 | 25 | std::string get_appPath(); 26 | void set_appPath(const std::string& val); 27 | std::string get_tempPath(); 28 | void set_tempPath(const std::string& val); 29 | 30 | std::string get_version(); 31 | 32 | std::string readAndRemoveErrorFile(std::string); 33 | std::string readFileClean(std::string fileName); 34 | FB::variant encryptMessage(const FB::variant& recipients,const FB::variant& msg); 35 | FB::variant decryptMessage(const FB::variant& password,const FB::variant& msg); 36 | FB::variant importKey(const FB::variant& pubKey); 37 | FB::variant listKeys(); 38 | FB::variant listPrivateKeys(); 39 | FB::variant clearSignMessage(const FB::variant& message,const FB::variant& password); 40 | FB::variant verifyMessage(const FB::variant& message); 41 | FB::variant testOptions(); 42 | 43 | FB_JSAPI_EVENT(fired, 3, (const FB::variant&, bool, int)); 44 | FB_JSAPI_EVENT(echo, 2, (const FB::variant&, const int)); 45 | FB_JSAPI_EVENT(notify, 0, ()); 46 | 47 | // Method test-event 48 | void testEvent(const FB::variant& s); 49 | 50 | private: 51 | gmailGPGWeakPtr m_plugin; 52 | FB::BrowserHostPtr m_host; 53 | 54 | std::string m_testString; 55 | std::string m_appPath; 56 | std::string m_tempPath; 57 | }; 58 | 59 | #endif // H_gmailGPGAPI 60 | 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Cr-GPG: 2 | 3 | A chrome plugin that enables gpg encryption and decryption for the gmail web interface. 4 | Download it from [here](http://thinkst.com/tools/cr-gpg/) 5 | 6 | A brief tutorial can be found [at](http://blog.thinkst.com/2011/09/chrome-extension-for-gpg-in-gmail.html) 7 | 8 | ## Known Issues: 9 | 10 | We have had users report issues with certain versions of mountain lion. 11 | If you encounter any issues please log an issue with as many details as 12 | possible to aid us in fixing this. 13 | 14 | ## Using the extension : 15 | 16 | Encrypting a message : 17 | The extension is hopefully easy enough to use , open up a gmail 18 | window to begin. To encrypt a new message use 19 | the compose button as normal , but you will notice that there is 20 | a encrypt link next to the Rich Formatting link. 21 | 22 | Clicking the button will encrypt the message that you are typing 23 | with the public key for the current recepients. If they are not 24 | found in your local pc keyring a error message will be displayed. 25 | 26 | If no recepients or message is enterd a error message will be 27 | displayed. 28 | 29 | Decrypting a message : 30 | Start of by clicking a email thread , this will show all mails 31 | in that thread. Below each mail in the a Decrypt message link 32 | will be shown. 33 | 34 | Clicking the link will prompt you for your passphrase with 35 | which to decrypt the message, a error will be show if no 36 | valid gpg data can be found or if the passphrase is incorrect. 37 | 38 | ## Building the Extension : 39 | 40 | Follow the intrsuction @ https://github.com/RC1140/cr-gpg/wiki/Compiling-extension-manually-(Linux) 41 | to build a custom version of the plugin , this is required for linux where various 42 | architectures require specific builds. 43 | 44 | ## Debugging Extensions : 45 | 46 | If you encounter a error or are unable to get the extension to run. Follow 47 | the intstructions @ https://github.com/RC1140/cr-gpg/wiki/Debugging which 48 | will allow you to find and fix any errors. This also assists when submitting 49 | bug requests as it allows the developers to pin point a issue. 50 | 51 | -------------------------------------------------------------------------------- /gmailGPG/generic/Factory.cpp: -------------------------------------------------------------------------------- 1 | /**********************************************************\ 2 | 3 | Auto-generated Factory.cpp 4 | 5 | This file contains the auto-generated factory methods 6 | for the gmailGPG project 7 | 8 | \**********************************************************/ 9 | 10 | #include "FactoryBase.h" 11 | #include "gmailGPG.h" 12 | #include 13 | 14 | class PluginFactory : public FB::FactoryBase 15 | { 16 | public: 17 | /////////////////////////////////////////////////////////////////////////////// 18 | /// @fn FB::PluginCorePtr createPlugin(const std::string& mimetype) 19 | /// 20 | /// @brief Creates a plugin object matching the provided mimetype 21 | /// If mimetype is empty, returns the default plugin 22 | /////////////////////////////////////////////////////////////////////////////// 23 | FB::PluginCorePtr createPlugin(const std::string& mimetype) 24 | { 25 | return boost::make_shared(); 26 | } 27 | 28 | /////////////////////////////////////////////////////////////////////////////// 29 | /// @see FB::FactoryBase::globalPluginInitialize 30 | /////////////////////////////////////////////////////////////////////////////// 31 | void globalPluginInitialize() 32 | { 33 | gmailGPG::StaticInitialize(); 34 | } 35 | 36 | /////////////////////////////////////////////////////////////////////////////// 37 | /// @see FB::FactoryBase::globalPluginDeinitialize 38 | /////////////////////////////////////////////////////////////////////////////// 39 | void globalPluginDeinitialize() 40 | { 41 | gmailGPG::StaticDeinitialize(); 42 | } 43 | }; 44 | 45 | /////////////////////////////////////////////////////////////////////////////// 46 | /// @fn getFactoryInstance() 47 | /// 48 | /// @brief Returns the factory instance for this plugin module 49 | /////////////////////////////////////////////////////////////////////////////// 50 | FB::FactoryBasePtr getFactoryInstance() 51 | { 52 | static boost::shared_ptr factory = boost::make_shared(); 53 | return factory; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /gmailGPG/windows/Factory.cpp: -------------------------------------------------------------------------------- 1 | /**********************************************************\ 2 | 3 | Auto-generated Factory.cpp 4 | 5 | This file contains the auto-generated factory methods 6 | for the gmailGPG project 7 | 8 | \**********************************************************/ 9 | 10 | #include "FactoryBase.h" 11 | #include "gmailGPG.h" 12 | #include 13 | 14 | class PluginFactory : public FB::FactoryBase 15 | { 16 | public: 17 | /////////////////////////////////////////////////////////////////////////////// 18 | /// @fn FB::PluginCorePtr createPlugin(const std::string& mimetype) 19 | /// 20 | /// @brief Creates a plugin object matching the provided mimetype 21 | /// If mimetype is empty, returns the default plugin 22 | /////////////////////////////////////////////////////////////////////////////// 23 | FB::PluginCorePtr createPlugin(const std::string& mimetype) 24 | { 25 | return boost::make_shared(); 26 | } 27 | 28 | /////////////////////////////////////////////////////////////////////////////// 29 | /// @see FB::FactoryBase::globalPluginInitialize 30 | /////////////////////////////////////////////////////////////////////////////// 31 | void globalPluginInitialize() 32 | { 33 | gmailGPG::StaticInitialize(); 34 | } 35 | 36 | /////////////////////////////////////////////////////////////////////////////// 37 | /// @see FB::FactoryBase::globalPluginDeinitialize 38 | /////////////////////////////////////////////////////////////////////////////// 39 | void globalPluginDeinitialize() 40 | { 41 | gmailGPG::StaticDeinitialize(); 42 | } 43 | }; 44 | 45 | /////////////////////////////////////////////////////////////////////////////// 46 | /// @fn getFactoryInstance() 47 | /// 48 | /// @brief Returns the factory instance for this plugin module 49 | /////////////////////////////////////////////////////////////////////////////// 50 | FB::FactoryBasePtr getFactoryInstance() 51 | { 52 | static boost::shared_ptr factory = boost::make_shared(); 53 | return factory; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /gmailGPG/generic/Mac/bundle_template/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${PLUGIN_NAME} 9 | CFBundleGetInfoString 10 | ${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION}, ${FBSTRING_LegalCopyright} 11 | CFBundleIdentifier 12 | com.${FBTYPELIB_NAME}.${FBSTRING_PluginName} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | BRPL 17 | CFBundleShortVersionString 18 | ${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${FBSTRING_PLUGIN_VERSION} 23 | CFPlugInDynamicRegisterFunction 24 | 25 | CFPlugInDynamicRegistration 26 | NO 27 | CFPlugInFactories 28 | 29 | 00000000-0000-0000-0000-000000000000 30 | MyFactoryFunction 31 | 32 | CFPlugInTypes 33 | 34 | 00000000-0000-0000-0000-000000000000 35 | 36 | 00000000-0000-0000-0000-000000000000 37 | 38 | 39 | CFPlugInUnloadFunction 40 | 41 | WebPluginName 42 | ${FBSTRING_ProductName} 43 | WebPluginDescription 44 | ${FBSTRING_FileDescription} 45 | WebPluginMIMETypes 46 | 47 | @foreach (FBSTRING_MIMEType CUR_MIMETYPE FBSTRING_FileDescription CUR_DESC) 48 | ${CUR_MIMETYPE} 49 | 50 | WebPluginExtensions 51 | 52 | 53 | 54 | WebPluginTypeDescription 55 | ${CUR_DESC} 56 | 57 | @endforeach 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /gmailGPG/windows/Mac/bundle_template/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${PLUGIN_NAME} 9 | CFBundleGetInfoString 10 | ${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION}, ${FBSTRING_LegalCopyright} 11 | CFBundleIdentifier 12 | com.${FBTYPELIB_NAME}.${FBSTRING_PluginName} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | BRPL 17 | CFBundleShortVersionString 18 | ${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${FBSTRING_PLUGIN_VERSION} 23 | CFPlugInDynamicRegisterFunction 24 | 25 | CFPlugInDynamicRegistration 26 | NO 27 | CFPlugInFactories 28 | 29 | 00000000-0000-0000-0000-000000000000 30 | MyFactoryFunction 31 | 32 | CFPlugInTypes 33 | 34 | 00000000-0000-0000-0000-000000000000 35 | 36 | 00000000-0000-0000-0000-000000000000 37 | 38 | 39 | CFPlugInUnloadFunction 40 | 41 | WebPluginName 42 | ${FBSTRING_ProductName} 43 | WebPluginDescription 44 | ${FBSTRING_FileDescription} 45 | WebPluginMIMETypes 46 | 47 | @foreach (FBSTRING_MIMEType CUR_MIMETYPE FBSTRING_FileDescription CUR_DESC) 48 | ${CUR_MIMETYPE} 49 | 50 | WebPluginExtensions 51 | 52 | 53 | 54 | WebPluginTypeDescription 55 | ${CUR_DESC} 56 | 57 | @endforeach 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /gmailGPG/generic/gmailGPG.h: -------------------------------------------------------------------------------- 1 | /**********************************************************\ 2 | 3 | Auto-generated gmailGPG.h 4 | 5 | This file contains the auto-generated main plugin object 6 | implementation for the gmailGPG project 7 | 8 | \**********************************************************/ 9 | #ifndef H_gmailGPGPLUGIN 10 | #define H_gmailGPGPLUGIN 11 | 12 | #include "PluginWindow.h" 13 | #include "PluginEvents/MouseEvents.h" 14 | #include "PluginEvents/AttachedEvent.h" 15 | 16 | #include "PluginCore.h" 17 | 18 | 19 | FB_FORWARD_PTR(gmailGPG) 20 | class gmailGPG : public FB::PluginCore 21 | { 22 | public: 23 | static void StaticInitialize(); 24 | static void StaticDeinitialize(); 25 | 26 | public: 27 | gmailGPG(); 28 | virtual ~gmailGPG(); 29 | 30 | public: 31 | void onPluginReady(); 32 | void shutdown(); 33 | virtual FB::JSAPIPtr createJSAPI(); 34 | // If you want your plugin to always be windowless, set this to true 35 | // If you want your plugin to be optionally windowless based on the 36 | // value of the "windowless" param tag, remove this method or return 37 | // FB::PluginCore::isWindowless() 38 | virtual bool isWindowless() { return false; } 39 | 40 | BEGIN_PLUGIN_EVENT_MAP() 41 | EVENTTYPE_CASE(FB::MouseDownEvent, onMouseDown, FB::PluginWindow) 42 | EVENTTYPE_CASE(FB::MouseUpEvent, onMouseUp, FB::PluginWindow) 43 | EVENTTYPE_CASE(FB::MouseMoveEvent, onMouseMove, FB::PluginWindow) 44 | EVENTTYPE_CASE(FB::MouseMoveEvent, onMouseMove, FB::PluginWindow) 45 | EVENTTYPE_CASE(FB::AttachedEvent, onWindowAttached, FB::PluginWindow) 46 | EVENTTYPE_CASE(FB::DetachedEvent, onWindowDetached, FB::PluginWindow) 47 | END_PLUGIN_EVENT_MAP() 48 | 49 | /** BEGIN EVENTDEF -- DON'T CHANGE THIS LINE **/ 50 | virtual bool onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *); 51 | virtual bool onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *); 52 | virtual bool onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *); 53 | virtual bool onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *); 54 | virtual bool onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *); 55 | /** END EVENTDEF -- DON'T CHANGE THIS LINE **/ 56 | }; 57 | 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /gmailGPG/windows/gmailGPG.h: -------------------------------------------------------------------------------- 1 | /**********************************************************\ 2 | 3 | Auto-generated gmailGPG.h 4 | 5 | This file contains the auto-generated main plugin object 6 | implementation for the gmailGPG project 7 | 8 | \**********************************************************/ 9 | #ifndef H_gmailGPGPLUGIN 10 | #define H_gmailGPGPLUGIN 11 | 12 | #include "PluginWindow.h" 13 | #include "PluginEvents/MouseEvents.h" 14 | #include "PluginEvents/AttachedEvent.h" 15 | 16 | #include "PluginCore.h" 17 | 18 | 19 | FB_FORWARD_PTR(gmailGPG) 20 | class gmailGPG : public FB::PluginCore 21 | { 22 | public: 23 | static void StaticInitialize(); 24 | static void StaticDeinitialize(); 25 | 26 | public: 27 | gmailGPG(); 28 | virtual ~gmailGPG(); 29 | 30 | public: 31 | void onPluginReady(); 32 | void shutdown(); 33 | virtual FB::JSAPIPtr createJSAPI(); 34 | // If you want your plugin to always be windowless, set this to true 35 | // If you want your plugin to be optionally windowless based on the 36 | // value of the "windowless" param tag, remove this method or return 37 | // FB::PluginCore::isWindowless() 38 | virtual bool isWindowless() { return false; } 39 | 40 | BEGIN_PLUGIN_EVENT_MAP() 41 | EVENTTYPE_CASE(FB::MouseDownEvent, onMouseDown, FB::PluginWindow) 42 | EVENTTYPE_CASE(FB::MouseUpEvent, onMouseUp, FB::PluginWindow) 43 | EVENTTYPE_CASE(FB::MouseMoveEvent, onMouseMove, FB::PluginWindow) 44 | EVENTTYPE_CASE(FB::MouseMoveEvent, onMouseMove, FB::PluginWindow) 45 | EVENTTYPE_CASE(FB::AttachedEvent, onWindowAttached, FB::PluginWindow) 46 | EVENTTYPE_CASE(FB::DetachedEvent, onWindowDetached, FB::PluginWindow) 47 | END_PLUGIN_EVENT_MAP() 48 | 49 | /** BEGIN EVENTDEF -- DON'T CHANGE THIS LINE **/ 50 | virtual bool onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *); 51 | virtual bool onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *); 52 | virtual bool onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *); 53 | virtual bool onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *); 54 | virtual bool onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *); 55 | /** END EVENTDEF -- DON'T CHANGE THIS LINE **/ 56 | }; 57 | 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /chromeExtension/popup.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | 3 | function getVersion() { 4 | if(chrome.app.getDetails()){ 5 | return chrome.app.getDetails().version; 6 | }else{ 7 | return ''; 8 | }; 9 | } 10 | 11 | function plugin0() 12 | { 13 | return document.getElementById('plugin0'); 14 | } 15 | $('.encrypt').click(function(){ 16 | chrome.extension.sendRequest({'messageType':'encrypt',encrypt: {'message':$('#ecmessage').val(),'maillist':$('#recipients').val().split(','),'domel':$(this).attr('id')}}, function(response) { 17 | var returnMessage = response.message; 18 | if(returnMessage.length == 1){ 19 | $('#ecmessage').val('Invalid Recipients or no public key found for recipients'); 20 | }else{ 21 | $('#ecmessage').val(returnMessage); 22 | } 23 | }); 24 | }); 25 | 26 | $('div.verify').click(function(){ 27 | $(this).html(''); 28 | }); 29 | 30 | $('.sign').click(function(){ 31 | chrome.extension.sendRequest({'messageType':'sign',sign: {'message':$('#sigmessage').val()}}, function(response) { 32 | if(!response.message.error){ 33 | $('#sigmessage').val(response.message.data); 34 | }else{ 35 | $('#sigmessage').val(JSON.stringify(response.message, undefined, 2)); 36 | }; 37 | }); 38 | }); 39 | $('.verify').click(function(){ 40 | var verify_status = plugin0().gpgVerify($('#sigmessage').val()); 41 | $('div.verify').text(JSON.stringify(verify_status, undefined, 2)); 42 | }); 43 | 44 | $('.import').click(function(){ 45 | chrome.extension.sendRequest({'messageType':'importkey',import: {'message':$('textarea.message').val()}}, function(response) { 46 | $('textarea.message').val(JSON.stringify(response.message, undefined, 2)); 47 | }); 48 | }); 49 | $('textarea').click(function(){ 50 | if($(this).text() == 'Enter text here'){ 51 | $(this).text(''); 52 | return; 53 | }; 54 | if($(this).text() == 'Please Paste your key here'){ 55 | $(this).text(''); 56 | return; 57 | }; 58 | 59 | }); 60 | 61 | $("#tabs").tabs(); 62 | 63 | 64 | $('#version').text(getVersion()); 65 | }); 66 | -------------------------------------------------------------------------------- /gmailGPG/generic/PluginConfig.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # 3 | # Auto-Generated Plugin Configuration file 4 | # for gmailGPG 5 | # 6 | #\**********************************************************/ 7 | 8 | set(PLUGIN_NAME "gmailGPG") 9 | set(PLUGIN_PREFIX "GGP") 10 | set(COMPANY_NAME "private") 11 | 12 | # ActiveX constants: 13 | set(FBTYPELIB_NAME gmailGPGLib) 14 | set(FBTYPELIB_DESC "gmailGPG 1.0 Type Library") 15 | set(IFBControl_DESC "gmailGPG Control Interface") 16 | set(FBControl_DESC "gmailGPG Control Class") 17 | set(IFBComJavascriptObject_DESC "gmailGPG IComJavascriptObject Interface") 18 | set(FBComJavascriptObject_DESC "gmailGPG ComJavascriptObject Class") 19 | set(IFBComEventSource_DESC "gmailGPG IFBComEventSource Interface") 20 | set(AXVERSION_NUM "1") 21 | 22 | # NOTE: THESE GUIDS *MUST* BE UNIQUE TO YOUR PLUGIN/ACTIVEX CONTROL! YES, ALL OF THEM! 23 | set(FBTYPELIB_GUID f58ad748-8959-50bb-8df4-c37a86b9e2c8) 24 | set(IFBControl_GUID 7cc7e041-140d-5935-b1cd-02ae930e6521) 25 | set(FBControl_GUID a3af9714-d10e-546e-9e97-448c822cc3f4) 26 | set(IFBComJavascriptObject_GUID 46887351-c689-52b9-9d5e-3ed853fb1990) 27 | set(FBComJavascriptObject_GUID 7a119fa9-460c-5dc6-b393-14ef15a88497) 28 | set(IFBComEventSource_GUID 2b1a0c49-de0d-5a15-93ef-9130081a0bbb) 29 | 30 | # these are the pieces that are relevant to using it from Javascript 31 | set(ACTIVEX_PROGID "private.gmailGPG") 32 | set(MOZILLA_PLUGINID "runawaycoder.co.za/gmailGPG") 33 | 34 | # strings 35 | set(FBSTRING_CompanyName "private") 36 | set(FBSTRING_FileDescription "gmail gpg plugin") 37 | set(FBSTRING_PLUGIN_VERSION "1.0.0.0") 38 | set(FBSTRING_LegalCopyright "Copyright 2011 private") 39 | set(FBSTRING_PluginFileName "np${PLUGIN_NAME}.dll") 40 | set(FBSTRING_ProductName "gmailGPG") 41 | set(FBSTRING_FileExtents "") 42 | set(FBSTRING_PluginName "gmailGPG") 43 | set(FBSTRING_MIMEType "application/x-gmailgpg") 44 | 45 | # Uncomment this next line if you're not planning on your plugin doing 46 | # any drawing: 47 | 48 | set (FB_GUI_DISABLED 1) 49 | 50 | # Mac plugin settings. If your plugin does not draw, set these all to 0 51 | set(FBMAC_USE_QUICKDRAW 0) 52 | set(FBMAC_USE_CARBON 0) 53 | set(FBMAC_USE_COCOA 0) 54 | set(FBMAC_USE_COREGRAPHICS 0) 55 | set(FBMAC_USE_COREANIMATION 0) 56 | set(FBMAC_USE_INVALIDATINGCOREANIMATION 0) 57 | 58 | # If you want to register per-machine on Windows, uncomment this line 59 | #set (FB_ATLREG_MACHINEWIDE 1) 60 | -------------------------------------------------------------------------------- /gmailGPG/windows/PluginConfig.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # 3 | # Auto-Generated Plugin Configuration file 4 | # for gmailGPG 5 | # 6 | #\**********************************************************/ 7 | 8 | set(PLUGIN_NAME "gmailGPG") 9 | set(PLUGIN_PREFIX "GGP") 10 | set(COMPANY_NAME "private") 11 | 12 | # ActiveX constants: 13 | set(FBTYPELIB_NAME gmailGPGLib) 14 | set(FBTYPELIB_DESC "gmailGPG 1.0 Type Library") 15 | set(IFBControl_DESC "gmailGPG Control Interface") 16 | set(FBControl_DESC "gmailGPG Control Class") 17 | set(IFBComJavascriptObject_DESC "gmailGPG IComJavascriptObject Interface") 18 | set(FBComJavascriptObject_DESC "gmailGPG ComJavascriptObject Class") 19 | set(IFBComEventSource_DESC "gmailGPG IFBComEventSource Interface") 20 | set(AXVERSION_NUM "1") 21 | 22 | # NOTE: THESE GUIDS *MUST* BE UNIQUE TO YOUR PLUGIN/ACTIVEX CONTROL! YES, ALL OF THEM! 23 | set(FBTYPELIB_GUID f58ad748-8959-50bb-8df4-c37a86b9e2c8) 24 | set(IFBControl_GUID 7cc7e041-140d-5935-b1cd-02ae930e6521) 25 | set(FBControl_GUID a3af9714-d10e-546e-9e97-448c822cc3f4) 26 | set(IFBComJavascriptObject_GUID 46887351-c689-52b9-9d5e-3ed853fb1990) 27 | set(FBComJavascriptObject_GUID 7a119fa9-460c-5dc6-b393-14ef15a88497) 28 | set(IFBComEventSource_GUID 2b1a0c49-de0d-5a15-93ef-9130081a0bbb) 29 | 30 | # these are the pieces that are relevant to using it from Javascript 31 | set(ACTIVEX_PROGID "private.gmailGPG") 32 | set(MOZILLA_PLUGINID "runawaycoder.co.za/gmailGPG") 33 | 34 | # strings 35 | set(FBSTRING_CompanyName "private") 36 | set(FBSTRING_FileDescription "gmail gpg plugin") 37 | set(FBSTRING_PLUGIN_VERSION "1.0.0.0") 38 | set(FBSTRING_LegalCopyright "Copyright 2011 private") 39 | set(FBSTRING_PluginFileName "${PLUGIN_NAME}.dll") 40 | set(FBSTRING_ProductName "gmailGPG") 41 | set(FBSTRING_FileExtents "") 42 | set(FBSTRING_PluginName "gmailGPG") 43 | set(FBSTRING_MIMEType "application/x-gmailgpg") 44 | 45 | # Uncomment this next line if you're not planning on your plugin doing 46 | # any drawing: 47 | 48 | set (FB_GUI_DISABLED 1) 49 | 50 | # Mac plugin settings. If your plugin does not draw, set these all to 0 51 | set(FBMAC_USE_QUICKDRAW 0) 52 | set(FBMAC_USE_CARBON 0) 53 | set(FBMAC_USE_COCOA 0) 54 | set(FBMAC_USE_COREGRAPHICS 0) 55 | set(FBMAC_USE_COREANIMATION 0) 56 | set(FBMAC_USE_INVALIDATINGCOREANIMATION 0) 57 | 58 | # If you want to register per-machine on Windows, uncomment this line 59 | #set (FB_ATLREG_MACHINEWIDE 1) 60 | -------------------------------------------------------------------------------- /chromeExtension/binaries/Mac/npwebpgPlugin-v0.5.9.plugin/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 10K549 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | webpgPlugin 11 | CFBundleGetInfoString 12 | webpgPlugin 0.5.9, Copyright 2012 CURE|THE|ITCH 13 | CFBundleIdentifier 14 | com.webpgPluginLib.WebPG 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | BRPL 19 | CFBundleShortVersionString 20 | 0.5.9 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0.5.9 25 | CFPlugInDynamicRegisterFunction 26 | 27 | CFPlugInDynamicRegistration 28 | NO 29 | CFPlugInFactories 30 | 31 | 00000000-0000-0000-0000-000000000000 32 | MyFactoryFunction 33 | 34 | CFPlugInTypes 35 | 36 | 00000000-0000-0000-0000-000000000000 37 | 38 | 00000000-0000-0000-0000-000000000000 39 | 40 | 41 | CFPlugInUnloadFunction 42 | 43 | DTCompiler 44 | 45 | DTPlatformBuild 46 | 4A304a 47 | DTPlatformVersion 48 | GM 49 | DTSDKBuild 50 | 4A304a 51 | DTSDKName 52 | macosx10.6 53 | DTXcode 54 | 0400 55 | DTXcodeBuild 56 | 4A304a 57 | WebPluginDescription 58 | A browser agnostic NPAPI interface to GnuPG 59 | WebPluginMIMETypes 60 | 61 | application/x-gmailgpg 62 | 63 | WebPluginExtensions 64 | 65 | 66 | 67 | WebPluginTypeDescription 68 | A browser agnostic NPAPI interface to GnuPG 69 | 70 | 71 | WebPluginName 72 | WebPG 73 | 74 | 75 | -------------------------------------------------------------------------------- /chromeExtension/options.js: -------------------------------------------------------------------------------- 1 | function getVersion() { 2 | if(chrome.app.getDetails()){ 3 | return chrome.app.getDetails().version; 4 | }else{ 5 | return '' 6 | }; 7 | }; 8 | chrome.extension.onRequest.addListener( 9 | function(request, sender, sendResponse) { 10 | if(request.messageType == 'alertUser'){ 11 | if(!request.gpg){ 12 | alert('No gpg path has been set , please update via the options page for the cr-gpg'); 13 | top.userAlerted = true; 14 | } 15 | if(!request.temp && !userAlerted){ 16 | alert('No temp path has been set , please update via the options page for the cr-gpg'); 17 | top.userAlerted = true; 18 | } 19 | } 20 | }); 21 | 22 | // Saves options to localStorage. 23 | function save_options() { 24 | localStorage["useAutoInclude"] = $('#useAutoInclude')[0].checked; 25 | if(localStorage["useAutoInclude"] != 'false'){ 26 | if($('#personaladdress').val() != ''){ 27 | localStorage["personaladdress"] = $('#personaladdress').val(); 28 | }else{ 29 | alert('You have ticked self sign but not provided a email address'); 30 | return; 31 | } 32 | }; 33 | localStorage["signingKeyID"] = $('#signingKeyID').val(); 34 | 35 | alert('Saved'); 36 | }; 37 | 38 | // Restores select box state to saved value from localStorage. 39 | function restore_options() { 40 | var tempPath = document.getElementById("tempPath"); 41 | if(localStorage["tempPath"]){ 42 | tempPath.value = localStorage["tempPath"]; 43 | }; 44 | if(localStorage["useAutoInclude"] && localStorage["useAutoInclude"] != 'false'){ 45 | $('#useAutoInclude')[0].checked = true; 46 | }; 47 | $('#signingKeyID').val(localStorage["signingKeyID"]); 48 | $('#personaladdress').val(localStorage["personaladdress"]); 49 | }; 50 | 51 | function restore_temp_default() { 52 | var tempPath = document.getElementById("tempPath"); 53 | switch($.client.os){ 54 | case 'Mac' : 55 | tempPath.value = '/tmp/'; 56 | break; 57 | case 'Windows' : 58 | tempPath.value = 'C:\\temp\\'; 59 | break; 60 | case 'Linux' : 61 | tempPath.value = '/tmp/'; 62 | break; 63 | } 64 | }; 65 | 66 | $(document).ready(function(){ 67 | $( "#tabs" ).tabs(); 68 | $('#saveButton').click(save_options); 69 | restore_options(); 70 | $('#version').text(getVersion()); 71 | }); 72 | -------------------------------------------------------------------------------- /chromeExtension/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | GPG Options 12 | 13 | 14 |
15 |
16 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
Encrypt to self :
Encrypt to self Email Address :
Signing KeyID:
33 | 34 | 35 |
36 |
37 |
38 | 39 |
Cr-gpg (Version : )
40 |
This plugin is Alpha
41 |

Cr-gpg is a quick hack to allow you to use common cryptographic functionality (provided by gpg) inside Gmail. 42 | It uses firebreath for browser compatability. 43 | (We said it was a quick hack!) 44 |

45 | Hacked together by: jameel@thinkst.com
46 | Grab new versions at: http://thinkst.com/tools/cr-gpg
47 |


48 |
49 |
home | blog |Copyright © 2012 - thinkst.com
50 |
51 | 52 | 53 |
54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /gmailGPG/generic/Win/projectDef.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # Auto-generated Windows project definition file for the 3 | # gmailGPG project 4 | #\**********************************************************/ 5 | 6 | # Windows template platform definition CMake file 7 | # Included from ../CMakeLists.txt 8 | 9 | # remember that the current source dir is the project root; this file is in Win/ 10 | file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 11 | Win/[^.]*.cpp 12 | Win/[^.]*.h 13 | Win/[^.]*.cmake 14 | ) 15 | 16 | # use this to add preprocessor definitions 17 | add_definitions( 18 | /D "_ATL_STATIC_REGISTRY" 19 | ) 20 | 21 | SOURCE_GROUP(Win FILES ${PLATFORM}) 22 | 23 | set (SOURCES 24 | ${SOURCES} 25 | ${PLATFORM} 26 | ) 27 | 28 | add_windows_plugin(${PROJECT_NAME} SOURCES) 29 | 30 | # This is an example of how to add a build step to sign the plugin DLL before 31 | # the WiX installer builds. The first filename (certificate.pfx) should be 32 | # the path to your pfx file. If it requires a passphrase, the passphrase 33 | # should be located inside the second file. If you don't need a passphrase 34 | # then set the second filename to "". If you don't want signtool to timestamp 35 | # your DLL then make the last parameter "". 36 | # 37 | # Note that this will not attempt to sign if the certificate isn't there -- 38 | # that's so that you can have development machines without the cert and it'll 39 | # still work. Your cert should only be on the build machine and shouldn't be in 40 | # source control! 41 | # -- uncomment lines below this to enable signing -- 42 | #firebreath_sign_plugin(${PROJECT_NAME} 43 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/certificate.pfx" 44 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/passphrase.txt" 45 | # "http://timestamp.verisign.com/scripts/timestamp.dll") 46 | 47 | # add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing! 48 | target_link_libraries(${PROJECT_NAME} 49 | ${PLUGIN_INTERNAL_DEPS} 50 | ) 51 | 52 | set(WIX_HEAT_FLAGS 53 | -gg # Generate GUIDs 54 | -srd # Suppress Root Dir 55 | -cg PluginDLLGroup # Set the Component group name 56 | -dr INSTALLDIR # Set the directory ID to put the files in 57 | ) 58 | 59 | add_wix_installer( ${PLUGIN_NAME} 60 | ${CMAKE_CURRENT_SOURCE_DIR}/Win/WiX/gmailGPGInstaller.wxs 61 | PluginDLLGroup 62 | ${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/ 63 | ${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/${FBSTRING_PluginFileName}.dll 64 | ${PROJECT_NAME} 65 | ) 66 | 67 | # This is an example of how to add a build step to sign the WiX installer 68 | # -- uncomment lines below this to enable signing -- 69 | #firebreath_sign_file("${PLUGIN_NAME}_WiXInstall" 70 | # "${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/${PLUGIN_NAME}.msi" 71 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/certificate.pfx" 72 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/passphrase.txt" 73 | # "http://timestamp.verisign.com/scripts/timestamp.dll") 74 | -------------------------------------------------------------------------------- /gmailGPG/windows/Win/projectDef.cmake: -------------------------------------------------------------------------------- 1 | #/**********************************************************\ 2 | # Auto-generated Windows project definition file for the 3 | # gmailGPG project 4 | #\**********************************************************/ 5 | 6 | # Windows template platform definition CMake file 7 | # Included from ../CMakeLists.txt 8 | 9 | # remember that the current source dir is the project root; this file is in Win/ 10 | file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 11 | Win/[^.]*.cpp 12 | Win/[^.]*.h 13 | Win/[^.]*.cmake 14 | ) 15 | 16 | # use this to add preprocessor definitions 17 | add_definitions( 18 | /D "_ATL_STATIC_REGISTRY" 19 | ) 20 | 21 | SOURCE_GROUP(Win FILES ${PLATFORM}) 22 | 23 | set (SOURCES 24 | ${SOURCES} 25 | ${PLATFORM} 26 | ) 27 | 28 | add_windows_plugin(${PROJECT_NAME} SOURCES) 29 | 30 | # This is an example of how to add a build step to sign the plugin DLL before 31 | # the WiX installer builds. The first filename (certificate.pfx) should be 32 | # the path to your pfx file. If it requires a passphrase, the passphrase 33 | # should be located inside the second file. If you don't need a passphrase 34 | # then set the second filename to "". If you don't want signtool to timestamp 35 | # your DLL then make the last parameter "". 36 | # 37 | # Note that this will not attempt to sign if the certificate isn't there -- 38 | # that's so that you can have development machines without the cert and it'll 39 | # still work. Your cert should only be on the build machine and shouldn't be in 40 | # source control! 41 | # -- uncomment lines below this to enable signing -- 42 | #firebreath_sign_plugin(${PROJECT_NAME} 43 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/certificate.pfx" 44 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/passphrase.txt" 45 | # "http://timestamp.verisign.com/scripts/timestamp.dll") 46 | 47 | # add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing! 48 | target_link_libraries(${PROJECT_NAME} 49 | ${PLUGIN_INTERNAL_DEPS} 50 | ) 51 | 52 | set(WIX_HEAT_FLAGS 53 | -gg # Generate GUIDs 54 | -srd # Suppress Root Dir 55 | -cg PluginDLLGroup # Set the Component group name 56 | -dr INSTALLDIR # Set the directory ID to put the files in 57 | ) 58 | 59 | add_wix_installer( ${PLUGIN_NAME} 60 | ${CMAKE_CURRENT_SOURCE_DIR}/Win/WiX/gmailGPGInstaller.wxs 61 | PluginDLLGroup 62 | ${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/ 63 | ${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/${FBSTRING_PluginFileName}.dll 64 | ${PROJECT_NAME} 65 | ) 66 | 67 | # This is an example of how to add a build step to sign the WiX installer 68 | # -- uncomment lines below this to enable signing -- 69 | #firebreath_sign_file("${PLUGIN_NAME}_WiXInstall" 70 | # "${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/${PLUGIN_NAME}.msi" 71 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/certificate.pfx" 72 | # "${CMAKE_CURRENT_SOURCE_DIR}/sign/passphrase.txt" 73 | # "http://timestamp.verisign.com/scripts/timestamp.dll") 74 | -------------------------------------------------------------------------------- /chromeExtension/jquery.client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var BrowserDetect = { 4 | init: function () { 5 | this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; 6 | this.version = this.searchVersion(navigator.userAgent) 7 | || this.searchVersion(navigator.appVersion) 8 | || "an unknown version"; 9 | this.OS = this.searchString(this.dataOS) || "an unknown OS"; 10 | }, 11 | searchString: function (data) { 12 | for (var i=0;i 2 | 3 | 4 | 5 | 6 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 34 | 35 | 36 | 43 | 44 | 45 | 46 | 47 | 54 | 55 | 56 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /gmailGPG/windows/Win/WiX/gmailGPGInstaller.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 34 | 35 | 36 | 43 | 44 | 45 | 46 | 47 | 54 | 55 | 56 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /chromeExtension/general.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 |
11 |
12 | 18 |
19 |
To import a users key, paste the ascii armored key below

20 |
21 |

22 | 23 |
24 |
home | blog |Copyright © 2012 - thinkst.com
25 |
26 |
27 |
Encrypt Text
28 |
29 | Recipients (comma separated) : 30 |
31 |

32 | 33 |
34 |
home |blog |Copyright © 2012 - thinkst.com
35 |
36 |
37 |
Sign Message
38 |
39 | Password : 40 |
41 | 42 | 43 |
44 | 45 | 46 |
47 |
home |blog |Copyright © 2012 - thinkst.com
48 |
49 |
50 |
Decrypt Message
51 |
52 | Password : 53 |
54 | 55 |
56 | 57 |
58 |
home |blog |Copyright © 2012 - thinkst.com
59 |
60 | 61 | 62 |
63 |
64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /chromeExtension/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 |
12 |
13 | 19 |
20 |
To import a users key, paste the ascii armored key below

21 |
22 |

23 | 24 |
25 |
home | blog |Copyright © 2012 - thinkst.com
26 |
27 |
28 |
Encrypt Text
29 |
30 | Recipients (comma separated) : 31 |
32 |

33 | 34 |
35 |
home |blog |Copyright © 2012 - thinkst.com
36 |
37 |
38 |
Sign Message
39 |
40 | 41 |
42 | 43 | 44 |
45 |
home |blog |Copyright © 2012 - thinkst.com
46 |
47 | 48 |
49 |
50 | 51 |
Cr-gpg (Version : )
52 |
This plugin is Beta
53 |

Cr-gpg is a quick hack to allow you to use common cryptographic functionality (provided by gpg) inside Gmail. 54 | It uses firebreath for browser compatability and doesnt use GPGME! 55 | (We said it was a quick hack!) 56 |

57 | Hacked together by: jameel@thinkst.com
58 | Grab new versions at: http://thinkst.com/tools/cr-gpg
59 |


60 |
61 |
home | blog |Copyright © 2012 - thinkst.com
62 |
63 | 64 |
65 |
66 |
67 | 68 | 69 | -------------------------------------------------------------------------------- /gmailGPG/generic/gmailGPG.cpp: -------------------------------------------------------------------------------- 1 | /**********************************************************\ 2 | 3 | Auto-generated gmailGPG.cpp 4 | 5 | This file contains the auto-generated main plugin object 6 | implementation for the gmailGPG project 7 | 8 | \**********************************************************/ 9 | 10 | #include "gmailGPGAPI.h" 11 | 12 | #include "gmailGPG.h" 13 | 14 | /////////////////////////////////////////////////////////////////////////////// 15 | /// @fn gmailGPG::StaticInitialize() 16 | /// 17 | /// @brief Called from PluginFactory::globalPluginInitialize() 18 | /// 19 | /// @see FB::FactoryBase::globalPluginInitialize 20 | /////////////////////////////////////////////////////////////////////////////// 21 | void gmailGPG::StaticInitialize() 22 | { 23 | // Place one-time initialization stuff here; As of FireBreath 1.4 this should only 24 | // be called once per process 25 | } 26 | 27 | /////////////////////////////////////////////////////////////////////////////// 28 | /// @fn gmailGPG::StaticInitialize() 29 | /// 30 | /// @brief Called from PluginFactory::globalPluginDeinitialize() 31 | /// 32 | /// @see FB::FactoryBase::globalPluginDeinitialize 33 | /////////////////////////////////////////////////////////////////////////////// 34 | void gmailGPG::StaticDeinitialize() 35 | { 36 | // Place one-time deinitialization stuff here. As of FireBreath 1.4 this should 37 | // always be called just before the plugin library is unloaded 38 | } 39 | 40 | /////////////////////////////////////////////////////////////////////////////// 41 | /// @brief gmailGPG constructor. Note that your API is not available 42 | /// at this point, nor the window. For best results wait to use 43 | /// the JSAPI object until the onPluginReady method is called 44 | /////////////////////////////////////////////////////////////////////////////// 45 | gmailGPG::gmailGPG() 46 | { 47 | } 48 | 49 | /////////////////////////////////////////////////////////////////////////////// 50 | /// @brief gmailGPG destructor. 51 | /////////////////////////////////////////////////////////////////////////////// 52 | gmailGPG::~gmailGPG() 53 | { 54 | // This is optional, but if you reset m_api (the shared_ptr to your JSAPI 55 | // root object) and tell the host to free the retained JSAPI objects then 56 | // unless you are holding another shared_ptr reference to your JSAPI object 57 | // they will be released here. 58 | releaseRootJSAPI(); 59 | m_host->freeRetainedObjects(); 60 | } 61 | 62 | void gmailGPG::onPluginReady() 63 | { 64 | // When this is called, the BrowserHost is attached, the JSAPI object is 65 | // created, and we are ready to interact with the page and such. The 66 | // PluginWindow may or may not have already fire the AttachedEvent at 67 | // this point. 68 | } 69 | 70 | void gmailGPG::shutdown() 71 | { 72 | // This will be called when it is time for the plugin to shut down; 73 | // any threads or anything else that may hold a shared_ptr to this 74 | // object should be released here so that this object can be safely 75 | // destroyed. This is the last point that shared_from_this and weak_ptr 76 | // references to this object will be valid 77 | } 78 | 79 | /////////////////////////////////////////////////////////////////////////////// 80 | /// @brief Creates an instance of the JSAPI object that provides your main 81 | /// Javascript interface. 82 | /// 83 | /// Note that m_host is your BrowserHost and shared_ptr returns a 84 | /// FB::PluginCorePtr, which can be used to provide a 85 | /// boost::weak_ptr for your JSAPI class. 86 | /// 87 | /// Be very careful where you hold a shared_ptr to your plugin class from, 88 | /// as it could prevent your plugin class from getting destroyed properly. 89 | /////////////////////////////////////////////////////////////////////////////// 90 | FB::JSAPIPtr gmailGPG::createJSAPI() 91 | { 92 | // m_host is the BrowserHost 93 | return boost::make_shared(FB::ptr_cast(shared_from_this()), m_host); 94 | } 95 | 96 | bool gmailGPG::onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *) 97 | { 98 | //printf("Mouse down at: %d, %d\n", evt->m_x, evt->m_y); 99 | return false; 100 | } 101 | 102 | bool gmailGPG::onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *) 103 | { 104 | //printf("Mouse up at: %d, %d\n", evt->m_x, evt->m_y); 105 | return false; 106 | } 107 | 108 | bool gmailGPG::onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *) 109 | { 110 | //printf("Mouse move at: %d, %d\n", evt->m_x, evt->m_y); 111 | return false; 112 | } 113 | bool gmailGPG::onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *) 114 | { 115 | // The window is attached; act appropriately 116 | return false; 117 | } 118 | 119 | bool gmailGPG::onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *) 120 | { 121 | // The window is about to be detached; act appropriately 122 | return false; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /gmailGPG/windows/gmailGPG.cpp: -------------------------------------------------------------------------------- 1 | /**********************************************************\ 2 | 3 | Auto-generated gmailGPG.cpp 4 | 5 | This file contains the auto-generated main plugin object 6 | implementation for the gmailGPG project 7 | 8 | \**********************************************************/ 9 | 10 | #include "gmailGPGAPI.h" 11 | 12 | #include "gmailGPG.h" 13 | 14 | /////////////////////////////////////////////////////////////////////////////// 15 | /// @fn gmailGPG::StaticInitialize() 16 | /// 17 | /// @brief Called from PluginFactory::globalPluginInitialize() 18 | /// 19 | /// @see FB::FactoryBase::globalPluginInitialize 20 | /////////////////////////////////////////////////////////////////////////////// 21 | void gmailGPG::StaticInitialize() 22 | { 23 | // Place one-time initialization stuff here; As of FireBreath 1.4 this should only 24 | // be called once per process 25 | } 26 | 27 | /////////////////////////////////////////////////////////////////////////////// 28 | /// @fn gmailGPG::StaticInitialize() 29 | /// 30 | /// @brief Called from PluginFactory::globalPluginDeinitialize() 31 | /// 32 | /// @see FB::FactoryBase::globalPluginDeinitialize 33 | /////////////////////////////////////////////////////////////////////////////// 34 | void gmailGPG::StaticDeinitialize() 35 | { 36 | // Place one-time deinitialization stuff here. As of FireBreath 1.4 this should 37 | // always be called just before the plugin library is unloaded 38 | } 39 | 40 | /////////////////////////////////////////////////////////////////////////////// 41 | /// @brief gmailGPG constructor. Note that your API is not available 42 | /// at this point, nor the window. For best results wait to use 43 | /// the JSAPI object until the onPluginReady method is called 44 | /////////////////////////////////////////////////////////////////////////////// 45 | gmailGPG::gmailGPG() 46 | { 47 | } 48 | 49 | /////////////////////////////////////////////////////////////////////////////// 50 | /// @brief gmailGPG destructor. 51 | /////////////////////////////////////////////////////////////////////////////// 52 | gmailGPG::~gmailGPG() 53 | { 54 | // This is optional, but if you reset m_api (the shared_ptr to your JSAPI 55 | // root object) and tell the host to free the retained JSAPI objects then 56 | // unless you are holding another shared_ptr reference to your JSAPI object 57 | // they will be released here. 58 | releaseRootJSAPI(); 59 | m_host->freeRetainedObjects(); 60 | } 61 | 62 | void gmailGPG::onPluginReady() 63 | { 64 | // When this is called, the BrowserHost is attached, the JSAPI object is 65 | // created, and we are ready to interact with the page and such. The 66 | // PluginWindow may or may not have already fire the AttachedEvent at 67 | // this point. 68 | } 69 | 70 | void gmailGPG::shutdown() 71 | { 72 | // This will be called when it is time for the plugin to shut down; 73 | // any threads or anything else that may hold a shared_ptr to this 74 | // object should be released here so that this object can be safely 75 | // destroyed. This is the last point that shared_from_this and weak_ptr 76 | // references to this object will be valid 77 | } 78 | 79 | /////////////////////////////////////////////////////////////////////////////// 80 | /// @brief Creates an instance of the JSAPI object that provides your main 81 | /// Javascript interface. 82 | /// 83 | /// Note that m_host is your BrowserHost and shared_ptr returns a 84 | /// FB::PluginCorePtr, which can be used to provide a 85 | /// boost::weak_ptr for your JSAPI class. 86 | /// 87 | /// Be very careful where you hold a shared_ptr to your plugin class from, 88 | /// as it could prevent your plugin class from getting destroyed properly. 89 | /////////////////////////////////////////////////////////////////////////////// 90 | FB::JSAPIPtr gmailGPG::createJSAPI() 91 | { 92 | // m_host is the BrowserHost 93 | return boost::make_shared(FB::ptr_cast(shared_from_this()), m_host); 94 | } 95 | 96 | bool gmailGPG::onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *) 97 | { 98 | //printf("Mouse down at: %d, %d\n", evt->m_x, evt->m_y); 99 | return false; 100 | } 101 | 102 | bool gmailGPG::onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *) 103 | { 104 | //printf("Mouse up at: %d, %d\n", evt->m_x, evt->m_y); 105 | return false; 106 | } 107 | 108 | bool gmailGPG::onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *) 109 | { 110 | //printf("Mouse move at: %d, %d\n", evt->m_x, evt->m_y); 111 | return false; 112 | } 113 | bool gmailGPG::onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *) 114 | { 115 | // The window is attached; act appropriately 116 | return false; 117 | } 118 | 119 | bool gmailGPG::onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *) 120 | { 121 | // The window is about to be detached; act appropriately 122 | return false; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /chromeExtension/background.js: -------------------------------------------------------------------------------- 1 | var alerted = false; 2 | function plugin0() 3 | { 4 | return document.getElementById('plugin0'); 5 | } 6 | 7 | chrome.extension.onRequest.addListener( 8 | function(request, sender, sendResponse) { 9 | if (request.messageType == 'encrypt'){ 10 | var mailList = request.encrypt.maillist; 11 | if( localStorage["useAutoInclude"] && localStorage["useAutoInclude"] != 'false'){ 12 | mailList.push(localStorage["personaladdress"]); 13 | } 14 | var mailMessage = request.encrypt.message; 15 | var currentPubKeyList = []; 16 | var list = plugin0().getPublicKeyList(); 17 | for(var k in list) 18 | { 19 | currentPubKeyList.push(list[k].email); 20 | } 21 | for(var encRec in mailList) 22 | { 23 | if(currentPubKeyList.indexOf(mailList[encRec]) == -1){ 24 | sendResponse({error:true,message: 'You do not have a public key stored for '+mailList[encRec] + ' please remove the user or import their public key',domid:request.encrypt.domel}); 25 | return; 26 | } 27 | 28 | } 29 | 30 | var enc_result = plugin0().gpgEncrypt(mailMessage, mailList, '', ''); 31 | if(!enc_result.error && enc_result.data){ 32 | sendResponse({message: enc_result.data,domid:request.encrypt.domel}); 33 | }else{ 34 | sendResponse({error:true,message: enc_result.error_string,domid:request.encrypt.domel}); 35 | }; 36 | }else if(request.messageType == 'importkey'){ 37 | var import_status = plugin0().gpgImportKey(request.import.message); 38 | sendResponse({message: import_status}); 39 | }else if(request.messageType == 'sign'){ 40 | var signing_key = ''; 41 | var privKeySet = plugin0().getPrivateKeyList(); 42 | var keyIDs = Object.keys(privKeySet); 43 | if(keyIDs.length > 0){ 44 | if(localStorage["signingKeyID"] && localStorage["signingKeyID"] != ''){ 45 | if(keyIDs.indexOf(localStorage["signingKeyID"]) != -1){ 46 | signing_key = localStorage["signingKeyID"]; 47 | }else{ 48 | if(request.sign.currentMail){ 49 | for(var sKey in privKeySet){ 50 | if(privKeySet[sKey].email == request.sign.currentMail){ 51 | signing_key = sKey; 52 | break; 53 | }; 54 | }; 55 | if(signing_key == ''){ 56 | signing_key = keyIDs[0]; 57 | }; 58 | }else{ 59 | signing_key = keyIDs[0]; 60 | }; 61 | 62 | }; 63 | }else{ 64 | if(request.sign.currentMail){ 65 | for(var sKey in privKeySet){ 66 | if(privKeySet[sKey].email == request.sign.currentMail){ 67 | signing_key = sKey; 68 | break; 69 | }; 70 | }; 71 | if(signing_key == ''){ 72 | signing_key = keyIDs[0]; 73 | }; 74 | }else{ 75 | signing_key = keyIDs[0]; 76 | }; 77 | }; 78 | }; 79 | var sign_status = plugin0().gpgSignText([signing_key],request.sign.message, 2); 80 | sendResponse({message: sign_status,domid:request.sign.domel}); 81 | }else if(request.messageType == 'verify'){ 82 | var verify_status = plugin0().gpgVerify(request.verify.message); 83 | sendResponse({message: verify_status ,domid:request.verify.domel}) 84 | }else if(request.messageType == 'verifyDetached'){ 85 | sendResponse({message:'Not Yet Support',domid:request.verify.domel}); 86 | //sendResponse({message: plugin0().verifyMessageDetached(request.verify.message,request.verify.sig),domid:request.verify.domel}); 87 | }else if(request.messageType == 'decrypt'){ 88 | //TODO : Make sure you handle the multidec call which handles encryption within encryption 89 | var dec_result = plugin0().gpgDecrypt(request.decrypt.message); 90 | if(!dec_result.error){ 91 | sendResponse({message: dec_result.data,domid:request.decrypt.domel}); 92 | }else{ 93 | sendResponse({message: 'An Error Occured',domid:request.decrypt.domel}); 94 | }; 95 | }else if(request.messageType == 'optionLoad'){ 96 | chrome.tabs.create({'selected':true,'url': chrome.extension.getURL('options.html')}); 97 | sendResponse('options opened'); 98 | }else if(request.messageType == 'testSettings'){ 99 | var returnMessage = plugin0().getPublicKeyList(); 100 | sendResponse(returnMessage); 101 | } 102 | } 103 | ); 104 | -------------------------------------------------------------------------------- /gmailGPG/generic/t-support.h: -------------------------------------------------------------------------------- 1 | /* t-support.h - Helper routines for regression tests. 2 | Copyright (C) 2000 Werner Koch (dd9jn) 3 | Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH 4 | 5 | This file is part of GPGME. 6 | 7 | GPGME is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | GPGME is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef HAVE_W32_SYSTEM 28 | #include 29 | #endif 30 | 31 | #include 32 | 33 | #ifndef DIM 34 | #define DIM(v) (sizeof(v)/sizeof((v)[0])) 35 | #endif 36 | 37 | #define fail_if_err(err) \ 38 | do \ 39 | { \ 40 | if (err) \ 41 | { \ 42 | fprintf (stderr, "%s:%d: %s: %s\n", \ 43 | __FILE__, __LINE__, gpgme_strsource (err), \ 44 | gpgme_strerror (err)); \ 45 | exit (1); \ 46 | } \ 47 | } \ 48 | while (0) 49 | 50 | 51 | static const char * 52 | nonnull (const char *s) 53 | { 54 | return s? s :"[none]"; 55 | } 56 | 57 | 58 | std::string 59 | print_data (gpgme_data_t dh) 60 | { 61 | #define BUF_SIZE 512 62 | char buf[BUF_SIZE + 1]; 63 | int ret; 64 | std::string rtd = ""; 65 | 66 | ret = gpgme_data_seek (dh, 0, SEEK_SET); 67 | if (ret) 68 | fail_if_err(gpgme_err_code_from_errno (errno)); 69 | while ((ret = gpgme_data_read (dh, buf, BUF_SIZE)) > 0) 70 | rtd.append(buf); 71 | 72 | return rtd; 73 | } 74 | 75 | 76 | gpgme_error_t 77 | passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info, 78 | int last_was_bad, int fd) 79 | { 80 | #ifdef HAVE_W32_SYSTEM 81 | DWORD written; 82 | WriteFile ((HANDLE) fd, "abc\n", 4, &written, 0); 83 | #else 84 | int res; 85 | char *pass = "abc\n"; 86 | int passlen = strlen (pass); 87 | int off = 0; 88 | 89 | do 90 | { 91 | res = write (fd, &pass[off], passlen - off); 92 | if (res > 0) 93 | off += res; 94 | } 95 | while (res > 0 && off != passlen); 96 | 97 | return off == passlen ? 0 : gpgme_error_from_errno (errno); 98 | #endif 99 | 100 | return 0; 101 | } 102 | 103 | 104 | /*char * 105 | make_filename (const char *fname) 106 | { 107 | const char *srcdir = getenv ("srcdir"); 108 | char *buf; 109 | 110 | if (!srcdir) 111 | srcdir = "."; 112 | buf = malloc (strlen(srcdir) + strlen(fname) + 2); 113 | if (!buf) 114 | exit (8); 115 | strcpy (buf, srcdir); 116 | strcat (buf, "/"); 117 | strcat (buf, fname); 118 | return buf; 119 | } 120 | */ 121 | 122 | void 123 | init_gpgme (gpgme_protocol_t proto) 124 | { 125 | gpgme_error_t err; 126 | 127 | gpgme_check_version (NULL); 128 | setlocale (LC_ALL, ""); 129 | gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); 130 | #ifndef HAVE_W32_SYSTEM 131 | gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); 132 | #endif 133 | 134 | err = gpgme_engine_check_version (proto); 135 | fail_if_err (err); 136 | } 137 | 138 | 139 | void 140 | print_import_result (gpgme_import_result_t r) 141 | { 142 | gpgme_import_status_t st; 143 | 144 | for (st=r->imports; st; st = st->next) 145 | { 146 | printf (" fpr: %s err: %d (%s) status:", nonnull (st->fpr), 147 | st->result, gpg_strerror (st->result)); 148 | if (st->status & GPGME_IMPORT_NEW) 149 | fputs (" new", stdout); 150 | if (st->status & GPGME_IMPORT_UID) 151 | fputs (" uid", stdout); 152 | if (st->status & GPGME_IMPORT_SIG) 153 | fputs (" sig", stdout); 154 | if (st->status & GPGME_IMPORT_SUBKEY) 155 | fputs (" subkey", stdout); 156 | if (st->status & GPGME_IMPORT_SECRET) 157 | fputs (" secret", stdout); 158 | putchar ('\n'); 159 | } 160 | printf ("key import summary:\n" 161 | " considered: %d\n" 162 | " no user id: %d\n" 163 | " imported: %d\n" 164 | " imported_rsa: %d\n" 165 | " unchanged: %d\n" 166 | " new user ids: %d\n" 167 | " new subkeys: %d\n" 168 | " new signatures: %d\n" 169 | " new revocations: %d\n" 170 | " secret read: %d\n" 171 | " secret imported: %d\n" 172 | " secret unchanged: %d\n" 173 | " skipped new keys: %d\n" 174 | " not imported: %d\n", 175 | r->considered, 176 | r->no_user_id, 177 | r->imported, 178 | r->imported_rsa, 179 | r->unchanged, 180 | r->new_user_ids, 181 | r->new_sub_keys, 182 | r->new_signatures, 183 | r->new_revocations, 184 | r->secret_read, 185 | r->secret_imported, 186 | r->secret_unchanged, 187 | r->skipped_new_keys, 188 | r->not_imported); 189 | } 190 | 191 | -------------------------------------------------------------------------------- /chromeExtension/jquery-ui-1.8.13.custom.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI Dialog 1.8.13 3 | * 4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * http://jquery.org/license 7 | * 8 | * http://docs.jquery.com/UI/Dialog 9 | * 10 | * Depends: 11 | * jquery.ui.core.js 12 | * jquery.ui.widget.js 13 | * jquery.ui.button.js 14 | * jquery.ui.draggable.js 15 | * jquery.ui.mouse.js 16 | * jquery.ui.position.js 17 | * jquery.ui.resizable.js 18 | */ 19 | (function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false, 20 | position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ 21 | b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), 22 | h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id", 23 | e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); 24 | a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== 25 | b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+= 26 | 1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== 27 | f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("
").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("
").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a, 28 | function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", 29 | handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition, 30 | originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize", 31 | f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "): 32 | [a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f); 33 | if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"): 34 | e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a= 35 | this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height- 36 | b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.13",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "), 37 | create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()
").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(), 38 | height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight); 39 | b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a", 174 | options: { 175 | disabled: false, 176 | 177 | // callbacks 178 | create: null 179 | }, 180 | _createWidget: function( options, element ) { 181 | element = $( element || this.defaultElement || this )[ 0 ]; 182 | this.element = $( element ); 183 | this.options = $.widget.extend( {}, 184 | this.options, 185 | this._getCreateOptions(), 186 | options ); 187 | 188 | this.bindings = $(); 189 | this.hoverable = $(); 190 | this.focusable = $(); 191 | 192 | if ( element !== this ) { 193 | $.data( element, this.widgetName, this ); 194 | this._bind({ remove: "destroy" }); 195 | } 196 | 197 | this._create(); 198 | this._trigger( "create" ); 199 | this._init(); 200 | }, 201 | _getCreateOptions: $.noop, 202 | _create: $.noop, 203 | _init: $.noop, 204 | 205 | destroy: function() { 206 | this._destroy(); 207 | // we can probably remove the unbind calls in 2.0 208 | // all event bindings should go through this._bind() 209 | this.element 210 | .unbind( "." + this.widgetName ) 211 | .removeData( this.widgetName ); 212 | this.widget() 213 | .unbind( "." + this.widgetName ) 214 | .removeAttr( "aria-disabled" ) 215 | .removeClass( 216 | this.widgetBaseClass + "-disabled " + 217 | "ui-state-disabled" ); 218 | 219 | // clean up events and states 220 | this.bindings.unbind( "." + this.widgetName ); 221 | this.hoverable.removeClass( "ui-state-hover" ); 222 | this.focusable.removeClass( "ui-state-focus" ); 223 | }, 224 | _destroy: $.noop, 225 | 226 | widget: function() { 227 | return this.element; 228 | }, 229 | 230 | option: function( key, value ) { 231 | var options = key, 232 | parts, 233 | curOption, 234 | i; 235 | 236 | if ( arguments.length === 0 ) { 237 | // don't return a reference to the internal hash 238 | return $.widget.extend( {}, this.options ); 239 | } 240 | 241 | if ( typeof key === "string" ) { 242 | // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 243 | options = {}; 244 | parts = key.split( "." ); 245 | key = parts.shift(); 246 | if ( parts.length ) { 247 | curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 248 | for ( i = 0; i < parts.length - 1; i++ ) { 249 | curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 250 | curOption = curOption[ parts[ i ] ]; 251 | } 252 | key = parts.pop(); 253 | if ( value === undefined ) { 254 | return curOption[ key ] === undefined ? null : curOption[ key ]; 255 | } 256 | curOption[ key ] = value; 257 | } else { 258 | if ( value === undefined ) { 259 | return this.options[ key ] === undefined ? null : this.options[ key ]; 260 | } 261 | options[ key ] = value; 262 | } 263 | } 264 | 265 | this._setOptions( options ); 266 | 267 | return this; 268 | }, 269 | _setOptions: function( options ) { 270 | var self = this; 271 | $.each( options, function( key, value ) { 272 | self._setOption( key, value ); 273 | }); 274 | 275 | return this; 276 | }, 277 | _setOption: function( key, value ) { 278 | this.options[ key ] = value; 279 | 280 | if ( key === "disabled" ) { 281 | this.widget() 282 | .toggleClass( this.widgetBaseClass + "-disabled ui-state-disabled", !!value ) 283 | .attr( "aria-disabled", value ); 284 | this.hoverable.removeClass( "ui-state-hover" ); 285 | this.focusable.removeClass( "ui-state-focus" ); 286 | } 287 | 288 | return this; 289 | }, 290 | 291 | enable: function() { 292 | return this._setOption( "disabled", false ); 293 | }, 294 | disable: function() { 295 | return this._setOption( "disabled", true ); 296 | }, 297 | 298 | _bind: function( element, handlers ) { 299 | // no element argument, shuffle and use this.element 300 | if ( !handlers ) { 301 | handlers = element; 302 | element = this.element; 303 | } else { 304 | // accept selectors, DOM elements 305 | element = $( element ); 306 | this.bindings = this.bindings.add( element ); 307 | } 308 | var instance = this; 309 | $.each( handlers, function( event, handler ) { 310 | element.bind( event + "." + instance.widgetName, function() { 311 | // allow widgets to customize the disabled handling 312 | // - disabled as an array instead of boolean 313 | // - disabled class as method for disabling individual parts 314 | if ( instance.options.disabled === true || 315 | $( this ).hasClass( "ui-state-disabled" ) ) { 316 | return; 317 | } 318 | return ( typeof handler === "string" ? instance[ handler ] : handler ) 319 | .apply( instance, arguments ); 320 | }); 321 | }); 322 | }, 323 | 324 | _hoverable: function( element ) { 325 | this.hoverable = this.hoverable.add( element ); 326 | this._bind( element, { 327 | mouseenter: function( event ) { 328 | $( event.currentTarget ).addClass( "ui-state-hover" ); 329 | }, 330 | mouseleave: function( event ) { 331 | $( event.currentTarget ).removeClass( "ui-state-hover" ); 332 | } 333 | }); 334 | }, 335 | 336 | _focusable: function( element ) { 337 | this.focusable = this.focusable.add( element ); 338 | this._bind( element, { 339 | focusin: function( event ) { 340 | $( event.currentTarget ).addClass( "ui-state-focus" ); 341 | }, 342 | focusout: function( event ) { 343 | $( event.currentTarget ).removeClass( "ui-state-focus" ); 344 | } 345 | }); 346 | }, 347 | 348 | _trigger: function( type, event, data ) { 349 | var callback = this.options[ type ], 350 | args; 351 | 352 | event = $.Event( event ); 353 | event.type = ( type === this.widgetEventPrefix ? 354 | type : 355 | this.widgetEventPrefix + type ).toLowerCase(); 356 | data = data || {}; 357 | 358 | // copy original event properties over to the new event 359 | // this would happen if we could call $.event.fix instead of $.Event 360 | // but we don't have a way to force an event to be fixed multiple times 361 | if ( event.originalEvent ) { 362 | for ( var i = $.event.props.length, prop; i; ) { 363 | prop = $.event.props[ --i ]; 364 | event[ prop ] = event.originalEvent[ prop ]; 365 | } 366 | } 367 | 368 | this.element.trigger( event, data ); 369 | 370 | args = $.isArray( data ) ? 371 | [ event ].concat( data ) : 372 | [ event, data ]; 373 | 374 | return !( $.isFunction( callback ) && 375 | callback.apply( this.element[0], args ) === false || 376 | event.isDefaultPrevented() ); 377 | } 378 | }; 379 | 380 | $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 381 | $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 382 | if ( typeof options === "string" ) { 383 | options = { effect: options }; 384 | } 385 | var hasOptions, 386 | effectName = !options ? 387 | method : 388 | options === true || typeof options === "number" ? 389 | defaultEffect : 390 | options.effect || defaultEffect; 391 | options = options || {}; 392 | if ( typeof options === "number" ) { 393 | options = { duration: options }; 394 | } 395 | hasOptions = !$.isEmptyObject( options ); 396 | options.complete = callback; 397 | if ( options.delay ) { 398 | element.delay( options.delay ); 399 | } 400 | if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { 401 | element[ method ]( options ); 402 | } else if ( effectName !== method && element[ effectName ] ) { 403 | element[ effectName ]( options.duration, options.easing, callback ); 404 | } else { 405 | element.queue(function( next ) { 406 | $( this )[ method ](); 407 | if ( callback ) { 408 | callback.call( element[ 0 ] ); 409 | } 410 | next(); 411 | }); 412 | } 413 | }; 414 | }); 415 | 416 | // DEPRECATED 417 | if ( $.uiBackCompat !== false ) { 418 | $.Widget.prototype._getCreateOptions = function() { 419 | return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; 420 | }; 421 | } 422 | 423 | })( jQuery ); 424 | -------------------------------------------------------------------------------- /gmailGPG/windows/gmailGPGAPI.cpp: -------------------------------------------------------------------------------- 1 | #include "JSObject.h" 2 | #include "variant_list.h" 3 | #include "DOM/Document.h" 4 | 5 | #include "gmailGPGAPI.h" 6 | 7 | #include 8 | #include 9 | #include 10 | //#include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | 19 | /////////////////////////////////////////////////////////////////////////////// 20 | /// @fn gmailGPGAPI::gmailGPGAPI(const gmailGPGPtr& plugin, const FB::BrowserHostPtr host) 21 | /// 22 | /// @brief Constructor for your JSAPI object. You should register your methods, properties, and events 23 | /// that should be accessible to Javascript from here. 24 | /// 25 | /// @see FB::JSAPIAuto::registerMethod 26 | /// @see FB::JSAPIAuto::registerProperty 27 | /// @see FB::JSAPIAuto::registerEvent 28 | /////////////////////////////////////////////////////////////////////////////// 29 | gmailGPGAPI::gmailGPGAPI(const gmailGPGPtr& plugin, const FB::BrowserHostPtr& host) : m_plugin(plugin), m_host(host) 30 | { 31 | registerMethod("encrypt", make_method(this, &gmailGPGAPI::encryptMessage)); 32 | registerMethod("decrypt", make_method(this, &gmailGPGAPI::decryptMessage)); 33 | registerMethod("importKey", make_method(this, &gmailGPGAPI::importKey)); 34 | registerMethod("listKeys", make_method(this, &gmailGPGAPI::listKeys)); 35 | registerMethod("listPrivateKeys", make_method(this, &gmailGPGAPI::listPrivateKeys)); 36 | registerMethod("clearSignMessage", make_method(this, &gmailGPGAPI::clearSignMessage)); 37 | registerMethod("verifyMessage", make_method(this, &gmailGPGAPI::verifyMessage)); 38 | 39 | registerMethod("testOptions", make_method(this, &gmailGPGAPI::testOptions)); 40 | 41 | // Read-only property 42 | registerProperty("version", 43 | make_property(this, 44 | &gmailGPGAPI::get_version)); 45 | registerProperty("appPath" ,make_property(this,&gmailGPGAPI::get_appPath,&gmailGPGAPI::set_appPath)); 46 | registerProperty("tempPath",make_property(this,&gmailGPGAPI::get_tempPath,&gmailGPGAPI::set_tempPath)); 47 | 48 | } 49 | 50 | gmailGPGAPI::~gmailGPGAPI() 51 | { 52 | } 53 | 54 | //Error handler file , this reads any messages that 55 | //may have been stored in the errorMessage file 56 | //and returns a string with this details to the caller. 57 | //"errorMessage.txt" 58 | std::string gmailGPGAPI::readAndRemoveErrorFile(const std::string fileName) 59 | { 60 | string errorFileLocation = m_tempPath + fileName; 61 | string returnData = ""; 62 | string line; 63 | ifstream myfile; 64 | myfile.open(errorFileLocation.c_str()); 65 | while ( myfile.good() ) 66 | { 67 | getline (myfile,line); 68 | returnData.append(line); 69 | returnData.append("\n"); 70 | } 71 | myfile.close(); 72 | remove(errorFileLocation.c_str()); 73 | return returnData; 74 | } 75 | 76 | gmailGPGPtr gmailGPGAPI::getPlugin() 77 | { 78 | gmailGPGPtr plugin(m_plugin.lock()); 79 | if (!plugin) { 80 | throw FB::script_error("The plugin is invalid"); 81 | } 82 | return plugin; 83 | } 84 | 85 | //Temp Path , this is where temp files are written 86 | std::string gmailGPGAPI::get_tempPath() 87 | { 88 | return m_tempPath; 89 | } 90 | void gmailGPGAPI::set_tempPath(const std::string& val) 91 | { 92 | m_tempPath = val; 93 | } 94 | 95 | //App path , this is where the gpg app can be found 96 | std::string gmailGPGAPI::get_appPath() 97 | { 98 | return m_appPath; 99 | } 100 | void gmailGPGAPI::set_appPath(const std::string& val) 101 | { 102 | m_appPath = val; 103 | } 104 | 105 | std::string gmailGPGAPI::get_version() 106 | { 107 | return "0.5.5"; 108 | } 109 | 110 | void gmailGPGAPI::testEvent(const FB::variant& var) 111 | { 112 | fire_fired(var, true, 1); 113 | } 114 | 115 | string exec(string cmd) { 116 | if (system(NULL)){ 117 | 118 | } 119 | else{ 120 | return (""); 121 | } 122 | 123 | system (cmd.c_str()); 124 | 125 | return ""; 126 | } 127 | 128 | //Encrypts a message with the list of recipients provided 129 | FB::variant gmailGPGAPI::encryptMessage(const FB::variant& recipients,const FB::variant& msg) 130 | { 131 | string tempFileLocation = m_tempPath + "errorMessage.txt"; 132 | string tempOutputLocation = m_tempPath + "outputMessage.txt"; 133 | string gpgFileLocation = "\""+m_appPath +"gpg.exe\" "; 134 | 135 | vector peopleToSendTo = recipients.convert_cast >(); 136 | string cmd = "c:\\windows\\system32\\cmd.exe /c "; 137 | cmd.append(gpgFileLocation); 138 | cmd.append("-e --armor"); 139 | cmd.append(" --trust-model=always"); 140 | for (unsigned int i = 0; i < peopleToSendTo.size(); i++) { 141 | cmd.append(" -r"); 142 | cmd.append(peopleToSendTo.at(i)); 143 | } 144 | cmd.append(" --output "); 145 | cmd.append(tempOutputLocation); 146 | cmd.append(" 2>"); 147 | cmd.append(tempFileLocation); 148 | 149 | sendMessageToCommand(cmd,msg.convert_cast()); 150 | 151 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 152 | string returnData = readAndRemoveErrorFile("outputMessage.txt"); 153 | 154 | string errorMessageChecker; 155 | errorMessageChecker = errorMessage; 156 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 157 | 158 | if(!errorMessageChecker.empty() && returnData.empty()) 159 | { 160 | return errorMessage; 161 | } 162 | 163 | return returnData; 164 | } 165 | 166 | //Decrypts a message using the password provided and the message passed in , this does require 167 | //that you have the private key installed locally. 168 | FB::variant gmailGPGAPI::decryptMessage(const FB::variant& password,const FB::variant& msg) 169 | { 170 | string tempFileLocation = m_tempPath + "tmpMessage.gpg"; 171 | string tempOutputLocation = m_tempPath + "outputMessage.gpg"; 172 | string errorFileLocation = m_tempPath + "errorMessage.txt"; 173 | string gpgFileLocation = "\""+m_appPath +"gpg.exe\" "; 174 | 175 | string cmd = "cmd.exe /c "; 176 | ifstream fin(tempFileLocation.c_str()); 177 | if(fin) 178 | { 179 | fin.close(); 180 | remove(tempFileLocation.c_str()); 181 | } 182 | ofstream encMessageContainer(tempFileLocation.c_str()); 183 | 184 | if (encMessageContainer.is_open()) 185 | { 186 | encMessageContainer << msg.convert_cast().c_str(); 187 | encMessageContainer.close(); 188 | } 189 | 190 | //cmd.append("echo "); 191 | //cmd.append(password.convert_cast()); 192 | //cmd.append(" | "); 193 | cmd.append(gpgFileLocation); 194 | cmd.append(" --no-tty --passphrase-fd 0"); 195 | cmd.append(" -d "); 196 | cmd.append(tempFileLocation); 197 | cmd.append(" 2>"); 198 | cmd.append(errorFileLocation); 199 | 200 | string returnData = getMessageFromCommand(cmd); 201 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 202 | 203 | remove(tempFileLocation.c_str()); 204 | 205 | string errorMessageChecker; 206 | errorMessageChecker = errorMessage; 207 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 208 | 209 | if(!errorMessageChecker.empty() && returnData.empty()) 210 | { 211 | return errorMessage; 212 | } 213 | 214 | return returnData; 215 | } 216 | 217 | string sendMessageToCommand(string command,string message){ 218 | //return command; 219 | FILE *fp; 220 | int status; 221 | char path[200]; 222 | string returnData =""; 223 | 224 | fp = _popen(command.c_str(), "w"); 225 | if (fp == NULL) 226 | return "Unable to open Stream"; 227 | 228 | fputs(message.c_str(),fp); 229 | status = _pclose(fp); 230 | if (status == -1) { 231 | return "stream close error"; 232 | } else { 233 | return returnData; 234 | } 235 | } 236 | 237 | string getMessageFromCommand(string command){ 238 | FILE *fp; 239 | int status; 240 | char path[200]; 241 | fp = _popen(command.c_str(), "r"); 242 | if (fp == NULL) 243 | return ""; 244 | 245 | string returnData = ""; 246 | while (fgets(path, 200, fp) != NULL) 247 | returnData.append(path); 248 | 249 | status = _pclose(fp); 250 | return returnData; 251 | } 252 | 253 | 254 | //Imports a users public key 255 | FB::variant gmailGPGAPI::importKey(const FB::variant& pubKey) 256 | { 257 | string errorFileLocation = m_tempPath + "errorMessage.txt"; 258 | string tempOutputLocation = m_tempPath + "outputMessage.txt"; 259 | string gpgFileLocation = "\""+m_appPath +"gpg.exe\" "; 260 | 261 | string cmd = "cmd.exe /c "; 262 | string tmpFileName = "/tmp/tmpMessage.gpg"; 263 | 264 | cmd.append("echo \""); 265 | cmd.append(pubKey.convert_cast()); 266 | cmd.append("\" | "); 267 | cmd.append(gpgFileLocation); 268 | cmd.append(" --import"); 269 | cmd.append(" 1>"); 270 | cmd.append(tempOutputLocation); 271 | cmd.append(" 2>"); 272 | cmd.append(errorFileLocation); 273 | 274 | exec(cmd); 275 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 276 | string returnData = readAndRemoveErrorFile("errorMessage.txt"); 277 | 278 | string errorMessageChecker; 279 | errorMessageChecker = errorMessage; 280 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 281 | 282 | if(!errorMessageChecker.empty()) 283 | { 284 | return errorMessage; 285 | } 286 | return returnData; 287 | } 288 | 289 | 290 | //Verifies wether a message is ok and has not been tampered with 291 | FB::variant gmailGPGAPI::verifyMessage(const FB::variant& message) 292 | { 293 | string errorFileLocation = m_tempPath + "errorMessage.txt"; 294 | string tempFileLocation = m_tempPath + "tmpMessage.gpg"; 295 | string gpgFileLocation = "\""+m_appPath +"gpg.exe\" "; 296 | 297 | string cmd = "cmd.exe /c "; 298 | cmd.append("echo \""); 299 | cmd.append(message.convert_cast()); 300 | cmd.append("\" | "); 301 | cmd.append(gpgFileLocation); 302 | cmd.append(" --no-tty --verify"); 303 | cmd.append(" 1>"); 304 | cmd.append(tempFileLocation); 305 | cmd.append(" 2>"); 306 | cmd.append(errorFileLocation); 307 | 308 | exec(cmd); 309 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 310 | string returnData = readAndRemoveErrorFile("errorMessage.txt"); 311 | 312 | string errorMessageChecker; 313 | errorMessageChecker = errorMessage; 314 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 315 | 316 | if(!errorMessageChecker.empty()) 317 | { 318 | return errorMessage; 319 | } 320 | return returnData; 321 | } 322 | 323 | //Verifies wether a message is ok and has not been tampered with 324 | FB::variant gmailGPGAPI::clearSignMessage(const FB::variant& message,const FB::variant& password) 325 | { 326 | string tempFileLocation = m_tempPath + "tmpMessage.gpg"; 327 | string errorFileLocation = m_tempPath + "errorMessage.txt"; 328 | string clearSigFileLocation = m_tempPath + "tmpMessage.gpg.asc"; 329 | 330 | string gpgFileLocation = "\""+m_appPath +"gpg.exe\" "; 331 | 332 | string returnData = ""; 333 | string cmd = "cmd.exe /c "; 334 | 335 | ifstream fin(tempFileLocation.c_str()); 336 | if(fin) 337 | { 338 | fin.close(); 339 | remove(tempFileLocation.c_str()); 340 | } 341 | ofstream encMessageContainer (tempFileLocation.c_str()); 342 | 343 | if (encMessageContainer.is_open()) 344 | { 345 | encMessageContainer << message.convert_cast().c_str(); 346 | encMessageContainer.close(); 347 | } 348 | 349 | cmd.append("echo \""); 350 | cmd.append(password.convert_cast()); 351 | cmd.append("\" |"); 352 | cmd.append(" "); 353 | cmd.append(gpgFileLocation); 354 | cmd.append(" --no-tty --passphrase-fd 0"); 355 | cmd.append(" --clearsign "); 356 | cmd.append(tempFileLocation); 357 | cmd.append(" 2>"); 358 | cmd.append(errorFileLocation); 359 | 360 | if (system(NULL)){ 361 | 362 | } 363 | else{ 364 | return (""); 365 | } 366 | 367 | system (cmd.c_str()); 368 | string sigMessage = readAndRemoveErrorFile("tmpMessage.gpg.asc"); 369 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 370 | remove(tempFileLocation.c_str()); 371 | 372 | string errorMessageChecker; 373 | errorMessageChecker = errorMessage; 374 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 375 | 376 | 377 | if(!errorMessageChecker.empty() && sigMessage.empty()) 378 | { 379 | return errorMessage; 380 | } 381 | 382 | return sigMessage; 383 | } 384 | 385 | FB::variant gmailGPGAPI::listKeys() 386 | { 387 | string errorFileLocation = m_tempPath +"errorMessage.txt"; 388 | string tempFileLocation = m_tempPath + "tmpMessage.gpg"; 389 | string gpgFileLocation = "cmd.exe /c \""+m_appPath +"gpg.exe\" "; 390 | 391 | string cmd = gpgFileLocation.append(" -k"); 392 | cmd.append(" 1>"); 393 | cmd.append(tempFileLocation); 394 | cmd.append(" 2>"); 395 | cmd.append(errorFileLocation); 396 | 397 | exec(cmd); 398 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 399 | string returnData = readAndRemoveErrorFile("tmpMessage.gpg"); 400 | 401 | string errorMessageChecker; 402 | errorMessageChecker = errorMessage; 403 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 404 | 405 | if(!errorMessageChecker.empty()) 406 | { 407 | return errorMessage; 408 | } 409 | return returnData; 410 | } 411 | 412 | FB::variant gmailGPGAPI::listPrivateKeys() 413 | { 414 | string errorFileLocation = m_tempPath +"errorMessage.txt"; 415 | string tempFileLocation = m_tempPath + "tmpMessage.gpg"; 416 | string gpgFileLocation = "cmd.exe /c \""+m_appPath +"gpg.exe\" "; 417 | 418 | string cmd = gpgFileLocation.append(" --list-secret-keys"); 419 | cmd.append(" 1>"); 420 | cmd.append(tempFileLocation); 421 | cmd.append(" 2>"); 422 | cmd.append(errorFileLocation); 423 | 424 | exec(cmd); 425 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 426 | string returnData = readAndRemoveErrorFile("tmpMessage.gpg"); 427 | 428 | string errorMessageChecker; 429 | errorMessageChecker = errorMessage; 430 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 431 | 432 | 433 | if(!errorMessageChecker.empty()) 434 | { 435 | return errorMessage; 436 | } 437 | return returnData; 438 | } 439 | 440 | FB::variant gmailGPGAPI::testOptions() 441 | { 442 | string errorFileLocation = m_tempPath +"errorMessage.txt"; 443 | string tempFileLocation = m_tempPath + "tmpMessage.gpg"; 444 | string gpgFileLocation = "\""+m_appPath +"gpg.exe\" "; 445 | 446 | string cmd = gpgFileLocation.append(" --version"); 447 | cmd.append(" 2>"); 448 | cmd.append(errorFileLocation); 449 | 450 | string errorMessage = readAndRemoveErrorFile("errorMessage.txt"); 451 | string returnData = getMessageFromCommand(cmd); 452 | 453 | string errorMessageChecker; 454 | errorMessageChecker = errorMessage; 455 | errorMessageChecker.erase(std::remove(errorMessageChecker.begin(), errorMessageChecker.end(), '\n'), errorMessageChecker.end()); 456 | 457 | if(!errorMessageChecker.empty() && returnData.empty()) 458 | { 459 | return errorMessage; 460 | } 461 | return returnData; 462 | 463 | } 464 | -------------------------------------------------------------------------------- /gmailGPG/generic/gmailGPGAPI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Note I have used various bit of code from 3 | * https://github.com/gpgauth/gpgauth-npapi/blob/master/gpgAuthPlugin/ 4 | * 5 | * The project is alot more mature than mine and 6 | * solved alot of the issues that I came across. 7 | * 8 | * */ 9 | #include "JSObject.h" 10 | #include "variant_list.h" 11 | #include "DOM/Document.h" 12 | #include "gmailGPGAPI.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "t-support.h" 23 | #include "b64.c" 24 | 25 | using namespace std; 26 | 27 | gmailGPGAPI::gmailGPGAPI(const gmailGPGPtr& plugin, const FB::BrowserHostPtr& host) : m_plugin(plugin), m_host(host) 28 | { 29 | registerMethod("encrypt", make_method(this, &gmailGPGAPI::encryptMessage)); 30 | registerMethod("decrypt", make_method(this, &gmailGPGAPI::decryptMessage)); 31 | registerMethod("importKey", make_method(this, &gmailGPGAPI::importKey)); 32 | registerMethod("listKeys", make_method(this, &gmailGPGAPI::listKeys)); 33 | registerMethod("listPrivateKeys", make_method(this, &gmailGPGAPI::listPrivateKeys)); 34 | registerMethod("clearSignMessage", make_method(this, &gmailGPGAPI::clearSignMessage)); 35 | registerMethod("verifyMessage", make_method(this, &gmailGPGAPI::verifyMessage)); 36 | registerMethod("verifyMessageDetached", make_method(this, &gmailGPGAPI::verifyMessageWithDetachedFile)); 37 | 38 | // Read-only property 39 | registerProperty("version", 40 | make_property(this, 41 | &gmailGPGAPI::get_version)); 42 | registerProperty("appPath" ,make_property(this,&gmailGPGAPI::get_appPath,&gmailGPGAPI::set_appPath)); 43 | registerProperty("tempPath",make_property(this,&gmailGPGAPI::get_tempPath,&gmailGPGAPI::set_tempPath)); 44 | 45 | } 46 | 47 | gmailGPGAPI::~gmailGPGAPI() 48 | { 49 | } 50 | 51 | inline std::string i_to_str(const int &number) 52 | { 53 | std::ostringstream oss; 54 | oss << number; 55 | return oss.str(); 56 | } 57 | 58 | //Error handler file , this reads any messages that 59 | //may have been stored in the errorMessage file 60 | //and returns a string with this details to the caller. 61 | //"errorMessage.txt" 62 | std::string gmailGPGAPI::readAndRemoveErrorFile(const std::string fileName) 63 | { 64 | string errorFileLocation = m_tempPath + fileName; 65 | string returnData = ""; 66 | string line; 67 | ifstream myfile; 68 | myfile.open(errorFileLocation.c_str()); 69 | while ( myfile.good() ) 70 | { 71 | getline (myfile,line); 72 | returnData.append(line); 73 | returnData.append("\n"); 74 | } 75 | myfile.close(); 76 | remove(errorFileLocation.c_str()); 77 | return returnData; 78 | } 79 | 80 | std::string gmailGPGAPI::readTempFile(const std::string fileName) 81 | { 82 | string returnData = ""; 83 | string line; 84 | ifstream myfile; 85 | myfile.open(fileName.c_str()); 86 | while ( myfile.good() ) 87 | { 88 | getline (myfile,line); 89 | returnData.append(line); 90 | returnData.append("\n"); 91 | } 92 | myfile.close(); 93 | return returnData; 94 | } 95 | 96 | gmailGPGPtr gmailGPGAPI::getPlugin() 97 | { 98 | gmailGPGPtr plugin(m_plugin.lock()); 99 | if (!plugin) { 100 | throw FB::script_error("The plugin is invalid"); 101 | } 102 | return plugin; 103 | } 104 | 105 | //Temp Path , this is where temp files are written 106 | std::string gmailGPGAPI::get_tempPath() 107 | { 108 | return m_tempPath; 109 | } 110 | void gmailGPGAPI::set_tempPath(const std::string& val) 111 | { 112 | m_tempPath = val; 113 | } 114 | 115 | //App path , this is where the gpg app can be found 116 | std::string gmailGPGAPI::get_appPath() 117 | { 118 | return m_appPath; 119 | } 120 | void gmailGPGAPI::set_appPath(const std::string& val) 121 | { 122 | m_appPath = val; 123 | } 124 | 125 | std::string gmailGPGAPI::get_version() 126 | { 127 | return "0.7.7-beta"; 128 | } 129 | 130 | string exec(string cmd) { 131 | if (system(NULL)){ 132 | 133 | } 134 | else{ 135 | return (""); 136 | } 137 | 138 | system (cmd.c_str()); 139 | 140 | return ""; 141 | } 142 | 143 | //Encrypts a message with the list of recipients provided 144 | FB::variant gmailGPGAPI::encryptMessage(const FB::variant& recipients,const FB::variant& msg) 145 | { 146 | vector peopleToSendTo = recipients.convert_cast >(); 147 | string returnData = ""; 148 | 149 | gpgme_ctx_t ctx; 150 | gpgme_error_t err; 151 | gpgme_data_t in, out; 152 | //peopleToSendTo.size() 153 | gpgme_key_t key[peopleToSendTo.size()+1];// = {NULL,NULL,NULL}; 154 | 155 | init_gpgme (GPGME_PROTOCOL_OpenPGP); 156 | 157 | err = gpgme_new (&ctx); 158 | gpgme_set_armor (ctx, 1); 159 | 160 | for(unsigned int i=0;i().c_str(), msg.convert_cast().length()+1, 1); 168 | //err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0); 169 | //fail_if_err (err); 170 | 171 | err = gpgme_data_new (&out); 172 | //fail_if_err (err); 173 | 174 | err = gpgme_op_encrypt (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); 175 | //fail_if_err (err); 176 | result = gpgme_op_encrypt_result (ctx); 177 | //if (result->invalid_recipients) 178 | //{ 179 | // fprintf (stderr, "Invalid recipient encountered: %s\n", 180 | // result->invalid_recipients->fpr); 181 | //exit (1); 182 | //} 183 | 184 | size_t out_size = 0; 185 | char* out_buf = gpgme_data_release_and_get_mem(out, &out_size); 186 | std::string returnMessage = std::string(out_buf); 187 | out = NULL; 188 | 189 | //returnData = print_data (out); 190 | for(int i=0;i().c_str(),msg.convert_cast().length(),1); 223 | returnData = gpgme_strerror(err); 224 | //fail_if_err (err); 225 | 226 | err = gpgme_data_new (&out); 227 | returnData = gpgme_strerror(err); 228 | //fail_if_err (err); 229 | 230 | err = gpgme_op_decrypt (ctx, in, out); 231 | 232 | size_t out_size = 0; 233 | char* out_buf = gpgme_data_release_and_get_mem (out, &out_size); 234 | std::string returnMessage = std::string(out_buf); 235 | out = NULL; 236 | 237 | returnData = gpgme_strerror(err); 238 | result = gpgme_op_decrypt_result (ctx); 239 | /* 240 | if (result->unsupported_algorithm) 241 | { 242 | fprintf (stderr, "%s:%i: unsupported algorithm: %s\n", 243 | __FILE__, __LINE__, result->unsupported_algorithm); 244 | exit (1); 245 | } 246 | */ 247 | //returnData = print_data(out); 248 | //returnData = gpgme_data_release_and_get_mem (out, &out_size); 249 | gpgme_data_release (in); 250 | gpgme_data_release (out); 251 | gpgme_release (ctx); 252 | return returnMessage; 253 | } 254 | 255 | //Imports a users public key 256 | FB::variant gmailGPGAPI::importKey(const FB::variant& pubKey) 257 | { 258 | gpgme_ctx_t ctx; 259 | gpgme_error_t err; 260 | gpgme_data_t in; 261 | gpgme_import_result_t result; 262 | 263 | init_gpgme (GPGME_PROTOCOL_OpenPGP); 264 | 265 | err = gpgme_new (&ctx); 266 | //fail_if_err (err); 267 | 268 | err = gpgme_data_new_from_mem(&in, pubKey.convert_cast().c_str(),pubKey.convert_cast().length(),1); 269 | //fail_if_err (err); 270 | 271 | err = gpgme_op_import (ctx, in); 272 | //fail_if_err (err); 273 | 274 | result = gpgme_op_import_result (ctx); 275 | 276 | gpgme_data_release (in); 277 | gpgme_release (ctx); 278 | return "OK"; 279 | } 280 | 281 | 282 | //Verifies wether a message is ok and has not been tampered with 283 | FB::variant gmailGPGAPI::verifyMessage(const FB::variant& message) 284 | { 285 | try { 286 | gpgme_ctx_t ctx; 287 | gpgme_error_t err; 288 | gpgme_verify_result_t result; 289 | init_gpgme (GPGME_PROTOCOL_OpenPGP); 290 | err = gpgme_new (&ctx); 291 | 292 | gpgme_data_t msg, out; 293 | err = gpgme_data_new_from_mem (&msg, message.convert_cast().c_str(), message.convert_cast().length()+1, 1); 294 | err = gpgme_data_new(&out); 295 | err = gpgme_op_verify (ctx, msg, NULL, out); 296 | result = gpgme_op_verify_result (ctx); 297 | 298 | if(result->signatures) 299 | { 300 | return result->signatures->summary; 301 | } 302 | size_t out_size = 0; 303 | char* msg_buf = gpgme_data_release_and_get_mem (out, &out_size); 304 | std::string returnMessage = std::string(msg_buf); 305 | msg = NULL; 306 | 307 | return returnMessage; 308 | } 309 | catch(exception& e) 310 | { 311 | return "Error Occured , Bad Message"; 312 | } 313 | } 314 | 315 | //Verifies wether a message is ok and has not been tampered with 316 | FB::variant gmailGPGAPI::verifyMessageWithDetachedFile(const FB::variant& message,const FB::variant& sig) 317 | { 318 | //Store the base64 data into the tmpMessage file. 319 | string tempFileLocation = m_tempPath + "tmpSig"; 320 | //The path below is where the base64 decoder will dump the binary data. 321 | string tempFileLocationFinal = m_tempPath + "tmpMessage.sig"; 322 | string tempMessageLocation = m_tempPath + "tmpMessage"; 323 | 324 | ofstream sigFile(tempFileLocation.c_str()); 325 | //Open file convert variable to text and dump data 326 | if(sigFile.is_open()) 327 | { 328 | sigFile << sig.convert_cast().c_str(); 329 | sigFile.close(); 330 | } 331 | 332 | ofstream msgFile(tempMessageLocation.c_str()); 333 | //Open file convert variable to text and dump data 334 | if(msgFile.is_open()) 335 | { 336 | msgFile<< message.convert_cast().c_str() <signatures) 366 | { 367 | return gpgme_strerror(result->signatures->status); 368 | //return result->signatures->summary; 369 | } 370 | return gpgme_strerror(err); 371 | } 372 | catch(exception& e) 373 | { 374 | return "Error Occured , Bad Message"; 375 | } 376 | } 377 | 378 | 379 | FB::variant gmailGPGAPI::clearSignMessage(const FB::variant& message) 380 | { 381 | gpgme_ctx_t ctx; 382 | gpgme_data_t in, out; 383 | gpgme_error_t err; 384 | gpgme_sign_result_t result; 385 | 386 | init_gpgme (GPGME_PROTOCOL_OpenPGP); 387 | err = gpgme_new (&ctx); 388 | 389 | char *agent_info = getenv ("GPG_AGENT_INFO"); 390 | if (!(agent_info && strchr (agent_info, ':'))) 391 | gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL); 392 | 393 | gpgme_set_armor (ctx, 1); 394 | 395 | err = gpgme_data_new_from_mem (&in, message.convert_cast().c_str(), message.convert_cast().length(), 1); 396 | err = gpgme_data_new (&out); 397 | err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_CLEAR); 398 | 399 | result = gpgme_op_sign_result (ctx); 400 | 401 | size_t out_size = 0; 402 | char* out_buf = gpgme_data_release_and_get_mem(out, &out_size); 403 | std::string returnData = std::string(out_buf); 404 | out = NULL; 405 | 406 | gpgme_data_release (in); 407 | gpgme_data_release (out); 408 | gpgme_release (ctx); 409 | 410 | return returnData; 411 | } 412 | 413 | FB::variant gmailGPGAPI::listKeys(const std::string& domain,int secret_only) 414 | { 415 | gpgme_ctx_t ctx; 416 | gpgme_error_t err; 417 | init_gpgme (GPGME_PROTOCOL_OpenPGP); 418 | err = gpgme_new (&ctx); 419 | 420 | gpgme_key_t key; 421 | gpgme_keylist_result_t result; 422 | gpgme_user_id_t uid; 423 | gpgme_key_sig_t sig; 424 | gpgme_subkey_t subkey; 425 | FB::VariantMap keylist_map; 426 | 427 | FB::VariantMap uid_map; 428 | 429 | err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); 430 | if(err != GPG_ERR_NO_ERROR) 431 | return "Protocol loading failed"; //get_error_map(__func__, gpgme_err_code (err), gpgme_strerror (err), __LINE__, __FILE__); 432 | 433 | /* apply the keylist mode to the context and set 434 | the keylist_mode 435 | NOTE: The keylist mode flag GPGME_KEYLIST_MODE_SIGS 436 | returns the signatures of UIDS with the key */ 437 | gpgme_set_keylist_mode (ctx, (gpgme_get_keylist_mode (ctx) 438 | | GPGME_KEYLIST_MODE_VALIDATE 439 | | GPGME_KEYLIST_MODE_SIGS)); 440 | 441 | /* gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only) */ 442 | if (domain.length() > 0){ // limit key listing to search criteria 'domain' 443 | err = gpgme_op_keylist_start (ctx, domain.c_str(), 0); 444 | } else { // list all keys 445 | err = gpgme_op_keylist_ext_start (ctx, NULL, secret_only, 0); 446 | } 447 | if(err != GPG_ERR_NO_ERROR) 448 | return "Something Broke";//get_error_map(__func__, gpgme_err_code (err), gpgme_strerror (err), __LINE__, __FILE__); 449 | //return keylist_map["error"] = "error: 3; Problem with keylist_start"; 450 | 451 | while (!(err = gpgme_op_keylist_next (ctx, &key))) 452 | { 453 | int nsigs; 454 | int tnsigs; 455 | FB::VariantMap key_map; 456 | 457 | if (key->uids && key->uids->name) 458 | key_map["name"] = nonnull (key->uids->name); 459 | if (key->subkeys && key->subkeys->fpr) 460 | key_map["fingerprint"] = nonnull (key->subkeys->fpr); 461 | if (key->uids && key->uids->email) 462 | key_map["email"] = nonnull (key->uids->email); 463 | key_map["expired"] = key->expired? true : false; 464 | key_map["revoked"] = key->revoked? true : false; 465 | key_map["disabled"] = key->disabled? true : false; 466 | key_map["invalid"] = key->invalid? true : false; 467 | key_map["secret"] = key->secret? true : false; 468 | key_map["protocol"] = key->protocol == GPGME_PROTOCOL_OpenPGP? "OpenPGP": 469 | key->protocol == GPGME_PROTOCOL_CMS? "CMS": 470 | key->protocol == GPGME_PROTOCOL_UNKNOWN? "Unknown": "[?]"; 471 | key_map["can_encrypt"] = key->can_encrypt? true : false; 472 | key_map["can_sign"] = key->can_sign? true : false; 473 | key_map["can_certify"] = key->can_certify? true : false; 474 | key_map["can_authenticate"] = key->can_authenticate? true : false; 475 | key_map["is_qualified"] = key->is_qualified? true : false; 476 | 477 | keylist_map[key->subkeys->keyid] = key_map; 478 | gpgme_key_unref (key); 479 | } 480 | 481 | if (gpg_err_code (err) != GPG_ERR_EOF) exit(6); 482 | err = gpgme_op_keylist_end (ctx); 483 | if(err != GPG_ERR_NO_ERROR) exit(7); 484 | result = gpgme_op_keylist_result (ctx); 485 | if (result->truncated) 486 | { 487 | return "Results Truncated";//get_error_map(__func__, gpgme_err_code (err), gpgme_strerror (err), __LINE__, __FILE__); 488 | //return keylist_map["error"] = "error: 4; Key listing unexpectedly truncated"; 489 | } 490 | gpgme_release (ctx); 491 | return keylist_map; 492 | } 493 | 494 | FB::variant gmailGPGAPI::listPrivateKeys() 495 | { 496 | return listKeys(NULL,1); 497 | } 498 | -------------------------------------------------------------------------------- /gmailGPG/generic/b64.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************\ 2 | 3 | MODULE NAME: b64.c 4 | 5 | AUTHOR: Bob Trower 08/04/01 6 | 7 | PROJECT: Crypt Data Packaging 8 | 9 | COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001 10 | 11 | NOTE: This source code may be used as you wish, subject to 12 | the MIT license. See the LICENCE section below. 13 | 14 | DESCRIPTION: 15 | This little utility implements the Base64 16 | Content-Transfer-Encoding standard described in 17 | RFC1113 (http://www.faqs.org/rfcs/rfc1113.html). 18 | 19 | This is the coding scheme used by MIME to allow 20 | binary data to be transferred by SMTP mail. 21 | 22 | Groups of 3 bytes from a binary stream are coded as 23 | groups of 4 bytes in a text stream. 24 | 25 | The input stream is 'padded' with zeros to create 26 | an input that is an even multiple of 3. 27 | 28 | A special character ('=') is used to denote padding so 29 | that the stream can be decoded back to its exact size. 30 | 31 | Encoded output is formatted in lines which should 32 | be a maximum of 72 characters to conform to the 33 | specification. This program defaults to 72 characters, 34 | but will allow more or less through the use of a 35 | switch. The program enforces a minimum line size 36 | of 4 characters. 37 | 38 | Example encoding: 39 | 40 | The stream 'ABCD' is 32 bits long. It is mapped as 41 | follows: 42 | 43 | ABCD 44 | 45 | A (65) B (66) C (67) D (68) (None) (None) 46 | 01000001 01000010 01000011 01000100 47 | 48 | 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=) 49 | 010000 010100 001001 000011 010001 000000 000000 000000 50 | 51 | 52 | QUJDRA== 53 | 54 | Decoding is the process in reverse. A 'decode' lookup 55 | table has been created to avoid string scans. 56 | 57 | DESIGN GOALS: Specifically: 58 | Code is a stand-alone utility to perform base64 59 | encoding/decoding. It should be genuinely useful 60 | when the need arises and it meets a need that is 61 | likely to occur for some users. 62 | Code acts as sample code to show the author's 63 | design and coding style. 64 | 65 | Generally: 66 | This program is designed to survive: 67 | Everything you need is in a single source file. 68 | It compiles cleanly using a vanilla ANSI C compiler. 69 | It does its job correctly with a minimum of fuss. 70 | The code is not overly clever, not overly simplistic 71 | and not overly verbose. 72 | Access is 'cut and paste' from a web page. 73 | Terms of use are reasonable. 74 | 75 | VALIDATION: Non-trivial code is never without errors. This 76 | file likely has some problems, since it has only 77 | been tested by the author. It is expected with most 78 | source code that there is a period of 'burn-in' when 79 | problems are identified and corrected. That being 80 | said, it is possible to have 'reasonably correct' 81 | code by following a regime of unit test that covers 82 | the most likely cases and regression testing prior 83 | to release. This has been done with this code and 84 | it has a good probability of performing as expected. 85 | 86 | Unit Test Cases: 87 | 88 | case 0:empty file: 89 | CASE0.DAT -> -> 90 | (Zero length target file created 91 | on both encode and decode.) 92 | 93 | case 1:One input character: 94 | CASE1.DAT A -> QQ== -> A 95 | 96 | case 2:Two input characters: 97 | CASE2.DAT AB -> QUJD -> AB 98 | 99 | case 3:Three input characters: 100 | CASE3.DAT ABC -> QUJD -> ABC 101 | 102 | case 4:Four input characters: 103 | case4.dat ABCD -> QUJDRA== -> ABCD 104 | 105 | case 5:All chars from 0 to ff, linesize set to 50: 106 | 107 | AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj 108 | JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH 109 | SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr 110 | bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P 111 | kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz 112 | tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX 113 | 2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7 114 | /P3+/w== 115 | 116 | case 6:Mime Block from e-mail: 117 | (Data same as test case 5) 118 | 119 | case 7: Large files: 120 | Tested 28 MB file in/out. 121 | 122 | case 8: Random Binary Integrity: 123 | This binary program (b64.exe) was encoded to base64, 124 | back to binary and then executed. 125 | 126 | case 9 Stress: 127 | All files in a working directory encoded/decoded 128 | and compared with file comparison utility to 129 | ensure that multiple runs do not cause problems 130 | such as exhausting file handles, tmp storage, etc. 131 | 132 | ------------- 133 | 134 | Syntax, operation and failure: 135 | All options/switches tested. Performs as 136 | expected. 137 | 138 | case 10: 139 | No Args -- Shows Usage Screen 140 | Return Code 1 (Invalid Syntax) 141 | case 11: 142 | One Arg (invalid) -- Shows Usage Screen 143 | Return Code 1 (Invalid Syntax) 144 | case 12: 145 | One Arg Help (-?) -- Shows detailed Usage Screen. 146 | Return Code 0 (Success -- help request is valid). 147 | case 13: 148 | One Arg Help (-h) -- Shows detailed Usage Screen. 149 | Return Code 0 (Success -- help request is valid). 150 | case 14: 151 | One Arg (valid) -- Uses stdin/stdout (filter) 152 | Return Code 0 (Sucess) 153 | case 15: 154 | Two Args (invalid file) -- shows system error. 155 | Return Code 2 (File Error) 156 | case 16: 157 | Encode non-existent file -- shows system error. 158 | Return Code 2 (File Error) 159 | case 17: 160 | Out of disk space -- shows system error. 161 | Return Code 3 (File I/O Error) 162 | 163 | ------------- 164 | 165 | Compile/Regression test: 166 | gcc compiled binary under Cygwin 167 | Microsoft Visual Studio under Windows 2000 168 | Microsoft Version 6.0 C under Windows 2000 169 | 170 | DEPENDENCIES: None 171 | 172 | LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. 173 | 174 | Permission is hereby granted, free of charge, to any person 175 | obtaining a copy of this software and associated 176 | documentation files (the "Software"), to deal in the 177 | Software without restriction, including without limitation 178 | the rights to use, copy, modify, merge, publish, distribute, 179 | sublicense, and/or sell copies of the Software, and to 180 | permit persons to whom the Software is furnished to do so, 181 | subject to the following conditions: 182 | 183 | The above copyright notice and this permission notice shall 184 | be included in all copies or substantial portions of the 185 | Software. 186 | 187 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 188 | KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 189 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 190 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 191 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 192 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 193 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 194 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 195 | 196 | VERSION HISTORY: 197 | Bob Trower 08/04/01 -- Create Version 0.00.00B 198 | 199 | \******************************************************************* */ 200 | 201 | #include 202 | #include 203 | 204 | /* 205 | ** Translation Table as described in RFC1113 206 | */ 207 | static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 208 | 209 | /* 210 | ** Translation Table to decode (created by author) 211 | */ 212 | static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; 213 | 214 | /* 215 | ** encodeblock 216 | ** 217 | ** encode 3 8-bit binary bytes as 4 '6-bit' characters 218 | */ 219 | void encodeblock( unsigned char in[3], unsigned char out[4], int len ) 220 | { 221 | out[0] = cb64[ in[0] >> 2 ]; 222 | out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; 223 | out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); 224 | out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '='); 225 | } 226 | 227 | /* 228 | ** encode 229 | ** 230 | ** base64 encode a stream adding padding and line breaks as per spec. 231 | */ 232 | void encode( FILE *infile, FILE *outfile, int linesize ) 233 | { 234 | unsigned char in[3], out[4]; 235 | int i, len, blocksout = 0; 236 | 237 | while( !feof( infile ) ) { 238 | len = 0; 239 | for( i = 0; i < 3; i++ ) { 240 | in[i] = (unsigned char) getc( infile ); 241 | if( !feof( infile ) ) { 242 | len++; 243 | } 244 | else { 245 | in[i] = 0; 246 | } 247 | } 248 | if( len ) { 249 | encodeblock( in, out, len ); 250 | for( i = 0; i < 4; i++ ) { 251 | putc( out[i], outfile ); 252 | } 253 | blocksout++; 254 | } 255 | if( blocksout >= (linesize/4) || feof( infile ) ) { 256 | if( blocksout ) { 257 | fprintf( outfile, "\r\n" ); 258 | } 259 | blocksout = 0; 260 | } 261 | } 262 | } 263 | 264 | /* 265 | ** decodeblock 266 | ** 267 | ** decode 4 '6-bit' characters into 3 8-bit binary bytes 268 | */ 269 | void decodeblock( unsigned char in[4], unsigned char out[3] ) 270 | { 271 | out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4); 272 | out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2); 273 | out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]); 274 | } 275 | 276 | /* 277 | ** decode 278 | ** 279 | ** decode a base64 encoded stream discarding padding, line breaks and noise 280 | */ 281 | void decode( FILE *infile, FILE *outfile ) 282 | { 283 | unsigned char in[4], out[3], v; 284 | int i, len; 285 | 286 | while( !feof( infile ) ) { 287 | for( len = 0, i = 0; i < 4 && !feof( infile ); i++ ) { 288 | v = 0; 289 | while( !feof( infile ) && v == 0 ) { 290 | v = (unsigned char) getc( infile ); 291 | v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); 292 | if( v ) { 293 | v = (unsigned char) ((v == '$') ? 0 : v - 61); 294 | } 295 | } 296 | if( !feof( infile ) ) { 297 | len++; 298 | if( v ) { 299 | in[ i ] = (unsigned char) (v - 1); 300 | } 301 | } 302 | else { 303 | in[i] = 0; 304 | } 305 | } 306 | if( len ) { 307 | decodeblock( in, out ); 308 | for( i = 0; i < len - 1; i++ ) { 309 | putc( out[i], outfile ); 310 | } 311 | } 312 | } 313 | } 314 | 315 | /* 316 | ** returnable errors 317 | ** 318 | ** Error codes returned to the operating system. 319 | ** 320 | */ 321 | #define B64_SYNTAX_ERROR 1 322 | #define B64_FILE_ERROR 2 323 | #define B64_FILE_IO_ERROR 3 324 | #define B64_ERROR_OUT_CLOSE 4 325 | #define B64_LINE_SIZE_TO_MIN 5 326 | 327 | /* 328 | ** b64_message 329 | ** 330 | ** Gather text messages in one place. 331 | ** 332 | */ 333 | char *b64_message( int errcode ) 334 | { 335 | #define B64_MAX_MESSAGES 6 336 | char *msgs[ B64_MAX_MESSAGES ] = { 337 | "b64:000:Invalid Message Code.", 338 | "b64:001:Syntax Error -- check help for usage.", 339 | "b64:002:File Error Opening/Creating Files.", 340 | "b64:003:File I/O Error -- Note: output file not removed.", 341 | "b64:004:Error on output file close.", 342 | "b64:004:linesize set to minimum." 343 | }; 344 | char *msg = msgs[ 0 ]; 345 | 346 | if( errcode > 0 && errcode < B64_MAX_MESSAGES ) { 347 | msg = msgs[ errcode ]; 348 | } 349 | 350 | return( msg ); 351 | } 352 | 353 | /* 354 | ** b64 355 | ** 356 | ** 'engine' that opens streams and calls encode/decode 357 | */ 358 | 359 | int b64( int opt, char *infilename, char *outfilename, int linesize ) 360 | { 361 | FILE *infile; 362 | int retcode = B64_FILE_ERROR; 363 | 364 | if( !infilename ) { 365 | infile = stdin; 366 | } 367 | else { 368 | infile = fopen( infilename, "rb" ); 369 | } 370 | if( !infile ) { 371 | perror( infilename ); 372 | } 373 | else { 374 | FILE *outfile; 375 | if( !outfilename ) { 376 | outfile = stdout; 377 | } 378 | else { 379 | outfile = fopen( outfilename, "wb" ); 380 | } 381 | if( !outfile ) { 382 | perror( outfilename ); 383 | } 384 | else { 385 | if( opt == 'e' ) { 386 | encode( infile, outfile, linesize ); 387 | } 388 | else { 389 | decode( infile, outfile ); 390 | } 391 | if (ferror( infile ) || ferror( outfile )) { 392 | retcode = B64_FILE_IO_ERROR; 393 | } 394 | else { 395 | retcode = 0; 396 | } 397 | if( outfile != stdout ) { 398 | if( fclose( outfile ) != 0 ) { 399 | perror( b64_message( B64_ERROR_OUT_CLOSE ) ); 400 | retcode = B64_FILE_IO_ERROR; 401 | } 402 | } 403 | } 404 | if( infile != stdin ) { 405 | fclose( infile ); 406 | } 407 | } 408 | 409 | return( retcode ); 410 | } 411 | 412 | /* 413 | ** showuse 414 | ** 415 | ** display usage information, help, version info 416 | */ 417 | void showuse( int morehelp ) 418 | { 419 | { 420 | printf( "\n" ); 421 | printf( " b64 (Base64 Encode/Decode) Bob Trower 08/03/01 \n" ); 422 | printf( " (C) Copr Bob Trower 1986-01. Version 0.00B \n" ); 423 | printf( " Usage: b64 -option [ -l num ] [ []] \n" ); 424 | printf( " Purpose: This program is a simple utility that implements\n" ); 425 | printf( " Base64 Content-Transfer-Encoding (RFC1113). \n" ); 426 | } 427 | if( !morehelp ) { 428 | printf( " Use -h option for additional help. \n" ); 429 | } 430 | else { 431 | printf( " Options: -e encode to Base64 -h This help text. \n" ); 432 | printf( " -d decode from Base64 -? This help text. \n" ); 433 | printf( " Note: -l use to change line size (from 72 characters)\n" ); 434 | printf( " Returns: 0 = success. Non-zero is an error code. \n" ); 435 | printf( " ErrCode: 1 = Bad Syntax, 2 = File Open, 3 = File I/O \n" ); 436 | printf( " Example: b64 -e binfile b64file <- Encode to b64 \n" ); 437 | printf( " b64 -d b64file binfile <- Decode from b64 \n" ); 438 | printf( " b64 -e -l40 infile outfile <- Line Length of 40 \n" ); 439 | printf( " Note: Will act as a filter, but this should only be \n" ); 440 | printf( " used on text files due to translations made by \n" ); 441 | printf( " operating systems. \n" ); 442 | printf( " Release: 0.00.00, Tue Aug 7 2:00:00 2001, ANSI-SOURCE C\n" ); 443 | } 444 | } 445 | 446 | #define B64_DEF_LINE_SIZE 72 447 | #define B64_MIN_LINE_SIZE 4 448 | 449 | #define THIS_OPT(ac, av) (ac > 1 ? av[1][0] == '-' ? av[1][1] : 0 : 0) 450 | 451 | /* 452 | ** main 453 | ** 454 | ** parse and validate arguments and call b64 engine or help 455 | */ 456 | int main( int argc, char **argv ) 457 | { 458 | int opt = 0; 459 | int retcode = 0; 460 | int linesize = B64_DEF_LINE_SIZE; 461 | char *infilename = NULL, *outfilename = NULL; 462 | 463 | while( THIS_OPT( argc, argv ) ) { 464 | switch( THIS_OPT(argc, argv) ) { 465 | case 'l': 466 | linesize = atoi( &(argv[1][2]) ); 467 | if( linesize < B64_MIN_LINE_SIZE ) { 468 | linesize = B64_MIN_LINE_SIZE; 469 | printf( "%s\n", b64_message( B64_LINE_SIZE_TO_MIN ) ); 470 | } 471 | break; 472 | case '?': 473 | case 'h': 474 | opt = 'h'; 475 | break; 476 | case 'e': 477 | case 'd': 478 | opt = THIS_OPT(argc, argv); 479 | break; 480 | default: 481 | opt = 0; 482 | break; 483 | } 484 | argv++; 485 | argc--; 486 | } 487 | switch( opt ) { 488 | case 'e': 489 | case 'd': 490 | infilename = argc > 1 ? argv[1] : NULL; 491 | outfilename = argc > 2 ? argv[2] : NULL; 492 | retcode = b64( opt, infilename, outfilename, linesize ); 493 | break; 494 | case 0: 495 | retcode = B64_SYNTAX_ERROR; 496 | case 'h': 497 | showuse( opt ); 498 | break; 499 | 500 | } 501 | if( retcode ) { 502 | printf( "%s\n", b64_message( retcode ) ); 503 | } 504 | 505 | return( retcode ); 506 | } 507 | -------------------------------------------------------------------------------- /chromeExtension/content_script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | //Listen for decrypt click 3 | var decryptMessageHandler = function(that){ 4 | var messageElement = $('body div.nH').contents().find('#'+$(that).attr('decid')).closest('.gs').find('.ii.gt'); 5 | var emailMessage = messageElement.text(); 6 | //If this currently exists in the message it means we have a embeded 7 | //sig , the - -- indicates this. 8 | var multiDec = false; 9 | if(emailMessage.indexOf('- -----BEGIN PGP MESSAGE') !== -1){ 10 | multiDec = true; 11 | } 12 | 13 | chrome.extension.sendRequest({'messageType':'decrypt',decrypt: {'message':emailMessage,'domel':$(that).attr('decid'),'multidec':multiDec}}, function(response) { 14 | if(response.message.indexOf('decryption failed') == -1){ 15 | if(response.message.indexOf('no valid OpenPGP data found') == -1){ 16 | var messageElement = $('body div.nH').contents().find('#'+response.domid.toString()).closest('.gs').find('.ii.gt'); 17 | if($.trim(response.message).length == 0){ 18 | alert('Invalid Passphrase'); 19 | }else{ 20 | $($(messageElement).children()[0]).css('white-space','pre'); 21 | $($(messageElement).children()[0]).text(response.message); 22 | } 23 | }else{ 24 | alert(response.message); 25 | } 26 | }else{ 27 | alert(response.message); 28 | }; 29 | }); 30 | }; 31 | 32 | var clearSignHandler = function(that){ 33 | event.preventDefault(); 34 | var messageElement = $('body div.nH').contents().find($(that)).closest('.fN').find('.Ak'); 35 | var emailMessage = messageElement.val(); 36 | jQuery.returnEl = that; 37 | var currentMail = document.getElementsByTagName('title')[0].innerHTML.split(' - ')[1]; 38 | chrome.extension.sendRequest({'messageType':'sign',sign: {'currentMail':currentMail,'message':emailMessage}}, function(response) { 39 | var returnMessage = response.message.data; 40 | if(returnMessage){ 41 | var messageElement = $('body div.nH').contents().find($(jQuery.returnEl)).closest('.fN').find('.Ak'); 42 | if(returnMessage.indexOf('gpg:') != -1){ 43 | alert(returnMessage); 44 | return; 45 | }; 46 | $(messageElement).val(returnMessage); 47 | }else{ 48 | alert('No public keys found for recipients'); 49 | } 50 | }); 51 | }; 52 | 53 | var composerHandler = function(that){ 54 | event.preventDefault(); 55 | var encryptionList = ''; 56 | var inlineReply = $(that).closest('.gs').find('textarea.dK.nr'); 57 | if(inlineReply.length == 0){ 58 | inlineReply = $(that).closest('.fN').find('textarea.dK.nr'); 59 | }; 60 | inlineReply.each(function(index,item){ 61 | if($(item).val() != ''){ 62 | var emailAddress = $(item).val(); 63 | if(/<[^>]*>/.test(emailAddress)){ 64 | emailAddress = emailAddress.match(/<[^>]*>/)[0].replace('<','').replace('>',''); 65 | emailAddress = emailAddress.trim(); 66 | }; 67 | encryptionList += emailAddress +','; 68 | } 69 | }); 70 | encryptionList = encryptionList.replace(/,$/,'').split(','); 71 | 72 | var composerDialog = $(['
', 75 | 'Mail Addresses:', 76 | '
', 77 | 'Message:
', 78 | '
'].join(' ')); 80 | $(composerDialog).attr('id',$(that).attr('id')); 81 | var MessageHandler = function(that){ 82 | var messageElement = $('body div.nH').contents().find('#'+$(that).attr('id')).closest('.fN').find('.Ak'); 83 | var returnMessage = $('.composerMessage').val(); 84 | if(returnMessage.indexOf('gpg:') != -1){ 85 | alert(returnMessage); 86 | return; 87 | }; 88 | $(messageElement).val(returnMessage); 89 | }; 90 | 91 | jQuery.dLoader = $(composerDialog).dialog({ 92 | width:550, 93 | buttons: [{ 94 | text: "Insert into Email", 95 | click: function(){ 96 | MessageHandler(that); 97 | $(this).dialog("close"); 98 | } 99 | }, { 100 | text: "Cancel", 101 | click: function () { 102 | $(this).dialog("close"); 103 | } 104 | }] 105 | }); 106 | 107 | 108 | }; 109 | var encryptionHandler= function(that){ 110 | var messageElement = $('body div.nH').contents().find('#'+$(that).attr('id')).closest('.fN').find('.Ak'); 111 | var inlineReply = $(that).closest('.gs').find('textarea.dK.nr'); 112 | if(inlineReply.length == 0){ 113 | inlineReply = $(that).closest('.fN').find('textarea.dK.nr'); 114 | }; 115 | 116 | var encryptionList = []; 117 | inlineReply.each(function(index,item){ 118 | if($(item).val() != ''){ 119 | var emailAddress = $(item).val(); 120 | var splitItems = emailAddress.split(',') 121 | $.each(splitItems,function(index,sItem){ 122 | if(/<[^>]*>/.test(sItem)){ 123 | sItem = sItem.match(/<[^>]*>/)[0].replace('<','').replace('>',''); 124 | sItem = sItem.trim(); 125 | }; 126 | encryptionList.push(sItem); 127 | }); 128 | 129 | } 130 | }); 131 | 132 | // encryptionList = encryptionList.replace(/,$/,'').split(','); 133 | encryptionList = encryptionList.filter(function(val) { return val.trim() !== '' }) 134 | //for(var i=0;i 1){ 142 | var messageElement = $('body div.nH').contents().find('#'+response.domid.toString()).closest('.fN').find('.Ak'); 143 | if(returnMessage.indexOf('gpg:') != -1){ 144 | alert(returnMessage); 145 | return; 146 | }; 147 | if (!response.error) { 148 | $(messageElement).val(returnMessage); 149 | }else{ 150 | alert(returnMessage); 151 | }; 152 | 153 | }else{ 154 | alert('No public keys found for recipients'); 155 | } 156 | }); 157 | }; 158 | jQuery.encryptionHandler = encryptionHandler; 159 | 160 | //Load up the decrypt and verify buttons on currently visible emails for the new theme 161 | var loadButtons = function(items){ 162 | $(items).each(function(loopindex,loopitem){ 163 | if(!$(this).prev().hasClass('customdec')){ 164 | var id = Math.floor(Math.random($(this).parent().parent().length)*16777215).toString(16); 165 | var decryptButton = [ '', 172 | '', 176 | '' ].join('') 177 | var verifyButton = [ '', 182 | '', 186 | '' ].join('') 187 | 188 | $(items[loopindex]).before(decryptButton + verifyButton); 189 | }; 190 | }); 191 | }; 192 | 193 | //Generic function handlers 194 | var loadGenericFunctionHandlers = function(searchLocation){ 195 | $('[customFunction="decrypt"]',searchLocation).unbind('click'); 196 | $('[customFunction="decrypt"]',searchLocation).click(function(){ 197 | event.preventDefault(); 198 | decryptMessageHandler(this); 199 | }); 200 | 201 | $('[customFunction="encrypt"]',searchLocation).unbind('click'); 202 | $('[customFunction="encrypt"]',searchLocation).click(function(){ 203 | event.preventDefault(); 204 | encryptionHandler(this); 205 | }); 206 | 207 | $('[customFunction="composer"]',searchLocation).unbind('click'); 208 | $('[customFunction="composer"]',searchLocation).click(function(){ 209 | event.preventDefault(); 210 | composerHandler(this); 211 | }); 212 | $('[customFunction="sign"]',searchLocation).unbind('click'); 213 | $('[customFunction="sign"]',searchLocation).click(function(){ 214 | event.preventDefault(); 215 | clearSignHandler(this); 216 | }); 217 | 218 | $('[customFunction="verify"]',searchLocation).unbind('click'); 219 | $('[customFunction="verify"]',searchLocation).click(function(){ 220 | event.preventDefault(); 221 | var messageElement = $(this).closest('.gs').find('.ii.gt').text(); 222 | 223 | //Code To handle importing and splitting of external sigs. 224 | var otherText = $(this).closest('.gs').find('.hq.gt a'); 225 | if(otherText.length > 0){ 226 | var pairs = $(otherText[0]).attr('href').split('&'); 227 | var nvpair = {}; 228 | $.each(pairs, function(i, v){ 229 | var pair = v.split('='); 230 | nvpair[pair[0]] = pair[1]; 231 | }); 232 | var superURL = ['https://mail.google.com/mail/u/0/?ui=2&ik=', 233 | nvpair.ik,'&view=om&th=',window.location.hash.split('/')[1]].join(''); 234 | $.get(superURL,function(dat){ 235 | //Find the bound seperator and store it and remove the search text 236 | var boundryRegex = new RegExp(/boundary=".*"/); 237 | if(!boundryRegex.test(dat)){ 238 | boundryRegex = new RegExp(/boundary=.*/); 239 | }; 240 | var separator = boundryRegex.exec(dat)[0]; 241 | separator = separator.replace('boundary=','').replace('"',''); 242 | //Split the message with the sperator we found and drop the first 2 243 | //and last element , these are just artifacts of the split mostly. 244 | var parts = dat.split(separator); 245 | parts.splice(0,2); 246 | parts.splice(parts.length-1,1); 247 | //Remove any trailing -- 248 | for(var i =0;i 1){ 280 | alert(returnMessage); 281 | return; 282 | }else{ 283 | alert('No public keys found for recipients'); 284 | } 285 | }); 286 | 287 | }); 288 | }else{ 289 | 290 | chrome.extension.sendRequest({'messageType':'verify',verify: {'message':messageElement,'domel':$(this).attr('id')}}, function(response) { 291 | var sigsStatus = ""; 292 | for(var stat in response.message.signatures){ 293 | var currenStat = response.message.signatures[stat] 294 | sigsStatus += "Signature With Fingerprint :" + currenStat.fingerprint + " [ " +currenStat.status + " ]\n"; 295 | }; 296 | if(sigsStatus == ''){ 297 | sigsStatus = "Unable to verify message"; 298 | }; 299 | alert(sigsStatus); 300 | }); 301 | } 302 | 303 | 304 | }); 305 | }; 306 | 307 | //Load the decrypt and verify buttons but only for the old theme 308 | var loadOldThemesButtons = function(searchLocation){ 309 | $('.Bs.nH.iY .cKWzSc.mD[role="button"]',searchLocation).each(function(index){ 310 | if($(this).find('span:contains(Reply)')){ 311 | if($('body div.nH').contents().find('.nH.oy8Mbf span:contains(Switch to the new look)').length !== 0){ 312 | if($(this).parent().prev().length == 0){ 313 | var id = Math.floor(Math.random($(this).parent().parent().length)*16777215).toString(16); 314 | $(this).parent().parent().prepend(['
Decrypt Message
', 315 | '
Verify Message
'].join('')); 316 | }; 317 | }; 318 | }; 319 | }); 320 | }; 321 | 322 | //Old theme support for the compose email section 323 | var loadComposeButtons = function(searchLocation){ 324 | $('span.es.el:contains(»)',searchLocation).each(function(){ 325 | if(!$(this).prev().hasClass('customdec')){ 326 | var id = Math.floor(Math.random($(this).parent().parent().length)*16777215).toString(16); 327 | var newButton = $(this).before( 328 | ['Encrypt Message  ', 329 | 'Compose Message In Popup  ', 330 | 'Sign Message   '].join('')); 331 | }; 332 | }); 333 | }; 334 | 335 | $('[customFunction="simpleEncrypt"]').live('click',function(){ 336 | event.preventDefault(); 337 | chrome.extension.sendRequest({'messageType':'encrypt',encrypt: {'message':$('.composerMessage').val(), 338 | 'maillist':$('.emailAddresses').val().split()}}, function(response) { 339 | var returnMessage = response.message; 340 | if(returnMessage.length > 1){ 341 | if(returnMessage.indexOf('gpg:') != -1){ 342 | alert(returnMessage); 343 | return; 344 | }; 345 | $('.composerMessage').val(returnMessage) 346 | }else{ 347 | alert('No public keys found for recipients'); 348 | } 349 | }); 350 | 351 | }); 352 | 353 | //Load up buttons on keypress 354 | //Load up buttons on mouseover 355 | //Tiny timeout is required so that the html can be rendered 356 | setTimeout(function(){ 357 | $('body div.nH').contents().on('mouseover','.nH[role="main"]',function(){ 358 | //loadOldThemesButtons(this); 359 | loadComposeButtons(this); 360 | loadButtons($(this).find('tr.acZ td.gH.acX div.T-I-Js-IF')); 361 | loadGenericFunctionHandlers(this); 362 | }); 363 | 364 | /*$('body div.nH').contents().keypress(function(e){ 365 | loadButtons($('body div.nH').contents().find('tr.acZ td.gH.acX div.T-I-Js-IF')); 366 | var highLevelCheck = $('body div.nH').contents().find('.nH'); 367 | loadGenericFunctionHandlers(highLevelCheck); 368 | //loadOldThemesButtons(highLevelCheck); 369 | loadComposeButtons(highLevelCheck); 370 | }); 371 | */ 372 | },1000); 373 | }); 374 | --------------------------------------------------------------------------------