[vlc-devel] Save HTTP username/passwords so the dialog doesn't pop up for each link from the same HTTP realm
James Bates
james.h.bates at gmail.com
Wed May 2 02:48:21 CEST 2012
Hello all,
I've been trying to develop the behaviour outlined in the title, and have almost succeeded (patch as it stands right now attached at bottom), but as a beginner-VLC developer, I would like some of the more experienced VLC-ers to have a look at it, before I submit an official patch.
The idea is to keep a "global" vlc_dictioary_t, indexed by HTTP REALM, with username/password pairs. Whenever a URL requires authentication, this dictionary is checked first for an entry, before the dialog box is popped up.
What I'm having most trouble with is getting a "global" variable set up: I'm using the API from vlc_variables.h, i.e. var_Get, var_Create and var_Set. The problem is that the vlc_object_t * that gets passed when the http module is called, is different on each call, and so I can't use that to create the "global" variable. As a result, I have a really ackward "find_root" function that traverses the vlc_object_t tree right the way up to the top, and using this root vlc_object_t, I do indeed seem to be able to set a "global" variable.
I imagine though that there is a more elegant way to do that. Could anyone suggest one?
Regards,
James Bates
diff --git a/modules/access/http.c b/modules/access/http.c
index 9817bca..6c1e0b8 100644
--- a/modules/access/http.c
+++ b/modules/access/http.c
@@ -192,6 +192,15 @@ struct access_sys_t
vlc_array_t * cookies;
};
+typedef struct username_password_pair_t {
+
+ char *psz_username;
+ char *psz_password;
+} username_password_pair_t;
+
+
+static vlc_object_t *find_root(vlc_object_t *o);
+
/* */
static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
unsigned i_redirect, vlc_array_t *cookies );
@@ -296,6 +305,23 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
http_auth_Init( &p_sys->auth );
http_auth_Init( &p_sys->proxy_auth );
+ /* Setup saved HTTP credentials dict, if necessary */
+ vlc_value_t val_savedpasswords;
+
+ if (var_Get(find_root(p_this), "access_http_savedpasswords", &val_savedpasswords) == VLC_ENOVAR) {
+
+ msg_Dbg( p_access, "No saved passwords dict yet => creating one");
+ val_savedpasswords.p_address = malloc(sizeof(vlc_dictionary_t));
+ vlc_dictionary_init((vlc_dictionary_t *) val_savedpasswords.p_address, 100);
+
+ var_Create(find_root(p_this), "access_http_savedpasswords", VLC_VAR_ADDRESS);
+ var_Set(find_root(p_this), "access_http_savedpasswords", val_savedpasswords);
+ }
+
+ vlc_dictionary_t *dict_savedpasswords = (vlc_dictionary_t *) val_savedpasswords.p_address;
+
+
+
/* Parse URI - remove spaces */
p = psz = strdup( p_access->psz_location );
while( (p = strchr( p, ' ' )) != NULL )
@@ -536,6 +562,31 @@ connect:
}
msg_Dbg( p_access, "authentication failed for realm %s",
p_sys->auth.psz_realm );
+
+ /* Check for saved username/password for this realm */
+ if (vlc_dictionary_has_key(dict_savedpasswords, p_sys->auth.psz_realm)) {
+
+ username_password_pair_t *credentials =
+ (username_password_pair_t *) vlc_dictionary_value_for_key(dict_savedpasswords, p_sys->auth.psz_realm);
+ p_sys->url.psz_username = strdup(credentials->psz_username);
+ p_sys->url.psz_password = strdup(credentials->psz_password);
+
+ msg_Dbg( p_access, "found saved username/password for user %s in realm %s",
+ p_sys->url.psz_username, p_sys->auth.psz_realm );
+
+ /* Clear value out of dictionary: should the cached result be wrong, and the authentication fail at the next connection
+ * attempt, then the dialog will be shown again
+ */
+ free(credentials->psz_username);
+ free(credentials->psz_password);
+ free(credentials);
+ vlc_dictionary_remove_value_for_key(dict_savedpasswords, p_sys->auth.psz_realm, NULL, NULL);
+
+ /* Attempt to connect again, with retrieved cached credentials */
+ Disconnect( p_access );
+ goto connect;
+ }
+
dialog_Login( p_access, &psz_login, &psz_password,
_("HTTP authentication"),
_("Please enter a valid login name and a password for realm %s."),
@@ -556,6 +607,18 @@ connect:
}
}
+ /* Connection authentication did not fail => save user & password if available */
+ if (p_sys->url.psz_username && p_sys->url.psz_password) {
+
+ username_password_pair_t *credentials = (username_password_pair_t *) malloc(sizeof(username_password_pair_t));
+ credentials->psz_username = strdup(p_sys->url.psz_username);
+ credentials->psz_password = strdup(p_sys->url.psz_password);
+
+ vlc_dictionary_insert(dict_savedpasswords, p_sys->auth.psz_realm, credentials);
+ msg_Dbg( p_access, "saved username/password for user %s of realm %s", p_sys->url.psz_username, p_sys->auth.psz_realm);
+ }
+
+
if( ( p_sys->i_code == 301 || p_sys->i_code == 302 ||
p_sys->i_code == 303 || p_sys->i_code == 307 ) &&
p_sys->psz_location && *p_sys->psz_location )
@@ -1776,3 +1839,14 @@ static int AuthCheckReply( access_t *p_access, const char *psz_header,
p_url->psz_username,
p_url->psz_password );
}
+
+static vlc_object_t *find_root(vlc_object_t *o) {
+
+ if (o->p_parent) {
+
+ return find_root(o->p_parent);
+ } else {
+
+ return o;
+ }
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4364 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20120502/760ad1a8/attachment.bin>
More information about the vlc-devel
mailing list