comparison libpurple/util.c @ 30578:0accc8adb18a

merge of '2f6318bd834113559a405ec68cdb178f2180b680' and '64e02b98551e11e093e4649f1516f3aceaa321e2'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 26 Sep 2010 20:16:15 +0000
parents 839f3d63acab
children 1b67c62c1051
comparison
equal deleted inserted replaced
30577:7b761c8601f7 30578:0accc8adb18a
26 #include "cipher.h" 26 #include "cipher.h"
27 #include "conversation.h" 27 #include "conversation.h"
28 #include "core.h" 28 #include "core.h"
29 #include "debug.h" 29 #include "debug.h"
30 #include "notify.h" 30 #include "notify.h"
31 #include "ntlm.h"
31 #include "prpl.h" 32 #include "prpl.h"
32 #include "prefs.h" 33 #include "prefs.h"
33 #include "util.h" 34 #include "util.h"
34 35
35 struct _PurpleUtilFetchUrlData 36 struct _PurpleUtilFetchUrlData
67 char *webdata; 68 char *webdata;
68 gsize len; 69 gsize len;
69 unsigned long data_len; 70 unsigned long data_len;
70 gssize max_len; 71 gssize max_len;
71 gboolean chunked; 72 gboolean chunked;
73 PurpleAccount *account;
72 }; 74 };
73 75
74 static char *custom_user_dir = NULL; 76 static char *custom_user_dir = NULL;
75 static char *user_dir = NULL; 77 static char *user_dir = NULL;
76 78
2051 return TRUE; 2053 return TRUE;
2052 } 2054 }
2053 return FALSE; 2055 return FALSE;
2054 } 2056 }
2055 2057
2058 static const char *
2059 process_link(GString *ret,
2060 const char *start, const char *c,
2061 int matchlen,
2062 const char *urlprefix,
2063 int inside_paren)
2064 {
2065 char *url_buf, *tmpurlbuf;
2066 const char *t;
2067
2068 for (t = c;; t++) {
2069 if (!badchar(*t) && !badentity(t))
2070 continue;
2071
2072 if (t - c == matchlen)
2073 break;
2074
2075 if (*t == ',' && *(t + 1) != ' ') {
2076 continue;
2077 }
2078
2079 if (t > start && *(t - 1) == '.')
2080 t--;
2081 if (t > start && *(t - 1) == ')' && inside_paren > 0)
2082 t--;
2083
2084 url_buf = g_strndup(c, t - c);
2085 tmpurlbuf = purple_unescape_html(url_buf);
2086 g_string_append_printf(ret, "<A HREF=\"%s%s\">%s</A>",
2087 urlprefix,
2088 tmpurlbuf, url_buf);
2089 g_free(tmpurlbuf);
2090 g_free(url_buf);
2091 return t;
2092 }
2093
2094 return c;
2095 }
2096
2056 char * 2097 char *
2057 purple_markup_linkify(const char *text) 2098 purple_markup_linkify(const char *text)
2058 { 2099 {
2059 const char *c, *t, *q = NULL; 2100 const char *c, *t, *q = NULL;
2060 char *tmpurlbuf, *url_buf; 2101 char *tmpurlbuf, *url_buf;
2098 c++; 2139 c++;
2099 if (!(*c)) 2140 if (!(*c))
2100 break; 2141 break;
2101 } 2142 }
2102 } 2143 }
2103 } else if ((*c=='h') && (!g_ascii_strncasecmp(c, "http://", 7) || 2144 } else if (!g_ascii_strncasecmp(c, "http://", 7)) {
2104 (!g_ascii_strncasecmp(c, "https://", 8)))) { 2145 c = process_link(ret, text, c, 7, "", inside_paren);
2105 t = c; 2146 } else if (!g_ascii_strncasecmp(c, "https://", 8)) {
2106 while (1) { 2147 c = process_link(ret, text, c, 8, "", inside_paren);
2107 if (badchar(*t) || badentity(t)) { 2148 } else if (!g_ascii_strncasecmp(c, "ftp://", 6)) {
2108 2149 c = process_link(ret, text, c, 6, "", inside_paren);
2109 if ((!g_ascii_strncasecmp(c, "http://", 7) && (t - c == 7)) || 2150 } else if (!g_ascii_strncasecmp(c, "sftp://", 7)) {
2110 (!g_ascii_strncasecmp(c, "https://", 8) && (t - c == 8))) { 2151 c = process_link(ret, text, c, 7, "", inside_paren);
2111 break; 2152 } else if (!g_ascii_strncasecmp(c, "file://", 7)) {
2112 } 2153 c = process_link(ret, text, c, 7, "", inside_paren);
2113 2154 } else if (!g_ascii_strncasecmp(c, "www.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) {
2114 if (*(t) == ',' && (*(t + 1) != ' ')) { 2155 c = process_link(ret, text, c, 4, "http://", inside_paren);
2115 t++; 2156 } else if (!g_ascii_strncasecmp(c, "ftp.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) {
2116 continue; 2157 c = process_link(ret, text, c, 4, "ftp://", inside_paren);
2117 } 2158 } else if (!g_ascii_strncasecmp(c, "xmpp:", 5) && (c == text || badchar(c[-1]) || badentity(c-1))) {
2118 2159 c = process_link(ret, text, c, 5, "", inside_paren);
2119 if (*(t - 1) == '.')
2120 t--;
2121 if ((*(t - 1) == ')' && (inside_paren > 0))) {
2122 t--;
2123 }
2124
2125 url_buf = g_strndup(c, t - c);
2126 tmpurlbuf = purple_unescape_html(url_buf);
2127 g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>",
2128 tmpurlbuf, url_buf);
2129 g_free(url_buf);
2130 g_free(tmpurlbuf);
2131 c = t;
2132 break;
2133 }
2134 t++;
2135
2136 }
2137 } else if (!g_ascii_strncasecmp(c, "www.", 4) && (c == text || badchar(c[-1]) || badentity(c-1))) {
2138 if (c[4] != '.') {
2139 t = c;
2140 while (1) {
2141 if (badchar(*t) || badentity(t)) {
2142 if (t - c == 4) {
2143 break;
2144 }
2145
2146 if (*(t) == ',' && (*(t + 1) != ' ')) {
2147 t++;
2148 continue;
2149 }
2150
2151 if (*(t - 1) == '.')
2152 t--;
2153 if ((*(t - 1) == ')' && (inside_paren > 0))) {
2154 t--;
2155 }
2156 url_buf = g_strndup(c, t - c);
2157 tmpurlbuf = purple_unescape_html(url_buf);
2158 g_string_append_printf(ret,
2159 "<A HREF=\"http://%s\">%s</A>", tmpurlbuf,
2160 url_buf);
2161 g_free(url_buf);
2162 g_free(tmpurlbuf);
2163 c = t;
2164 break;
2165 }
2166 t++;
2167 }
2168 }
2169 } else if (!g_ascii_strncasecmp(c, "ftp://", 6) || !g_ascii_strncasecmp(c, "sftp://", 7)) {
2170 t = c;
2171 while (1) {
2172 if (badchar(*t) || badentity(t)) {
2173
2174 if ((!g_ascii_strncasecmp(c, "ftp://", 6) && (t - c == 6)) ||
2175 (!g_ascii_strncasecmp(c, "sftp://", 7) && (t - c == 7))) {
2176 break;
2177 }
2178
2179 if (*(t - 1) == '.')
2180 t--;
2181 if ((*(t - 1) == ')' && (inside_paren > 0))) {
2182 t--;
2183 }
2184 url_buf = g_strndup(c, t - c);
2185 tmpurlbuf = purple_unescape_html(url_buf);
2186 g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>",
2187 tmpurlbuf, url_buf);
2188 g_free(url_buf);
2189 g_free(tmpurlbuf);
2190 c = t;
2191 break;
2192 }
2193 if (!t)
2194 break;
2195 t++;
2196
2197 }
2198 } else if (!g_ascii_strncasecmp(c, "ftp.", 4) && (c == text || badchar(c[-1]) || badentity(c-1))) {
2199 if (c[4] != '.') {
2200 t = c;
2201 while (1) {
2202 if (badchar(*t) || badentity(t)) {
2203 if (t - c == 4) {
2204 break;
2205 }
2206 if (*(t - 1) == '.')
2207 t--;
2208 if ((*(t - 1) == ')' && (inside_paren > 0))) {
2209 t--;
2210 }
2211 url_buf = g_strndup(c, t - c);
2212 tmpurlbuf = purple_unescape_html(url_buf);
2213 g_string_append_printf(ret,
2214 "<A HREF=\"ftp://%s\">%s</A>", tmpurlbuf,
2215 url_buf);
2216 g_free(url_buf);
2217 g_free(tmpurlbuf);
2218 c = t;
2219 break;
2220 }
2221 if (!t)
2222 break;
2223 t++;
2224 }
2225 }
2226 } else if (!g_ascii_strncasecmp(c, "mailto:", 7)) { 2160 } else if (!g_ascii_strncasecmp(c, "mailto:", 7)) {
2227 t = c; 2161 t = c;
2228 while (1) { 2162 while (1) {
2229 if (badchar(*t) || badentity(t)) { 2163 if (badchar(*t) || badentity(t)) {
2230 char *d; 2164 char *d;
2231 if (t - c == 7) { 2165 if (t - c == 7) {
2232 break; 2166 break;
2233 } 2167 }
2234 if (*(t - 1) == '.') 2168 if (t > text && *(t - 1) == '.')
2235 t--; 2169 t--;
2236 if ((d = strstr(c + 7, "?")) != NULL && d < t) 2170 if ((d = strstr(c + 7, "?")) != NULL && d < t)
2237 url_buf = g_strndup(c + 7, d - c - 7); 2171 url_buf = g_strndup(c + 7, d - c - 7);
2238 else 2172 else
2239 url_buf = g_strndup(c + 7, t - c - 7); 2173 url_buf = g_strndup(c + 7, t - c - 7);
2249 g_free(url_buf); 2183 g_free(url_buf);
2250 g_free(tmpurlbuf); 2184 g_free(tmpurlbuf);
2251 c = t; 2185 c = t;
2252 break; 2186 break;
2253 } 2187 }
2254 if (!t)
2255 break;
2256 t++; 2188 t++;
2257
2258 }
2259 } else if ((*c=='x') && (!g_ascii_strncasecmp(c, "xmpp:", 5)) &&
2260 (c == text || badchar(c[-1]) || badentity(c-1))) {
2261 t = c;
2262 while (1) {
2263 if (badchar(*t) || badentity(t)) {
2264
2265 if (t - c == 5) {
2266 break;
2267 }
2268
2269 if (*(t) == ',' && (*(t + 1) != ' ')) {
2270 t++;
2271 continue;
2272 }
2273
2274 if (*(t - 1) == '.')
2275 t--;
2276 if ((*(t - 1) == ')' && (inside_paren > 0))) {
2277 t--;
2278 }
2279
2280 url_buf = g_strndup(c, t - c);
2281 tmpurlbuf = purple_unescape_html(url_buf);
2282 g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>",
2283 tmpurlbuf, url_buf);
2284 g_free(url_buf);
2285 g_free(tmpurlbuf);
2286 c = t;
2287 break;
2288 }
2289 t++;
2290
2291 } 2189 }
2292 } else if (c != text && (*c == '@')) { 2190 } else if (c != text && (*c == '@')) {
2293 int flag; 2191 int flag;
2294 GString *gurl_buf = NULL; 2192 GString *gurl_buf = NULL;
2295 const char illegal_chars[] = "!@#$%^&*()[]{}/|\\<>\":;\r\n \0"; 2193 const char illegal_chars[] = "!@#$%^&*()[]{}/|\\<>\":;\r\n \0";
2912 } 2810 }
2913 2811
2914 progname = g_find_program_in_path(argv[0]); 2812 progname = g_find_program_in_path(argv[0]);
2915 is_valid = (progname != NULL); 2813 is_valid = (progname != NULL);
2916 2814
2815 if(purple_debug_is_verbose())
2816 purple_debug_info("program_is_valid", "Tested program %s. %s.\n", program,
2817 is_valid ? "Valid" : "Invalid");
2818
2917 g_strfreev(argv); 2819 g_strfreev(argv);
2918 g_free(progname); 2820 g_free(progname);
2919 2821
2920 return is_valid; 2822 return is_valid;
2921 } 2823 }
3215 3117
3216 for (i = 0, j = 0; text[i]; i++) 3118 for (i = 0, j = 0; text[i]; i++)
3217 if (text[i] != thechar) 3119 if (text[i] != thechar)
3218 text[j++] = text[i]; 3120 text[j++] = text[i];
3219 3121
3220 text[j++] = '\0'; 3122 text[j] = '\0';
3221 } 3123 }
3222 3124
3223 void 3125 void
3224 purple_util_chrreplace(char *string, char delimiter, 3126 purple_util_chrreplace(char *string, char delimiter,
3225 char replacement) 3127 char replacement)
3523 gboolean 3425 gboolean
3524 purple_url_parse(const char *url, char **ret_host, int *ret_port, 3426 purple_url_parse(const char *url, char **ret_host, int *ret_port,
3525 char **ret_path, char **ret_user, char **ret_passwd) 3427 char **ret_path, char **ret_user, char **ret_passwd)
3526 { 3428 {
3527 gboolean is_https = FALSE; 3429 gboolean is_https = FALSE;
3528 char scan_info[255]; 3430 const char * scan_info;
3529 char port_str[6]; 3431 char port_str[6];
3530 int f; 3432 int f;
3531 const char *at, *slash; 3433 const char *at, *slash;
3532 const char *turl; 3434 const char *turl;
3533 char host[256], path[256], user[256], passwd[256]; 3435 char host[256], path[256], user[256], passwd[256];
3534 int port = 0; 3436 int port = 0;
3535 /* hyphen at end includes it in control set */ 3437 /* hyphen at end includes it in control set */
3536 static const char addr_ctrl[] = "A-Za-z0-9.-"; 3438
3537 static const char port_ctrl[] = "0-9"; 3439 #define ADDR_CTRL "A-Za-z0-9.-"
3538 static const char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-"; 3440 #define PORT_CTRL "0-9"
3539 static const char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3441 #define PAGE_CTRL "A-Za-z0-9.~_/:*!@&%%?=+^-"
3540 static const char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3442 #define USER_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
3443 #define PASSWD_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
3541 3444
3542 g_return_val_if_fail(url != NULL, FALSE); 3445 g_return_val_if_fail(url != NULL, FALSE);
3543 3446
3544 if ((turl = purple_strcasestr(url, "http://")) != NULL) 3447 if ((turl = purple_strcasestr(url, "http://")) != NULL)
3545 { 3448 {
3555 3458
3556 /* parse out authentication information if supplied */ 3459 /* parse out authentication information if supplied */
3557 /* Only care about @ char BEFORE the first / */ 3460 /* Only care about @ char BEFORE the first / */
3558 at = strchr(url, '@'); 3461 at = strchr(url, '@');
3559 slash = strchr(url, '/'); 3462 slash = strchr(url, '/');
3560 if ((at != NULL) && 3463 f = 0;
3561 (((slash != NULL) && (strlen(at) > strlen(slash))) || 3464 if (at && (!slash || at < slash)) {
3562 (slash == NULL))) { 3465 scan_info = "%255[" USER_CTRL "]:%255[" PASSWD_CTRL "]^@";
3563 g_snprintf(scan_info, sizeof(scan_info),
3564 "%%255[%s]:%%255[%s]^@", user_ctrl, passwd_ctrl);
3565 f = sscanf(url, scan_info, user, passwd); 3466 f = sscanf(url, scan_info, user, passwd);
3566 3467
3567 if (f ==1 ) { 3468 if (f == 1) {
3568 /* No passwd, possibly just username supplied */ 3469 /* No passwd, possibly just username supplied */
3569 g_snprintf(scan_info, sizeof(scan_info), 3470 scan_info = "%255[" USER_CTRL "]^@";
3570 "%%255[%s]^@", user_ctrl);
3571 f = sscanf(url, scan_info, user); 3471 f = sscanf(url, scan_info, user);
3572 *passwd = '\0';
3573 } 3472 }
3574 3473
3575 url = at+1; /* move pointer after the @ char */ 3474 url = at+1; /* move pointer after the @ char */
3576 } else { 3475 }
3476
3477 if (f < 1) {
3577 *user = '\0'; 3478 *user = '\0';
3578 *passwd = '\0'; 3479 *passwd = '\0';
3579 } 3480 } else if (f == 1)
3580 3481 *passwd = '\0';
3581 g_snprintf(scan_info, sizeof(scan_info), 3482
3582 "%%255[%s]:%%5[%s]/%%255[%s]", addr_ctrl, port_ctrl, page_ctrl); 3483 scan_info = "%255[" ADDR_CTRL "]:%5[" PORT_CTRL "]/%255[" PAGE_CTRL "]";
3583
3584 f = sscanf(url, scan_info, host, port_str, path); 3484 f = sscanf(url, scan_info, host, port_str, path);
3585 3485
3586 if (f == 1) 3486 if (f == 1)
3587 { 3487 {
3588 g_snprintf(scan_info, sizeof(scan_info), 3488 scan_info = "%255[" ADDR_CTRL "]/%255[" PAGE_CTRL "]";
3589 "%%255[%s]/%%255[%s]",
3590 addr_ctrl, page_ctrl);
3591 f = sscanf(url, scan_info, host, path); 3489 f = sscanf(url, scan_info, host, path);
3592 /* Use the default port */ 3490 /* Use the default port */
3593 if (is_https) 3491 if (is_https)
3594 g_snprintf(port_str, sizeof(port_str), "443"); 3492 g_snprintf(port_str, sizeof(port_str), "443");
3595 else 3493 else
3609 if (ret_path != NULL) *ret_path = g_strdup(path); 3507 if (ret_path != NULL) *ret_path = g_strdup(path);
3610 if (ret_user != NULL) *ret_user = g_strdup(user); 3508 if (ret_user != NULL) *ret_user = g_strdup(user);
3611 if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd); 3509 if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd);
3612 3510
3613 return ((*host != '\0') ? TRUE : FALSE); 3511 return ((*host != '\0') ? TRUE : FALSE);
3512
3513 #undef ADDR_CTRL
3514 #undef PORT_CTRL
3515 #undef PAGE_CTRL
3516 #undef USER_CTRL
3517 #undef PASSWD_CTRL
3614 } 3518 }
3615 3519
3616 /** 3520 /**
3617 * The arguments to this function are similar to printf. 3521 * The arguments to this function are similar to printf.
3618 */ 3522 */
3721 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port, 3625 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port,
3722 &gfud->website.page, &gfud->website.user, &gfud->website.passwd); 3626 &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
3723 3627
3724 if (purple_strcasestr(new_url, "https://") != NULL) { 3628 if (purple_strcasestr(new_url, "https://") != NULL) {
3725 gfud->is_ssl = TRUE; 3629 gfud->is_ssl = TRUE;
3726 gfud->ssl_connection = purple_ssl_connect(NULL, 3630 gfud->ssl_connection = purple_ssl_connect(gfud->account,
3727 gfud->website.address, gfud->website.port, 3631 gfud->website.address, gfud->website.port,
3728 ssl_url_fetch_connect_cb, ssl_url_fetch_error_cb, gfud); 3632 ssl_url_fetch_connect_cb, ssl_url_fetch_error_cb, gfud);
3729 } else { 3633 } else {
3730 gfud->connect_data = purple_proxy_connect(NULL, NULL, 3634 gfud->connect_data = purple_proxy_connect(NULL, gfud->account,
3731 gfud->website.address, gfud->website.port, 3635 gfud->website.address, gfud->website.port,
3732 url_fetch_connect_cb, gfud); 3636 url_fetch_connect_cb, gfud);
3733 } 3637 }
3734 3638
3735 if (gfud->ssl_connection == NULL && gfud->connect_data == NULL) 3639 if (gfud->ssl_connection == NULL && gfud->connect_data == NULL)
4017 PurpleUtilFetchUrlData *gfud; 3921 PurpleUtilFetchUrlData *gfud;
4018 int len, total_len; 3922 int len, total_len;
4019 3923
4020 gfud = data; 3924 gfud = data;
4021 3925
4022 if (gfud->request == NULL) 3926 if (gfud->request == NULL) {
4023 { 3927
3928 PurpleProxyInfo *gpi = purple_proxy_get_setup(gfud->account);
3929 GString *request_str = g_string_new(NULL);
3930
3931 g_string_append_printf(request_str, "GET %s%s HTTP/%s\r\n"
3932 "Connection: close\r\n",
3933 (gfud->full ? "" : "/"),
3934 (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")),
3935 (gfud->http11 ? "1.1" : "1.0"));
3936
3937 if (gfud->user_agent)
3938 g_string_append_printf(request_str, "User-Agent: %s\r\n", gfud->user_agent);
3939
4024 /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1 3940 /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1
4025 * clients must know how to handle the "chunked" transfer encoding. 3941 * clients must know how to handle the "chunked" transfer encoding.
4026 * Purple doesn't know how to handle "chunked", so should always send 3942 * Purple doesn't know how to handle "chunked", so should always send
4027 * the Host header regardless, to get around some observed problems 3943 * the Host header regardless, to get around some observed problems
4028 */ 3944 */
4029 if (gfud->user_agent) { 3945 g_string_append_printf(request_str, "Accept: */*\r\n"
4030 gfud->request = g_strdup_printf( 3946 "Host: %s\r\n",
4031 "GET %s%s HTTP/%s\r\n" 3947 (gfud->website.address ? gfud->website.address : ""));
4032 "Connection: close\r\n" 3948
4033 "User-Agent: %s\r\n" 3949 if (purple_proxy_info_get_username(gpi) != NULL
4034 "Accept: */*\r\n" 3950 && (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR
4035 "Host: %s\r\n\r\n", 3951 || purple_proxy_info_get_type(gpi) == PURPLE_PROXY_HTTP)) {
4036 (gfud->full ? "" : "/"), 3952 /* This chunk of code was copied from proxy.c http_start_connect_tunneling()
4037 (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), 3953 * This is really a temporary hack - we need a more complete proxy handling solution,
4038 (gfud->http11 ? "1.1" : "1.0"), 3954 * so I didn't think it was worthwhile to refactor for reuse
4039 (gfud->user_agent ? gfud->user_agent : ""), 3955 */
4040 (gfud->website.address ? gfud->website.address : "")); 3956 char *t1, *t2, *ntlm_type1;
4041 } else { 3957 char hostname[256];
4042 gfud->request = g_strdup_printf( 3958 int ret;
4043 "GET %s%s HTTP/%s\r\n" 3959
4044 "Connection: close\r\n" 3960 ret = gethostname(hostname, sizeof(hostname));
4045 "Accept: */*\r\n" 3961 hostname[sizeof(hostname) - 1] = '\0';
4046 "Host: %s\r\n\r\n", 3962 if (ret < 0 || hostname[0] == '\0') {
4047 (gfud->full ? "" : "/"), 3963 purple_debug_warning("util", "proxy - gethostname() failed -- is your hostname set?");
4048 (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), 3964 strcpy(hostname, "localhost");
4049 (gfud->http11 ? "1.1" : "1.0"), 3965 }
4050 (gfud->website.address ? gfud->website.address : "")); 3966
4051 } 3967 t1 = g_strdup_printf("%s:%s",
3968 purple_proxy_info_get_username(gpi),
3969 purple_proxy_info_get_password(gpi) ?
3970 purple_proxy_info_get_password(gpi) : "");
3971 t2 = purple_base64_encode((const guchar *)t1, strlen(t1));
3972 g_free(t1);
3973
3974 ntlm_type1 = purple_ntlm_gen_type1(hostname, "");
3975
3976 g_string_append_printf(request_str,
3977 "Proxy-Authorization: Basic %s\r\n"
3978 "Proxy-Authorization: NTLM %s\r\n"
3979 "Proxy-Connection: Keep-Alive\r\n",
3980 t2, ntlm_type1);
3981 g_free(ntlm_type1);
3982 g_free(t2);
3983 }
3984
3985 g_string_append(request_str, "\r\n");
3986
3987 gfud->request = g_string_free(request_str, FALSE);
4052 } 3988 }
4053 3989
4054 if(purple_debug_is_unsafe()) 3990 if(purple_debug_is_unsafe())
4055 purple_debug_misc("util", "Request: '%s'\n", gfud->request); 3991 purple_debug_misc("util", "Request: '%s'\n", gfud->request);
4056 else 3992 else
4185 gfud->full = full; 4121 gfud->full = full;
4186 gfud->request = g_strdup(request); 4122 gfud->request = g_strdup(request);
4187 gfud->include_headers = include_headers; 4123 gfud->include_headers = include_headers;
4188 gfud->fd = -1; 4124 gfud->fd = -1;
4189 gfud->max_len = max_len; 4125 gfud->max_len = max_len;
4126 gfud->account = account;
4190 4127
4191 purple_url_parse(url, &gfud->website.address, &gfud->website.port, 4128 purple_url_parse(url, &gfud->website.address, &gfud->website.port,
4192 &gfud->website.page, &gfud->website.user, &gfud->website.passwd); 4129 &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
4193 4130
4194 if (purple_strcasestr(url, "https://") != NULL) { 4131 if (purple_strcasestr(url, "https://") != NULL) {
4338 const char *c, *domain; 4275 const char *c, *domain;
4339 static char *rfc822_specials = "()<>@,;:\\\"[]"; 4276 static char *rfc822_specials = "()<>@,;:\\\"[]";
4340 4277
4341 g_return_val_if_fail(address != NULL, FALSE); 4278 g_return_val_if_fail(address != NULL, FALSE);
4342 4279
4280 if (*address == '.') return FALSE;
4281
4343 /* first we validate the name portion (name@domain) (rfc822)*/ 4282 /* first we validate the name portion (name@domain) (rfc822)*/
4344 for (c = address; *c; c++) { 4283 for (c = address; *c; c++) {
4345 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) { 4284 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) {
4346 while (*++c) { 4285 while (*++c) {
4347 if (*c == '\\') { 4286 if (*c == '\\') {
4371 /* next we validate the domain portion (name@domain) (rfc1035 & rfc1011) */ 4310 /* next we validate the domain portion (name@domain) (rfc1035 & rfc1011) */
4372 if (!*(domain = ++c)) return FALSE; 4311 if (!*(domain = ++c)) return FALSE;
4373 do { 4312 do {
4374 if (*c == '.' && (c == domain || *(c - 1) == '.' || *(c - 1) == '-')) 4313 if (*c == '.' && (c == domain || *(c - 1) == '.' || *(c - 1) == '-'))
4375 return FALSE; 4314 return FALSE;
4376 if (*c == '-' && *(c - 1) == '.') return FALSE; 4315 if (*c == '-' && (*(c - 1) == '.' || *(c - 1) == '@')) return FALSE;
4377 if ((*c < '0' && *c != '-' && *c != '.') || (*c > '9' && *c < 'A') || 4316 if ((*c < '0' && *c != '-' && *c != '.') || (*c > '9' && *c < 'A') ||
4378 (*c > 'Z' && *c < 'a') || (*c > 'z')) return FALSE; 4317 (*c > 'Z' && *c < 'a') || (*c > 'z')) return FALSE;
4379 } while (*++c); 4318 } while (*++c);
4380 4319
4381 if (*(c - 1) == '-') return FALSE; 4320 if (*(c - 1) == '-') return FALSE;
4958 sprintf(buf + j, "%%%02x", utf_char[i] & 0xff); 4897 sprintf(buf + j, "%%%02x", utf_char[i] & 0xff);
4959 j += 3; 4898 j += 3;
4960 } 4899 }
4961 } 4900 }
4962 } 4901 }
4963 4902 #ifdef _WIN32
4903 /* File/Directory names in windows cannot end in periods/spaces.
4904 * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
4905 */
4906 while (j > 0 && (buf[j - 1] == '.' || buf[j - 1] == ' '))
4907 j--;
4908 #endif
4964 buf[j] = '\0'; 4909 buf[j] = '\0';
4965 4910
4966 return buf; 4911 return buf;
4967 } 4912 }
4968 4913