Mercurial > pidgin
comparison libpurple/protocols/oscar/clientlogin.c @ 28255:79c14adf9669
Change purple_url_encode() to not encode . _ - ~ because it's not
necessary. Also use capital letters instead of lowercase. RFC3986
says capital letters are a SHOULD and that lowercase letters should
be equivalent.
AOL's clientlogin authentication requires both of these changes for
our signature to match up with the signature generated on AOL's side.
Original I had implemented an oscar-specific version of our url
encode function with these two changes, but I'm pretty sure it's
safe to make this in purple_url_encode(). It looks like it's almost
always used to encode pieces of URLs. MSN uses it for a few other
things... I tested setting those characters in your friendly name
and it works fine.
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Fri, 11 Sep 2009 18:17:03 +0000 |
parents | 2987756bc600 |
children | 17617d892bc4 |
comparison
equal
deleted
inserted
replaced
28254:a7f47621ad53 | 28255:79c14adf9669 |
---|---|
60 od->icq ? "prpl-icq-clientkey" : "prpl-aim-clientkey", | 60 od->icq ? "prpl-icq-clientkey" : "prpl-aim-clientkey", |
61 DEFAULT_CLIENT_KEY); | 61 DEFAULT_CLIENT_KEY); |
62 } | 62 } |
63 | 63 |
64 /** | 64 /** |
65 * This is similar to purple_url_encode() except that it follows | |
66 * RFC3986 a little more closely by not encoding - . _ and ~ | |
67 * It also uses capital letters as hex characters because capital | |
68 * letters are required by AOL. The RFC says that capital letters | |
69 * are a SHOULD and that URLs that use capital letters are | |
70 * equivalent to URLs that use small letters. | |
71 * | |
72 * TODO: Check if purple_url_encode() can be replaced with this | |
73 * version without breaking anything. | |
74 */ | |
75 static const char *oscar_auth_url_encode(const char *str) | |
76 { | |
77 const char *iter; | |
78 static char buf[BUF_LEN]; | |
79 char utf_char[6]; | |
80 guint i, j = 0; | |
81 | |
82 g_return_val_if_fail(str != NULL, NULL); | |
83 g_return_val_if_fail(g_utf8_validate(str, -1, NULL), NULL); | |
84 | |
85 iter = str; | |
86 for (; *iter && j < (BUF_LEN - 1) ; iter = g_utf8_next_char(iter)) { | |
87 gunichar c = g_utf8_get_char(iter); | |
88 /* If the character is an ASCII character and is alphanumeric | |
89 * no need to escape */ | |
90 if ((c < 128 && isalnum(c)) || c =='-' || c == '.' || c == '_' || c == '~') { | |
91 buf[j++] = c; | |
92 } else { | |
93 int bytes = g_unichar_to_utf8(c, utf_char); | |
94 for (i = 0; i < bytes; i++) { | |
95 if (j > (BUF_LEN - 4)) | |
96 break; | |
97 sprintf(buf + j, "%%%02X", utf_char[i] & 0xff); | |
98 j += 3; | |
99 } | |
100 } | |
101 } | |
102 | |
103 buf[j] = '\0'; | |
104 | |
105 return buf; | |
106 } | |
107 | |
108 /** | |
109 * @return A null-terminated base64 encoded version of the HMAC | 65 * @return A null-terminated base64 encoded version of the HMAC |
110 * calculated using the given key and data. | 66 * calculated using the given key and data. |
111 */ | 67 */ |
112 static gchar *hmac_sha256(const char *key, const char *message) | 68 static gchar *hmac_sha256(const char *key, const char *message) |
113 { | 69 { |
132 static gchar *generate_signature(const char *method, const char *url, const char *parameters, const char *session_key) | 88 static gchar *generate_signature(const char *method, const char *url, const char *parameters, const char *session_key) |
133 { | 89 { |
134 char *encoded_url, *signature_base_string, *signature; | 90 char *encoded_url, *signature_base_string, *signature; |
135 const char *encoded_parameters; | 91 const char *encoded_parameters; |
136 | 92 |
137 encoded_url = g_strdup(oscar_auth_url_encode(url)); | 93 encoded_url = g_strdup(purple_url_encode(url)); |
138 encoded_parameters = oscar_auth_url_encode(parameters); | 94 encoded_parameters = purple_url_encode(parameters); |
139 signature_base_string = g_strdup_printf("%s&%s&%s", | 95 signature_base_string = g_strdup_printf("%s&%s&%s", |
140 method, encoded_url, encoded_parameters); | 96 method, encoded_url, encoded_parameters); |
141 g_free(encoded_url); | 97 g_free(encoded_url); |
142 | 98 |
143 signature = hmac_sha256(session_key, signature_base_string); | 99 signature = hmac_sha256(session_key, signature_base_string); |
307 query_string = g_strdup_printf("a=%s" | 263 query_string = g_strdup_printf("a=%s" |
308 "&f=xml" | 264 "&f=xml" |
309 "&k=%s" | 265 "&k=%s" |
310 "&ts=%" PURPLE_TIME_T_MODIFIER | 266 "&ts=%" PURPLE_TIME_T_MODIFIER |
311 "&useTLS=0", | 267 "&useTLS=0", |
312 oscar_auth_url_encode(token), get_client_key(od), hosttime); | 268 purple_url_encode(token), get_client_key(od), hosttime); |
313 signature = generate_signature("GET", URL_START_OSCAR_SESSION, | 269 signature = generate_signature("GET", URL_START_OSCAR_SESSION, |
314 query_string, session_key); | 270 query_string, session_key); |
315 url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s", | 271 url = g_strdup_printf(URL_START_OSCAR_SESSION "?%s&sig_sha256=%s", |
316 query_string, signature); | 272 query_string, signature); |
317 g_free(query_string); | 273 g_free(query_string); |
551 | 507 |
552 /* Construct the body of the HTTP POST request */ | 508 /* Construct the body of the HTTP POST request */ |
553 body = g_string_new(""); | 509 body = g_string_new(""); |
554 g_string_append_printf(body, "devId=%s", get_client_key(od)); | 510 g_string_append_printf(body, "devId=%s", get_client_key(od)); |
555 g_string_append_printf(body, "&f=xml"); | 511 g_string_append_printf(body, "&f=xml"); |
556 g_string_append_printf(body, "&pwd=%s", oscar_auth_url_encode(password)); | 512 g_string_append_printf(body, "&pwd=%s", purple_url_encode(password)); |
557 g_string_append_printf(body, "&s=%s", oscar_auth_url_encode(username)); | 513 g_string_append_printf(body, "&s=%s", purple_url_encode(username)); |
558 g_free(password); | 514 g_free(password); |
559 | 515 |
560 /* Construct an HTTP POST request */ | 516 /* Construct an HTTP POST request */ |
561 request = g_string_new("POST /auth/clientLogin HTTP/1.0\r\n" | 517 request = g_string_new("POST /auth/clientLogin HTTP/1.0\r\n" |
562 "Connection: close\r\n" | 518 "Connection: close\r\n" |