Regenerable files dropped from CVS
[middleman.git] / src / network.c
1 /*
2     MiddleMan filtering proxy server
3     Copyright (C) 2002  Jason McLaughlin
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <netdb.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <sys/time.h>
30 #include <netinet/tcp.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include "proto.h"
34
35 time_t last_dns_expire = 0;
36 extern HASH_TABLE *dns_cache;
37 extern char username[];
38 SOCKLIST socklist[MAXLISTENPORTS];
39 pthread_mutex_t dns_cache_lock = PTHREAD_MUTEX_INITIALIZER;
40
41 /*
42 initialize the socket list
43 */
44 void net_init()
45 {
46         int i;
47
48         for (i = 0; i < MAXLISTENPORTS; i++) {
49                 socklist[i].status = NET_UNUSED;
50                 socklist[i].ip = NULL;
51                 socklist[i].port = 0;
52         }
53 }
54
55 /*
56 open a listening socket on a specific port and ip
57 */
58 int net_listen(int port, char *ip)
59 {
60         int i, x = -1, on = 1;
61         struct sockaddr_in saddr;
62
63         for (i = 0; i < MAXLISTENPORTS; i++) {
64                 if (socklist[i].status == NET_UNUSED) {
65                         x = i;
66                         break;
67                 }
68         }
69
70         if (x == -1)
71                 return -1;
72
73         socklist[x].fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
74         if (socklist[x].fd == -1)
75                 return -1;
76
77         /* this allows the proxy to successfully bind to the socket again when the server is restarted,
78            otherwise it would have to wait for all connections is TIME_WAIT to be cleaned up */
79         setsockopt(socklist[x].fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
80
81         /* TCP_NODELAY prevents the kernel from buffering the socket, which is only useful for interactive
82            connections such as telnet or ssh */
83         setsockopt(socklist[x].fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
84
85         fcntl(socklist[x].fd, F_SETFL, FD_CLOEXEC);
86
87         memset(&saddr, 0, sizeof(struct sockaddr_in));
88
89         saddr.sin_family = AF_INET;
90         saddr.sin_port = htons(port);
91
92         if (ip == NULL)
93                 saddr.sin_addr.s_addr = INADDR_ANY;
94         else
95                 saddr.sin_addr.s_addr = inet_addr(ip);
96
97         i = bind(socklist[x].fd, (struct sockaddr *) &saddr, sizeof(saddr));
98         if (i == -1) {
99                 close(socklist[x].fd);
100                 return -1;
101         }
102
103         i = listen(socklist[x].fd, 25);
104         if (i == -1) {
105                 close(socklist[x].fd);
106                 return -1;
107         }
108
109         if (ip != NULL)
110                 socklist[x].ip = xstrdup(ip);
111         else
112                 socklist[x].ip = NULL;
113
114         socklist[x].port = port;
115         socklist[x].status = NET_LISTEN;
116
117         return x;
118 }
119
120 /*
121 poll on every open listening socket in socklist until timeout is reached (or forever if 
122 timeout is -1), accept then return a pointer to a CONNECTION struct
123 */
124 CONNECTION *net_accept(int timeout)
125 {
126         int i, x = 0, j, newfd;
127         struct sockaddr_in saddr;
128         unsigned int sl = sizeof(struct sockaddr);
129         CONNECTION *connection;
130         struct pollfd pfd[MAXLISTENPORTS];
131
132         for (i = 0; i < MAXLISTENPORTS; i++) {
133                 if (socklist[i].status == NET_LISTEN) {
134                         pfd[x].fd = socklist[i].fd;
135                         pfd[x].events = POLLIN;
136
137                         x++;
138                 } else break;
139         }
140
141         j = p_poll(pfd, x, (timeout != -1) ? timeout * 1000 : -1);
142
143         if (j > 0) {
144                 for (i = 0; i < MAXLISTENPORTS; i++) {
145                         if (pfd[i].revents & POLLIN) {
146                                 newfd = accept(socklist[i].fd, (struct sockaddr *) &saddr, &sl);
147
148                                 if (newfd == -1)
149                                         return NULL;
150
151                                 connection = xmalloc(sizeof(CONNECTION));
152
153                                 connection->client = sock_new(newfd);
154                                 connection->server = NULL;
155                                 connection->port = socklist[i].port;
156                                 connection->ip = xstrdup(inet_ntoa(saddr.sin_addr));
157                                 connection->buffer = FALSE;
158                                 connection->site_host = NULL;
159                                 connection->site_port = -1;
160                                 connection->bypass = connection->obypass = 0;
161                                 connection->header = NULL;
162                                 connection->rheader = NULL;
163                                 connection->keepalive_client = FALSE;
164                                 connection->keepalive_server = FALSE;
165                                 connection->request = FALSE;
166                                 connection->proxy_host = NULL;
167                                 connection->proxy_type = PROXY_DIRECT;
168                                 connection->proxy_username = NULL;
169                                 connection->proxy_password = NULL;
170                                 connection->proxy_domain = NULL;
171                                 connection->proxy_auth = NULL;
172                                 connection->authenticate = FALSE;
173
174                                 return connection;
175                         }
176                 }
177         }
178
179         return NULL;
180 }
181
182 /*
183 open a connection to somewhere and return file descriptor
184 */
185 int net_connect(char *host, int port)
186 {
187         int fd, ret, on = TRUE;
188         HOSTENT *hostent;
189         struct sockaddr_in saddr;
190
191         if (!host || port <= 0)
192                 return ERROR_UNKNOWN;
193
194         memset(&saddr, 0, sizeof(saddr));
195
196         hostent = net_dns(host);
197         if (hostent == NULL)
198                 return ERROR_DNS;
199
200         saddr.sin_addr = *(struct in_addr *)hostent->addr;
201
202         hostent_free(hostent);
203
204         saddr.sin_family = AF_INET;
205         saddr.sin_port = htons(port);
206
207         fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
208         if (fd == -1)
209                 return ERROR_CONNECT;
210
211         setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
212         fcntl(fd, F_SETFL, FD_CLOEXEC);
213
214         ret = connect(fd, (struct sockaddr *) &saddr, sizeof(saddr));
215         if (ret == -1) {
216                 close(fd);
217
218                 return ERROR_CONNECT;
219         }
220
221         return fd;
222 }
223
224 /*
225 close a connection and free used memory from structure
226 */
227 void net_close(CONNECTION * connection)
228 {
229         if (!connection)
230                 return;
231
232         sock_close(connection->client);
233
234         FREE_AND_NULL(connection->ip);
235         FREE_AND_NULL(connection->proxy_host);
236         FREE_AND_NULL(connection->proxy_username);
237         FREE_AND_NULL(connection->proxy_password);
238         FREE_AND_NULL(connection->proxy_domain);
239         FREE_AND_NULL(connection->proxy_auth);
240         FREE_AND_NULL(connection->site_host);
241
242         xfree(connection);
243 }
244
245 /*
246 close all open listening sockets
247 */
248 void net_listen_closeall()
249 {
250         int i;
251
252         for (i = 0; i < MAXLISTENPORTS; i++) {
253                 if (socklist[i].status == NET_LISTEN) {
254                         close(socklist[i].fd);
255                         if (socklist[i].ip != NULL)
256                                 xfree(socklist[i].ip);
257                         socklist[i].status = NET_UNUSED;
258                 }
259         }
260 }
261
262 /*
263 load <network> section from XML_LIST
264 */
265 NETWORK *network_load(NETWORK * network, XML_LIST * xml_list)
266 {
267         NETWORK *network_tmp = network;
268         struct LISTEN_LIST *listen_list = NULL;
269
270         if (network_tmp == NULL) {
271                 network_tmp = xmalloc(sizeof(NETWORK));
272                 network_tmp->listen_list = NULL;
273                 network_tmp->id = 0;
274
275                 network = network_tmp;
276
277                 pthread_rwlock_init(&network_tmp->lock, NULL);
278         } else
279                 listen_list = network->listen_list;
280
281         while ((xml_list = xml_section(xml_list, "<network>"))) {
282                 XML_LIST_LOOP(xml_list, "<network>") {
283                         XML_LIST_CMP(xml_list, "<listen>") {
284                                 listen_list = listen_list_new(listen_list);
285                                 listen_list->id = network->id++;
286
287                                 if (network_tmp->listen_list == NULL)
288                                         network_tmp->listen_list = listen_list;
289                                 XML_LIST_LOOP(xml_list, "<listen>") {
290                                         XML_LIST_CMP(xml_list, "<ip>") {
291                                                 xml_list = xml_list->next;
292                                                 if (xml_list->type == XML_VALUE)
293                                                         listen_list_insert(listen_list, xml_list->item, NULL);
294                                         }
295                                         XML_LIST_CMP(xml_list, "<port>") {
296                                                 xml_list = xml_list->next;
297                                                 if (xml_list->type == XML_VALUE)
298                                                         listen_list_insert(listen_list, NULL, xml_list->item);
299                                         }
300                                 }
301                         }
302                 }
303         }
304
305         return network;
306 }
307
308 XML_LIST *network_xml(NETWORK * network, XML_LIST * xml_list)
309 {
310         char buf[16], *ptr;
311         struct LISTEN_LIST *ll;
312
313         if (network == NULL)
314                 return xml_list;
315
316         pthread_rwlock_rdlock(&network->lock);
317
318         xml_list = xml_list_add(xml_list, "<network>", XML_TAG);
319
320         ll = network->listen_list;
321
322         for (ll = network->listen_list; ll; ll = ll->next) {
323                 xml_list = xml_list_add(xml_list, "<listen>", XML_TAG);
324
325                 xml_list = xml_list_add(xml_list, "<port>", XML_TAG);
326                 snprintf(buf, sizeof(buf), "%d", ll->port);
327                 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
328                 xml_list = xml_list_add(xml_list, "</port>", XML_TAG);
329
330                 if (ll->ip != NULL) {
331                         xml_list = xml_list_add(xml_list, "<ip>", XML_TAG);
332                         ptr = string_to_xml(ll->ip);
333                         xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
334                         xfree(ptr);
335                         xml_list = xml_list_add(xml_list, "</ip>", XML_TAG);
336                 }
337
338                 xml_list = xml_list_add(xml_list, "</listen>", XML_TAG);
339         }
340
341         xml_list = xml_list_add(xml_list, "</network>", XML_TAG);
342
343         pthread_rwlock_unlock(&network->lock);
344
345         return xml_list;
346 }
347 void listen_list_insert(struct LISTEN_LIST *x, char *a, char *b)
348 {
349         if (a != NULL) {
350                 FREE_AND_NULL(x->ip);
351
352                 if (strcmp(a, ""))
353                         x->ip = xstrdup(a);
354         }
355         if (b != NULL)
356                 x->port = atoi(b);
357 }
358
359 struct LISTEN_LIST *listen_list_delete(struct LISTEN_LIST *x)
360 {
361         struct LISTEN_LIST *start = x;
362
363         while (start->prev != NULL)
364                 start = start->prev;
365
366         if (x->next != NULL)
367                 x->next->prev = x->prev;
368         if (x->prev != NULL)
369                 x->prev->next = x->next;
370         else
371                 start = start->next;
372
373         FREE_AND_NULL(x->ip);
374         FREE_AND_NULL(x->proxy);
375
376         xfree(x);
377
378         return start;
379 }
380
381 struct LISTEN_LIST *listen_list_new(struct LISTEN_LIST *x)
382 {
383         if (x == NULL) {
384                 x = xmalloc(sizeof(struct LISTEN_LIST));
385                 x->prev = NULL;
386         } else {
387                 while (x->next != NULL)
388                         x = x->next;
389                 x->next = xmalloc(sizeof(struct LISTEN_LIST));
390                 x->next->prev = x;
391                 x = x->next;
392         }
393         x->port = -1;
394         x->ip = NULL;
395         x->next = NULL;
396
397         return x;
398 }
399
400 /*
401 free memory allocated by network_load
402 */
403 void network_free(NETWORK * network)
404 {
405         struct LISTEN_LIST *listen_list, *tmp_list;
406
407         if (!network)
408                 return;
409
410         listen_list = network->listen_list;
411
412         while (listen_list != NULL) {
413                 tmp_list = listen_list->next;
414                 if (listen_list->ip != NULL)
415                         xfree(listen_list->ip);
416                 if (listen_list->proxy != NULL)
417                         xfree(listen_list->proxy);
418                 xfree(listen_list);
419                 listen_list = tmp_list;
420         }
421
422         pthread_rwlock_destroy(&network->lock);
423
424         xfree(network);
425 }
426
427 /*
428 look through network->listen_list linked list and bind to listening ports
429 */
430 void network_check(NETWORK * network)
431 {
432         int ret;
433         struct LISTEN_LIST *listen_list;
434
435         if (!network)
436                 return;
437
438         listen_list = network->listen_list;
439
440         pthread_rwlock_rdlock(&network->lock);
441
442         while (listen_list != NULL) {
443                 if (listen_list->port != -1) {
444                         ret = net_listen(listen_list->port, listen_list->ip);
445
446                         if (ret != -1)
447                                 putlog(MMLOG_NETWORK, "listening on %s:%d", (listen_list->ip != NULL) ? listen_list->ip : "0.0.0.0", listen_list->port);
448                         else
449                                 putlog(MMLOG_NETWORK, "failed to bind to %s:%d", (listen_list->ip != NULL) ? listen_list->ip : "0.0.0.0", listen_list->port);
450                 }
451
452                 listen_list = listen_list->next;
453         }
454
455         pthread_rwlock_unlock(&network->lock);
456 }
457
458 /*
459 relay anything from one socket to another, and vice versa
460 */
461 int net_proxy(CONNECTION * connection, int len)
462 {
463         int x, bytes = 0;
464         char buf[BLOCKSIZE];
465         struct pollfd pfd[2];
466         SOCKET *sock1, *sock2;
467
468         sock1 = connection->client;
469         sock2 = connection->server;
470
471         pfd[0].fd = sock1->fd;
472         pfd[0].events = POLLIN;
473         pfd[1].fd = sock2->fd;
474         pfd[1].events = POLLIN;
475
476         while (1) {
477                 x = p_poll(pfd, 2, (sock1->inbuf_len != 0 || sock2->inbuf_len != 0) ? 0 : -1);
478                 if (sock1->inbuf_len != 0 || pfd[0].revents & POLLIN) {
479                         x = sock_read(sock1, buf, (len != -1) ? (len - bytes < sizeof(buf)) ? len - bytes : sizeof(buf) : sizeof(buf));
480                         if (x > 0)
481                                 sock_write(sock2, buf, x);
482                         else
483                                 break;
484
485                         bytes += x;
486                 } else if (pfd[0].revents & (POLLHUP | POLLERR))
487                         break;
488
489                 if (sock1->inbuf_len != 0 || pfd[1].revents & POLLIN) {
490                         x = sock_read(sock2, buf, (len != -1) ? (len - bytes < sizeof(buf)) ? len - bytes : sizeof(buf) : sizeof(buf));
491                         if (x > 0)
492                                 sock_write(sock1, buf, x);
493                         else
494                                 break;
495
496                         bytes += x;
497                 } else if (pfd[1].revents & (POLLHUP | POLLERR))
498                         break;
499
500                 if (len != -1 && bytes == len)
501                         break;
502         }
503
504         return bytes;
505 }
506
507 /*
508 tranfer data one way between two sockets
509 */
510 int net_transfer(CONNECTION * connection, int flags, int bytes)
511 {
512         int x;
513         char buf[BLOCKSIZE];
514         struct pollfd pfd[2];
515         SOCKET *sock1, *sock2;
516
517         sock1 = (flags == SERVER) ? connection->server : connection->client;
518         sock2 = (flags == SERVER) ? connection->client : connection->server;
519
520         pfd[0].fd = sock1->fd;
521         pfd[0].events = POLLIN;
522         pfd[1].fd = sock2->fd;
523         pfd[1].events = POLLIN;
524
525         while (bytes == -1 || bytes > 0) {
526                 x = p_poll(pfd, 2, (sock1->inbuf_len != 0) ? 0 : -1);
527                 if (sock1->inbuf_len != 0 || pfd[0].revents & POLLIN) {
528                         x = sock_read(sock1, buf, (bytes != -1) ? (bytes < sizeof(buf)) ? bytes : sizeof(buf) : sizeof(buf));
529
530                         if (bytes != -1)
531                                 bytes -= x;
532
533                         if (x > 0) {
534                                 x = sock_write(sock2, buf, x);
535                                 if (x == -1)
536                                         break;
537                         } else
538                                 break;
539                 } else if (pfd[0].revents & (POLLHUP | POLLERR))
540                         break;
541
542                 if (pfd[1].revents & POLLIN) {
543                         x = sock_read(sock2, NULL, -1);
544                         if (x <= 0)
545                                 break;
546                 } else if (pfd[1].revents & (POLLHUP | POLLERR))
547                         break;
548         }
549
550         return bytes;
551 }
552
553 int putsock(SOCKET * sock, char *format, ...)
554 {
555         char buf[8096];
556         va_list va;
557
558         va_start(va, format);
559         vsnprintf(buf, sizeof(buf), format, va);
560         va_end(va);
561
562         return sock_write(sock, buf, strlen(buf));
563 }
564
565 void net_filebuf_read(FILEBUF * filebuf, CONNECTION * connection, int flags, int bytes)
566 {
567         int x;
568         char buf[BLOCKSIZE];
569         struct pollfd pfd[2];
570         SOCKET *sock1, *sock2;
571
572         sock1 = (flags == SERVER) ? connection->server : connection->client;
573         sock2 = (flags == SERVER) ? connection->client : connection->server;
574
575         pfd[0].fd = sock1->fd;
576         pfd[0].events = POLLIN;
577
578         if (sock2 != NULL) {
579                 pfd[1].fd = sock2->fd;
580                 pfd[1].events = POLLIN;
581         } else pfd[1].revents = 0;
582
583         while (bytes == -1 || bytes > 0) {
584                 x = p_poll(pfd, (sock2 != NULL) ? 2 : 1, (sock1->inbuf_len != 0) ? 0 : -1);
585                 if (sock1->inbuf_len != 0 || pfd[0].revents & POLLIN) {
586                         x = sock_read(sock1, buf, (bytes != -1) ? (bytes < sizeof(buf)) ? bytes : sizeof(buf) : sizeof(buf));
587                         if (x > 0) {
588                                 if (filebuf != NULL) filebuf_add(filebuf, buf, x);
589
590                                 if (bytes != -1)
591                                         bytes -= x;
592                         } else
593                                 break;
594                 } else if (pfd[0].revents & (POLLHUP | POLLERR))
595                         break;
596
597                 if (pfd[1].revents & POLLIN) {
598                         x = sock_read(sock2, NULL, -1);
599                         if (x <= 0)
600                                 break;
601                 } else if (pfd[1].revents & (POLLHUP | POLLERR))
602                         break;
603         }
604 }
605
606 int net_filebuf_send(FILEBUF * filebuf, CONNECTION * connection, int flags)
607 {
608         SOCKET *sock;
609
610         sock = (flags == SERVER) ? connection->server : connection->client;
611
612         return sock_write(sock, filebuf->data, filebuf->size);
613 }
614
615 /*
616 perform a dns lookup, using cached response from a previous lookup if possible
617 */
618 HOSTENT *net_dns(char *host)
619 {
620         time_t t;
621         char *string, hst[128], buf[24];
622         HOSTENT *hostent;
623
624         pthread_mutex_lock(&dns_cache_lock);
625
626         t = time(NULL);
627
628         s_strncpy(hst, host, 128);
629         string_tolower(hst);
630
631         if (last_dns_expire == 0)
632                 last_dns_expire = t;
633
634         if (t - last_dns_expire >= DNS_EXPIRE) {
635                 putlog(MMLOG_DEBUG, "dns cache expire: entry > %d seconds", DNS_EXPIRE);
636
637                 hash_expire(dns_cache, DNS_EXPIRE);
638                 last_dns_expire = t;
639         }
640
641         if (isip(host)) {
642                 hostent = xmalloc(sizeof(HOSTENT));
643                 hostent->addr = xmalloc(sizeof(struct in_addr));
644                 hostent->len = sizeof(struct in_addr);
645
646                 inet_aton(host, hostent->addr);
647         } else {
648                 string = hash_search(dns_cache, hst);
649                 if (string == NULL) {
650                         pthread_mutex_unlock(&dns_cache_lock);
651
652                         hostent = p_gethostbyname(host);
653                         if (hostent == NULL)
654                                 return NULL;
655
656                         pthread_mutex_lock(&dns_cache_lock);
657
658                         s_strncpy(buf, inet_ntoa(*hostent->addr), sizeof(buf));
659
660                         hash_insert(dns_cache, hst, xstrdup(buf));
661
662                         putlog(MMLOG_DEBUG, "dns cache insert: %s -> %s", hst, buf);
663                 } else {
664                         putlog(MMLOG_DEBUG, "dns cache hit: %s -> %s", hst, string);
665
666                         hostent = xmalloc(sizeof(HOSTENT));
667                         hostent->addr = xmalloc(sizeof(struct in_addr));
668                         hostent->len = sizeof(struct in_addr);
669
670                         inet_aton(string, hostent->addr);
671                 }
672         }
673
674         pthread_mutex_unlock(&dns_cache_lock);
675
676         return hostent;
677 }
678
679 /*
680 connect through socks4 server
681 */
682 int net_socks4(CONNECTION * connection, char *host, int port)
683 {
684         int ret;
685         char buf[64];
686         HOSTENT *hostent;
687
688         hostent = net_dns(host);
689         if (hostent == NULL)
690                 return ERROR_DNS;
691
692         ret = snprintf(buf, sizeof(buf), "\004\001%c%c%c%c%c%c%s", (port >> 8) % 256, port % 256, '0', '0', '0', '0', username);
693         memcpy(&buf[4], hostent->addr, hostent->len);
694
695         hostent_free(hostent);
696
697         sock_write(connection->server, buf, ret + 1);
698
699         /* come on.. what are the changes we won't get the packet in one read() ? :) */
700         sock_read(connection->server, buf, 8);
701
702         switch (buf[1]) {
703         case SOCKS_GRANTED:
704                 ret = TRUE;
705                 break;
706         case SOCKS_FAILED:
707                 ret = ERROR_CONNECT;
708                 break;
709         case SOCKS_BADIDENT:
710         case SOCKS_NOIDENT:
711                 ret = ERROR_AUTH;
712                 break;
713         default:
714                 ret = ERROR_UNKNOWN;
715         }
716
717         return ret;
718 }