Mercurial > pidgin
comparison libfaim/aim_conn.c @ 935:5e6ca3dd4d02
[gaim-migrate @ 945]
yay. thanks bmiller
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Fri, 22 Sep 2000 10:16:40 +0000 |
parents | e1da6a6ec42b |
children | 1d8f05ea6bdf |
comparison
equal
deleted
inserted
replaced
934:e5da96def4bd | 935:5e6ca3dd4d02 |
---|---|
160 faim_mutex_unlock(&sess->connlistlock); | 160 faim_mutex_unlock(&sess->connlistlock); |
161 return cur; | 161 return cur; |
162 } | 162 } |
163 | 163 |
164 /* | 164 /* |
165 * An extrememly quick and dirty SOCKS5 interface. | |
166 */ | |
167 static int aim_proxyconnect(struct aim_session_t *sess, | |
168 char *host, unsigned short port, | |
169 int *statusret) | |
170 { | |
171 int fd = -1; | |
172 | |
173 if (strlen(sess->socksproxy.server)) { /* connecting via proxy */ | |
174 int i; | |
175 unsigned char buf[512]; | |
176 struct sockaddr_in sa; | |
177 struct hostent *hp; | |
178 char *proxy; | |
179 unsigned short proxyport = 1080; | |
180 | |
181 for(i=0;i<(int)strlen(sess->socksproxy.server);i++) { | |
182 if (sess->socksproxy.server[i] == ':') { | |
183 proxyport = atoi(&(sess->socksproxy.server[i+1])); | |
184 break; | |
185 } | |
186 } | |
187 proxy = (char *)malloc(i+1); | |
188 strncpy(proxy, sess->socksproxy.server, i); | |
189 proxy[i] = '\0'; | |
190 | |
191 if (!(hp = gethostbyname(proxy))) { | |
192 printf("proxyconnect: unable to resolve proxy name\n"); | |
193 *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR); | |
194 return -1; | |
195 } | |
196 free(proxy); | |
197 | |
198 memset(&sa.sin_zero, 0, 8); | |
199 sa.sin_port = htons(proxyport); | |
200 memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); | |
201 sa.sin_family = hp->h_addrtype; | |
202 | |
203 fd = socket(hp->h_addrtype, SOCK_STREAM, 0); | |
204 if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { | |
205 printf("proxyconnect: unable to connect to proxy\n"); | |
206 close(fd); | |
207 return -1; | |
208 } | |
209 | |
210 i = 0; | |
211 buf[0] = 0x05; /* SOCKS version 5 */ | |
212 if (strlen(sess->socksproxy.username)) { | |
213 buf[1] = 0x02; /* two methods */ | |
214 buf[2] = 0x00; /* no authentication */ | |
215 buf[3] = 0x02; /* username/password authentication */ | |
216 i = 4; | |
217 } else { | |
218 buf[1] = 0x01; | |
219 buf[2] = 0x00; | |
220 i = 3; | |
221 } | |
222 | |
223 if (write(fd, buf, i) < i) { | |
224 *statusret = errno; | |
225 close(fd); | |
226 return -1; | |
227 } | |
228 | |
229 if (read(fd, buf, 2) < 2) { | |
230 *statusret = errno; | |
231 close(fd); | |
232 return -1; | |
233 } | |
234 | |
235 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { | |
236 *statusret = EINVAL; | |
237 close(fd); | |
238 return -1; | |
239 } | |
240 | |
241 /* check if we're doing username authentication */ | |
242 if (buf[1] == 0x02) { | |
243 i = aimutil_put8(buf, 0x01); /* version 1 */ | |
244 i += aimutil_put8(buf+i, strlen(sess->socksproxy.username)); | |
245 i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username)); | |
246 i += aimutil_put8(buf+i, strlen(sess->socksproxy.password)); | |
247 i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password)); | |
248 if (write(fd, buf, i) < i) { | |
249 *statusret = errno; | |
250 close(fd); | |
251 return -1; | |
252 } | |
253 if (read(fd, buf, 2) < 2) { | |
254 *statusret = errno; | |
255 close(fd); | |
256 return -1; | |
257 } | |
258 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { | |
259 *statusret = EINVAL; | |
260 close(fd); | |
261 return -1; | |
262 } | |
263 } | |
264 | |
265 i = aimutil_put8(buf, 0x05); | |
266 i += aimutil_put8(buf+i, 0x01); /* CONNECT */ | |
267 i += aimutil_put8(buf+i, 0x00); /* reserved */ | |
268 i += aimutil_put8(buf+i, 0x03); /* address type: host name */ | |
269 i += aimutil_put8(buf+i, strlen(host)); | |
270 i += aimutil_putstr(buf+i, host, strlen(host)); | |
271 i += aimutil_put16(buf+i, port); | |
272 | |
273 if (write(fd, buf, i) < i) { | |
274 *statusret = errno; | |
275 close(fd); | |
276 return -1; | |
277 } | |
278 if (read(fd, buf, 10) < 10) { | |
279 *statusret = errno; | |
280 close(fd); | |
281 return -1; | |
282 } | |
283 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { | |
284 *statusret = EINVAL; | |
285 close(fd); | |
286 return -1; | |
287 } | |
288 | |
289 } else { /* connecting directly */ | |
290 struct sockaddr_in sa; | |
291 struct hostent *hp; | |
292 | |
293 if (!(hp = gethostbyname(host))) { | |
294 *statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR); | |
295 return -1; | |
296 } | |
297 | |
298 memset(&sa.sin_zero, 0, 8); | |
299 sa.sin_port = htons(port); | |
300 memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); | |
301 sa.sin_family = hp->h_addrtype; | |
302 | |
303 fd = socket(hp->h_addrtype, SOCK_STREAM, 0); | |
304 if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) { | |
305 close(fd); | |
306 fd = -1; | |
307 } | |
308 } | |
309 return fd; | |
310 } | |
311 | |
312 /* | |
165 * aim_newconn(type, dest) | 313 * aim_newconn(type, dest) |
166 * | 314 * |
167 * Opens a new connection to the specified dest host of type type. | 315 * Opens a new connection to the specified dest host of type type. |
168 * | 316 * |
169 * TODO: fix for proxies | 317 * TODO: fix for proxies |
212 } | 360 } |
213 host = (char *)malloc(i+1); | 361 host = (char *)malloc(i+1); |
214 strncpy(host, dest, i); | 362 strncpy(host, dest, i); |
215 host[i] = '\0'; | 363 host[i] = '\0'; |
216 | 364 |
217 hp = gethostbyname(host); | 365 if ((ret = aim_proxyconnect(sess, host, port, &connstruct->status)) < 0) { |
218 free(host); | 366 connstruct->fd = -1; |
219 | 367 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); |
220 if (hp == NULL) { | 368 free(host); |
221 connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR); | |
222 faim_mutex_unlock(&connstruct->active); | 369 faim_mutex_unlock(&connstruct->active); |
223 return connstruct; | 370 return connstruct; |
224 } | 371 } else |
225 | 372 connstruct->fd = ret; |
226 memset(&sa.sin_zero, 0, 8); | |
227 sa.sin_port = htons(port); | |
228 memcpy(&sa.sin_addr, hp->h_addr, hp->h_length); | |
229 sa.sin_family = hp->h_addrtype; | |
230 | |
231 connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0); | |
232 ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)); | |
233 if(ret < 0) { | |
234 connstruct->fd = -1; | |
235 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); | |
236 faim_mutex_unlock(&connstruct->active); | |
237 return connstruct; | |
238 } | |
239 | 373 |
240 faim_mutex_unlock(&connstruct->active); | 374 faim_mutex_unlock(&connstruct->active); |
375 | |
376 free(host); | |
241 | 377 |
242 return connstruct; | 378 return connstruct; |
243 } | 379 } |
244 | 380 |
245 faim_export int aim_conngetmaxfd(struct aim_session_t *sess) | 381 faim_export int aim_conngetmaxfd(struct aim_session_t *sess) |
370 faim_mutex_unlock(&conn->active); | 506 faim_mutex_unlock(&conn->active); |
371 | 507 |
372 return 0; | 508 return 0; |
373 } | 509 } |
374 | 510 |
511 /* | |
512 * Call this with your SOCKS5 proxy server parameters before | |
513 * the first call to aim_newconn(). If called with all NULL | |
514 * args, it will clear out a previously set proxy. | |
515 * | |
516 * Set username and password to NULL if not applicable. | |
517 * | |
518 */ | |
519 faim_export void aim_setupproxy(struct aim_session_t *sess, char *server, char *username, char *password) | |
520 { | |
521 /* clear out the proxy info */ | |
522 if (!server || !strlen(server)) { | |
523 memset(sess->socksproxy.server, 0, sizeof(sess->socksproxy.server)); | |
524 memset(sess->socksproxy.username, 0, sizeof(sess->socksproxy.username)); | |
525 memset(sess->socksproxy.password, 0, sizeof(sess->socksproxy.password)); | |
526 return; | |
527 } | |
528 | |
529 strncpy(sess->socksproxy.server, server, sizeof(sess->socksproxy.server)); | |
530 if (username && strlen(username)) | |
531 strncpy(sess->socksproxy.username, username, sizeof(sess->socksproxy.username)); | |
532 if (password && strlen(password)) | |
533 strncpy(sess->socksproxy.password, password, sizeof(sess->socksproxy.password)); | |
534 return; | |
535 } | |
536 | |
375 faim_export void aim_session_init(struct aim_session_t *sess) | 537 faim_export void aim_session_init(struct aim_session_t *sess) |
376 { | 538 { |
377 if (!sess) | 539 if (!sess) |
378 return; | 540 return; |
379 | 541 |