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