Mercurial > pidgin.yaz
annotate src/proxy.c @ 338:9d258a0aa560
[gaim-migrate @ 348]
Whoa, all kinds of things happened here. The applet looks better. The
preferences dialog changes based on your compile-time options (oscar,
gnome). Whispering works again. libfaim got updated; it can almost do
RVOUS stuff, and hopefully soon can make requests too. The applet doesn't
need to have its sounds go through GNOME, although it still can. There
is code to facilitate SOCKS5 support (all that needs to be done is to
actually write the code to communicate with the proxy server).
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Tue, 06 Jun 2000 09:55:30 +0000 |
| parents | 5b28ef2b550e |
| children | b402a23f35df |
| rev | line source |
|---|---|
| 1 | 1 /* |
| 2 * gaim | |
| 3 * | |
| 4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
| 5 * | |
| 6 * This program is free software; you can redistribute it and/or modify | |
| 7 * it under the terms of the GNU General Public License as published by | |
| 8 * the Free Software Foundation; either version 2 of the License, or | |
| 9 * (at your option) any later version. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License | |
| 17 * along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 * | |
| 20 */ | |
| 21 | |
| 22 /* this is a little piece of code to handle proxy connection */ | |
| 23 /* it is intended to : 1st handle http proxy, using the CONNECT command | |
| 24 , 2nd provide an easy way to add socks support */ | |
| 25 | |
| 26 #include <stdio.h> | |
| 27 #include <stdlib.h> | |
| 28 #include <string.h> | |
| 29 #include <sys/types.h> | |
| 30 #include <sys/socket.h> | |
| 31 #include <netdb.h> | |
| 32 #include <netinet/in.h> | |
| 33 #include <gtk/gtk.h> | |
| 34 #include "gaim.h" | |
| 35 #include "proxy.h" | |
| 36 | |
| 37 | |
|
210
ec0686b3b03f
[gaim-migrate @ 220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
79
diff
changeset
|
38 /* static int proxy_inited=0; */ |
| 1 | 39 int proxy_type = 0; |
| 40 char proxy_host[256]; | |
| 41 int proxy_port = 3128; | |
| 42 char *proxy_realhost = NULL; | |
| 43 | |
| 44 /* this code is borrowed from cvs 1.10 */ | |
| 45 static int | |
| 46 proxy_recv_line (int sock, char **resultp) | |
| 47 { | |
| 48 int c; | |
| 49 char *result; | |
| 50 size_t input_index = 0; | |
| 51 size_t result_size = 80; | |
| 52 | |
| 79 | 53 result = g_malloc (result_size); |
| 1 | 54 |
| 55 while (1) | |
| 56 { | |
| 57 char ch; | |
| 58 if (recv (sock, &ch, 1, 0) < 0) | |
| 59 fprintf (stderr, "recv() error from proxy server\n"); | |
| 60 c = ch; | |
| 61 | |
| 62 if (c == EOF) | |
| 63 { | |
| 79 | 64 g_free (result); |
| 1 | 65 |
| 66 /* It's end of file. */ | |
| 67 fprintf(stderr, "end of file from server\n"); | |
| 68 } | |
| 69 | |
| 70 if (c == '\012') | |
| 71 break; | |
| 72 | |
| 73 result[input_index++] = c; | |
| 74 while (input_index + 1 >= result_size) | |
| 75 { | |
| 76 result_size *= 2; | |
| 79 | 77 result = (char *) g_realloc (result, result_size); |
| 1 | 78 } |
| 79 } | |
| 80 | |
| 81 if (resultp) | |
| 82 *resultp = result; | |
| 83 | |
| 84 /* Terminate it just for kicks, but we *can* deal with embedded NULs. */ | |
| 85 result[input_index] = '\0'; | |
| 86 | |
| 87 if (resultp == NULL) | |
| 79 | 88 g_free (result); |
| 1 | 89 return input_index; |
| 90 } | |
| 91 | |
| 92 | |
| 93 struct hostent *proxy_gethostbyname(char *host) | |
| 94 { | |
| 95 | |
| 96 if (proxy_type == PROXY_NONE) | |
| 97 return (gethostbyname(host)); | |
| 98 | |
| 99 if (proxy_realhost != NULL) | |
| 100 g_free(proxy_realhost); | |
| 101 | |
| 102 /* we keep the real host name for the Connect command */ | |
| 103 proxy_realhost = (char *) strdup(host); | |
| 104 | |
| 105 return (gethostbyname(proxy_host)); | |
| 106 | |
| 107 } | |
| 108 | |
| 109 | |
| 110 int proxy_connect(int sockfd, struct sockaddr *serv_addr, int | |
| 111 addrlen ) | |
| 112 { | |
| 113 struct sockaddr_in name; | |
| 114 int ret; | |
| 115 | |
| 116 switch (proxy_type) { | |
| 117 case PROXY_NONE: | |
| 118 /* normal use */ | |
| 119 return (connect(sockfd,serv_addr,addrlen)); | |
| 120 break; | |
| 121 case PROXY_HTTP: /* Http proxy */ | |
| 122 /* do the tunneling */ | |
| 123 /* step one : connect to proxy */ | |
| 124 { | |
| 125 struct hostent *hostinfo; | |
| 126 unsigned short shortport = proxy_port; | |
| 127 | |
| 128 memset (&name, 0, sizeof (name)); | |
| 129 name.sin_family = AF_INET; | |
| 130 name.sin_port = htons (shortport); | |
| 131 hostinfo = gethostbyname (proxy_host); | |
| 132 if (hostinfo == NULL) { | |
| 133 fprintf (stderr, "Unknown host %s.\n", proxy_host); | |
| 134 return (-1); | |
| 135 } | |
| 136 name.sin_addr = *(struct in_addr *) hostinfo->h_addr; | |
| 137 } | |
| 138 sprintf(debug_buff,"Trying to connect ...\n"); | |
| 139 debug_print(debug_buff); | |
| 140 if ((ret = connect(sockfd,(struct sockaddr *)&name,sizeof(name)))<0) | |
| 141 return(ret); | |
| 142 | |
| 143 /* step two : do proxy tunneling init */ | |
| 144 { | |
| 145 char cmd[80]; | |
| 146 char *inputline; | |
| 147 unsigned short realport=ntohs(((struct sockaddr_in *)serv_addr)->sin_port); | |
| 148 sprintf(cmd,"CONNECT %s:%d HTTP/1.1\n\r\n\r",proxy_realhost,realport); | |
| 149 sprintf(debug_buff,"<%s>\n",cmd); | |
| 150 debug_print(debug_buff); | |
| 151 if (send(sockfd,cmd,strlen(cmd),0)<0) | |
| 152 return(-1); | |
| 153 if (proxy_recv_line(sockfd,&inputline) < 0) { | |
| 154 return(-1); | |
| 155 } | |
| 156 sprintf(debug_buff,"<%s>\n",inputline); | |
| 157 debug_print(debug_buff); | |
| 158 if (memcmp("HTTP/1.0 200 Connection established",inputline,35)) | |
| 159 if (memcmp("HTTP/1.1 200 Connection established",inputline,35)) { | |
| 160 free(inputline); | |
| 161 return(-1); | |
| 162 } | |
| 163 | |
| 164 while (strlen(inputline)>1) { | |
| 165 free(inputline); | |
| 166 if (proxy_recv_line(sockfd,&inputline) < 0) { | |
| 167 return(-1); | |
| 168 } | |
| 169 sprintf(debug_buff,"<%s>\n",inputline); | |
| 170 debug_print(debug_buff); | |
| 171 } | |
| 172 free(inputline); | |
| 173 } | |
| 174 | |
| 175 return ret; | |
| 176 break; | |
|
338
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
253
diff
changeset
|
177 case PROXY_SOCKS4: /* Socks v4 proxy (? I'm not a proxy hacker) */ |
|
234
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
178 /* this is going to be a cross between the HTTP proxy code |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
179 * above and the TiK proxy code, translated from tcl->C */ |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
180 { |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
181 struct hostent *hostinfo; |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
182 unsigned short shortport = proxy_port; |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
183 |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
184 memset(&name, 0, sizeof (name)); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
185 name.sin_family = AF_INET; |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
186 name.sin_port = htons (shortport); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
187 hostinfo = gethostbyname (proxy_host); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
188 if (hostinfo == NULL) { |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
189 fprintf (stderr, "Unknown host %s.\n", proxy_host); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
190 return (-1); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
191 } |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
192 name.sin_addr = *(struct in_addr *) hostinfo->h_addr; |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
193 } |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
194 sprintf(debug_buff,"Trying to connect ...\n"); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
195 debug_print(debug_buff); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
196 if ((ret = connect(sockfd,(struct sockaddr *)&name,sizeof(name)))<0) |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
197 return(ret); |
|
253
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
198 |
|
234
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
199 /* here's where it's no longer http proxy and is now tik */ |
|
253
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
200 { |
|
234
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
201 char cmd[80]; |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
202 char *inputline; |
|
253
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
203 unsigned short realport=((struct sockaddr_in *)serv_addr)->sin_port; |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
204 unsigned long realhost=((struct sockaddr_in *)serv_addr)->sin_addr.s_addr; |
|
234
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
205 |
|
253
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
206 cmd[0] = 4; cmd[0] = 1; |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
207 memcpy(cmd + 2, &realport, 2); |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
208 memcpy(cmd + 4, &realhost, 4); |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
209 cmd[8] = 0; |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
210 if (send(sockfd,cmd,8,0)<0) |
|
234
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
211 return(-1); |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
212 if (proxy_recv_line(sockfd,&inputline) < 0) { |
|
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
213 return(-1); |
|
253
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
214 } |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
215 if (inputline[1] != 90) { |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
216 sprintf(debug_buff, "request failed: %d\n", |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
217 inputline[1]); |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
218 debug_print(debug_buff); |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
219 if (inputline[1] == 91) |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
220 do_error_dialog("The SOCKS proxy denied" |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
221 "your request.", |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
222 "Gaim - Proxy Error"); |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
223 else |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
224 do_error_dialog("Unknown SOCKS error.", |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
225 "Gaim - Proxy Error"); |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
226 return -1; |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
227 } |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
228 } |
|
5b28ef2b550e
[gaim-migrate @ 263]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
234
diff
changeset
|
229 return ret; |
| 1 | 230 break; |
|
338
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
253
diff
changeset
|
231 case PROXY_SOCKS5: |
|
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
253
diff
changeset
|
232 return -1; |
|
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
253
diff
changeset
|
233 break; |
| 1 | 234 default: |
| 235 fprintf(stderr,"Unknown proxy type : %d.\n",proxy_type); | |
| 236 break; | |
| 237 } | |
| 238 return(-1); | |
| 239 } | |
| 240 |
