updated on Thu Jan 26 16:09:46 UTC 2012
[aur-mirror.git] / midori-passwordmanager / passwordmanager.c
blobb28858806eaedf5eeecacdb09b16f06e1306fb20
1 /*
2 Copyright (C) 2011 Giuseppe Borzi <gborzi@ieee.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 Derived from formhistory.c extension, copyrighted by
10 Alexander Butenko <a.butenka@gmail.com>
11 Christian Dywan <christian@twotoasts.de>
14 #include <midori/midori.h>
16 #include "config.h"
17 #include "midori/sokoke.h"
19 #include <gnome-keyring.h>
20 #include <glib/gstdio.h>
21 #include <stdlib.h>
23 #ifdef G_OS_WIN32
24 #define LIBPREFIX ""
25 #else
26 #define LIBPREFIX "lib"
27 #endif
29 static GHashTable* log_pass;
30 static gchar* jspassm;
32 static gboolean
33 passwman_prepare_js ()
35 gchar* passwordmanager;
36 guint i;
37 gchar* file;
39 file = sokoke_find_data_filename ("passwordmanager.js", TRUE);
40 if (!g_file_get_contents (file, &passwordmanager, NULL, NULL))
42 g_free (file);
43 return FALSE;
45 g_strchomp (passwordmanager);
47 jspassm = g_strdup_printf ( "%s", passwordmanager );
48 g_strstrip (jspassm);
49 g_free (file);
50 g_free (passwordmanager);
52 return TRUE;
53 /* gchar* data_name;
54 gchar* data_path;
55 gchar* passwordmanager;
56 gchar* file;
58 data_name = g_build_filename (PACKAGE_NAME, "res", NULL);
59 data_path = sokoke_find_data_filename (data_name,TRUE);
60 g_free (data_name);
61 file = g_build_filename(data_path,G_DIR_SEPARATOR_S,\
62 "passwordmanager.js",NULL);
63 if (!g_file_get_contents (file, &passwordmanager, NULL, NULL))
64 return FALSE;
65 g_strchomp (passwordmanager);
67 jspassm = g_strdup_printf ( "%s", passwordmanager );
68 g_strstrip (jspassm);
69 g_free (data_path);
70 g_free (file);
71 g_free (passwordmanager);
72 return TRUE;*/
75 static gchar*
76 cleanurl( const gchar *url )
78 gchar *cleaned, *id;
79 gssize il = -1;
80 gsize lprt;
81 if ( ( id = g_strstr_len(url+8,il,"/") ) != NULL )
83 lprt = id - url;
84 cleaned = g_strndup(url,lprt);
86 else
87 cleaned = g_strdup(url);
88 return cleaned;
91 static gchar*
92 passwman_build_js( const gchar *url )
94 gchar* script, *array;
96 if ( log_pass && ( array = g_hash_table_lookup(log_pass,url) ) )
97 script = g_strdup_printf("function getValue() { "
98 "var values = new Array(%s);"
99 "return values;"
100 "};"
101 "%s"
102 "window.addEventListener('load',"
103 "function() {PassMan.fillogpass(document);} , true);",
104 array,
105 jspassm);
106 else
107 script = NULL;
108 return script;
111 static gboolean
112 passwman_navigation_decision_cb (WebKitWebView* web_view,
113 WebKitWebFrame* web_frame,
114 WebKitNetworkRequest* request,
115 WebKitWebNavigationAction* action,
116 WebKitWebPolicyDecision* decision,
117 MidoriExtension* extension)
119 gchar* url;
120 url = cleanurl( webkit_web_view_get_uri(web_view) );
121 if ( log_pass )
123 gchar *array, *script;
124 array = g_hash_table_lookup(log_pass,url);
125 if ( array == NULL )
126 script = g_strdup_printf ("function getValue() { "
127 "var values = new Array();"
128 "return values;"
129 "};"
130 "%s"
131 "PassMan.dologpass(document);"
132 "Store.dump();",
133 jspassm);
134 else
135 script = g_strdup_printf ("function getValue() { "
136 "var values = new Array(%s);"
137 "return values;"
138 "};"
139 "%s"
140 "PassMan.dologpass(document);"
141 "Store.dump();",
142 array,
143 jspassm);
144 if (webkit_web_navigation_action_get_reason (action) == \
145 WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED)
147 JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
148 gchar* value = sokoke_js_script_eval (js_context, script, NULL);
149 if (value && *value)
151 guint32 item_id;
152 g_hash_table_insert(log_pass,g_strdup(url),g_strdup(value));
153 if ( g_strcmp0(value,"\"0\"") == 0 )
154 gnome_keyring_set_network_password_sync(NULL,
155 "__never_store_here__",
156 "midori",
157 url,
158 NULL,
159 NULL,
160 NULL,
162 "whatever",
163 &item_id);
164 else
166 gchar *id;
167 gchar **up;
168 gsize lprt;
169 id = g_strrstr(value,"\",\""); lprt = id-value;
170 id = g_strrstr_len(value,lprt,"\",\""); id += 3;
171 up = g_strsplit(id,"\"",4);
172 gnome_keyring_set_network_password_sync(NULL,
173 up[0],
174 "midori",
175 url,
176 NULL,
177 NULL,
178 NULL,
180 up[2],
181 &item_id);
182 g_strfreev(up);
188 g_free(script);
190 g_free(url);
191 return FALSE;
194 static void
195 passwman_window_object_cleared_cb (WebKitWebView* web_view,
196 WebKitWebFrame* web_frame,
197 JSContextRef js_context,
198 JSObjectRef js_window)
200 gchar* url; gchar* script;
201 url = cleanurl( webkit_web_view_get_uri(web_view) );
202 script = passwman_build_js (url);
203 if ( script ) {
204 sokoke_js_script_eval (js_context, script, NULL);
205 g_free (script);
207 g_free(url);
210 static void
211 passwman_add_tab_cb (MidoriBrowser* browser,
212 MidoriView* view,
213 MidoriExtension* extension)
215 GtkWidget* web_view = midori_view_get_web_view (view);
216 g_signal_connect (web_view, "window-object-cleared",
217 G_CALLBACK (passwman_window_object_cleared_cb), NULL);
218 g_signal_connect (web_view, "navigation-policy-decision-requested",
219 G_CALLBACK (passwman_navigation_decision_cb), extension);
222 static void
223 passwman_deactivate_cb (MidoriExtension* extension,
224 MidoriBrowser* browser);
226 static void
227 passwman_add_tab_foreach_cb (MidoriView* view,
228 MidoriBrowser* browser,
229 MidoriExtension* extension)
231 passwman_add_tab_cb (browser, view, extension);
234 static void
235 passwman_app_add_browser_cb (MidoriApp* app,
236 MidoriBrowser* browser,
237 MidoriExtension* extension)
239 midori_browser_foreach (browser,
240 (GtkCallback)passwman_add_tab_foreach_cb, extension);
241 g_signal_connect (browser, "add-tab",
242 G_CALLBACK (passwman_add_tab_cb), extension);
243 g_signal_connect (extension, "deactivate",
244 G_CALLBACK (passwman_deactivate_cb), browser);
247 static void
248 passwman_deactivate_tabs (MidoriView* view,
249 MidoriBrowser* browser,
250 MidoriExtension* extension)
252 GtkWidget* web_view = midori_view_get_web_view (view);
253 g_signal_handlers_disconnect_by_func (
254 web_view, passwman_window_object_cleared_cb, NULL);
255 g_signal_handlers_disconnect_by_func (
256 web_view, passwman_navigation_decision_cb, extension);
259 static void
260 passwman_deactivate_cb(MidoriExtension* extension,
261 MidoriBrowser* browser)
263 MidoriApp* app = midori_extension_get_app (extension);
265 g_signal_handlers_disconnect_by_func (
266 browser, passwman_add_tab_cb, extension);
267 g_signal_handlers_disconnect_by_func (
268 extension, passwman_deactivate_cb, browser);
269 g_signal_handlers_disconnect_by_func (
270 app, passwman_app_add_browser_cb, extension);
271 midori_browser_foreach (browser,
272 (GtkCallback)passwman_deactivate_tabs, extension);
274 katze_assign (jspassm, NULL);
275 if (log_pass)
276 g_hash_table_destroy (log_pass);
279 static void
280 passwman_activate_cb (MidoriExtension* extension,
281 MidoriApp* app)
283 KatzeArray* browsers;
284 MidoriBrowser* browser;
286 log_pass = g_hash_table_new_full (g_str_hash, g_str_equal,
287 (GDestroyNotify)g_free,
288 (GDestroyNotify)g_free);
289 if ( !jspassm )
290 passwman_prepare_js();
291 GnomeKeyringResult res; GList *results; results = NULL;
292 res = gnome_keyring_find_network_password_sync(NULL,
293 "midori",
294 NULL,
295 NULL,
296 NULL,
297 NULL,
299 &results);
300 if ( res == GNOME_KEYRING_RESULT_OK ) {
301 GList *r; gchar *nlp; gchar *server; gchar *tmp;
302 for( r = results; r; r = r->next ) {
303 GnomeKeyringNetworkPasswordData* data = \
304 (GnomeKeyringNetworkPasswordData*)r->data;
305 server = data->server;
306 if ( g_strcmp0(data->user,"__never_store_here__") == 0 )
307 nlp = g_strdup("\"0\"");
308 else if ( ( tmp = g_hash_table_lookup(log_pass,server) ) )
310 if ( g_strcmp0(tmp,"\"0\"") == 0 )
311 nlp = g_strdup("\"0\"");
312 else
314 gssize il = -1; gchar *id, *num; gsize lprt, n;
315 id = g_strstr_len(tmp,il,","); lprt = id - tmp -1;
316 num = g_strndup(tmp+1,lprt); n = atoi(num)+1;
317 nlp = g_strdup_printf("\"%i\"%s,\"%s\",\"%s\"",n,id,\
318 data->user,data->password);
321 else
322 nlp = g_strdup_printf("\"1\",\"%s\",\"%s\"",data->user,data->password);
323 g_hash_table_insert(log_pass,g_strdup(server),nlp);
325 gnome_keyring_network_password_list_free(results);
327 browsers = katze_object_get_object (app, "browsers");
328 KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
329 passwman_app_add_browser_cb (app, browser, extension);
330 g_signal_connect (app, "add-browser",
331 G_CALLBACK (passwman_app_add_browser_cb), extension);
333 g_object_unref (browsers);
336 MidoriExtension*
337 extension_init (void)
339 gboolean should_init = TRUE;
340 const gchar* ver;
341 gchar* desc;
342 MidoriExtension* extension;
344 if ( passwman_prepare_js() && gnome_keyring_is_available() )
346 ver = "0.3" MIDORI_VERSION_SUFFIX;
347 desc = g_strdup (_("Stores login/password data"));
349 else
351 desc = g_strdup_printf (_("Not available: %s"),
352 _("Resource files or gnome-keyring"));
353 ver = NULL;
354 should_init = FALSE;
357 extension = g_object_new (MIDORI_TYPE_EXTENSION,
358 "name", _("Password Manager"),
359 "description", desc,
360 "version", ver,
361 "authors", "Giuseppe Borzi <gborzi@ieee.org>",
362 NULL);
363 g_free (desc);
365 if (should_init)
366 g_signal_connect (extension, "activate",
367 G_CALLBACK (passwman_activate_cb), NULL);
369 return extension;