Mercurial > pidgin
annotate src/proxy.c @ 268:f8a29745247c
[gaim-migrate @ 278]
Two star college football players need to pass the final to play in the big
game. The professor loves football, but knows these guys aren't the brightest
bulbs in teh box, so he gives them a special final, puts them in a room by
themselves, and gives them an hour.
The guys look at each other, and start in on the final, which has only one
question: "What did Old MacDonald have?"
One guy looks at the other and says, "Do you know the answer to this?"
The other guy says, "Duh, a farm."
"How do you spell that?"
"Stupid! EIEIO!"
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Thu, 25 May 2000 18:58:21 +0000 |
| parents | 5b28ef2b550e |
| children | 9d258a0aa560 |
| 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; | |
|
234
985635758c33
[gaim-migrate @ 244]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
210
diff
changeset
|
177 case PROXY_SOCKS: /* Socks v4 proxy (? I'm not a proxy hacker) */ |
|
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; |
| 231 default: | |
| 232 fprintf(stderr,"Unknown proxy type : %d.\n",proxy_type); | |
| 233 break; | |
| 234 } | |
| 235 return(-1); | |
| 236 } | |
| 237 |
