Mercurial > pidgin
comparison src/proxy.c @ 1252:46c09828e929
[gaim-migrate @ 1262]
still need to do buddy.c, conversation.c, dialogs.c, prefs.c.
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Wed, 13 Dec 2000 22:12:02 +0000 |
| parents | 56c7ceb986a8 |
| children | 153eb28ea454 |
comparison
equal
deleted
inserted
replaced
| 1251:2d12541cedb1 | 1252:46c09828e929 |
|---|---|
| 37 #include <gtk/gtk.h> | 37 #include <gtk/gtk.h> |
| 38 #include "gaim.h" | 38 #include "gaim.h" |
| 39 #include "proxy.h" | 39 #include "proxy.h" |
| 40 | 40 |
| 41 /* this code is borrowed from cvs 1.10 */ | 41 /* this code is borrowed from cvs 1.10 */ |
| 42 static int proxy_recv_line (int sock, char **resultp) | 42 static int proxy_recv_line(int sock, char **resultp) |
| 43 { | 43 { |
| 44 int c; | 44 int c; |
| 45 char *result; | 45 char *result; |
| 46 size_t input_index = 0; | 46 size_t input_index = 0; |
| 47 size_t result_size = 80; | 47 size_t result_size = 80; |
| 48 | 48 |
| 49 result = g_malloc (result_size); | 49 result = g_malloc(result_size); |
| 50 | 50 |
| 51 while (1) | 51 while (1) { |
| 52 { | 52 char ch; |
| 53 char ch; | 53 if (recv(sock, &ch, 1, 0) < 0) |
| 54 if (recv (sock, &ch, 1, 0) < 0) | 54 debug_printf("recv() error from proxy server\n"); |
| 55 fprintf (stderr, "recv() error from proxy server\n"); | 55 c = ch; |
| 56 c = ch; | 56 |
| 57 | 57 if (c == EOF) { |
| 58 if (c == EOF) | 58 g_free(result); |
| 59 { | 59 |
| 60 g_free (result); | 60 /* It's end of file. */ |
| 61 | 61 debug_printf("end of file from server\n"); |
| 62 /* It's end of file. */ | 62 } |
| 63 fprintf(stderr, "end of file from server\n"); | 63 |
| 64 } | 64 if (c == '\012') |
| 65 | 65 break; |
| 66 if (c == '\012') | 66 |
| 67 break; | 67 result[input_index++] = c; |
| 68 | 68 while (input_index + 1 >= result_size) { |
| 69 result[input_index++] = c; | 69 result_size *= 2; |
| 70 while (input_index + 1 >= result_size) | 70 result = (char *)g_realloc(result, result_size); |
| 71 { | 71 } |
| 72 result_size *= 2; | 72 } |
| 73 result = (char *) g_realloc (result, result_size); | 73 |
| 74 } | 74 if (resultp) |
| 75 } | 75 *resultp = result; |
| 76 | 76 |
| 77 if (resultp) | 77 /* Terminate it just for kicks, but we *can* deal with embedded NULs. */ |
| 78 *resultp = result; | 78 result[input_index] = '\0'; |
| 79 | 79 |
| 80 /* Terminate it just for kicks, but we *can* deal with embedded NULs. */ | 80 if (resultp == NULL) |
| 81 result[input_index] = '\0'; | 81 g_free(result); |
| 82 | 82 return input_index; |
| 83 if (resultp == NULL) | |
| 84 g_free (result); | |
| 85 return input_index; | |
| 86 } | 83 } |
| 87 | 84 |
| 88 static int proxy_connect_none(char *host, unsigned short port) | 85 static int proxy_connect_none(char *host, unsigned short port) |
| 89 { | 86 { |
| 90 struct sockaddr_in sin; | 87 struct sockaddr_in sin; |
| 91 struct hostent *hp; | 88 struct hostent *hp; |
| 92 int fd = -1; | 89 int fd = -1; |
| 93 | 90 |
| 94 debug_printf("connecting to %s:%d with no proxy\n", host, port); | 91 debug_printf("connecting to %s:%d with no proxy\n", host, port); |
| 95 | 92 |
| 96 if (!(hp = gethostbyname(host))) | 93 if (!(hp = gethostbyname(host))) |
| 97 return -1; | 94 return -1; |
| 98 | 95 |
| 99 memset(&sin, 0, sizeof(struct sockaddr_in)); | 96 memset(&sin, 0, sizeof(struct sockaddr_in)); |
| 100 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); | 97 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); |
| 101 sin.sin_family = hp->h_addrtype; | 98 sin.sin_family = hp->h_addrtype; |
| 113 } | 110 } |
| 114 | 111 |
| 115 #define HTTP_GOODSTRING "HTTP/1.0 200 Connection established" | 112 #define HTTP_GOODSTRING "HTTP/1.0 200 Connection established" |
| 116 #define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established" | 113 #define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established" |
| 117 | 114 |
| 118 static int proxy_connect_http(char *host, unsigned short port, | 115 static int proxy_connect_http(char *host, unsigned short port, char *proxyhost, unsigned short proxyport) |
| 119 char *proxyhost, unsigned short proxyport) | |
| 120 { | 116 { |
| 121 struct hostent *hp; | 117 struct hostent *hp; |
| 122 struct sockaddr_in sin; | 118 struct sockaddr_in sin; |
| 123 int fd = -1; | 119 int fd = -1; |
| 124 char cmd[384]; | 120 char cmd[384]; |
| 125 char *inputline; | 121 char *inputline; |
| 126 | 122 |
| 127 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport); | 123 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport); |
| 128 | 124 |
| 129 if (!(hp = gethostbyname(proxyhost))) | 125 if (!(hp = gethostbyname(proxyhost))) |
| 130 return -1; | 126 return -1; |
| 131 | 127 |
| 132 memset(&sin, 0, sizeof(struct sockaddr_in)); | 128 memset(&sin, 0, sizeof(struct sockaddr_in)); |
| 133 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); | 129 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); |
| 134 sin.sin_family = hp->h_addrtype; | 130 sin.sin_family = hp->h_addrtype; |
| 142 return -1; | 138 return -1; |
| 143 } | 139 } |
| 144 | 140 |
| 145 snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\n\r\n\r", host, port); | 141 snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\n\r\n\r", host, port); |
| 146 | 142 |
| 147 if (send(fd, cmd, strlen(cmd),0) < 0) | 143 if (send(fd, cmd, strlen(cmd), 0) < 0) |
| 148 return -1; | 144 return -1; |
| 149 if (proxy_recv_line(fd, &inputline) < 0) | 145 if (proxy_recv_line(fd, &inputline) < 0) |
| 150 return -1; | 146 return -1; |
| 151 | 147 |
| 152 if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING) == 0) || | 148 if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING) == 0) || |
| 153 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2) == 0)))) { | 149 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2) == 0)))) { |
| 154 while (strlen(inputline) > 1) { | 150 while (strlen(inputline) > 1) { |
| 155 free(inputline); | 151 free(inputline); |
| 156 if (proxy_recv_line(fd, &inputline) < 0) | 152 if (proxy_recv_line(fd, &inputline) < 0) |
| 157 return -1; | 153 return -1; |
| 158 } | 154 } |
| 166 | 162 |
| 167 return -1; | 163 return -1; |
| 168 } | 164 } |
| 169 | 165 |
| 170 static int proxy_connect_socks4(char *host, unsigned short port, | 166 static int proxy_connect_socks4(char *host, unsigned short port, |
| 171 char *proxyhost, unsigned short proxyport) | 167 char *proxyhost, unsigned short proxyport) |
| 172 { | 168 { |
| 173 struct sockaddr_in sin; | 169 struct sockaddr_in sin; |
| 174 unsigned char packet[12]; | 170 unsigned char packet[12]; |
| 175 struct hostent *hp; | 171 struct hostent *hp; |
| 176 int fd = -1; | 172 int fd = -1; |
| 177 | 173 |
| 178 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport); | 174 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport); |
| 179 | 175 |
| 180 if (!(hp = gethostbyname(proxyhost))) | 176 if (!(hp = gethostbyname(proxyhost))) |
| 181 return -1; | 177 return -1; |
| 182 | 178 |
| 183 memset(&sin, 0, sizeof(struct sockaddr_in)); | 179 memset(&sin, 0, sizeof(struct sockaddr_in)); |
| 184 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); | 180 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); |
| 185 sin.sin_family = hp->h_addrtype; | 181 sin.sin_family = hp->h_addrtype; |
| 197 if (!(hp = gethostbyname(host))) | 193 if (!(hp = gethostbyname(host))) |
| 198 return -1; | 194 return -1; |
| 199 | 195 |
| 200 packet[0] = 4; | 196 packet[0] = 4; |
| 201 packet[1] = 1; | 197 packet[1] = 1; |
| 202 packet[2] = (((unsigned short) htons(port)) >> 8); | 198 packet[2] = (((unsigned short)htons(port)) >> 8); |
| 203 packet[3] = (((unsigned short) htons(port)) & 0xff); | 199 packet[3] = (((unsigned short)htons(port)) & 0xff); |
| 204 packet[4] = (unsigned char) (hp->h_addr_list[0])[0]; | 200 packet[4] = (unsigned char)(hp->h_addr_list[0])[0]; |
| 205 packet[5] = (unsigned char) (hp->h_addr_list[0])[1]; | 201 packet[5] = (unsigned char)(hp->h_addr_list[0])[1]; |
| 206 packet[6] = (unsigned char) (hp->h_addr_list[0])[2]; | 202 packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; |
| 207 packet[7] = (unsigned char) (hp->h_addr_list[0])[3]; | 203 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; |
| 208 packet[8] = 0; | 204 packet[8] = 0; |
| 209 if (write(fd, packet, 9) == 9) { | 205 if (write(fd, packet, 9) == 9) { |
| 210 memset(packet, 0, sizeof(packet)); | 206 memset(packet, 0, sizeof(packet)); |
| 211 if (read(fd, packet, 9) >= 4 && packet[1] == 90) | 207 if (read(fd, packet, 9) >= 4 && packet[1] == 90) |
| 212 return fd; | 208 return fd; |
| 215 | 211 |
| 216 return -1; | 212 return -1; |
| 217 } | 213 } |
| 218 | 214 |
| 219 static int proxy_connect_socks5(char *host, unsigned short port, | 215 static int proxy_connect_socks5(char *host, unsigned short port, |
| 220 char *proxyhost, unsigned short proxyport) | 216 char *proxyhost, unsigned short proxyport) |
| 221 { | 217 { |
| 222 int i, fd = -1; | 218 int i, fd = -1; |
| 223 unsigned char buf[512]; | 219 unsigned char buf[512]; |
| 224 struct sockaddr_in sin; | 220 struct sockaddr_in sin; |
| 225 struct hostent *hp; | 221 struct hostent *hp; |
| 226 | 222 |
| 227 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport); | 223 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport); |
| 228 | 224 |
| 229 if (!(hp = gethostbyname(proxyhost))) | 225 if (!(hp = gethostbyname(proxyhost))) |
| 230 return -1; | 226 return -1; |
| 231 | 227 |
| 232 memset(&sin, 0, sizeof(struct sockaddr_in)); | 228 memset(&sin, 0, sizeof(struct sockaddr_in)); |
| 233 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); | 229 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); |
| 234 sin.sin_family = hp->h_addrtype; | 230 sin.sin_family = hp->h_addrtype; |
| 241 close(fd); | 237 close(fd); |
| 242 return -1; | 238 return -1; |
| 243 } | 239 } |
| 244 | 240 |
| 245 i = 0; | 241 i = 0; |
| 246 buf[0] = 0x05; /* SOCKS version 5 */ | 242 buf[0] = 0x05; /* SOCKS version 5 */ |
| 247 buf[1] = 0x01; | 243 buf[1] = 0x01; |
| 248 buf[2] = 0x00; | 244 buf[2] = 0x00; |
| 249 i = 3; | 245 i = 3; |
| 250 | 246 |
| 251 if (write(fd, buf, i) < i) { | 247 if (write(fd, buf, i) < i) { |
| 262 close(fd); | 258 close(fd); |
| 263 return -1; | 259 return -1; |
| 264 } | 260 } |
| 265 | 261 |
| 266 buf[0] = 0x05; | 262 buf[0] = 0x05; |
| 267 buf[1] = 0x01; /* CONNECT */ | 263 buf[1] = 0x01; /* CONNECT */ |
| 268 buf[2] = 0x00; /* reserved */ | 264 buf[2] = 0x00; /* reserved */ |
| 269 buf[3] = 0x03; /* address type -- host name */ | 265 buf[3] = 0x03; /* address type -- host name */ |
| 270 buf[4] = strlen(host); | 266 buf[4] = strlen(host); |
| 271 memcpy(buf+5, host, strlen(host)); | 267 memcpy(buf + 5, host, strlen(host)); |
| 272 buf[5+strlen(host)] = htons(port) >> 8; | 268 buf[5 + strlen(host)] = htons(port) >> 8; |
| 273 buf[5+strlen(host)+1] = htons(port) & 0xff; | 269 buf[5 + strlen(host) + 1] = htons(port) & 0xff; |
| 274 | 270 |
| 275 if (write(fd, buf, (5+strlen(host)+2)) < (5+strlen(host)+2)) { | 271 if (write(fd, buf, (5 + strlen(host) + 2)) < (5 + strlen(host) + 2)) { |
| 276 close(fd); | 272 close(fd); |
| 277 return -1; | 273 return -1; |
| 278 } | 274 } |
| 279 if (read(fd, buf, 10) < 10) { | 275 if (read(fd, buf, 10) < 10) { |
| 280 close(fd); | 276 close(fd); |
| 290 | 286 |
| 291 int proxy_connect(char *host, int port, char *proxyhost, int proxyport, int proxytype) | 287 int proxy_connect(char *host, int port, char *proxyhost, int proxyport, int proxytype) |
| 292 { | 288 { |
| 293 if (!host || !port || (port == -1)) | 289 if (!host || !port || (port == -1)) |
| 294 return -1; | 290 return -1; |
| 295 else if ((proxytype == PROXY_NONE) || | 291 else if ((proxytype == PROXY_NONE) || |
| 296 !proxyhost || !proxyhost[0] || | 292 !proxyhost || !proxyhost[0] || |
| 297 !proxyport || (proxyport == -1)) | 293 !proxyport || (proxyport == -1)) return proxy_connect_none(host, port); |
| 298 return proxy_connect_none(host, port); | |
| 299 else if (proxytype == PROXY_HTTP) | 294 else if (proxytype == PROXY_HTTP) |
| 300 return proxy_connect_http(host, port, proxyhost, proxyport); | 295 return proxy_connect_http(host, port, proxyhost, proxyport); |
| 301 else if (proxytype == PROXY_SOCKS4) | 296 else if (proxytype == PROXY_SOCKS4) |
| 302 return proxy_connect_socks4(host, port, proxyhost, proxyport); | 297 return proxy_connect_socks4(host, port, proxyhost, proxyport); |
| 303 else if (proxytype == PROXY_SOCKS5) | 298 else if (proxytype == PROXY_SOCKS5) |
