source: murachi/esteidfirefoxplugin/firefox/plugin.c @ 5d188ab

Last change on this file since 5d188ab was 7d3ae3e, checked in by antonioaraujob <aaraujo@…>, 9 years ago

Agregados archivos fuentes del complemento esteidfirefoxplugin de Estonia para firmar electrónicamente un hash.

  • Property mode set to 100644
File size: 9.7 KB
Line 
1/*
2 * Estonian ID card plugin for web browsers
3 *
4 * Copyright (C) 2010-2011 Codeborne <info@codeborne.com>
5 *
6 * This is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <ctype.h>
26
27#include "version.h"
28#include "plugin.h"
29#include "plugin-class.h"
30#include "esteid_mime_types.h"
31#include "esteid_misc.h"
32
33//#define PLUGIN_NAME        "EstEID Firefox plug-in"
34//#define PLUGIN_DESCRIPTION "Allows digital signing with Estonian ID cards"
35
36NPNetscapeFuncs* browserFunctions;
37
38extern char EstEID_error[1024];
39extern int EstEID_errorCode;
40extern bool allowedSite;
41
42bool isSameIdentifier(NPIdentifier identifier, const char* name) {
43        return browserFunctions->getstringidentifier(name) == identifier;
44}
45
46bool copyStringToNPVariant(const char *string, NPVariant *variant) {
47        char *out = (char *)browserFunctions->memalloc(strlen(string) + 1);
48        strcpy(out, string);
49        STRINGZ_TO_NPVARIANT(out, *variant);
50        return true;
51}
52
53NPUTF8* createStringFromNPVariant(const NPVariant *variant) {
54        if (!NPVARIANT_IS_STRING(*variant)) {
55                return strdup("");
56        }
57        size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
58        NPUTF8 *result = (NPUTF8 *)malloc(length + 1);
59        memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
60        result[length] = '\0';
61        return result;
62}
63
64NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pluginFuncs) {
65        EstEID_log("");
66        pluginFuncs->version = 11;
67        pluginFuncs->size = sizeof(*pluginFuncs);
68        pluginFuncs->newp = NPP_New;
69        pluginFuncs->destroy = NPP_Destroy;
70        pluginFuncs->setwindow = NPP_SetWindow;
71        pluginFuncs->newstream = NPP_NewStream;
72        pluginFuncs->destroystream = NPP_DestroyStream;
73        pluginFuncs->asfile = NPP_StreamAsFile;
74        pluginFuncs->writeready = NPP_WriteReady;
75        pluginFuncs->write = NPP_Write;
76        pluginFuncs->print = NPP_Print;
77        pluginFuncs->event = NPP_HandleEvent;
78        pluginFuncs->urlnotify = NPP_URLNotify;
79        pluginFuncs->getvalue = NPP_GetValue;
80        pluginFuncs->setvalue = NPP_SetValue;
81        return NPERR_NO_ERROR;
82}
83
84#if defined(XP_MACOSX) || defined(_WIN32)
85
86NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* browserFuncs) {
87        browserFunctions = browserFuncs;
88        return NPERR_NO_ERROR;
89}
90#else
91
92NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs) {
93        EstEID_log("");
94        browserFunctions = browserFuncs;
95        return NP_GetEntryPoints(pluginFuncs);
96}
97#endif
98
99NP_EXPORT(NPError) NP_Shutdown(void) {
100        EstEID_log("");
101        EstEID_freeCerts();
102        return NPERR_NO_ERROR;
103}
104
105#ifdef _WIN32
106HINSTANCE pluginInstance;
107BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
108        EstEID_log("reason: %lu", reason);
109        pluginInstance = instance;
110        if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {
111                DisableThreadLibraryCalls(instance);
112        }
113    return TRUE;
114}
115
116#else
117NP_EXPORT(const char*) NP_GetMIMEDescription() {
118        char *mime = (char *) MIME_TYPE "::" PLUGIN_NAME;
119        EstEID_log("NP_GetMIMEDescription: %s", mime);
120        return mime;
121}
122
123#endif
124
125NP_EXPORT(char*) NP_GetPluginVersion() {
126        EstEID_log("NP_GetPluginVersion: %s", ESTEID_PLUGIN_VERSION);
127        return(char *)ESTEID_PLUGIN_VERSION;
128}
129
130NP_EXPORT(NPError) NP_GetValue(void* future, NPPVariable aVariable, void* aValue) {
131        switch (aVariable) {
132                case NPPVpluginNameString:
133                        *((char**)aValue) = (char *)PLUGIN_NAME;
134                        break;
135                case NPPVpluginDescriptionString:
136                        *((char**)aValue) = (char *)PLUGIN_DESCRIPTION;
137                        break;
138                default:
139                        return NPERR_INVALID_PARAM;
140                        break;
141        }
142        return NPERR_NO_ERROR;
143}
144
145int is_allowed_protocol(char *protocol) {
146        #ifdef DEVELOPMENT_MODE
147        EstEID_log("protocol %s is allowed in development mode", protocol);
148        return TRUE;
149        #else
150        int allowed = (!STRCASECMP("https", protocol)); 
151        EstEID_log("protocol %s is %sallowed", protocol, allowed ? "" : "not ");
152        return allowed;
153        #endif
154}
155
156#define MAX_PROTOCOL_NAME_LENGTH 5
157int is_from_allowed_url(NPP instanceData) {
158
159        NPObject *windowObject = NULL;
160
161        browserFunctions->getvalue(instanceData, NPNVWindowNPObject, &windowObject);
162        NPIdentifier identifier = browserFunctions->getstringidentifier("location");
163        NPVariant variantValue;
164        browserFunctions->getproperty(instanceData, windowObject, identifier, &variantValue);
165        NPObject *locationObj = NPVARIANT_TO_OBJECT(variantValue);
166        identifier =  browserFunctions->getstringidentifier("href");
167        browserFunctions->getproperty(instanceData, locationObj, identifier, &variantValue);
168        EstEID_log("href=%s", NPVARIANT_TO_STRING(variantValue).UTF8Characters);
169        char protocol[MAX_PROTOCOL_NAME_LENGTH + 1];
170        memset(protocol, '\0', MAX_PROTOCOL_NAME_LENGTH + 1);
171        strncpy(protocol, (const char *)NPVARIANT_TO_STRING(variantValue).UTF8Characters, MAX_PROTOCOL_NAME_LENGTH);
172        char *p = protocol;
173        while(isalpha(*p)){
174                p++;
175        }
176        *p = '\0';
177
178        EstEID_log("detected protocol: %s", protocol);
179        return is_allowed_protocol(protocol);
180}
181
182
183int loadErrorShown;
184
185NPError NPP_New(NPMIMEType mimeType, NPP instanceData, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved) {
186        EstEID_log("LOADED PLUGIN PKCS11 VERSION %s", ESTEID_PLUGIN_VERSION);
187        EstEID_log("instanceData=%p, mimeType=%s", instanceData, mimeType);
188#ifdef XP_MACOSX
189        browserFunctions->setvalue(instanceData, NPPVpluginEventModel, (void*)NPEventModelCocoa);
190        browserFunctions->setvalue(instanceData, NPPVpluginDrawingModel, (void*)NPDrawingModelCoreGraphics);
191#endif
192
193#ifdef DEVELOPMENT_MODE
194        EstEID_log("*** NB! Plugin is built in development mode, all protocols are allowed! ***");
195#endif
196       
197#if defined(XP_MACOSX) && defined(__LP64__)
198        EstEID_log("Mac OSX x86_64 mode detected, dialogs are displayed in separate windows, not as sheets tied to browser window");
199#endif
200
201        browserFunctions->setvalue(instanceData, NPPVpluginWindowBool, (void*)false);
202
203        if (!EstEID_loadLibrary()) {
204                if (!loadErrorShown) {
205                        NPVariant result;
206                        char code[2048];
207                        sprintf(code, "alert('EstEID Plugin initialization failed:\\n%s');", EstEID_error);
208                        NPString codeString = {strdup(code), strlen(code)};
209                        NPObject *windowObject;
210                        browserFunctions->getvalue(instanceData, NPNVWindowNPObject, &windowObject);
211                        browserFunctions->evaluate(instanceData, windowObject, &codeString, &result);
212                        browserFunctions->releasevariantvalue(&result);
213                        loadErrorShown = 1;
214                }
215                return NPERR_MODULE_LOAD_FAILED_ERROR;
216        }
217        EstEID_log("loaded");
218        PluginInstance *pluginInstance = (PluginInstance *)browserFunctions->createobject(instanceData, pluginClass());
219        pluginInstance->npp = instanceData;
220        pluginInstance->nativeWindowHandle = NULL;     
221
222        if( is_from_allowed_url(instanceData) ) {
223                allowedSite = TRUE;
224        }
225        else {
226                allowedSite = FALSE;
227                EstEID_log("URL did dot pass examination");
228        }
229
230        instanceData->pdata = pluginInstance;
231        EstEID_log("no error on NPP_New");
232        return NPERR_NO_ERROR;
233}
234
235NPError NPP_Destroy(NPP instanceData, NPSavedData** save) {
236        EstEID_log("instanceData=%p", instanceData);
237        browserFunctions->releaseobject((NPObject *)instanceData->pdata);
238        return NPERR_NO_ERROR;
239}
240
241NPError NPP_GetValue(NPP instanceData, NPPVariable variable, void *value) {
242        LOG_LOCATION;
243        if (variable == NPPVpluginScriptableNPObject) {
244                NPObject *plugin = (NPObject *)instanceData->pdata;
245                browserFunctions->retainobject(plugin);
246                *((void **)value) = plugin;
247                return NPERR_NO_ERROR;
248        }
249        return NPERR_GENERIC_ERROR;
250}
251
252NPError NPP_SetValue(NPP instanceData, NPNVariable variable, void *value) {
253        EstEID_log("instanceData=%p, variable=%i, value=%p", instanceData, variable, value);
254        return NPERR_GENERIC_ERROR;
255}
256
257NPError NPP_SetWindow(NPP instanceData, NPWindow* window) {
258        LOG_LOCATION;
259        if (window == NULL || instanceData == NULL) return NPERR_NO_ERROR;
260        PluginInstance* currentInstance = (PluginInstance*)(instanceData->pdata);
261
262        EstEID_log("window=%p, window->window=%p, currentInstance=%p, nativeWindowHandle=%p", window, window->window, currentInstance, currentInstance->nativeWindowHandle);
263
264        if (currentInstance && window->window && (currentInstance->nativeWindowHandle != window->window)) {
265                currentInstance->nativeWindowHandle = window->window;
266                EstEID_log("nativeWindowHandle=%p", currentInstance->nativeWindowHandle);
267        }
268        EstEID_log("nativeWindowHandle=%p", currentInstance->nativeWindowHandle);
269
270        return NPERR_NO_ERROR;
271}
272
273NPError NPP_NewStream(NPP instanceData, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) {
274        return NPERR_NO_ERROR;
275}
276
277NPError NPP_DestroyStream(NPP instanceData, NPStream* stream, NPReason reason) {
278        return NPERR_NO_ERROR;
279}
280
281int32_t NPP_WriteReady(NPP instanceData, NPStream* stream) {
282        return 0;
283}
284
285int32_t NPP_Write(NPP instanceData, NPStream* stream, int32_t offset, int32_t len, void* buffer) {
286        return 0;
287}
288
289void NPP_StreamAsFile(NPP instanceData, NPStream* stream, const char* fname) {
290}
291
292void NPP_Print(NPP instanceData, NPPrint* platformPrint) {
293}
294
295int16_t NPP_HandleEvent(NPP instanceData, void* event) {
296        return 0;
297}
298
299void NPP_URLNotify(NPP instanceData, const char* url, NPReason reason, void* notifyData) {
300}
301
302void drawPlugin(NPP instanceData) {
303}
304
Note: See TracBrowser for help on using the repository browser.