Mercurial > pidgin
comparison src/proxy.c @ 14096:a70c6011dc81
[gaim-migrate @ 16725]
Rename "phb" to "connect_info" everywhere
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 12 Aug 2006 20:40:07 +0000 |
parents | 3b871b67556d |
children | 7ded3834168f |
comparison
equal
deleted
inserted
replaced
14095:3b871b67556d | 14096:a70c6011dc81 |
---|---|
67 "Command not supported\n", | 67 "Command not supported\n", |
68 "Address type not supported\n" | 68 "Address type not supported\n" |
69 }; | 69 }; |
70 | 70 |
71 static GaimProxyInfo *global_proxy_info = NULL; | 71 static GaimProxyInfo *global_proxy_info = NULL; |
72 static GSList *phbs = NULL; | 72 static GSList *connect_infos = NULL; |
73 | 73 |
74 static void try_connect(struct _GaimProxyConnectInfo *); | 74 static void try_connect(struct _GaimProxyConnectInfo *); |
75 | 75 |
76 /************************************************************************** | 76 /************************************************************************** |
77 * Proxy structure API | 77 * Proxy structure API |
255 /************************************************************************** | 255 /************************************************************************** |
256 * Proxy API | 256 * Proxy API |
257 **************************************************************************/ | 257 **************************************************************************/ |
258 | 258 |
259 static void | 259 static void |
260 gaim_proxy_phb_destroy(struct _GaimProxyConnectInfo *phb) | 260 gaim_proxy_connect_info_destroy(struct _GaimProxyConnectInfo *connect_info) |
261 { | 261 { |
262 phbs = g_slist_remove(phbs, phb); | 262 connect_infos = g_slist_remove(connect_infos, connect_info); |
263 | 263 |
264 if (phb->inpa > 0) | 264 if (connect_info->inpa > 0) |
265 gaim_input_remove(phb->inpa); | 265 gaim_input_remove(connect_info->inpa); |
266 | 266 |
267 while (phb->hosts != NULL) | 267 while (connect_info->hosts != NULL) |
268 { | 268 { |
269 /* Discard the length... */ | 269 /* Discard the length... */ |
270 phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); | 270 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); |
271 /* Free the address... */ | 271 /* Free the address... */ |
272 g_free(phb->hosts->data); | 272 g_free(connect_info->hosts->data); |
273 phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); | 273 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); |
274 } | 274 } |
275 | 275 |
276 g_free(phb->host); | 276 g_free(connect_info->host); |
277 g_free(phb->write_buffer); | 277 g_free(connect_info->write_buffer); |
278 g_free(phb->read_buffer); | 278 g_free(connect_info->read_buffer); |
279 g_free(phb); | 279 g_free(connect_info); |
280 } | 280 } |
281 | 281 |
282 static void | 282 static void |
283 gaim_proxy_phb_connected(struct _GaimProxyConnectInfo *phb, int fd) | 283 gaim_proxy_connect_info_connected(struct _GaimProxyConnectInfo *connect_info, int fd) |
284 { | 284 { |
285 phb->connect_cb(phb->data, fd); | 285 connect_info->connect_cb(connect_info->data, fd); |
286 gaim_proxy_phb_destroy(phb); | 286 gaim_proxy_connect_info_destroy(connect_info); |
287 } | 287 } |
288 | 288 |
289 /** | 289 /** |
290 * @param error An error message explaining why the connection | 290 * @param error An error message explaining why the connection |
291 * failed. This will be passed to the callback function | 291 * failed. This will be passed to the callback function |
292 * specified in the call to gaim_proxy_connect(). | 292 * specified in the call to gaim_proxy_connect(). |
293 */ | 293 */ |
294 static void | 294 static void |
295 gaim_proxy_phb_error(struct _GaimProxyConnectInfo *phb, const gchar *error_message) | 295 gaim_proxy_connect_info_error(struct _GaimProxyConnectInfo *connect_info, const gchar *error_message) |
296 { | 296 { |
297 if (phb->error_cb == NULL) | 297 if (connect_info->error_cb == NULL) |
298 { | 298 { |
299 /* | 299 /* |
300 * TODO | 300 * TODO |
301 * While we're transitioning to the new gaim_proxy_connect() | 301 * While we're transitioning to the new gaim_proxy_connect() |
302 * code, not all callers supply an error_cb. If this is the | 302 * code, not all callers supply an error_cb. If this is the |
303 * case then they're expecting connect_cb to be called with | 303 * case then they're expecting connect_cb to be called with |
304 * an fd of -1 in the case of an error. Once all callers have | 304 * an fd of -1 in the case of an error. Once all callers have |
305 * been changed this whole if statement should be removed. | 305 * been changed this whole if statement should be removed. |
306 */ | 306 */ |
307 phb->connect_cb(phb->data, -1); | 307 connect_info->connect_cb(connect_info->data, -1); |
308 gaim_proxy_phb_destroy(phb); | 308 gaim_proxy_connect_info_destroy(connect_info); |
309 return; | 309 return; |
310 } | 310 } |
311 | 311 |
312 phb->error_cb(phb->data, error_message); | 312 connect_info->error_cb(connect_info->data, error_message); |
313 gaim_proxy_phb_destroy(phb); | 313 gaim_proxy_connect_info_destroy(connect_info); |
314 } | 314 } |
315 | 315 |
316 #if defined(__unix__) || defined(__APPLE__) | 316 #if defined(__unix__) || defined(__APPLE__) |
317 | 317 |
318 /* | 318 /* |
988 #endif /* not __unix__ or __APPLE__ or _WIN32 */ | 988 #endif /* not __unix__ or __APPLE__ or _WIN32 */ |
989 | 989 |
990 static void | 990 static void |
991 no_one_calls(gpointer data, gint source, GaimInputCondition cond) | 991 no_one_calls(gpointer data, gint source, GaimInputCondition cond) |
992 { | 992 { |
993 struct _GaimProxyConnectInfo *phb = data; | 993 struct _GaimProxyConnectInfo *connect_info = data; |
994 socklen_t len; | 994 socklen_t len; |
995 int error=0, ret; | 995 int error=0, ret; |
996 | 996 |
997 gaim_debug_info("proxy", "Connected.\n"); | 997 gaim_debug_info("proxy", "Connected.\n"); |
998 | 998 |
1014 return; /* we'll be called again later */ | 1014 return; /* we'll be called again later */ |
1015 if (ret < 0 || error != 0) { | 1015 if (ret < 0 || error != 0) { |
1016 if (ret!=0) | 1016 if (ret!=0) |
1017 error = errno; | 1017 error = errno; |
1018 close(source); | 1018 close(source); |
1019 gaim_input_remove(phb->inpa); | 1019 gaim_input_remove(connect_info->inpa); |
1020 phb->inpa = 0; | 1020 connect_info->inpa = 0; |
1021 | 1021 |
1022 gaim_debug_error("proxy", | 1022 gaim_debug_error("proxy", |
1023 "getsockopt SO_ERROR check: %s\n", strerror(error)); | 1023 "getsockopt SO_ERROR check: %s\n", strerror(error)); |
1024 | 1024 |
1025 try_connect(phb); | 1025 try_connect(connect_info); |
1026 return; | 1026 return; |
1027 } | 1027 } |
1028 | 1028 |
1029 gaim_input_remove(phb->inpa); | 1029 gaim_input_remove(connect_info->inpa); |
1030 phb->inpa = 0; | 1030 connect_info->inpa = 0; |
1031 | 1031 |
1032 gaim_proxy_phb_connected(phb, source); | 1032 gaim_proxy_connect_info_connected(connect_info, source); |
1033 } | 1033 } |
1034 | 1034 |
1035 static gboolean clean_connect(gpointer data) | 1035 static gboolean clean_connect(gpointer data) |
1036 { | 1036 { |
1037 struct _GaimProxyConnectInfo *phb = data; | 1037 struct _GaimProxyConnectInfo *connect_info = data; |
1038 | 1038 |
1039 gaim_proxy_phb_connected(phb, phb->port); | 1039 gaim_proxy_connect_info_connected(connect_info, connect_info->port); |
1040 | 1040 |
1041 return FALSE; | 1041 return FALSE; |
1042 } | 1042 } |
1043 | 1043 |
1044 | 1044 |
1045 static int | 1045 static int |
1046 proxy_connect_none(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) | 1046 proxy_connect_none(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) |
1047 { | 1047 { |
1048 int fd = -1; | 1048 int fd = -1; |
1049 | 1049 |
1050 gaim_debug_info("proxy", | 1050 gaim_debug_info("proxy", |
1051 "Connecting to %s:%d with no proxy\n", phb->host, phb->port); | 1051 "Connecting to %s:%d with no proxy\n", connect_info->host, connect_info->port); |
1052 | 1052 |
1053 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { | 1053 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
1054 gaim_debug_error("proxy", | 1054 gaim_debug_error("proxy", |
1055 "Unable to create socket: %s\n", strerror(errno)); | 1055 "Unable to create socket: %s\n", strerror(errno)); |
1056 return -1; | 1056 return -1; |
1063 if (connect(fd, (struct sockaddr *)addr, addrlen) < 0) { | 1063 if (connect(fd, (struct sockaddr *)addr, addrlen) < 0) { |
1064 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 1064 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
1065 /* This just confuses people. */ | 1065 /* This just confuses people. */ |
1066 /* gaim_debug_warning("proxy", | 1066 /* gaim_debug_warning("proxy", |
1067 "Connect would have blocked.\n"); */ | 1067 "Connect would have blocked.\n"); */ |
1068 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, phb); | 1068 connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, connect_info); |
1069 } | 1069 } |
1070 else { | 1070 else { |
1071 gaim_debug_error("proxy", | 1071 gaim_debug_error("proxy", |
1072 "Connect failed: %s\n", strerror(errno)); | 1072 "Connect failed: %s\n", strerror(errno)); |
1073 close(fd); | 1073 close(fd); |
1083 gaim_debug_error("proxy", "getsockopt failed.\n"); | 1083 gaim_debug_error("proxy", "getsockopt failed.\n"); |
1084 close(fd); | 1084 close(fd); |
1085 return -1; | 1085 return -1; |
1086 } | 1086 } |
1087 /* TODO: Why is the following line so strange? */ | 1087 /* TODO: Why is the following line so strange? */ |
1088 phb->port = fd; /* bleh */ | 1088 connect_info->port = fd; /* bleh */ |
1089 gaim_timeout_add(10, clean_connect, phb); /* we do this because we never | 1089 gaim_timeout_add(10, clean_connect, connect_info); /* we do this because we never |
1090 want to call our callback | 1090 want to call our callback |
1091 before we return. */ | 1091 before we return. */ |
1092 } | 1092 } |
1093 | 1093 |
1094 return fd; | 1094 return fd; |
1095 } | 1095 } |
1096 | 1096 |
1097 static void | 1097 static void |
1098 proxy_do_write(gpointer data, gint source, GaimInputCondition cond) | 1098 proxy_do_write(gpointer data, gint source, GaimInputCondition cond) |
1099 { | 1099 { |
1100 struct _GaimProxyConnectInfo *phb = data; | 1100 struct _GaimProxyConnectInfo *connect_info = data; |
1101 const guchar *request = phb->write_buffer + phb->written_len; | 1101 const guchar *request = connect_info->write_buffer + connect_info->written_len; |
1102 gsize request_len = phb->write_buf_len - phb->written_len; | 1102 gsize request_len = connect_info->write_buf_len - connect_info->written_len; |
1103 | 1103 |
1104 int ret = write(source, request, request_len); | 1104 int ret = write(source, request, request_len); |
1105 | 1105 |
1106 if(ret < 0 && errno == EAGAIN) | 1106 if(ret < 0 && errno == EAGAIN) |
1107 return; | 1107 return; |
1108 else if(ret < 0) { | 1108 else if(ret < 0) { |
1109 gaim_input_remove(phb->inpa); | 1109 gaim_input_remove(connect_info->inpa); |
1110 phb->inpa = 0; | 1110 connect_info->inpa = 0; |
1111 close(source); | 1111 close(source); |
1112 g_free(phb->write_buffer); | 1112 g_free(connect_info->write_buffer); |
1113 phb->write_buffer = NULL; | 1113 connect_info->write_buffer = NULL; |
1114 try_connect(phb); | 1114 try_connect(connect_info); |
1115 return; | 1115 return; |
1116 } else if (ret < request_len) { | 1116 } else if (ret < request_len) { |
1117 phb->written_len += ret; | 1117 connect_info->written_len += ret; |
1118 return; | 1118 return; |
1119 } | 1119 } |
1120 | 1120 |
1121 gaim_input_remove(phb->inpa); | 1121 gaim_input_remove(connect_info->inpa); |
1122 g_free(phb->write_buffer); | 1122 g_free(connect_info->write_buffer); |
1123 phb->write_buffer = NULL; | 1123 connect_info->write_buffer = NULL; |
1124 | 1124 |
1125 /* register the response handler for the response */ | 1125 /* register the response handler for the response */ |
1126 phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, phb->read_cb, phb); | 1126 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_READ, connect_info->read_cb, connect_info); |
1127 } | 1127 } |
1128 | 1128 |
1129 #define HTTP_GOODSTRING "HTTP/1.0 200" | 1129 #define HTTP_GOODSTRING "HTTP/1.0 200" |
1130 #define HTTP_GOODSTRING2 "HTTP/1.1 200" | 1130 #define HTTP_GOODSTRING2 "HTTP/1.1 200" |
1131 | 1131 |
1133 static void | 1133 static void |
1134 http_canread(gpointer data, gint source, GaimInputCondition cond) | 1134 http_canread(gpointer data, gint source, GaimInputCondition cond) |
1135 { | 1135 { |
1136 int len, headers_len, status = 0; | 1136 int len, headers_len, status = 0; |
1137 gboolean error; | 1137 gboolean error; |
1138 struct _GaimProxyConnectInfo *phb = data; | 1138 struct _GaimProxyConnectInfo *connect_info = data; |
1139 guchar *p; | 1139 guchar *p; |
1140 gsize max_read; | 1140 gsize max_read; |
1141 gchar *msg; | 1141 gchar *msg; |
1142 | 1142 |
1143 if(phb->read_buffer == NULL) { | 1143 if(connect_info->read_buffer == NULL) { |
1144 phb->read_buf_len = 8192; | 1144 connect_info->read_buf_len = 8192; |
1145 phb->read_buffer = g_malloc(phb->read_buf_len); | 1145 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); |
1146 phb->read_len = 0; | 1146 connect_info->read_len = 0; |
1147 } | 1147 } |
1148 | 1148 |
1149 p = phb->read_buffer + phb->read_len; | 1149 p = connect_info->read_buffer + connect_info->read_len; |
1150 max_read = phb->read_buf_len - phb->read_len - 1; | 1150 max_read = connect_info->read_buf_len - connect_info->read_len - 1; |
1151 | 1151 |
1152 len = read(source, p, max_read); | 1152 len = read(source, p, max_read); |
1153 if(len < 0 && errno == EAGAIN) | 1153 if(len < 0 && errno == EAGAIN) |
1154 return; | 1154 return; |
1155 else if(len <= 0) { | 1155 else if(len <= 0) { |
1156 close(source); | 1156 close(source); |
1157 gaim_proxy_phb_error(phb, _("Lost connection with server for an unknown reason.")); | 1157 gaim_proxy_connect_info_error(connect_info, _("Lost connection with server for an unknown reason.")); |
1158 return; | 1158 return; |
1159 } else { | 1159 } else { |
1160 phb->read_len += len; | 1160 connect_info->read_len += len; |
1161 } | 1161 } |
1162 p[len] = '\0'; | 1162 p[len] = '\0'; |
1163 | 1163 |
1164 if((p = (guchar *)g_strstr_len((const gchar *)phb->read_buffer, phb->read_len, "\r\n\r\n"))) { | 1164 if((p = (guchar *)g_strstr_len((const gchar *)connect_info->read_buffer, connect_info->read_len, "\r\n\r\n"))) { |
1165 *p = '\0'; | 1165 *p = '\0'; |
1166 headers_len = (p - phb->read_buffer) + 4; | 1166 headers_len = (p - connect_info->read_buffer) + 4; |
1167 } else if(len == max_read) | 1167 } else if(len == max_read) |
1168 headers_len = len; | 1168 headers_len = len; |
1169 else | 1169 else |
1170 return; | 1170 return; |
1171 | 1171 |
1172 error = strncmp((const char *)phb->read_buffer, "HTTP/", 5) != 0; | 1172 error = strncmp((const char *)connect_info->read_buffer, "HTTP/", 5) != 0; |
1173 if (!error) | 1173 if (!error) |
1174 { | 1174 { |
1175 int major; | 1175 int major; |
1176 p = phb->read_buffer + 5; | 1176 p = connect_info->read_buffer + 5; |
1177 major = strtol((const char *)p, (char **)&p, 10); | 1177 major = strtol((const char *)p, (char **)&p, 10); |
1178 error = (major == 0) || (*p != '.'); | 1178 error = (major == 0) || (*p != '.'); |
1179 if(!error) { | 1179 if(!error) { |
1180 int minor; | 1180 int minor; |
1181 p++; | 1181 p++; |
1188 } | 1188 } |
1189 } | 1189 } |
1190 } | 1190 } |
1191 | 1191 |
1192 /* Read the contents */ | 1192 /* Read the contents */ |
1193 p = (guchar *)g_strrstr((const gchar *)phb->read_buffer, "Content-Length: "); | 1193 p = (guchar *)g_strrstr((const gchar *)connect_info->read_buffer, "Content-Length: "); |
1194 if (p != NULL) | 1194 if (p != NULL) |
1195 { | 1195 { |
1196 gchar *tmp; | 1196 gchar *tmp; |
1197 int len = 0; | 1197 int len = 0; |
1198 char tmpc; | 1198 char tmpc; |
1203 len = atoi((const char *)p); | 1203 len = atoi((const char *)p); |
1204 if(tmp) | 1204 if(tmp) |
1205 *tmp = '\r'; | 1205 *tmp = '\r'; |
1206 | 1206 |
1207 /* Compensate for what has already been read */ | 1207 /* Compensate for what has already been read */ |
1208 len -= phb->read_len - headers_len; | 1208 len -= connect_info->read_len - headers_len; |
1209 /* I'm assuming that we're doing this to prevent the server from | 1209 /* I'm assuming that we're doing this to prevent the server from |
1210 complaining / breaking since we don't read the whole page */ | 1210 complaining / breaking since we don't read the whole page */ |
1211 while(len--) { | 1211 while(len--) { |
1212 /* TODO: deal with EAGAIN (and other errors) better */ | 1212 /* TODO: deal with EAGAIN (and other errors) better */ |
1213 if (read(source, &tmpc, 1) < 0 && errno != EAGAIN) | 1213 if (read(source, &tmpc, 1) < 0 && errno != EAGAIN) |
1217 | 1217 |
1218 if (error) | 1218 if (error) |
1219 { | 1219 { |
1220 close(source); | 1220 close(source); |
1221 msg = g_strdup_printf("Unable to parse response from HTTP proxy: %s\n", | 1221 msg = g_strdup_printf("Unable to parse response from HTTP proxy: %s\n", |
1222 phb->read_buffer); | 1222 connect_info->read_buffer); |
1223 gaim_proxy_phb_error(phb, msg); | 1223 gaim_proxy_connect_info_error(connect_info, msg); |
1224 g_free(msg); | 1224 g_free(msg); |
1225 return; | 1225 return; |
1226 } | 1226 } |
1227 else if (status != 200) | 1227 else if (status != 200) |
1228 { | 1228 { |
1229 gaim_debug_error("proxy", | 1229 gaim_debug_error("proxy", |
1230 "Proxy server replied with:\n%s\n", | 1230 "Proxy server replied with:\n%s\n", |
1231 phb->read_buffer); | 1231 connect_info->read_buffer); |
1232 | 1232 |
1233 | 1233 |
1234 if(status == 407 /* Proxy Auth */) { | 1234 if(status == 407 /* Proxy Auth */) { |
1235 gchar *ntlm; | 1235 gchar *ntlm; |
1236 if((ntlm = g_strrstr((const gchar *)phb->read_buffer, "Proxy-Authenticate: NTLM "))) { /* Check for Type-2 */ | 1236 if((ntlm = g_strrstr((const gchar *)connect_info->read_buffer, "Proxy-Authenticate: NTLM "))) { /* Check for Type-2 */ |
1237 gchar *tmp = ntlm; | 1237 gchar *tmp = ntlm; |
1238 guint8 *nonce; | 1238 guint8 *nonce; |
1239 gchar *domain = (gchar*)gaim_proxy_info_get_username(phb->gpi); | 1239 gchar *domain = (gchar*)gaim_proxy_info_get_username(connect_info->gpi); |
1240 gchar *username; | 1240 gchar *username; |
1241 gchar *request; | 1241 gchar *request; |
1242 gchar *response; | 1242 gchar *response; |
1243 username = strchr(domain, '\\'); | 1243 username = strchr(domain, '\\'); |
1244 if (username == NULL) | 1244 if (username == NULL) |
1245 { | 1245 { |
1246 close(source); | 1246 close(source); |
1247 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); | 1247 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); |
1248 gaim_proxy_phb_error(phb, msg); | 1248 gaim_proxy_connect_info_error(connect_info, msg); |
1249 g_free(msg); | 1249 g_free(msg); |
1250 return; | 1250 return; |
1251 } | 1251 } |
1252 *username = '\0'; | 1252 *username = '\0'; |
1253 username++; | 1253 username++; |
1254 ntlm += strlen("Proxy-Authenticate: NTLM "); | 1254 ntlm += strlen("Proxy-Authenticate: NTLM "); |
1255 while(*tmp != '\r' && *tmp != '\0') tmp++; | 1255 while(*tmp != '\r' && *tmp != '\0') tmp++; |
1256 *tmp = '\0'; | 1256 *tmp = '\0'; |
1257 nonce = gaim_ntlm_parse_type2(ntlm, NULL); | 1257 nonce = gaim_ntlm_parse_type2(ntlm, NULL); |
1258 response = gaim_ntlm_gen_type3(username, | 1258 response = gaim_ntlm_gen_type3(username, |
1259 (gchar*) gaim_proxy_info_get_password(phb->gpi), | 1259 (gchar*) gaim_proxy_info_get_password(connect_info->gpi), |
1260 (gchar*) gaim_proxy_info_get_host(phb->gpi), | 1260 (gchar*) gaim_proxy_info_get_host(connect_info->gpi), |
1261 domain, nonce, NULL); | 1261 domain, nonce, NULL); |
1262 username--; | 1262 username--; |
1263 *username = '\\'; | 1263 *username = '\\'; |
1264 request = g_strdup_printf( | 1264 request = g_strdup_printf( |
1265 "CONNECT %s:%d HTTP/1.1\r\n" | 1265 "CONNECT %s:%d HTTP/1.1\r\n" |
1266 "Host: %s:%d\r\n" | 1266 "Host: %s:%d\r\n" |
1267 "Proxy-Authorization: NTLM %s\r\n" | 1267 "Proxy-Authorization: NTLM %s\r\n" |
1268 "Proxy-Connection: Keep-Alive\r\n\r\n", | 1268 "Proxy-Connection: Keep-Alive\r\n\r\n", |
1269 phb->host, phb->port, phb->host, | 1269 connect_info->host, connect_info->port, connect_info->host, |
1270 phb->port, response); | 1270 connect_info->port, response); |
1271 g_free(response); | 1271 g_free(response); |
1272 | 1272 |
1273 gaim_input_remove(phb->inpa); | 1273 gaim_input_remove(connect_info->inpa); |
1274 g_free(phb->read_buffer); | 1274 g_free(connect_info->read_buffer); |
1275 phb->read_buffer = NULL; | 1275 connect_info->read_buffer = NULL; |
1276 | 1276 |
1277 phb->write_buffer = (guchar *)request; | 1277 connect_info->write_buffer = (guchar *)request; |
1278 phb->write_buf_len = strlen(request); | 1278 connect_info->write_buf_len = strlen(request); |
1279 phb->written_len = 0; | 1279 connect_info->written_len = 0; |
1280 | 1280 |
1281 phb->read_cb = http_canread; | 1281 connect_info->read_cb = http_canread; |
1282 | 1282 |
1283 phb->inpa = gaim_input_add(source, | 1283 connect_info->inpa = gaim_input_add(source, |
1284 GAIM_INPUT_WRITE, proxy_do_write, phb); | 1284 GAIM_INPUT_WRITE, proxy_do_write, connect_info); |
1285 | 1285 |
1286 proxy_do_write(phb, source, cond); | 1286 proxy_do_write(connect_info, source, cond); |
1287 return; | 1287 return; |
1288 } else if((ntlm = g_strrstr((const char *)phb->read_buffer, "Proxy-Authenticate: NTLM"))) { /* Empty message */ | 1288 } else if((ntlm = g_strrstr((const char *)connect_info->read_buffer, "Proxy-Authenticate: NTLM"))) { /* Empty message */ |
1289 gchar request[2048]; | 1289 gchar request[2048]; |
1290 gchar *domain = (gchar*) gaim_proxy_info_get_username(phb->gpi); | 1290 gchar *domain = (gchar*) gaim_proxy_info_get_username(connect_info->gpi); |
1291 gchar *username; | 1291 gchar *username; |
1292 int request_len; | 1292 int request_len; |
1293 username = strchr(domain, '\\'); | 1293 username = strchr(domain, '\\'); |
1294 if (username == NULL) | 1294 if (username == NULL) |
1295 { | 1295 { |
1296 close(source); | 1296 close(source); |
1297 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); | 1297 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); |
1298 gaim_proxy_phb_error(phb, msg); | 1298 gaim_proxy_connect_info_error(connect_info, msg); |
1299 g_free(msg); | 1299 g_free(msg); |
1300 return; | 1300 return; |
1301 } | 1301 } |
1302 *username = '\0'; | 1302 *username = '\0'; |
1303 | 1303 |
1304 request_len = g_snprintf(request, sizeof(request), | 1304 request_len = g_snprintf(request, sizeof(request), |
1305 "CONNECT %s:%d HTTP/1.1\r\n" | 1305 "CONNECT %s:%d HTTP/1.1\r\n" |
1306 "Host: %s:%d\r\n", | 1306 "Host: %s:%d\r\n", |
1307 phb->host, phb->port, | 1307 connect_info->host, connect_info->port, |
1308 phb->host, phb->port); | 1308 connect_info->host, connect_info->port); |
1309 | 1309 |
1310 g_return_if_fail(request_len < sizeof(request)); | 1310 g_return_if_fail(request_len < sizeof(request)); |
1311 request_len += g_snprintf(request + request_len, | 1311 request_len += g_snprintf(request + request_len, |
1312 sizeof(request) - request_len, | 1312 sizeof(request) - request_len, |
1313 "Proxy-Authorization: NTLM %s\r\n" | 1313 "Proxy-Authorization: NTLM %s\r\n" |
1314 "Proxy-Connection: Keep-Alive\r\n\r\n", | 1314 "Proxy-Connection: Keep-Alive\r\n\r\n", |
1315 gaim_ntlm_gen_type1( | 1315 gaim_ntlm_gen_type1( |
1316 (gchar*) gaim_proxy_info_get_host(phb->gpi), | 1316 (gchar*) gaim_proxy_info_get_host(connect_info->gpi), |
1317 domain)); | 1317 domain)); |
1318 *username = '\\'; | 1318 *username = '\\'; |
1319 | 1319 |
1320 gaim_input_remove(phb->inpa); | 1320 gaim_input_remove(connect_info->inpa); |
1321 g_free(phb->read_buffer); | 1321 g_free(connect_info->read_buffer); |
1322 phb->read_buffer = NULL; | 1322 connect_info->read_buffer = NULL; |
1323 | 1323 |
1324 phb->write_buffer = g_memdup(request, request_len); | 1324 connect_info->write_buffer = g_memdup(request, request_len); |
1325 phb->write_buf_len = request_len; | 1325 connect_info->write_buf_len = request_len; |
1326 phb->written_len = 0; | 1326 connect_info->written_len = 0; |
1327 | 1327 |
1328 phb->read_cb = http_canread; | 1328 connect_info->read_cb = http_canread; |
1329 | 1329 |
1330 phb->inpa = gaim_input_add(source, | 1330 connect_info->inpa = gaim_input_add(source, |
1331 GAIM_INPUT_WRITE, proxy_do_write, phb); | 1331 GAIM_INPUT_WRITE, proxy_do_write, connect_info); |
1332 | 1332 |
1333 proxy_do_write(phb, source, cond); | 1333 proxy_do_write(connect_info, source, cond); |
1334 return; | 1334 return; |
1335 } else { | 1335 } else { |
1336 close(source); | 1336 close(source); |
1337 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); | 1337 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); |
1338 gaim_proxy_phb_error(phb, msg); | 1338 gaim_proxy_connect_info_error(connect_info, msg); |
1339 g_free(msg); | 1339 g_free(msg); |
1340 return; | 1340 return; |
1341 } | 1341 } |
1342 } | 1342 } |
1343 if(status == 403 /* Forbidden */ ) { | 1343 if(status == 403 /* Forbidden */ ) { |
1344 msg = g_strdup_printf(_("Access denied: HTTP proxy server forbids port %d tunnelling."), phb->port); | 1344 msg = g_strdup_printf(_("Access denied: HTTP proxy server forbids port %d tunnelling."), connect_info->port); |
1345 gaim_proxy_phb_error(phb, msg); | 1345 gaim_proxy_connect_info_error(connect_info, msg); |
1346 g_free(msg); | 1346 g_free(msg); |
1347 } else { | 1347 } else { |
1348 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); | 1348 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); |
1349 gaim_proxy_phb_error(phb, msg); | 1349 gaim_proxy_connect_info_error(connect_info, msg); |
1350 g_free(msg); | 1350 g_free(msg); |
1351 } | 1351 } |
1352 } else { | 1352 } else { |
1353 gaim_input_remove(phb->inpa); | 1353 gaim_input_remove(connect_info->inpa); |
1354 phb->inpa = 0; | 1354 connect_info->inpa = 0; |
1355 g_free(phb->read_buffer); | 1355 g_free(connect_info->read_buffer); |
1356 phb->read_buffer = NULL; | 1356 connect_info->read_buffer = NULL; |
1357 gaim_debug_info("proxy", "HTTP proxy connection established\n"); | 1357 gaim_debug_info("proxy", "HTTP proxy connection established\n"); |
1358 gaim_proxy_phb_connected(phb, source); | 1358 gaim_proxy_connect_info_connected(connect_info, source); |
1359 return; | 1359 return; |
1360 } | 1360 } |
1361 } | 1361 } |
1362 | 1362 |
1363 | 1363 |
1365 static void | 1365 static void |
1366 http_canwrite(gpointer data, gint source, GaimInputCondition cond) | 1366 http_canwrite(gpointer data, gint source, GaimInputCondition cond) |
1367 { | 1367 { |
1368 char request[8192]; | 1368 char request[8192]; |
1369 int request_len = 0; | 1369 int request_len = 0; |
1370 struct _GaimProxyConnectInfo *phb = data; | 1370 struct _GaimProxyConnectInfo *connect_info = data; |
1371 socklen_t len; | 1371 socklen_t len; |
1372 int error = ETIMEDOUT; | 1372 int error = ETIMEDOUT; |
1373 | 1373 |
1374 gaim_debug_info("http proxy", "Connected.\n"); | 1374 gaim_debug_info("http proxy", "Connected.\n"); |
1375 | 1375 |
1376 if (phb->inpa > 0) | 1376 if (connect_info->inpa > 0) |
1377 { | 1377 { |
1378 gaim_input_remove(phb->inpa); | 1378 gaim_input_remove(connect_info->inpa); |
1379 phb->inpa = 0; | 1379 connect_info->inpa = 0; |
1380 } | 1380 } |
1381 | 1381 |
1382 len = sizeof(error); | 1382 len = sizeof(error); |
1383 | 1383 |
1384 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 1384 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
1385 close(source); | 1385 close(source); |
1386 | 1386 |
1387 try_connect(phb); | 1387 try_connect(connect_info); |
1388 return; | 1388 return; |
1389 } | 1389 } |
1390 | 1390 |
1391 gaim_debug_info("proxy", "using CONNECT tunnelling for %s:%d\n", | 1391 gaim_debug_info("proxy", "using CONNECT tunnelling for %s:%d\n", |
1392 phb->host, phb->port); | 1392 connect_info->host, connect_info->port); |
1393 request_len = g_snprintf(request, sizeof(request), | 1393 request_len = g_snprintf(request, sizeof(request), |
1394 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", | 1394 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", |
1395 phb->host, phb->port, phb->host, phb->port); | 1395 connect_info->host, connect_info->port, connect_info->host, connect_info->port); |
1396 | 1396 |
1397 if (gaim_proxy_info_get_username(phb->gpi) != NULL) { | 1397 if (gaim_proxy_info_get_username(connect_info->gpi) != NULL) { |
1398 char *t1, *t2; | 1398 char *t1, *t2; |
1399 t1 = g_strdup_printf("%s:%s", | 1399 t1 = g_strdup_printf("%s:%s", |
1400 gaim_proxy_info_get_username(phb->gpi), | 1400 gaim_proxy_info_get_username(connect_info->gpi), |
1401 gaim_proxy_info_get_password(phb->gpi) ? | 1401 gaim_proxy_info_get_password(connect_info->gpi) ? |
1402 gaim_proxy_info_get_password(phb->gpi) : ""); | 1402 gaim_proxy_info_get_password(connect_info->gpi) : ""); |
1403 t2 = gaim_base64_encode((const guchar *)t1, strlen(t1)); | 1403 t2 = gaim_base64_encode((const guchar *)t1, strlen(t1)); |
1404 g_free(t1); | 1404 g_free(t1); |
1405 g_return_if_fail(request_len < sizeof(request)); | 1405 g_return_if_fail(request_len < sizeof(request)); |
1406 | 1406 |
1407 request_len += g_snprintf(request + request_len, | 1407 request_len += g_snprintf(request + request_len, |
1408 sizeof(request) - request_len, | 1408 sizeof(request) - request_len, |
1409 "Proxy-Authorization: Basic %s\r\n" | 1409 "Proxy-Authorization: Basic %s\r\n" |
1410 "Proxy-Authorization: NTLM %s\r\n" | 1410 "Proxy-Authorization: NTLM %s\r\n" |
1411 "Proxy-Connection: Keep-Alive\r\n", t2, | 1411 "Proxy-Connection: Keep-Alive\r\n", t2, |
1412 gaim_ntlm_gen_type1( | 1412 gaim_ntlm_gen_type1( |
1413 (gchar*)gaim_proxy_info_get_host(phb->gpi),"")); | 1413 (gchar*)gaim_proxy_info_get_host(connect_info->gpi),"")); |
1414 g_free(t2); | 1414 g_free(t2); |
1415 } | 1415 } |
1416 | 1416 |
1417 g_return_if_fail(request_len < sizeof(request)); | 1417 g_return_if_fail(request_len < sizeof(request)); |
1418 strcpy(request + request_len, "\r\n"); | 1418 strcpy(request + request_len, "\r\n"); |
1419 request_len += 2; | 1419 request_len += 2; |
1420 phb->write_buffer = g_memdup(request, request_len); | 1420 connect_info->write_buffer = g_memdup(request, request_len); |
1421 phb->write_buf_len = request_len; | 1421 connect_info->write_buf_len = request_len; |
1422 phb->written_len = 0; | 1422 connect_info->written_len = 0; |
1423 | 1423 |
1424 phb->read_cb = http_canread; | 1424 connect_info->read_cb = http_canread; |
1425 | 1425 |
1426 phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, | 1426 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, |
1427 phb); | 1427 connect_info); |
1428 | 1428 |
1429 proxy_do_write(phb, source, cond); | 1429 proxy_do_write(connect_info, source, cond); |
1430 } | 1430 } |
1431 | 1431 |
1432 static int | 1432 static int |
1433 proxy_connect_http(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) | 1433 proxy_connect_http(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) |
1434 { | 1434 { |
1435 int fd = -1; | 1435 int fd = -1; |
1436 | 1436 |
1437 gaim_debug_info("http proxy", | 1437 gaim_debug_info("http proxy", |
1438 "Connecting to %s:%d via %s:%d using HTTP\n", | 1438 "Connecting to %s:%d via %s:%d using HTTP\n", |
1439 (phb->host ? phb->host : "(null)"), phb->port, | 1439 (connect_info->host ? connect_info->host : "(null)"), connect_info->port, |
1440 (gaim_proxy_info_get_host(phb->gpi) ? gaim_proxy_info_get_host(phb->gpi) : "(null)"), | 1440 (gaim_proxy_info_get_host(connect_info->gpi) ? gaim_proxy_info_get_host(connect_info->gpi) : "(null)"), |
1441 gaim_proxy_info_get_port(phb->gpi)); | 1441 gaim_proxy_info_get_port(connect_info->gpi)); |
1442 | 1442 |
1443 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { | 1443 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
1444 return -1; | 1444 return -1; |
1445 } | 1445 } |
1446 | 1446 |
1452 if (connect(fd, addr, addrlen) < 0) { | 1452 if (connect(fd, addr, addrlen) < 0) { |
1453 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 1453 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
1454 gaim_debug_warning("http proxy", | 1454 gaim_debug_warning("http proxy", |
1455 "Connect would have blocked.\n"); | 1455 "Connect would have blocked.\n"); |
1456 | 1456 |
1457 if (phb->port != 80) { | 1457 if (connect_info->port != 80) { |
1458 /* we need to do CONNECT first */ | 1458 /* we need to do CONNECT first */ |
1459 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, | 1459 connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, |
1460 http_canwrite, phb); | 1460 http_canwrite, connect_info); |
1461 } else { | 1461 } else { |
1462 gaim_debug_info("proxy", "HTTP proxy connection established\n"); | 1462 gaim_debug_info("proxy", "HTTP proxy connection established\n"); |
1463 gaim_proxy_phb_connected(phb, fd); | 1463 gaim_proxy_connect_info_connected(connect_info, fd); |
1464 } | 1464 } |
1465 } else { | 1465 } else { |
1466 close(fd); | 1466 close(fd); |
1467 return -1; | 1467 return -1; |
1468 } | 1468 } |
1477 len = sizeof(error); | 1477 len = sizeof(error); |
1478 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 1478 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
1479 close(fd); | 1479 close(fd); |
1480 return -1; | 1480 return -1; |
1481 } | 1481 } |
1482 http_canwrite(phb, fd, GAIM_INPUT_WRITE); | 1482 http_canwrite(connect_info, fd, GAIM_INPUT_WRITE); |
1483 } | 1483 } |
1484 | 1484 |
1485 return fd; | 1485 return fd; |
1486 } | 1486 } |
1487 | 1487 |
1488 | 1488 |
1489 static void | 1489 static void |
1490 s4_canread(gpointer data, gint source, GaimInputCondition cond) | 1490 s4_canread(gpointer data, gint source, GaimInputCondition cond) |
1491 { | 1491 { |
1492 struct _GaimProxyConnectInfo *phb = data; | 1492 struct _GaimProxyConnectInfo *connect_info = data; |
1493 guchar *buf; | 1493 guchar *buf; |
1494 int len, max_read; | 1494 int len, max_read; |
1495 | 1495 |
1496 /* This is really not going to block under normal circumstances, but to | 1496 /* This is really not going to block under normal circumstances, but to |
1497 * be correct, we deal with the unlikely scenario */ | 1497 * be correct, we deal with the unlikely scenario */ |
1498 | 1498 |
1499 if (phb->read_buffer == NULL) { | 1499 if (connect_info->read_buffer == NULL) { |
1500 phb->read_buf_len = 12; | 1500 connect_info->read_buf_len = 12; |
1501 phb->read_buffer = g_malloc(phb->read_buf_len); | 1501 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); |
1502 phb->read_len = 0; | 1502 connect_info->read_len = 0; |
1503 } | 1503 } |
1504 | 1504 |
1505 buf = phb->read_buffer + phb->read_len; | 1505 buf = connect_info->read_buffer + connect_info->read_len; |
1506 max_read = phb->read_buf_len - phb->read_len; | 1506 max_read = connect_info->read_buf_len - connect_info->read_len; |
1507 | 1507 |
1508 len = read(source, buf, max_read); | 1508 len = read(source, buf, max_read); |
1509 | 1509 |
1510 if ((len < 0 && errno == EAGAIN) || (len > 0 && len + phb->read_len < 4)) | 1510 if ((len < 0 && errno == EAGAIN) || (len > 0 && len + connect_info->read_len < 4)) |
1511 return; | 1511 return; |
1512 else if (len + phb->read_len >= 4) { | 1512 else if (len + connect_info->read_len >= 4) { |
1513 if (phb->read_buffer[1] == 90) { | 1513 if (connect_info->read_buffer[1] == 90) { |
1514 gaim_proxy_phb_connected(phb, source); | 1514 gaim_proxy_connect_info_connected(connect_info, source); |
1515 return; | 1515 return; |
1516 } | 1516 } |
1517 } | 1517 } |
1518 | 1518 |
1519 gaim_input_remove(phb->inpa); | 1519 gaim_input_remove(connect_info->inpa); |
1520 phb->inpa = 0; | 1520 connect_info->inpa = 0; |
1521 g_free(phb->read_buffer); | 1521 g_free(connect_info->read_buffer); |
1522 phb->read_buffer = NULL; | 1522 connect_info->read_buffer = NULL; |
1523 | 1523 |
1524 close(source); | 1524 close(source); |
1525 | 1525 |
1526 try_connect(phb); | 1526 try_connect(connect_info); |
1527 } | 1527 } |
1528 | 1528 |
1529 static void | 1529 static void |
1530 s4_canwrite(gpointer data, gint source, GaimInputCondition cond) | 1530 s4_canwrite(gpointer data, gint source, GaimInputCondition cond) |
1531 { | 1531 { |
1532 unsigned char packet[9]; | 1532 unsigned char packet[9]; |
1533 struct hostent *hp; | 1533 struct hostent *hp; |
1534 struct _GaimProxyConnectInfo *phb = data; | 1534 struct _GaimProxyConnectInfo *connect_info = data; |
1535 socklen_t len; | 1535 socklen_t len; |
1536 int error = ETIMEDOUT; | 1536 int error = ETIMEDOUT; |
1537 | 1537 |
1538 gaim_debug_info("socks4 proxy", "Connected.\n"); | 1538 gaim_debug_info("socks4 proxy", "Connected.\n"); |
1539 | 1539 |
1540 if (phb->inpa > 0) | 1540 if (connect_info->inpa > 0) |
1541 { | 1541 { |
1542 gaim_input_remove(phb->inpa); | 1542 gaim_input_remove(connect_info->inpa); |
1543 phb->inpa = 0; | 1543 connect_info->inpa = 0; |
1544 } | 1544 } |
1545 | 1545 |
1546 len = sizeof(error); | 1546 len = sizeof(error); |
1547 | 1547 |
1548 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 1548 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
1549 close(source); | 1549 close(source); |
1550 | 1550 |
1551 try_connect(phb); | 1551 try_connect(connect_info); |
1552 return; | 1552 return; |
1553 } | 1553 } |
1554 | 1554 |
1555 /* | 1555 /* |
1556 * The socks4 spec doesn't include support for doing host name | 1556 * The socks4 spec doesn't include support for doing host name |
1558 * extensions to the protocol. Since we don't know if a | 1558 * extensions to the protocol. Since we don't know if a |
1559 * server supports this, it would need to be implemented | 1559 * server supports this, it would need to be implemented |
1560 * with an option, or some detection mechanism - in the | 1560 * with an option, or some detection mechanism - in the |
1561 * meantime, stick with plain old SOCKS4. | 1561 * meantime, stick with plain old SOCKS4. |
1562 */ | 1562 */ |
1563 if (!(hp = gethostbyname(phb->host))) { | 1563 if (!(hp = gethostbyname(connect_info->host))) { |
1564 close(source); | 1564 close(source); |
1565 | 1565 |
1566 try_connect(phb); | 1566 try_connect(connect_info); |
1567 return; | 1567 return; |
1568 } | 1568 } |
1569 | 1569 |
1570 packet[0] = 4; | 1570 packet[0] = 4; |
1571 packet[1] = 1; | 1571 packet[1] = 1; |
1572 packet[2] = phb->port >> 8; | 1572 packet[2] = connect_info->port >> 8; |
1573 packet[3] = phb->port & 0xff; | 1573 packet[3] = connect_info->port & 0xff; |
1574 packet[4] = (unsigned char)(hp->h_addr_list[0])[0]; | 1574 packet[4] = (unsigned char)(hp->h_addr_list[0])[0]; |
1575 packet[5] = (unsigned char)(hp->h_addr_list[0])[1]; | 1575 packet[5] = (unsigned char)(hp->h_addr_list[0])[1]; |
1576 packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; | 1576 packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; |
1577 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; | 1577 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; |
1578 packet[8] = 0; | 1578 packet[8] = 0; |
1579 | 1579 |
1580 phb->write_buffer = g_memdup(packet, sizeof(packet)); | 1580 connect_info->write_buffer = g_memdup(packet, sizeof(packet)); |
1581 phb->write_buf_len = sizeof(packet); | 1581 connect_info->write_buf_len = sizeof(packet); |
1582 phb->written_len = 0; | 1582 connect_info->written_len = 0; |
1583 phb->read_cb = s4_canread; | 1583 connect_info->read_cb = s4_canread; |
1584 | 1584 |
1585 phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, phb); | 1585 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info); |
1586 | 1586 |
1587 proxy_do_write(phb, source, cond); | 1587 proxy_do_write(connect_info, source, cond); |
1588 } | 1588 } |
1589 | 1589 |
1590 static int | 1590 static int |
1591 proxy_connect_socks4(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) | 1591 proxy_connect_socks4(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) |
1592 { | 1592 { |
1593 int fd = -1; | 1593 int fd = -1; |
1594 | 1594 |
1595 gaim_debug_info("socks4 proxy", | 1595 gaim_debug_info("socks4 proxy", |
1596 "Connecting to %s:%d via %s:%d using SOCKS4\n", | 1596 "Connecting to %s:%d via %s:%d using SOCKS4\n", |
1597 phb->host, phb->port, | 1597 connect_info->host, connect_info->port, |
1598 gaim_proxy_info_get_host(phb->gpi), | 1598 gaim_proxy_info_get_host(connect_info->gpi), |
1599 gaim_proxy_info_get_port(phb->gpi)); | 1599 gaim_proxy_info_get_port(connect_info->gpi)); |
1600 | 1600 |
1601 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) | 1601 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) |
1602 return -1; | 1602 return -1; |
1603 | 1603 |
1604 fcntl(fd, F_SETFL, O_NONBLOCK); | 1604 fcntl(fd, F_SETFL, O_NONBLOCK); |
1608 | 1608 |
1609 if (connect(fd, addr, addrlen) < 0) { | 1609 if (connect(fd, addr, addrlen) < 0) { |
1610 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 1610 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
1611 gaim_debug_warning("socks4 proxy", | 1611 gaim_debug_warning("socks4 proxy", |
1612 "Connect would have blocked.\n"); | 1612 "Connect would have blocked.\n"); |
1613 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); | 1613 connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, connect_info); |
1614 } | 1614 } |
1615 else { | 1615 else { |
1616 close(fd); | 1616 close(fd); |
1617 return -1; | 1617 return -1; |
1618 } | 1618 } |
1628 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 1628 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
1629 close(fd); | 1629 close(fd); |
1630 return -1; | 1630 return -1; |
1631 } | 1631 } |
1632 | 1632 |
1633 s4_canwrite(phb, fd, GAIM_INPUT_WRITE); | 1633 s4_canwrite(connect_info, fd, GAIM_INPUT_WRITE); |
1634 } | 1634 } |
1635 | 1635 |
1636 return fd; | 1636 return fd; |
1637 } | 1637 } |
1638 | 1638 |
1639 static void | 1639 static void |
1640 s5_canread_again(gpointer data, gint source, GaimInputCondition cond) | 1640 s5_canread_again(gpointer data, gint source, GaimInputCondition cond) |
1641 { | 1641 { |
1642 guchar *dest, *buf; | 1642 guchar *dest, *buf; |
1643 struct _GaimProxyConnectInfo *phb = data; | 1643 struct _GaimProxyConnectInfo *connect_info = data; |
1644 int len; | 1644 int len; |
1645 | 1645 |
1646 if (phb->read_buffer == NULL) { | 1646 if (connect_info->read_buffer == NULL) { |
1647 phb->read_buf_len = 512; | 1647 connect_info->read_buf_len = 512; |
1648 phb->read_buffer = g_malloc(phb->read_buf_len); | 1648 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); |
1649 phb->read_len = 0; | 1649 connect_info->read_len = 0; |
1650 } | 1650 } |
1651 | 1651 |
1652 dest = phb->read_buffer + phb->read_len; | 1652 dest = connect_info->read_buffer + connect_info->read_len; |
1653 buf = phb->read_buffer; | 1653 buf = connect_info->read_buffer; |
1654 | 1654 |
1655 gaim_debug_info("socks5 proxy", "Able to read again.\n"); | 1655 gaim_debug_info("socks5 proxy", "Able to read again.\n"); |
1656 | 1656 |
1657 len = read(source, dest, (phb->read_buf_len - phb->read_len)); | 1657 len = read(source, dest, (connect_info->read_buf_len - connect_info->read_len)); |
1658 if(len < 0 && errno == EAGAIN) | 1658 if(len < 0 && errno == EAGAIN) |
1659 return; | 1659 return; |
1660 else if(len <= 0) { | 1660 else if(len <= 0) { |
1661 gaim_debug_warning("socks5 proxy", "or not...\n"); | 1661 gaim_debug_warning("socks5 proxy", "or not...\n"); |
1662 close(source); | 1662 close(source); |
1663 gaim_input_remove(phb->inpa); | 1663 gaim_input_remove(connect_info->inpa); |
1664 phb->inpa = 0; | 1664 connect_info->inpa = 0; |
1665 g_free(phb->read_buffer); | 1665 g_free(connect_info->read_buffer); |
1666 phb->read_buffer = NULL; | 1666 connect_info->read_buffer = NULL; |
1667 try_connect(phb); | 1667 try_connect(connect_info); |
1668 return; | 1668 return; |
1669 } | 1669 } |
1670 phb->read_len += len; | 1670 connect_info->read_len += len; |
1671 | 1671 |
1672 if(phb->read_len < 4) | 1672 if(connect_info->read_len < 4) |
1673 return; | 1673 return; |
1674 | 1674 |
1675 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { | 1675 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { |
1676 if ((buf[0] == 0x05) && (buf[1] < 0x09)) | 1676 if ((buf[0] == 0x05) && (buf[1] < 0x09)) |
1677 gaim_debug_error("socks5 proxy", socks5errors[buf[1]]); | 1677 gaim_debug_error("socks5 proxy", socks5errors[buf[1]]); |
1678 else | 1678 else |
1679 gaim_debug_error("socks5 proxy", "Bad data.\n"); | 1679 gaim_debug_error("socks5 proxy", "Bad data.\n"); |
1680 close(source); | 1680 close(source); |
1681 gaim_input_remove(phb->inpa); | 1681 gaim_input_remove(connect_info->inpa); |
1682 phb->inpa = 0; | 1682 connect_info->inpa = 0; |
1683 g_free(phb->read_buffer); | 1683 g_free(connect_info->read_buffer); |
1684 phb->read_buffer = NULL; | 1684 connect_info->read_buffer = NULL; |
1685 try_connect(phb); | 1685 try_connect(connect_info); |
1686 return; | 1686 return; |
1687 } | 1687 } |
1688 | 1688 |
1689 /* Skip past BND.ADDR */ | 1689 /* Skip past BND.ADDR */ |
1690 switch(buf[3]) { | 1690 switch(buf[3]) { |
1691 case 0x01: /* the address is a version-4 IP address, with a length of 4 octets */ | 1691 case 0x01: /* the address is a version-4 IP address, with a length of 4 octets */ |
1692 if(phb->read_len < 4 + 4) | 1692 if(connect_info->read_len < 4 + 4) |
1693 return; | 1693 return; |
1694 buf += 4 + 4; | 1694 buf += 4 + 4; |
1695 break; | 1695 break; |
1696 case 0x03: /* the address field contains a fully-qualified domain name. The first | 1696 case 0x03: /* the address field contains a fully-qualified domain name. The first |
1697 octet of the address field contains the number of octets of name that | 1697 octet of the address field contains the number of octets of name that |
1698 follow, there is no terminating NUL octet. */ | 1698 follow, there is no terminating NUL octet. */ |
1699 if(phb->read_len < 4 + 1) | 1699 if(connect_info->read_len < 4 + 1) |
1700 return; | 1700 return; |
1701 buf += 4 + 1; | 1701 buf += 4 + 1; |
1702 if(phb->read_len < 4 + 1 + buf[0]) | 1702 if(connect_info->read_len < 4 + 1 + buf[0]) |
1703 return; | 1703 return; |
1704 buf += buf[0]; | 1704 buf += buf[0]; |
1705 break; | 1705 break; |
1706 case 0x04: /* the address is a version-6 IP address, with a length of 16 octets */ | 1706 case 0x04: /* the address is a version-6 IP address, with a length of 16 octets */ |
1707 if(phb->read_len < 4 + 16) | 1707 if(connect_info->read_len < 4 + 16) |
1708 return; | 1708 return; |
1709 buf += 4 + 16; | 1709 buf += 4 + 16; |
1710 break; | 1710 break; |
1711 } | 1711 } |
1712 | 1712 |
1713 if(phb->read_len < (buf - phb->read_buffer) + 2) | 1713 if(connect_info->read_len < (buf - connect_info->read_buffer) + 2) |
1714 return; | 1714 return; |
1715 | 1715 |
1716 /* Skip past BND.PORT */ | 1716 /* Skip past BND.PORT */ |
1717 buf += 2; | 1717 buf += 2; |
1718 | 1718 |
1719 gaim_proxy_phb_connected(phb, source); | 1719 gaim_proxy_connect_info_connected(connect_info, source); |
1720 } | 1720 } |
1721 | 1721 |
1722 static void | 1722 static void |
1723 s5_sendconnect(gpointer data, int source) | 1723 s5_sendconnect(gpointer data, int source) |
1724 { | 1724 { |
1725 struct _GaimProxyConnectInfo *phb = data; | 1725 struct _GaimProxyConnectInfo *connect_info = data; |
1726 int hlen = strlen(phb->host); | 1726 int hlen = strlen(connect_info->host); |
1727 phb->write_buf_len = 5 + hlen + 2; | 1727 connect_info->write_buf_len = 5 + hlen + 2; |
1728 phb->write_buffer = g_malloc(phb->write_buf_len); | 1728 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); |
1729 phb->written_len = 0; | 1729 connect_info->written_len = 0; |
1730 | 1730 |
1731 phb->write_buffer[0] = 0x05; | 1731 connect_info->write_buffer[0] = 0x05; |
1732 phb->write_buffer[1] = 0x01; /* CONNECT */ | 1732 connect_info->write_buffer[1] = 0x01; /* CONNECT */ |
1733 phb->write_buffer[2] = 0x00; /* reserved */ | 1733 connect_info->write_buffer[2] = 0x00; /* reserved */ |
1734 phb->write_buffer[3] = 0x03; /* address type -- host name */ | 1734 connect_info->write_buffer[3] = 0x03; /* address type -- host name */ |
1735 phb->write_buffer[4] = hlen; | 1735 connect_info->write_buffer[4] = hlen; |
1736 memcpy(phb->write_buffer + 5, phb->host, hlen); | 1736 memcpy(connect_info->write_buffer + 5, connect_info->host, hlen); |
1737 phb->write_buffer[5 + hlen] = phb->port >> 8; | 1737 connect_info->write_buffer[5 + hlen] = connect_info->port >> 8; |
1738 phb->write_buffer[5 + hlen + 1] = phb->port & 0xff; | 1738 connect_info->write_buffer[5 + hlen + 1] = connect_info->port & 0xff; |
1739 | 1739 |
1740 phb->read_cb = s5_canread_again; | 1740 connect_info->read_cb = s5_canread_again; |
1741 | 1741 |
1742 phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, phb); | 1742 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info); |
1743 proxy_do_write(phb, source, GAIM_INPUT_WRITE); | 1743 proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); |
1744 } | 1744 } |
1745 | 1745 |
1746 static void | 1746 static void |
1747 s5_readauth(gpointer data, gint source, GaimInputCondition cond) | 1747 s5_readauth(gpointer data, gint source, GaimInputCondition cond) |
1748 { | 1748 { |
1749 struct _GaimProxyConnectInfo *phb = data; | 1749 struct _GaimProxyConnectInfo *connect_info = data; |
1750 int len; | 1750 int len; |
1751 | 1751 |
1752 if (phb->read_buffer == NULL) { | 1752 if (connect_info->read_buffer == NULL) { |
1753 phb->read_buf_len = 2; | 1753 connect_info->read_buf_len = 2; |
1754 phb->read_buffer = g_malloc(phb->read_buf_len); | 1754 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); |
1755 phb->read_len = 0; | 1755 connect_info->read_len = 0; |
1756 } | 1756 } |
1757 | 1757 |
1758 gaim_debug_info("socks5 proxy", "Got auth response.\n"); | 1758 gaim_debug_info("socks5 proxy", "Got auth response.\n"); |
1759 | 1759 |
1760 len = read(source, phb->read_buffer + phb->read_len, | 1760 len = read(source, connect_info->read_buffer + connect_info->read_len, |
1761 phb->read_buf_len - phb->read_len); | 1761 connect_info->read_buf_len - connect_info->read_len); |
1762 if(len < 0 && errno == EAGAIN) | 1762 if(len < 0 && errno == EAGAIN) |
1763 return; | 1763 return; |
1764 else if(len <= 0) { | 1764 else if(len <= 0) { |
1765 close(source); | 1765 close(source); |
1766 gaim_input_remove(phb->inpa); | 1766 gaim_input_remove(connect_info->inpa); |
1767 phb->inpa = 0; | 1767 connect_info->inpa = 0; |
1768 g_free(phb->read_buffer); | 1768 g_free(connect_info->read_buffer); |
1769 phb->read_buffer = NULL; | 1769 connect_info->read_buffer = NULL; |
1770 try_connect(phb); | 1770 try_connect(connect_info); |
1771 return; | 1771 return; |
1772 } | 1772 } |
1773 phb->read_len += len; | 1773 connect_info->read_len += len; |
1774 | 1774 |
1775 if (phb->read_len < 2) | 1775 if (connect_info->read_len < 2) |
1776 return; | 1776 return; |
1777 | 1777 |
1778 gaim_input_remove(phb->inpa); | 1778 gaim_input_remove(connect_info->inpa); |
1779 phb->inpa = 0; | 1779 connect_info->inpa = 0; |
1780 | 1780 |
1781 if ((phb->read_buffer[0] != 0x01) || (phb->read_buffer[1] != 0x00)) { | 1781 if ((connect_info->read_buffer[0] != 0x01) || (connect_info->read_buffer[1] != 0x00)) { |
1782 close(source); | 1782 close(source); |
1783 g_free(phb->read_buffer); | 1783 g_free(connect_info->read_buffer); |
1784 phb->read_buffer = NULL; | 1784 connect_info->read_buffer = NULL; |
1785 try_connect(phb); | 1785 try_connect(connect_info); |
1786 return; | 1786 return; |
1787 } | 1787 } |
1788 | 1788 |
1789 g_free(phb->read_buffer); | 1789 g_free(connect_info->read_buffer); |
1790 phb->read_buffer = NULL; | 1790 connect_info->read_buffer = NULL; |
1791 | 1791 |
1792 s5_sendconnect(phb, source); | 1792 s5_sendconnect(connect_info, source); |
1793 } | 1793 } |
1794 | 1794 |
1795 static void hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd, unsigned char * response) | 1795 static void hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd, unsigned char * response) |
1796 { | 1796 { |
1797 GaimCipher *cipher; | 1797 GaimCipher *cipher; |
1837 | 1837 |
1838 static void | 1838 static void |
1839 s5_readchap(gpointer data, gint source, GaimInputCondition cond) | 1839 s5_readchap(gpointer data, gint source, GaimInputCondition cond) |
1840 { | 1840 { |
1841 guchar *cmdbuf, *buf; | 1841 guchar *cmdbuf, *buf; |
1842 struct _GaimProxyConnectInfo *phb = data; | 1842 struct _GaimProxyConnectInfo *connect_info = data; |
1843 int len, navas, currentav; | 1843 int len, navas, currentav; |
1844 | 1844 |
1845 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got CHAP response.\n"); | 1845 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got CHAP response.\n"); |
1846 | 1846 |
1847 if (phb->read_buffer == NULL) { | 1847 if (connect_info->read_buffer == NULL) { |
1848 phb->read_buf_len = 20; | 1848 connect_info->read_buf_len = 20; |
1849 phb->read_buffer = g_malloc(phb->read_buf_len); | 1849 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); |
1850 phb->read_len = 0; | 1850 connect_info->read_len = 0; |
1851 } | 1851 } |
1852 | 1852 |
1853 len = read(source, phb->read_buffer + phb->read_len, | 1853 len = read(source, connect_info->read_buffer + connect_info->read_len, |
1854 phb->read_buf_len - phb->read_len); | 1854 connect_info->read_buf_len - connect_info->read_len); |
1855 | 1855 |
1856 if(len < 0 && errno == EAGAIN) | 1856 if(len < 0 && errno == EAGAIN) |
1857 return; | 1857 return; |
1858 else if(len <= 0) { | 1858 else if(len <= 0) { |
1859 close(source); | 1859 close(source); |
1860 gaim_input_remove(phb->inpa); | 1860 gaim_input_remove(connect_info->inpa); |
1861 phb->inpa = 0; | 1861 connect_info->inpa = 0; |
1862 g_free(phb->read_buffer); | 1862 g_free(connect_info->read_buffer); |
1863 phb->read_buffer = NULL; | 1863 connect_info->read_buffer = NULL; |
1864 try_connect(phb); | 1864 try_connect(connect_info); |
1865 return; | 1865 return; |
1866 } | 1866 } |
1867 phb->read_len += len; | 1867 connect_info->read_len += len; |
1868 | 1868 |
1869 if (phb->read_len < 2) | 1869 if (connect_info->read_len < 2) |
1870 return; | 1870 return; |
1871 | 1871 |
1872 cmdbuf = phb->read_buffer; | 1872 cmdbuf = connect_info->read_buffer; |
1873 | 1873 |
1874 if (*cmdbuf != 0x01) { | 1874 if (*cmdbuf != 0x01) { |
1875 close(source); | 1875 close(source); |
1876 gaim_input_remove(phb->inpa); | 1876 gaim_input_remove(connect_info->inpa); |
1877 phb->inpa = 0; | 1877 connect_info->inpa = 0; |
1878 g_free(phb->read_buffer); | 1878 g_free(connect_info->read_buffer); |
1879 phb->read_buffer = NULL; | 1879 connect_info->read_buffer = NULL; |
1880 try_connect(phb); | 1880 try_connect(connect_info); |
1881 return; | 1881 return; |
1882 } | 1882 } |
1883 cmdbuf++; | 1883 cmdbuf++; |
1884 | 1884 |
1885 navas = *cmdbuf; | 1885 navas = *cmdbuf; |
1886 cmdbuf++; | 1886 cmdbuf++; |
1887 | 1887 |
1888 for (currentav = 0; currentav < navas; currentav++) { | 1888 for (currentav = 0; currentav < navas; currentav++) { |
1889 if (phb->read_len - (cmdbuf - phb->read_buffer) < 2) | 1889 if (connect_info->read_len - (cmdbuf - connect_info->read_buffer) < 2) |
1890 return; | 1890 return; |
1891 if (phb->read_len - (cmdbuf - phb->read_buffer) < cmdbuf[1]) | 1891 if (connect_info->read_len - (cmdbuf - connect_info->read_buffer) < cmdbuf[1]) |
1892 return; | 1892 return; |
1893 buf = cmdbuf + 2; | 1893 buf = cmdbuf + 2; |
1894 switch (cmdbuf[0]) { | 1894 switch (cmdbuf[0]) { |
1895 case 0x00: | 1895 case 0x00: |
1896 /* Did auth work? */ | 1896 /* Did auth work? */ |
1897 if (buf[0] == 0x00) { | 1897 if (buf[0] == 0x00) { |
1898 gaim_input_remove(phb->inpa); | 1898 gaim_input_remove(connect_info->inpa); |
1899 phb->inpa = 0; | 1899 connect_info->inpa = 0; |
1900 g_free(phb->read_buffer); | 1900 g_free(connect_info->read_buffer); |
1901 phb->read_buffer = NULL; | 1901 connect_info->read_buffer = NULL; |
1902 /* Success */ | 1902 /* Success */ |
1903 s5_sendconnect(phb, source); | 1903 s5_sendconnect(connect_info, source); |
1904 return; | 1904 return; |
1905 } else { | 1905 } else { |
1906 /* Failure */ | 1906 /* Failure */ |
1907 gaim_debug_warning("proxy", | 1907 gaim_debug_warning("proxy", |
1908 "socks5 CHAP authentication " | 1908 "socks5 CHAP authentication " |
1909 "failed. Disconnecting..."); | 1909 "failed. Disconnecting..."); |
1910 close(source); | 1910 close(source); |
1911 gaim_input_remove(phb->inpa); | 1911 gaim_input_remove(connect_info->inpa); |
1912 phb->inpa = 0; | 1912 connect_info->inpa = 0; |
1913 g_free(phb->read_buffer); | 1913 g_free(connect_info->read_buffer); |
1914 phb->read_buffer = NULL; | 1914 connect_info->read_buffer = NULL; |
1915 try_connect(phb); | 1915 try_connect(connect_info); |
1916 return; | 1916 return; |
1917 } | 1917 } |
1918 break; | 1918 break; |
1919 case 0x03: | 1919 case 0x03: |
1920 /* Server wants our credentials */ | 1920 /* Server wants our credentials */ |
1921 | 1921 |
1922 phb->write_buf_len = 16 + 4; | 1922 connect_info->write_buf_len = 16 + 4; |
1923 phb->write_buffer = g_malloc(phb->write_buf_len); | 1923 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); |
1924 phb->written_len = 0; | 1924 connect_info->written_len = 0; |
1925 | 1925 |
1926 hmacmd5_chap(buf, cmdbuf[1], | 1926 hmacmd5_chap(buf, cmdbuf[1], |
1927 gaim_proxy_info_get_password(phb->gpi), | 1927 gaim_proxy_info_get_password(connect_info->gpi), |
1928 phb->write_buffer + 4); | 1928 connect_info->write_buffer + 4); |
1929 phb->write_buffer[0] = 0x01; | 1929 connect_info->write_buffer[0] = 0x01; |
1930 phb->write_buffer[1] = 0x01; | 1930 connect_info->write_buffer[1] = 0x01; |
1931 phb->write_buffer[2] = 0x04; | 1931 connect_info->write_buffer[2] = 0x04; |
1932 phb->write_buffer[3] = 0x10; | 1932 connect_info->write_buffer[3] = 0x10; |
1933 | 1933 |
1934 gaim_input_remove(phb->inpa); | 1934 gaim_input_remove(connect_info->inpa); |
1935 g_free(phb->read_buffer); | 1935 g_free(connect_info->read_buffer); |
1936 phb->read_buffer = NULL; | 1936 connect_info->read_buffer = NULL; |
1937 | 1937 |
1938 phb->read_cb = s5_readchap; | 1938 connect_info->read_cb = s5_readchap; |
1939 | 1939 |
1940 phb->inpa = gaim_input_add(source, | 1940 connect_info->inpa = gaim_input_add(source, |
1941 GAIM_INPUT_WRITE, proxy_do_write, phb); | 1941 GAIM_INPUT_WRITE, proxy_do_write, connect_info); |
1942 | 1942 |
1943 proxy_do_write(phb, source, GAIM_INPUT_WRITE); | 1943 proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); |
1944 break; | 1944 break; |
1945 case 0x11: | 1945 case 0x11: |
1946 /* Server wants to select an algorithm */ | 1946 /* Server wants to select an algorithm */ |
1947 if (buf[0] != 0x85) { | 1947 if (buf[0] != 0x85) { |
1948 /* Only currently support HMAC-MD5 */ | 1948 /* Only currently support HMAC-MD5 */ |
1951 "algorithm that we did not advertise " | 1951 "algorithm that we did not advertise " |
1952 "as supporting. This is a violation " | 1952 "as supporting. This is a violation " |
1953 "of the socks5 CHAP specification. " | 1953 "of the socks5 CHAP specification. " |
1954 "Disconnecting..."); | 1954 "Disconnecting..."); |
1955 close(source); | 1955 close(source); |
1956 gaim_input_remove(phb->inpa); | 1956 gaim_input_remove(connect_info->inpa); |
1957 phb->inpa = 0; | 1957 connect_info->inpa = 0; |
1958 g_free(phb->read_buffer); | 1958 g_free(connect_info->read_buffer); |
1959 phb->read_buffer = NULL; | 1959 connect_info->read_buffer = NULL; |
1960 try_connect(phb); | 1960 try_connect(connect_info); |
1961 return; | 1961 return; |
1962 } | 1962 } |
1963 break; | 1963 break; |
1964 } | 1964 } |
1965 cmdbuf = buf + cmdbuf[1]; | 1965 cmdbuf = buf + cmdbuf[1]; |
1970 } | 1970 } |
1971 | 1971 |
1972 static void | 1972 static void |
1973 s5_canread(gpointer data, gint source, GaimInputCondition cond) | 1973 s5_canread(gpointer data, gint source, GaimInputCondition cond) |
1974 { | 1974 { |
1975 struct _GaimProxyConnectInfo *phb = data; | 1975 struct _GaimProxyConnectInfo *connect_info = data; |
1976 int len; | 1976 int len; |
1977 | 1977 |
1978 if (phb->read_buffer == NULL) { | 1978 if (connect_info->read_buffer == NULL) { |
1979 phb->read_buf_len = 2; | 1979 connect_info->read_buf_len = 2; |
1980 phb->read_buffer = g_malloc(phb->read_buf_len); | 1980 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); |
1981 phb->read_len = 0; | 1981 connect_info->read_len = 0; |
1982 } | 1982 } |
1983 | 1983 |
1984 gaim_debug_info("socks5 proxy", "Able to read.\n"); | 1984 gaim_debug_info("socks5 proxy", "Able to read.\n"); |
1985 | 1985 |
1986 len = read(source, phb->read_buffer + phb->read_len, | 1986 len = read(source, connect_info->read_buffer + connect_info->read_len, |
1987 phb->read_buf_len - phb->read_len); | 1987 connect_info->read_buf_len - connect_info->read_len); |
1988 if(len < 0 && errno == EAGAIN) | 1988 if(len < 0 && errno == EAGAIN) |
1989 return; | 1989 return; |
1990 else if(len <= 0) { | 1990 else if(len <= 0) { |
1991 close(source); | 1991 close(source); |
1992 gaim_input_remove(phb->inpa); | 1992 gaim_input_remove(connect_info->inpa); |
1993 phb->inpa = 0; | 1993 connect_info->inpa = 0; |
1994 g_free(phb->read_buffer); | 1994 g_free(connect_info->read_buffer); |
1995 phb->read_buffer = NULL; | 1995 connect_info->read_buffer = NULL; |
1996 try_connect(phb); | 1996 try_connect(connect_info); |
1997 return; | 1997 return; |
1998 } | 1998 } |
1999 phb->read_len += len; | 1999 connect_info->read_len += len; |
2000 | 2000 |
2001 if (phb->read_len < 2) | 2001 if (connect_info->read_len < 2) |
2002 return; | 2002 return; |
2003 | 2003 |
2004 gaim_input_remove(phb->inpa); | 2004 gaim_input_remove(connect_info->inpa); |
2005 phb->inpa = 0; | 2005 connect_info->inpa = 0; |
2006 | 2006 |
2007 if ((phb->read_buffer[0] != 0x05) || (phb->read_buffer[1] == 0xff)) { | 2007 if ((connect_info->read_buffer[0] != 0x05) || (connect_info->read_buffer[1] == 0xff)) { |
2008 close(source); | 2008 close(source); |
2009 g_free(phb->read_buffer); | 2009 g_free(connect_info->read_buffer); |
2010 phb->read_buffer = NULL; | 2010 connect_info->read_buffer = NULL; |
2011 try_connect(phb); | 2011 try_connect(connect_info); |
2012 return; | 2012 return; |
2013 } | 2013 } |
2014 | 2014 |
2015 if (phb->read_buffer[1] == 0x02) { | 2015 if (connect_info->read_buffer[1] == 0x02) { |
2016 gsize i, j; | 2016 gsize i, j; |
2017 const char *u, *p; | 2017 const char *u, *p; |
2018 | 2018 |
2019 u = gaim_proxy_info_get_username(phb->gpi); | 2019 u = gaim_proxy_info_get_username(connect_info->gpi); |
2020 p = gaim_proxy_info_get_password(phb->gpi); | 2020 p = gaim_proxy_info_get_password(connect_info->gpi); |
2021 | 2021 |
2022 i = (u == NULL) ? 0 : strlen(u); | 2022 i = (u == NULL) ? 0 : strlen(u); |
2023 j = (p == NULL) ? 0 : strlen(p); | 2023 j = (p == NULL) ? 0 : strlen(p); |
2024 | 2024 |
2025 phb->write_buf_len = 1 + 1 + i + 1 + j; | 2025 connect_info->write_buf_len = 1 + 1 + i + 1 + j; |
2026 phb->write_buffer = g_malloc(phb->write_buf_len); | 2026 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); |
2027 phb->written_len = 0; | 2027 connect_info->written_len = 0; |
2028 | 2028 |
2029 phb->write_buffer[0] = 0x01; /* version 1 */ | 2029 connect_info->write_buffer[0] = 0x01; /* version 1 */ |
2030 phb->write_buffer[1] = i; | 2030 connect_info->write_buffer[1] = i; |
2031 if (u != NULL) | 2031 if (u != NULL) |
2032 memcpy(phb->write_buffer + 2, u, i); | 2032 memcpy(connect_info->write_buffer + 2, u, i); |
2033 phb->write_buffer[2 + i] = j; | 2033 connect_info->write_buffer[2 + i] = j; |
2034 if (p != NULL) | 2034 if (p != NULL) |
2035 memcpy(phb->write_buffer + 2 + i + 1, p, j); | 2035 memcpy(connect_info->write_buffer + 2 + i + 1, p, j); |
2036 | 2036 |
2037 g_free(phb->read_buffer); | 2037 g_free(connect_info->read_buffer); |
2038 phb->read_buffer = NULL; | 2038 connect_info->read_buffer = NULL; |
2039 | 2039 |
2040 phb->read_cb = s5_readauth; | 2040 connect_info->read_cb = s5_readauth; |
2041 | 2041 |
2042 phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, | 2042 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, |
2043 proxy_do_write, phb); | 2043 proxy_do_write, connect_info); |
2044 | 2044 |
2045 proxy_do_write(phb, source, GAIM_INPUT_WRITE); | 2045 proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); |
2046 | 2046 |
2047 return; | 2047 return; |
2048 } else if (phb->read_buffer[1] == 0x03) { | 2048 } else if (connect_info->read_buffer[1] == 0x03) { |
2049 gsize userlen; | 2049 gsize userlen; |
2050 userlen = strlen(gaim_proxy_info_get_username(phb->gpi)); | 2050 userlen = strlen(gaim_proxy_info_get_username(connect_info->gpi)); |
2051 | 2051 |
2052 phb->write_buf_len = 7 + userlen; | 2052 connect_info->write_buf_len = 7 + userlen; |
2053 phb->write_buffer = g_malloc(phb->write_buf_len); | 2053 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); |
2054 phb->written_len = 0; | 2054 connect_info->written_len = 0; |
2055 | 2055 |
2056 phb->write_buffer[0] = 0x01; | 2056 connect_info->write_buffer[0] = 0x01; |
2057 phb->write_buffer[1] = 0x02; | 2057 connect_info->write_buffer[1] = 0x02; |
2058 phb->write_buffer[2] = 0x11; | 2058 connect_info->write_buffer[2] = 0x11; |
2059 phb->write_buffer[3] = 0x01; | 2059 connect_info->write_buffer[3] = 0x01; |
2060 phb->write_buffer[4] = 0x85; | 2060 connect_info->write_buffer[4] = 0x85; |
2061 phb->write_buffer[5] = 0x02; | 2061 connect_info->write_buffer[5] = 0x02; |
2062 phb->write_buffer[6] = userlen; | 2062 connect_info->write_buffer[6] = userlen; |
2063 memcpy(phb->write_buffer + 7, | 2063 memcpy(connect_info->write_buffer + 7, |
2064 gaim_proxy_info_get_username(phb->gpi), userlen); | 2064 gaim_proxy_info_get_username(connect_info->gpi), userlen); |
2065 | 2065 |
2066 g_free(phb->read_buffer); | 2066 g_free(connect_info->read_buffer); |
2067 phb->read_buffer = NULL; | 2067 connect_info->read_buffer = NULL; |
2068 | 2068 |
2069 phb->read_cb = s5_readchap; | 2069 connect_info->read_cb = s5_readchap; |
2070 | 2070 |
2071 phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, | 2071 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, |
2072 proxy_do_write, phb); | 2072 proxy_do_write, connect_info); |
2073 | 2073 |
2074 proxy_do_write(phb, source, GAIM_INPUT_WRITE); | 2074 proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); |
2075 | 2075 |
2076 return; | 2076 return; |
2077 } else { | 2077 } else { |
2078 g_free(phb->read_buffer); | 2078 g_free(connect_info->read_buffer); |
2079 phb->read_buffer = NULL; | 2079 connect_info->read_buffer = NULL; |
2080 | 2080 |
2081 s5_sendconnect(phb, source); | 2081 s5_sendconnect(connect_info, source); |
2082 } | 2082 } |
2083 } | 2083 } |
2084 | 2084 |
2085 static void | 2085 static void |
2086 s5_canwrite(gpointer data, gint source, GaimInputCondition cond) | 2086 s5_canwrite(gpointer data, gint source, GaimInputCondition cond) |
2087 { | 2087 { |
2088 unsigned char buf[5]; | 2088 unsigned char buf[5]; |
2089 int i; | 2089 int i; |
2090 struct _GaimProxyConnectInfo *phb = data; | 2090 struct _GaimProxyConnectInfo *connect_info = data; |
2091 socklen_t len; | 2091 socklen_t len; |
2092 int error = ETIMEDOUT; | 2092 int error = ETIMEDOUT; |
2093 | 2093 |
2094 gaim_debug_info("socks5 proxy", "Connected.\n"); | 2094 gaim_debug_info("socks5 proxy", "Connected.\n"); |
2095 | 2095 |
2096 if (phb->inpa > 0) | 2096 if (connect_info->inpa > 0) |
2097 { | 2097 { |
2098 gaim_input_remove(phb->inpa); | 2098 gaim_input_remove(connect_info->inpa); |
2099 phb->inpa = 0; | 2099 connect_info->inpa = 0; |
2100 } | 2100 } |
2101 | 2101 |
2102 len = sizeof(error); | 2102 len = sizeof(error); |
2103 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 2103 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
2104 close(source); | 2104 close(source); |
2105 | 2105 |
2106 try_connect(phb); | 2106 try_connect(connect_info); |
2107 return; | 2107 return; |
2108 } | 2108 } |
2109 | 2109 |
2110 i = 0; | 2110 i = 0; |
2111 buf[0] = 0x05; /* SOCKS version 5 */ | 2111 buf[0] = 0x05; /* SOCKS version 5 */ |
2112 | 2112 |
2113 if (gaim_proxy_info_get_username(phb->gpi) != NULL) { | 2113 if (gaim_proxy_info_get_username(connect_info->gpi) != NULL) { |
2114 buf[1] = 0x03; /* three methods */ | 2114 buf[1] = 0x03; /* three methods */ |
2115 buf[2] = 0x00; /* no authentication */ | 2115 buf[2] = 0x00; /* no authentication */ |
2116 buf[3] = 0x03; /* CHAP authentication */ | 2116 buf[3] = 0x03; /* CHAP authentication */ |
2117 buf[4] = 0x02; /* username/password authentication */ | 2117 buf[4] = 0x02; /* username/password authentication */ |
2118 i = 5; | 2118 i = 5; |
2121 buf[1] = 0x01; | 2121 buf[1] = 0x01; |
2122 buf[2] = 0x00; | 2122 buf[2] = 0x00; |
2123 i = 3; | 2123 i = 3; |
2124 } | 2124 } |
2125 | 2125 |
2126 phb->write_buf_len = i; | 2126 connect_info->write_buf_len = i; |
2127 phb->write_buffer = g_malloc(phb->write_buf_len); | 2127 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); |
2128 memcpy(phb->write_buffer, buf, i); | 2128 memcpy(connect_info->write_buffer, buf, i); |
2129 | 2129 |
2130 phb->read_cb = s5_canread; | 2130 connect_info->read_cb = s5_canread; |
2131 | 2131 |
2132 phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, phb); | 2132 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info); |
2133 proxy_do_write(phb, source, GAIM_INPUT_WRITE); | 2133 proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); |
2134 } | 2134 } |
2135 | 2135 |
2136 static int | 2136 static int |
2137 proxy_connect_socks5(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) | 2137 proxy_connect_socks5(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) |
2138 { | 2138 { |
2139 int fd = -1; | 2139 int fd = -1; |
2140 | 2140 |
2141 gaim_debug_info("socks5 proxy", | 2141 gaim_debug_info("socks5 proxy", |
2142 "Connecting to %s:%d via %s:%d using SOCKS5\n", | 2142 "Connecting to %s:%d via %s:%d using SOCKS5\n", |
2143 phb->host, phb->port, | 2143 connect_info->host, connect_info->port, |
2144 gaim_proxy_info_get_host(phb->gpi), | 2144 gaim_proxy_info_get_host(connect_info->gpi), |
2145 gaim_proxy_info_get_port(phb->gpi)); | 2145 gaim_proxy_info_get_port(connect_info->gpi)); |
2146 | 2146 |
2147 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) | 2147 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) |
2148 return -1; | 2148 return -1; |
2149 | 2149 |
2150 fcntl(fd, F_SETFL, O_NONBLOCK); | 2150 fcntl(fd, F_SETFL, O_NONBLOCK); |
2155 if (connect(fd, addr, addrlen) < 0) { | 2155 if (connect(fd, addr, addrlen) < 0) { |
2156 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 2156 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
2157 gaim_debug_warning("socks5 proxy", | 2157 gaim_debug_warning("socks5 proxy", |
2158 "Connect would have blocked.\n"); | 2158 "Connect would have blocked.\n"); |
2159 | 2159 |
2160 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); | 2160 connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, connect_info); |
2161 } | 2161 } |
2162 else { | 2162 else { |
2163 close(fd); | 2163 close(fd); |
2164 return -1; | 2164 return -1; |
2165 } | 2165 } |
2176 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 2176 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
2177 close(fd); | 2177 close(fd); |
2178 return -1; | 2178 return -1; |
2179 } | 2179 } |
2180 | 2180 |
2181 s5_canwrite(phb, fd, GAIM_INPUT_WRITE); | 2181 s5_canwrite(connect_info, fd, GAIM_INPUT_WRITE); |
2182 } | 2182 } |
2183 | 2183 |
2184 return fd; | 2184 return fd; |
2185 } | 2185 } |
2186 | 2186 |
2187 static void try_connect(struct _GaimProxyConnectInfo *phb) | 2187 static void try_connect(struct _GaimProxyConnectInfo *connect_info) |
2188 { | 2188 { |
2189 size_t addrlen; | 2189 size_t addrlen; |
2190 struct sockaddr *addr; | 2190 struct sockaddr *addr; |
2191 int ret = -1; | 2191 int ret = -1; |
2192 | 2192 |
2193 while (phb->hosts) { | 2193 while (connect_info->hosts) { |
2194 addrlen = GPOINTER_TO_INT(phb->hosts->data); | 2194 addrlen = GPOINTER_TO_INT(connect_info->hosts->data); |
2195 phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); | 2195 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); |
2196 addr = phb->hosts->data; | 2196 addr = connect_info->hosts->data; |
2197 phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); | 2197 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); |
2198 | 2198 |
2199 switch (gaim_proxy_info_get_type(phb->gpi)) { | 2199 switch (gaim_proxy_info_get_type(connect_info->gpi)) { |
2200 case GAIM_PROXY_NONE: | 2200 case GAIM_PROXY_NONE: |
2201 ret = proxy_connect_none(phb, addr, addrlen); | 2201 ret = proxy_connect_none(connect_info, addr, addrlen); |
2202 break; | 2202 break; |
2203 | 2203 |
2204 case GAIM_PROXY_HTTP: | 2204 case GAIM_PROXY_HTTP: |
2205 ret = proxy_connect_http(phb, addr, addrlen); | 2205 ret = proxy_connect_http(connect_info, addr, addrlen); |
2206 break; | 2206 break; |
2207 | 2207 |
2208 case GAIM_PROXY_SOCKS4: | 2208 case GAIM_PROXY_SOCKS4: |
2209 ret = proxy_connect_socks4(phb, addr, addrlen); | 2209 ret = proxy_connect_socks4(connect_info, addr, addrlen); |
2210 break; | 2210 break; |
2211 | 2211 |
2212 case GAIM_PROXY_SOCKS5: | 2212 case GAIM_PROXY_SOCKS5: |
2213 ret = proxy_connect_socks5(phb, addr, addrlen); | 2213 ret = proxy_connect_socks5(connect_info, addr, addrlen); |
2214 break; | 2214 break; |
2215 | 2215 |
2216 case GAIM_PROXY_USE_ENVVAR: | 2216 case GAIM_PROXY_USE_ENVVAR: |
2217 ret = proxy_connect_http(phb, addr, addrlen); | 2217 ret = proxy_connect_http(connect_info, addr, addrlen); |
2218 break; | 2218 break; |
2219 | 2219 |
2220 default: | 2220 default: |
2221 break; | 2221 break; |
2222 } | 2222 } |
2226 if (ret > 0) | 2226 if (ret > 0) |
2227 break; | 2227 break; |
2228 } | 2228 } |
2229 | 2229 |
2230 if (ret < 0) { | 2230 if (ret < 0) { |
2231 gaim_proxy_phb_error(phb, _("TODO")); | 2231 gaim_proxy_connect_info_error(connect_info, _("TODO")); |
2232 } | 2232 } |
2233 } | 2233 } |
2234 | 2234 |
2235 static void | 2235 static void |
2236 connection_host_resolved(GSList *hosts, gpointer data, | 2236 connection_host_resolved(GSList *hosts, gpointer data, |
2237 const char *error_message) | 2237 const char *error_message) |
2238 { | 2238 { |
2239 struct _GaimProxyConnectInfo *phb = (struct _GaimProxyConnectInfo*)data; | 2239 struct _GaimProxyConnectInfo *connect_info = (struct _GaimProxyConnectInfo*)data; |
2240 | 2240 |
2241 phb->hosts = hosts; | 2241 connect_info->hosts = hosts; |
2242 | 2242 |
2243 try_connect(phb); | 2243 try_connect(connect_info); |
2244 } | 2244 } |
2245 | 2245 |
2246 GaimProxyInfo * | 2246 GaimProxyInfo * |
2247 gaim_proxy_get_setup(GaimAccount *account) | 2247 gaim_proxy_get_setup(GaimAccount *account) |
2248 { | 2248 { |
2314 GaimProxyConnectFunction connect_cb, | 2314 GaimProxyConnectFunction connect_cb, |
2315 GaimProxyErrorFunction error_cb, gpointer data) | 2315 GaimProxyErrorFunction error_cb, gpointer data) |
2316 { | 2316 { |
2317 const char *connecthost = host; | 2317 const char *connecthost = host; |
2318 int connectport = port; | 2318 int connectport = port; |
2319 struct _GaimProxyConnectInfo *phb; | 2319 struct _GaimProxyConnectInfo *connect_info; |
2320 | 2320 |
2321 g_return_val_if_fail(host != NULL, NULL); | 2321 g_return_val_if_fail(host != NULL, NULL); |
2322 g_return_val_if_fail(port > 0, NULL); | 2322 g_return_val_if_fail(port > 0, NULL); |
2323 g_return_val_if_fail(connect_cb != NULL, NULL); | 2323 g_return_val_if_fail(connect_cb != NULL, NULL); |
2324 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ | 2324 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ |
2325 | 2325 |
2326 phb = g_new0(struct _GaimProxyConnectInfo, 1); | 2326 connect_info = g_new0(struct _GaimProxyConnectInfo, 1); |
2327 phb->connect_cb = connect_cb; | 2327 connect_info->connect_cb = connect_cb; |
2328 phb->error_cb = error_cb; | 2328 connect_info->error_cb = error_cb; |
2329 phb->data = data; | 2329 connect_info->data = data; |
2330 phb->host = g_strdup(host); | 2330 connect_info->host = g_strdup(host); |
2331 phb->port = port; | 2331 connect_info->port = port; |
2332 phb->gpi = gaim_proxy_get_setup(account); | 2332 connect_info->gpi = gaim_proxy_get_setup(account); |
2333 | 2333 |
2334 if ((gaim_proxy_info_get_type(phb->gpi) != GAIM_PROXY_NONE) && | 2334 if ((gaim_proxy_info_get_type(connect_info->gpi) != GAIM_PROXY_NONE) && |
2335 (gaim_proxy_info_get_host(phb->gpi) == NULL || | 2335 (gaim_proxy_info_get_host(connect_info->gpi) == NULL || |
2336 gaim_proxy_info_get_port(phb->gpi) <= 0)) { | 2336 gaim_proxy_info_get_port(connect_info->gpi) <= 0)) { |
2337 | 2337 |
2338 gaim_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid.")); | 2338 gaim_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid.")); |
2339 gaim_proxy_phb_destroy(phb); | 2339 gaim_proxy_connect_info_destroy(connect_info); |
2340 return NULL; | 2340 return NULL; |
2341 } | 2341 } |
2342 | 2342 |
2343 switch (gaim_proxy_info_get_type(phb->gpi)) | 2343 switch (gaim_proxy_info_get_type(connect_info->gpi)) |
2344 { | 2344 { |
2345 case GAIM_PROXY_NONE: | 2345 case GAIM_PROXY_NONE: |
2346 break; | 2346 break; |
2347 | 2347 |
2348 case GAIM_PROXY_HTTP: | 2348 case GAIM_PROXY_HTTP: |
2349 case GAIM_PROXY_SOCKS4: | 2349 case GAIM_PROXY_SOCKS4: |
2350 case GAIM_PROXY_SOCKS5: | 2350 case GAIM_PROXY_SOCKS5: |
2351 case GAIM_PROXY_USE_ENVVAR: | 2351 case GAIM_PROXY_USE_ENVVAR: |
2352 connecthost = gaim_proxy_info_get_host(phb->gpi); | 2352 connecthost = gaim_proxy_info_get_host(connect_info->gpi); |
2353 connectport = gaim_proxy_info_get_port(phb->gpi); | 2353 connectport = gaim_proxy_info_get_port(connect_info->gpi); |
2354 break; | 2354 break; |
2355 | 2355 |
2356 default: | 2356 default: |
2357 gaim_proxy_phb_destroy(phb); | 2357 gaim_proxy_connect_info_destroy(connect_info); |
2358 return NULL; | 2358 return NULL; |
2359 } | 2359 } |
2360 | 2360 |
2361 if (gaim_gethostbyname_async(connecthost, | 2361 if (gaim_gethostbyname_async(connecthost, |
2362 connectport, connection_host_resolved, phb) != 0) | 2362 connectport, connection_host_resolved, connect_info) != 0) |
2363 { | 2363 { |
2364 gaim_proxy_phb_destroy(phb); | 2364 gaim_proxy_connect_info_destroy(connect_info); |
2365 return NULL; | 2365 return NULL; |
2366 } | 2366 } |
2367 | 2367 |
2368 phbs = g_slist_prepend(phbs, phb); | 2368 connect_infos = g_slist_prepend(connect_infos, connect_info); |
2369 | 2369 |
2370 return phb; | 2370 return connect_info; |
2371 } | 2371 } |
2372 | 2372 |
2373 /* | 2373 /* |
2374 * Combine some of this code with gaim_proxy_connect() | 2374 * Combine some of this code with gaim_proxy_connect() |
2375 */ | 2375 */ |
2376 GaimProxyConnectInfo * | 2376 GaimProxyConnectInfo * |
2377 gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, | 2377 gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, |
2378 GaimProxyConnectFunction connect_cb, | 2378 GaimProxyConnectFunction connect_cb, |
2379 GaimProxyErrorFunction error_cb, gpointer data) | 2379 GaimProxyErrorFunction error_cb, gpointer data) |
2380 { | 2380 { |
2381 struct _GaimProxyConnectInfo *phb; | 2381 struct _GaimProxyConnectInfo *connect_info; |
2382 | 2382 |
2383 g_return_val_if_fail(host != NULL, NULL); | 2383 g_return_val_if_fail(host != NULL, NULL); |
2384 g_return_val_if_fail(port > 0, NULL); | 2384 g_return_val_if_fail(port > 0, NULL); |
2385 g_return_val_if_fail(connect_cb != NULL, NULL); | 2385 g_return_val_if_fail(connect_cb != NULL, NULL); |
2386 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ | 2386 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ |
2387 | 2387 |
2388 phb = g_new0(struct _GaimProxyConnectInfo, 1); | 2388 connect_info = g_new0(struct _GaimProxyConnectInfo, 1); |
2389 phb->connect_cb = connect_cb; | 2389 connect_info->connect_cb = connect_cb; |
2390 phb->error_cb = error_cb; | 2390 connect_info->error_cb = error_cb; |
2391 phb->data = data; | 2391 connect_info->data = data; |
2392 phb->host = g_strdup(host); | 2392 connect_info->host = g_strdup(host); |
2393 phb->port = port; | 2393 connect_info->port = port; |
2394 phb->gpi = gpi; | 2394 connect_info->gpi = gpi; |
2395 | 2395 |
2396 if (gaim_gethostbyname_async(gaim_proxy_info_get_host(gpi), | 2396 if (gaim_gethostbyname_async(gaim_proxy_info_get_host(gpi), |
2397 gaim_proxy_info_get_port(gpi), connection_host_resolved, phb) != 0) | 2397 gaim_proxy_info_get_port(gpi), connection_host_resolved, connect_info) != 0) |
2398 { | 2398 { |
2399 gaim_proxy_phb_destroy(phb); | 2399 gaim_proxy_connect_info_destroy(connect_info); |
2400 return NULL; | 2400 return NULL; |
2401 } | 2401 } |
2402 | 2402 |
2403 phbs = g_slist_prepend(phbs, phb); | 2403 connect_infos = g_slist_prepend(connect_infos, connect_info); |
2404 | 2404 |
2405 return phb; | 2405 return connect_info; |
2406 } | 2406 } |
2407 | 2407 |
2408 | 2408 |
2409 static void | 2409 static void |
2410 proxy_pref_cb(const char *name, GaimPrefType type, | 2410 proxy_pref_cb(const char *name, GaimPrefType type, |
2483 } | 2483 } |
2484 | 2484 |
2485 void | 2485 void |
2486 gaim_proxy_uninit(void) | 2486 gaim_proxy_uninit(void) |
2487 { | 2487 { |
2488 while (phbs != NULL) | 2488 while (connect_infos != NULL) |
2489 gaim_proxy_phb_destroy(phbs->data); | 2489 gaim_proxy_connect_info_destroy(connect_infos->data); |
2490 } | 2490 } |