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>
17 #include "midori/sokoke.h"
19 #include <gnome-keyring.h>
20 #include <glib/gstdio.h>
26 #define LIBPREFIX "lib"
29 static GHashTable
* log_pass
;
30 static gchar
* jspassm
;
33 passwman_prepare_js ()
35 gchar
* passwordmanager
;
39 file
= sokoke_find_data_filename ("passwordmanager.js", TRUE
);
40 if (!g_file_get_contents (file
, &passwordmanager
, NULL
, NULL
))
45 g_strchomp (passwordmanager
);
47 jspassm
= g_strdup_printf ( "%s", passwordmanager
);
50 g_free (passwordmanager
);
55 gchar* passwordmanager;
58 data_name = g_build_filename (PACKAGE_NAME, "res", NULL);
59 data_path = sokoke_find_data_filename (data_name,TRUE);
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))
65 g_strchomp (passwordmanager);
67 jspassm = g_strdup_printf ( "%s", passwordmanager );
71 g_free (passwordmanager);
76 cleanurl( const gchar
*url
)
81 if ( ( id
= g_strstr_len(url
+8,il
,"/") ) != NULL
)
84 cleaned
= g_strndup(url
,lprt
);
87 cleaned
= g_strdup(url
);
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);"
102 "window.addEventListener('load',"
103 "function() {PassMan.fillogpass(document);} , true);",
112 passwman_navigation_decision_cb (WebKitWebView
* web_view
,
113 WebKitWebFrame
* web_frame
,
114 WebKitNetworkRequest
* request
,
115 WebKitWebNavigationAction
* action
,
116 WebKitWebPolicyDecision
* decision
,
117 MidoriExtension
* extension
)
120 url
= cleanurl( webkit_web_view_get_uri(web_view
) );
123 gchar
*array
, *script
;
124 array
= g_hash_table_lookup(log_pass
,url
);
126 script
= g_strdup_printf ("function getValue() { "
127 "var values = new Array();"
131 "PassMan.dologpass(document);"
135 script
= g_strdup_printf ("function getValue() { "
136 "var values = new Array(%s);"
140 "PassMan.dologpass(document);"
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
);
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__",
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
,
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
);
204 sokoke_js_script_eval (js_context
, script
, NULL
);
211 passwman_add_tab_cb (MidoriBrowser
* browser
,
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
);
223 passwman_deactivate_cb (MidoriExtension
* extension
,
224 MidoriBrowser
* browser
);
227 passwman_add_tab_foreach_cb (MidoriView
* view
,
228 MidoriBrowser
* browser
,
229 MidoriExtension
* extension
)
231 passwman_add_tab_cb (browser
, view
, extension
);
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
);
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
);
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
);
276 g_hash_table_destroy (log_pass
);
280 passwman_activate_cb (MidoriExtension
* extension
,
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
);
290 passwman_prepare_js();
291 GnomeKeyringResult res
; GList
*results
; results
= NULL
;
292 res
= gnome_keyring_find_network_password_sync(NULL
,
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\"");
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
);
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
);
337 extension_init (void)
339 gboolean should_init
= TRUE
;
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"));
351 desc
= g_strdup_printf (_("Not available: %s"),
352 _("Resource files or gnome-keyring"));
357 extension
= g_object_new (MIDORI_TYPE_EXTENSION
,
358 "name", _("Password Manager"),
361 "authors", "Giuseppe Borzi <gborzi@ieee.org>",
366 g_signal_connect (extension
, "activate",
367 G_CALLBACK (passwman_activate_cb
), NULL
);