1 /* Copyright 2008-2019 Bernhard R. Fischer, Daniel Haslinger.
2  *
3  * This file is part of OnionCat.
4  *
5  * OnionCat 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, version 3 of the License.
8  *
9  * OnionCat is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with OnionCat. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*! \file ocatroute.c
19  *  Contains functions for managing both kind of TCP peers.
20  *  Those are active SOCKS4A and passive TCP-LISTEN.
21  *
22  *  @author Bernhard Fischer <rahra _at_ cypherpunk at>
23  *  \date 2019/09/08
24  */
25 
26 
27 #include "ocat.h"
28 #include "ocat_netdesc.h"
29 
30 #ifdef HAVE_STRUCT_IPHDR
31 #define IPPKTLEN(x) ntohs(((struct iphdr*) (x))->tot_len)
32 #define IPHDLEN sizeof(struct iphdr)
33 #else
34 #define IPPKTLEN(x) ntohs(((struct ip*) (x))->ip_len)
35 #define IPHDLEN sizeof(struct ip)
36 #endif
37 
38 // file descriptors of socket_receiver pipe
39 // used for internal communication
40 static int lpfd_[2];
41 
42 #ifdef PACKET_QUEUE
43 // packet queue pointer
44 static PacketQueue_t *queue_ = NULL;
45 // mutex and condition variable for packet queue
46 static pthread_mutex_t queue_mutex_ = PTHREAD_MUTEX_INITIALIZER;
47 static pthread_cond_t queue_cond_ = PTHREAD_COND_INITIALIZER;
48 #endif
49 
50 
forward_packet(const struct in6_addr * addr,const char * buf,int buflen)51 int forward_packet(const struct in6_addr *addr, const char *buf, int buflen)
52 {
53    OcatPeer_t *peer;
54    int len;
55 
56    lock_peers();
57    if ((peer = search_peer(addr)))
58       lock_peer(peer);
59    unlock_peers();
60 
61    if (!peer)
62    {
63       log_debug("no peer for forwarding");
64       return E_FWD_NOPEER;
65    }
66 
67    log_debug("forwarding %d bytes to TCP fd %d", buflen, peer->tcpfd);
68 
69    if ((len = send(peer->tcpfd, buf, buflen, MSG_DONTWAIT)) == -1)
70    {
71       log_msg(LOG_ERR, "could not write %d bytes to peer %d: \"%s\", dropping", buflen, peer->tcpfd, strerror(errno));
72    }
73    else
74    {
75       if (len != buflen)
76       {
77          // FIXME: there should be sender frag handling!
78          log_msg(LOG_ERR, "could not write %d bytes to peer %d, %d bytes written", buflen, peer->tcpfd, len);
79       }
80       peer->time = time(NULL);
81       peer->out += len;
82    }
83    unlock_peer(peer);
84 
85    return 0;
86 }
87 
88 
89 #ifdef PACKET_QUEUE
queue_packet(const struct in6_addr * addr,const char * buf,int buflen)90 void queue_packet(const struct in6_addr *addr, const char *buf, int buflen)
91 {
92    PacketQueue_t *queue;
93 
94    log_debug("copying packet to heap for queue");
95    if (!(queue = malloc(sizeof(PacketQueue_t) + buflen)))
96    {
97       log_msg(LOG_ERR, "%s for packet to queue", strerror(errno));
98       return;
99    }
100 
101    //memcpy(&queue->addr, addr, sizeof(struct in6_addr));
102    IN6_ADDR_COPY(&queue->addr, addr);
103    queue->psize = buflen;
104    queue->data = ((char*)queue) + sizeof(PacketQueue_t);
105    memcpy(queue->data, buf, buflen);
106    queue->time = time(NULL);
107 
108    log_debug("queuing packet");
109    pthread_mutex_lock(&queue_mutex_);
110    queue->next = queue_;
111    queue_ = queue;
112    log_debug("waking up dequeuer");
113    pthread_cond_signal(&queue_cond_);
114    pthread_mutex_unlock(&queue_mutex_);
115 }
116 
117 
packet_dequeuer(void * p)118 void *packet_dequeuer(void *p)
119 {
120    PacketQueue_t **queue, *fqueue;
121    struct timespec ts;
122    struct timeval tv;
123    int rc, timed = 0;
124    time_t delay;
125 
126    for (;;)
127    {
128       pthread_mutex_lock(&queue_mutex_);
129       if (timed)
130       {
131           // replaced clock_gettime() due to portability issues
132          if (gettimeofday(&tv, NULL) == -1)
133          {
134             log_msg(LOG_ERR, "couldn't gettime: \"%s\"", strerror(errno));
135             memset(&tv, 0, sizeof(tv));
136          }
137          else
138          {
139             ts.tv_sec = tv.tv_sec;
140             ts.tv_nsec = tv.tv_usec * 1000;
141          }
142          ts.tv_sec += DEQUEUER_WAKEUP;
143          log_debug("timed conditional wait...");
144          rc = pthread_cond_timedwait(&queue_cond_, &queue_mutex_, &ts);
145       }
146       else
147       {
148          log_debug("conditional wait...");
149          rc = pthread_cond_wait(&queue_cond_, &queue_mutex_);
150       }
151 
152       if (rc)
153          log_msg(LOG_EMERG, "woke up: \"%s\"", strerror(rc));
154 
155       log_debug("starting dequeuing");
156       for (queue = &queue_; *queue; /*queue = &(*queue)->next*/)
157       {
158          rc = forward_packet(&(*queue)->addr, (*queue)->data, (*queue)->psize);
159 
160          // delete packet from queue if it was sent or is too old
161          delay = time(NULL) - (*queue)->time;
162          if (!rc || (delay > MAX_QUEUE_DELAY))
163          {
164             fqueue = *queue;
165             *queue = (*queue)->next;
166             free(fqueue);
167             log_debug("packet dequeued, delay = %d", delay);
168             continue;
169          }
170          queue = &(*queue)->next;
171       }
172       timed = queue_ != NULL;
173       pthread_mutex_unlock(&queue_mutex_);
174    }
175 }
176 #endif
177 
178 
cleanup_socket(int fd,OcatPeer_t * peer)179 void cleanup_socket(int fd, OcatPeer_t *peer)
180 {
181    log_msg(LOG_INFO | LOG_FCONN, "fd %d reached EOF, closing.", fd);
182    oe_close(fd);
183    lock_peers();
184    delete_peer(peer);
185    unlock_peers();
186 }
187 
188 
189 #ifdef HANDLE_HTTP
190 #define BSTRLEN 1024
191 
handle_http(const OcatPeer_t * peer)192 int handle_http(const OcatPeer_t *peer)
193 {
194    time_t t;
195    char response[BSTRLEN], timestr[BSTRLEN];
196    struct tm tm;
197 
198    // simple check if packet could be an HTTP request
199    if (strncmp(peer->fragbuf, "GET ", 4))
200       return 0;
201 
202    t = time(NULL);
203    (void) localtime_r(&t, &tm);
204    strftime(timestr, BSTRLEN, "%a, %d %b %Y %H:%M:%S %z", &tm);
205    snprintf(response, BSTRLEN,
206          "HTTP/1.0 301 HTTP not possible\r\nLocation: %s\r\nDate: %s\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n"
207          "<html><body><h1>HTTP not possible!<br>OnionCat is running on this port at \"%s.onion\"</h1></body></html>\r\n",
208          OCAT_URL, timestr, CNF(onion_url)
209          );
210    log_msg(LOG_NOTICE, "request seems to be HTTP");
211    if (send(peer->tcpfd, response, strlen(response), MSG_DONTWAIT) == -1)
212       log_msg(LOG_ERR, "could not send html response");
213 
214    return 1;
215 }
216 #endif
217 
218 
set_peer_dest(struct in6_addr * dest,const struct in6_addr * addr)219 int set_peer_dest(struct in6_addr *dest, const struct in6_addr *addr)
220 {
221    if (!has_tor_prefix(addr))
222    {
223       log_debug("remote address does not have OC prefix");
224       return -1;
225    }
226 
227    if (IN6_ARE_ADDR_EQUAL(addr, &CNF(ocat_addr)))
228    {
229       log_debug("source address is local address");
230       return -1;
231    }
232 
233    *dest = *addr;
234    return 0;
235 }
236 
237 
238 /*! Set select timeout a little bit "random" to diverse wakeup periods. */
set_select_timeout(struct timeval * tv)239 void set_select_timeout(struct timeval *tv)
240 {
241    tv->tv_usec = rand() % 1000000;
242    tv->tv_sec = SELECT_TIMEOUT + (tv->tv_usec & 1);
243    log_debug("timeout %d.%06d", tv->tv_sec, tv->tv_usec);
244 }
245 
246 
set_tunheader(char * buf,uint32_t tunhdr)247 void set_tunheader(char *buf, uint32_t tunhdr)
248 {
249    uint32_t *ibuf = (uint32_t*) buf;
250    *ibuf = tunhdr;
251 }
252 
253 
get_tunheader(char * buf)254 uint32_t get_tunheader(char *buf)
255 {
256    uint32_t *ibuf = (uint32_t*) buf;
257    return *ibuf;
258 }
259 
260 
ident_loopback(OcatPeer_t * peer,const struct ip6_hdr * i6h)261 int ident_loopback(OcatPeer_t *peer, const struct ip6_hdr *i6h)
262 {
263    OcatPeer_t *lpeer;
264    int flow;
265 
266    // check if ip6 packet without content (header only)
267    if (i6h->ip6_nxt != IPPROTO_NONE)
268       return -1;
269    log_debug("packet seems to be keepalive");
270 
271    // check if flowlabel is set
272    if (!(flow = ntohl(i6h->ip6_flow) & 0xfffff))
273       return -1;
274 
275    lock_peers();
276    if ((lpeer = search_peer(&CNF(ocat_addr))))
277    {
278       if (lpeer == peer)
279       {
280          log_msg(LOG_ERR, "peer points back to self, this should not happen!");
281          unlock_peers();
282          return -1;
283       }
284       lock_peer(lpeer);
285    }
286    unlock_peers();
287 
288    if (lpeer == NULL)
289    {
290       log_msg(LOG_ERR, "peer not found");
291       return -1;
292    }
293 
294    log_debug("found peer to myself");
295    if (lpeer->dir != PEER_OUTGOING)
296    {
297       unlock_peer(lpeer);
298       log_msg(LOG_ERR, "peer is not OUTGOING, something went wrong...");
299       return -1;
300    }
301 
302    if ((lpeer->rand & 0xfffff) != flow)
303    {
304       log_msg(LOG_ERR, "flowlabel does not match: rand = 0x%05x, flow = 0x%05x", lpeer->rand & 0xfffff, flow);
305       unlock_peer(lpeer);
306       return -1;
307    }
308 
309    log_debug("identified valid loopback keepalive");
310 
311    unlock_peer(lpeer);
312    return 0;
313 }
314 
315 
socket_receiver(void * p)316 void *socket_receiver(void *p)
317 {
318    int maxfd, len;
319    char buf[FRAME_SIZE];
320    char addr[INET6_ADDRSTRLEN];
321    fd_set rset;
322    OcatPeer_t *peer;
323    struct in6_addr *in6;
324    int drop = 0;
325    struct ether_header *eh = (struct ether_header*) (buf + 4);
326    struct timeval tv;
327 
328    if (pipe(lpfd_) < 0)
329       log_msg(LOG_EMERG, "could not create pipe for socket_receiver: \"%s\"", strerror(errno)), exit(1);
330 
331    for (;;)
332    {
333       // check for termination request
334       if (term_req())
335          break;
336 
337       FD_ZERO(&rset);
338       FD_SET(lpfd_[0], &rset);
339       maxfd = lpfd_[0];
340 
341       // create set for all available peers to read
342       lock_peers();
343       for (peer = get_first_peer(); peer; peer = peer->next)
344       {
345          lock_peer(peer);
346          // only select active peers
347          if (peer->state != PEER_ACTIVE)
348          {
349             unlock_peer(peer);
350             continue;
351          }
352 
353          if (peer->tcpfd >= FD_SETSIZE)
354             log_msg(LOG_EMERG, "%d >= FD_SETIZE(%d)", peer->tcpfd, FD_SETSIZE), exit(1);
355 
356          FD_SET(peer->tcpfd, &rset);
357          if (peer->tcpfd > maxfd)
358             maxfd = peer->tcpfd;
359          unlock_peer(peer);
360       }
361       unlock_peers();
362 
363       set_select_timeout(&tv);
364       log_debug("selecting (maxfd = %d)", maxfd);
365       if ((maxfd = select(maxfd + 1, &rset, NULL, NULL, &tv)) == -1)
366       {
367          log_msg(LOG_ERR, "select encountered error: \"%s\", restarting", strerror(errno));
368          continue;
369       }
370 
371       // thread woke up because of internal pipe read => restart selection
372       if (FD_ISSET(lpfd_[0], &rset))
373       {
374          read(lpfd_[0], buf, FRAME_SIZE - 4);
375          maxfd--;
376       }
377 
378       peer = NULL;
379       while (maxfd)
380       {
381          // the following 10 locs look somehow strange and someone may tend
382          // to write this as a for loop but it's necessary for thread locking!
383          lock_peers();
384          if (!peer)
385             peer = get_first_peer();
386          else if (!(peer = peer->next))
387          {
388             log_msg(LOG_EMERG, "fd %d ready but no peer found");
389             unlock_peers();
390             break;
391          }
392          lock_peer(peer);
393          unlock_peers();
394 
395          if (peer->state != PEER_ACTIVE)
396          {
397             unlock_peer(peer);
398             continue;
399          }
400 
401          if (!FD_ISSET(peer->tcpfd, &rset))
402          {
403             unlock_peer(peer);
404             continue;
405          }
406 
407          maxfd--;
408          log_debug("reading from %d", peer->tcpfd);
409 
410          // read/append data to peer's fragment buffer
411          if ((len = read(peer->tcpfd, peer->fragbuf + peer->fraglen, FRAME_SIZE - 4 - peer->fraglen)) == -1)
412          {
413             // this might happen on linux, see SELECT(2)
414             log_debug("spurious wakup of %d: \"%s\"", peer->tcpfd, strerror(errno));
415             unlock_peer(peer);
416             continue;
417          }
418 
419          log_debug("received %d bytes on %d", len, peer->tcpfd);
420          // if len == 0 EOF reached => close session
421          if (!len)
422          {
423             log_msg(LOG_INFO | LOG_FCONN, "fd %d reached EOF, closing.", peer->tcpfd);
424             oe_close(peer->tcpfd);
425             // restart connection of permanent peers
426             if (peer->perm)
427             {
428                log_debug("reconnection permanent peer");
429                socks_queue(peer->addr, 1);
430             }
431             unlock_peer(peer);
432 
433             // deleting peer
434             // FIXME: there might be a race-condition with restarted permanent peers
435             lock_peers();
436             delete_peer(peer);
437             unlock_peers();
438 
439             continue;
440          }
441 
442          peer->fraglen += len;
443          // update timestamp
444          peer->time = time(NULL);
445          peer->in += len;
446 
447          while (peer->fraglen)
448          {
449             // incoming packet seems to be IPv6
450             if ((peer->fragbuf[0] & 0xf0) == 0x60)
451             {
452                log_debug("identified IPv6 packet");
453                if ((peer->fraglen < IP6HLEN) || (peer->fraglen < ntohs(((struct ip6_hdr*) peer->fragbuf)->ip6_plen) + IP6HLEN))
454                {
455                   log_debug("keeping %d bytes frag", peer->fraglen);
456                   break;
457                }
458 
459                len = ntohs(((struct ip6_hdr*)peer->fragbuf)->ip6_plen) + IP6HLEN;
460                *peer->tunhdr = CNF(fhd_key[IPV6_KEY]);
461             }
462             // incoming packet seems to be IPv4
463             else if ((peer->fragbuf[0] & 0xf0) == 0x40)
464             {
465                if ((peer->fragbuf[0] & 0x0f) < 5)
466                {
467                   log_debug("dropping packet, not IPv4 - resetting fragment buffer");
468                   peer->fraglen = 0;
469                   break;
470                }
471 
472  #ifdef HANDLE_HTTP
473                if (handle_http(peer))
474                {
475                   log_msg(LOG_INFO | LOG_FCONN, "closing %d due to HTTP", peer->tcpfd);
476                   oe_close(peer->tcpfd);
477                   unlock_peer(peer);
478                   lock_peers();
479                   delete_peer(peer);
480                   unlock_peers();
481                }
482 #endif
483 
484                log_debug("identified IPv4 packet");
485                if ((peer->fraglen < IPHDLEN) || (peer->fraglen < IPPKTLEN(peer->fragbuf)))
486                {
487                   log_debug("keeping %d bytes frag", peer->fraglen);
488                   break;
489                }
490 
491                len = IPPKTLEN(peer->fragbuf);
492                *peer->tunhdr = CNF(fhd_key[IPV4_KEY]);
493             }
494             else
495             {
496                /*
497                log_debug("fragment buffer reset");
498                peer->fraglen = 0;
499                */
500                log_debug("fragment buffer resynchronization");
501                len = 1;
502                drop = 1;
503                break;
504             }
505 
506             // identify remote loopback
507             if (!drop && IN6_IS_ADDR_UNSPECIFIED(&peer->addr))
508             {
509                if (!ident_loopback(peer, (struct ip6_hdr*)peer->fragbuf))
510                {
511                   run_ocat_thread("rloopback", remote_loopback_responder, (void*)(uintptr_t) peer->tcpfd);
512 
513                   // remove peer
514                   log_msg(LOG_INFO, "mark peer on fd %d for deletion", peer->tcpfd);
515                   peer->state = PEER_DELETE;
516                }
517             }
518 
519             // set IP address if it is not set yet and frame is valid and in bidirectional mode
520             if (!CNF(unidirectional) && !drop && IN6_IS_ADDR_UNSPECIFIED(&peer->addr))
521             {
522                if (*peer->tunhdr == CNF(fhd_key[IPV6_KEY]))
523                {
524                   //memcpy(&peer->addr, &((struct ip6_hdr*)peer->fragbuf)->ip6_src, sizeof(struct in6_addr));
525                   if (set_peer_dest(&peer->addr, &((struct ip6_hdr*)peer->fragbuf)->ip6_src))
526                      drop = 1;
527                }
528                else if (*peer->tunhdr == CNF(fhd_key[IPV4_KEY]))
529                {
530                   // check if there is a route back
531 #ifdef HAVE_STRUCT_IPHDR
532                   if (!(in6 = ipv4_lookup_route(ntohl(((struct iphdr*) peer->fragbuf)->saddr))))
533 #else
534                   if (!(in6 = ipv4_lookup_route(ntohl(((struct ip*) peer->fragbuf)->ip_src.s_addr))))
535 #endif
536                   {
537                      drop = 1;
538                      log_debug("no route back");
539                   }
540                   else
541                   {
542                      //memcpy(&peer->addr, in6, sizeof(struct in6_addr));
543                      if (set_peer_dest(&peer->addr, in6))
544                         drop = 1;
545                   }
546                }
547 
548                if (!drop)
549                   log_msg(LOG_INFO | LOG_FCONN, "incoming connection on %d from %s is now identified", peer->tcpfd,
550                      inet_ntop(AF_INET6, &peer->addr, addr, INET6_ADDRSTRLEN));
551             }
552 
553             if (!drop)
554             {
555                // write directly on TUN device
556                if (!CNF(use_tap))
557                {
558                   log_debug("writing to tun %d framesize %d + %d", CNF(tunfd[1]), len, 4 - BUF_OFF);
559                   if (tun_write(CNF(tunfd[1]), ((char*) peer->tunhdr) + BUF_OFF, len + 4 - BUF_OFF) != (len + 4 - BUF_OFF))
560                      log_msg(LOG_ERR, "could not write %d bytes to tunnel %d", len + 4 - BUF_OFF, CNF(tunfd[1]));
561                }
562                // create ethernet header and handle MAC on TAP device
563                else if (*peer->tunhdr == CNF(fhd_key[IPV6_KEY]))
564                {
565                   log_debug("creating ethernet header");
566 
567                   // FIXME: should differentiate between IPv6 and IP!!
568                   memset(eh->ether_dst, 0, ETHER_ADDR_LEN);
569                   if (mac_set(&((struct ip6_hdr*)peer->fragbuf)->ip6_dst, eh->ether_dst) == -1)
570                   {
571                      log_debug("dest MAC unknown, resolving");
572                      ndp_solicit(&((struct ip6_hdr*)peer->fragbuf)->ip6_src, &((struct ip6_hdr*)peer->fragbuf)->ip6_dst);
573                   }
574                   else
575                   {
576                      set_tunheader(buf, *peer->tunhdr);
577                      memcpy(buf + 4 + sizeof(struct ether_header), peer->fragbuf, len);
578                      memcpy(eh->ether_src, CNF(ocat_hwaddr), ETHER_ADDR_LEN);
579 
580                      if (*peer->tunhdr == CNF(fhd_key[IPV6_KEY]))
581                         eh->ether_type = htons(ETHERTYPE_IPV6);
582                      else if (*peer->tunhdr == CNF(fhd_key[IPV4_KEY]))
583                         eh->ether_type = htons(ETHERTYPE_IP);
584 
585                      if (tun_write(CNF(tunfd[1]), buf + BUF_OFF, len + 4 + sizeof(struct ether_header) - BUF_OFF) != (len + 4 + sizeof(struct ether_header) - BUF_OFF))
586                         log_msg(LOG_ERR, "could not write %d bytes to tunnel %d", len + 4 + sizeof(struct ether_header) - BUF_OFF, CNF(tunfd[1]));
587                   }
588                }
589                else
590                {
591                   log_debug("protocol %x not implemented on TAP device", ntohs(*peer->tunhdr));
592                }
593             }
594             else
595             {
596                log_msg(LOG_ERR, "dropping packet with %d bytes", len);
597                drop = 0;
598             }
599 
600             peer->fraglen -= len;
601             if (peer->fraglen)
602             {
603                log_debug("moving fragment. fragsize %d", peer->fraglen);
604                memmove(peer->fragbuf, peer->fragbuf + len, FRAME_SIZE - 4 - len);
605             }
606             else
607                log_debug("fragbuf empty");
608 
609         } // while (peer->fraglen)
610 
611          if (peer->state == PEER_DELETE)
612          {
613             unlock_peer(peer);
614             lock_peers();
615             delete_peer(peer);
616             unlock_peers();
617             continue;
618          }
619          unlock_peer(peer);
620       } // while (maxfd)
621    } // for (;;)
622 
623    // closing pipe
624    oe_close(lpfd_[0]);
625    oe_close(lpfd_[1]);
626 
627    return NULL;
628 }
629 
630 
set_nonblock(int fd)631 void set_nonblock(int fd)
632 {
633    long flags;
634 
635    if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
636    {
637       log_msg(LOG_ERR, "could not get socket flags for %d: \"%s\"", fd, strerror(errno));
638       flags = 0;
639    }
640    log_debug("O_NONBLOCK currently is %x", flags & O_NONBLOCK);
641 
642    if ((fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1)
643       log_msg(LOG_ERR, "could not set O_NONBLOCK for %d: \"%s\"", fd, strerror(errno));
644 }
645 
646 
insert_peer(int fd,const SocksQueue_t * sq,time_t dly)647 int insert_peer(int fd, const SocksQueue_t *sq, /*const struct in6_addr *addr,*/ time_t dly)
648 {
649    OcatPeer_t *peer;
650 
651    log_msg(LOG_INFO | LOG_FCONN, "inserting peer fd %d to active peer list", fd);
652 
653    set_nonblock(fd);
654 
655    lock_peers();
656    if (!(peer = get_empty_peer()))
657    {
658       unlock_peers();
659       log_msg(LOG_ERR, "could not get new empty peer");
660       return 0;
661    }
662    lock_peer(peer);
663    unlock_peers();
664 
665    peer->tcpfd = fd;
666    peer->state = PEER_ACTIVE;
667    peer->otime = peer->time = time(NULL);
668    peer->sdelay = dly;
669    if (sq)
670    {
671       //memcpy(&peer->addr, &sq->addr, sizeof(struct in6_addr));
672       IN6_ADDR_COPY(&peer->addr, &sq->addr);
673       peer->dir = PEER_OUTGOING;
674       peer->perm = sq->perm;
675    }
676    else
677       peer->dir = PEER_INCOMING;
678    unlock_peer(peer);
679 
680    // wake up socket_receiver
681    log_debug("waking up socket_receiver");
682    if (write(lpfd_[1], &fd, 1) != 1)
683       log_msg(LOG_EMERG, "couldn't write to socket_receiver pipe: \"%s\"", strerror(errno));
684 
685    return 1;
686 }
687 
688 
insert_anon_peer(int fd)689 int insert_anon_peer(int fd)
690 {
691    return insert_peer(fd, NULL, 0);
692 }
693 
694 
create_listener(struct sockaddr * addr,int sock_len)695 int create_listener(struct sockaddr *addr, int sock_len)
696 {
697    int family;
698    int fd, so;
699 
700    switch (addr->sa_family)
701    {
702       case AF_INET:
703          family = PF_INET;
704          break;
705       case AF_INET6:
706          family = PF_INET6;
707          break;
708       default:
709          log_msg(LOG_EMERG, "unknown address family %d", addr->sa_family);
710          return -1;
711    }
712 
713    if ((fd = socket(family, SOCK_STREAM, 0)) < 0)
714    {
715       log_msg(LOG_EMERG, "could not create listener socker: \"%s\"", strerror(errno));
716       return -1;
717    }
718 
719    so = 1;
720    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so)) == -1)
721       log_msg(LOG_WARNING, "could not set socket %d to SO_REUSEADDR: \"%s\"", fd, strerror(errno));
722    if (bind(fd, addr, sock_len) == -1)
723    {
724       log_msg(LOG_EMERG, "could not bind listener %d: \"%s\"", fd, strerror(errno));
725       oe_close(fd);
726       return -1;
727    }
728 
729    if (listen(fd, 32) < 0)
730    {
731       log_msg(LOG_EMERG, "could not bring listener %d to listening state: \"%s\"", fd, strerror(errno));
732       oe_close(fd);
733       return -1;
734    }
735 
736    log_debug("created listener, fd = %d", fd);
737    return fd;
738 }
739 
740 
741 /*! run_listeners(...) is a generic socket acceptor for TCP ports.  It listens
742  * on a given list of sockets.  Every time a connection comes in the function
743  * action_accept is called with the incoming file descriptor as parameter.
744  *
745  * @param addr Double pointer to sockaddr structs. It MUST be terminated by a
746  * null pointer.
747  * @param sockfd Points to an int array. The array must contain at least as
748  * much entries as the sockaddr pointer has entries.
749  * @param action_accept Function pointer to function that should be called if a
750  * connection arrives.
751  * @return Always 0.
752  */
run_listeners(struct sockaddr ** addr,int * sockfd,int cnt,int (action_accept)(int))753 int run_listeners(struct sockaddr **addr, int *sockfd, int cnt, int (action_accept)(int))
754 {
755    int fd;
756    struct sockaddr_in6 in6;
757    fd_set rset;
758    int maxfd, i;
759    socklen_t alen;
760    char iabuf[INET6_ADDRSTRLEN];
761    struct timeval tv;
762 
763    for (i = 0; i < cnt; i++)
764    {
765       log_debug("create listener");
766       if ((sockfd[i] = create_listener(addr[i], SOCKADDR_SIZE(addr[i]))) == -1)
767          log_msg(LOG_EMERG, "exiting"), exit(1);
768    }
769 
770    set_thread_ready();
771    for (;;)
772    {
773       // check for termination request
774       if (term_req())
775          break;
776 
777       log_debug("setting up fd_set");
778       FD_ZERO(&rset);
779       maxfd = -1;
780       for (i = 0; i < cnt; i++)
781       {
782          if (sockfd[i] == -1)
783             continue;
784 
785          FD_SET(sockfd[i], &rset);
786          if (sockfd[i] > maxfd)
787             maxfd = sockfd[i];
788       }
789 
790       if (maxfd == -1)
791       {
792          log_debug("no active listener fds available");
793          break;
794       }
795 
796       set_select_timeout(&tv);
797       log_debug("selecting (maxfd = %d)", maxfd);
798       if ((maxfd = select(maxfd + 1, &rset, NULL, NULL, &tv)) == -1)
799       {
800          log_debug("select returned: \"%s\"", strerror(errno));
801          continue;
802       }
803       log_debug("select returned %d fds ready", maxfd);
804 
805       for (i = 0; maxfd && (i < cnt); i++)
806       {
807          log_debug("checking fd %d (maxfd = %d, i = %d)", sockfd[i], maxfd, i);
808          if (!FD_ISSET(sockfd[i], &rset))
809             continue;
810          maxfd--;
811          alen = sizeof(in6);
812          log_debug("accepting connection on %d", sockfd[i]);
813          if ((fd = accept(sockfd[i], (struct sockaddr*) &in6, &alen)) < 0)
814          {
815             log_msg(LOG_ERR, "error accepting connection on %d: \"%s\"", sockfd[i], strerror(errno));
816             // FIXME: there should be additional error handling!
817             continue;
818          }
819 
820          inet_ntop(in6.sin6_family,
821                in6.sin6_family == AF_INET6 ? &in6.sin6_addr :
822                (void*) &((struct sockaddr_in*) &in6)->sin_addr,
823                iabuf, INET6_ADDRSTRLEN);
824          log_msg(LOG_INFO | LOG_FCONN, "connection %d [%d] accepted on listener %d from %s port %d", fd, i, sockfd[i], iabuf, ntohs(in6.sin6_port));
825          (void) action_accept(fd);
826       } // for
827    }
828 
829    // closing listeners
830    for (i = 0; i < cnt; i++)
831       oe_close(sockfd[i]);
832 
833    log_debug("run_listeners returns");
834    return 0;
835 }
836 
837 
socket_acceptor(void * p)838 void *socket_acceptor(void *p)
839 {
840    run_listeners(CNF(oc_listen), CNF(oc_listen_fd), CNF(oc_listen_cnt), insert_anon_peer);
841    return NULL;
842 }
843 
844 
845 #ifdef HAVE_STRUCT_IPHDR
846 /* helper function to avoid pointer aliasing */
get_saddr(const struct iphdr * ihdr)847 static uint32_t get_saddr(const struct iphdr *ihdr)
848 {
849    return ihdr->daddr;
850 }
851 #else
852 /* helper function to avoid pointer aliasing */
get_saddr(const struct ip * ihdr)853 static uint32_t get_saddr(const struct ip *ihdr)
854 {
855    return ihdr->ip_dst.s_addr;
856 }
857 #endif
858 
859 
packet_forwarder(void)860 void packet_forwarder(void)
861 {
862    char buf[FRAME_SIZE];
863    int rlen;
864    struct in6_addr *dest, destbuf;
865    struct in_addr in;
866    struct ether_header *eh = (struct ether_header*) &buf[4];
867 #ifdef PACKET_LOG
868    int pktlog;
869 
870    log_debug("opening packetlog");
871    if ((pktlog = open("pkt_log", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1)
872       log_debug("could not open packet log: %s", strerror(errno));
873 #endif
874 
875    for (;;)
876    {
877       // check for termination request
878       if (term_req())
879          break;
880 
881 #ifdef __OpenBSD__
882       // workaround for OpenBSD userland threads
883       fcntl(CNF(tunfd[0]), F_SETFL, fcntl(CNF(tunfd[0]), F_GETFL) & ~O_NONBLOCK);
884 #endif
885       log_debug("reading from tunfd[0] = %d", CNF(tunfd[0]));
886       if ((rlen = tun_read(CNF(tunfd[0]), buf + BUF_OFF, FRAME_SIZE - BUF_OFF)) == -1)
887       {
888          rlen = errno;
889          log_debug("read from tun %d returned on error: \"%s\"", CNF(tunfd[0]), strerror(rlen));
890          if (rlen == EINTR)
891          {
892             log_debug("signal caught");
893             if (CNF(sig_term))
894             {
895                log_msg(LOG_NOTICE, "caught termination request");
896                // set global termination flag
897                set_term_req();
898             }
899             if (CNF(sig_usr1))
900             {
901                lock_setup();
902                CNF(clear_stats) = 1;
903                unlock_setup();
904                log_msg(LOG_NOTICE, "stats will be cleared after next stats output");
905             }
906          }
907          log_debug("restarting");
908          continue;
909       }
910       rlen += BUF_OFF;
911 
912       log_debug("received on tunfd %d, framesize %d + %d", CNF(tunfd[0]), rlen - 4, 4 - BUF_OFF);
913 
914 #ifdef PACKET_LOG
915       if ((pktlog != -1) && (write(pktlog, buf, rlen) == -1))
916          log_debug("could not write frame to packet log: %s", strerror(errno));
917 #endif
918 
919       // just to be on the safe side but this should never happen
920       if ((!CNF(use_tap) && (rlen < 4)) || (CNF(use_tap) && (rlen < 4 + sizeof(struct ether_header))))
921       {
922          log_msg(LOG_ERR, "frame effectively too short (rlen = %d)", rlen);
923          continue;
924       }
925 
926       // in case of TAP device handle ethernet header
927       if (CNF(use_tap))
928       {
929          if (eth_check(buf, rlen))
930             continue;
931 
932          // removing ethernet header
933          // FIXME: it would be better to adjust pointers instead of moving data
934          rlen -= sizeof(struct ether_header);
935          memmove(eh, eh + 1, rlen - 4);
936       }
937 
938 #if defined(__sun__) || defined(__CYGWIN__)
939       // Solaris tunnel driver does not send tunnel
940       // header thus we guess and set it manually
941       if ((buf[BUF_OFF] & 0xf0) == 0x60)
942          set_tunheader(buf, CNF(fhd_key[IPV6_KEY]));
943       else if ((buf[BUF_OFF] & 0xf0) == 0x40)
944          set_tunheader(buf, CNF(fhd_key[IPV4_KEY]));
945       else
946          set_tunheader(buf, -1);
947 #endif
948 
949       if (get_tunheader(buf) == CNF(fhd_key[IPV6_KEY]))
950       {
951          if (((rlen - 4) < IP6HLEN))
952          {
953             log_debug("IPv6 packet too short (%d bytes). dropping", rlen - 4);
954             continue;
955          }
956 
957          IN6_ADDR_COPY(&destbuf, &buf[4 + offsetof(struct ip6_hdr, ip6_dst)]);
958          if (!(dest = ipv6_lookup_route(&destbuf)))
959             dest = &destbuf;
960 
961          if (!has_tor_prefix(dest))
962          {
963             char abuf[INET6_ADDRSTRLEN];
964             log_msg(LOG_ERR, "no route to destination %s, dropping frame.", inet_ntop(AF_INET6, &destbuf, abuf, INET6_ADDRSTRLEN));
965             continue;
966          }
967       }
968       else if (get_tunheader(buf) == CNF(fhd_key[IPV4_KEY]))
969       {
970          if (((rlen - 4) < IPHDLEN))
971          {
972             log_debug("IPv4 packet too short (%d bytes). dropping", rlen - 4);
973             continue;
974          }
975 
976 #ifdef HAVE_STRUCT_IPHDR
977          in.s_addr = get_saddr((struct iphdr*) &buf[4]);
978 #else
979          in.s_addr = get_saddr((struct ip*) &buf[4]);
980 #endif
981          if (!(dest = ipv4_lookup_route(ntohl(in.s_addr))))
982          {
983             log_msg(LOG_ERR, "no route to destination %s, dropping frame.", inet_ntoa(in));
984             continue;
985          }
986       }
987       else
988       {
989          log_msg(LOG_ERR, "protocol 0x%08x not supported. dropping frame.", ntohl(get_tunheader(buf)));
990          continue;
991       }
992 
993       // now forward either directly or to the queue
994       if (forward_packet(dest, buf + 4, rlen - 4) == E_FWD_NOPEER)
995       {
996          log_debug("adding destination to SOCKS queue");
997          socks_queue(*dest, 0);
998 #ifdef PACKET_QUEUE
999          log_debug("queuing packet");
1000          queue_packet(dest, buf + 4, rlen - 4);
1001 #endif
1002       }
1003    }
1004 }
1005 
1006 
send_keepalive(OcatPeer_t * peer)1007 int send_keepalive(OcatPeer_t *peer)
1008 {
1009    struct ip6_hdr hdr;
1010    int len;
1011 
1012    memset(&hdr, 0, sizeof(hdr));
1013    //memcpy(&hdr.ip6_dst, &peer->addr, sizeof(struct in6_addr));
1014    IN6_ADDR_COPY(&hdr.ip6_dst, &peer->addr);
1015    //memcpy(&hdr.ip6_src, &CNF(ocat_addr), sizeof(struct in6_addr));
1016    IN6_ADDR_COPY(&hdr.ip6_src, &CNF(ocat_addr));
1017    hdr.ip6_flow = htonl(peer->rand & 0xfffff);
1018    hdr.ip6_vfc = 0x60;
1019    hdr.ip6_nxt = IPPROTO_NONE;
1020    hdr.ip6_hops = 1;
1021 
1022    log_debug("sending %d bytes keepalive to fd %d", sizeof(hdr), peer->tcpfd);
1023 
1024    if ((len = send(peer->tcpfd, &hdr, sizeof(hdr), MSG_DONTWAIT)) == -1)
1025    {
1026       log_msg(LOG_ERR, "could not send keepalive: %s", strerror(errno));
1027       return -1;
1028    }
1029    peer->out += len;
1030    if (len != sizeof(hdr))
1031    {
1032       log_msg(LOG_ERR, "sending of %d bytes keepalive truncated to %d", sizeof(hdr), len);
1033       return -1;
1034    }
1035    return 0;
1036 }
1037 
1038 
socket_cleaner(void * ptr)1039 void *socket_cleaner(void *ptr)
1040 {
1041    OcatPeer_t *peer, **p;
1042    int stat_wup = 0;
1043    time_t act_time;
1044 
1045    for (;;)
1046    {
1047       // check for termination request
1048       if (term_req())
1049          break;
1050 
1051       sleep(CLEANER_WAKEUP);
1052       log_debug("wakeup");
1053 
1054       act_time = time(NULL);
1055 
1056       // stats output
1057       if (act_time - stat_wup >= STAT_WAKEUP)
1058       {
1059          stat_wup = act_time;
1060          //log_msg(LOG_INFO, "stats: ... (not implemented yet)");
1061 
1062          lock_setup();
1063          if (CNF(clear_stats))
1064          {
1065             CNF(clear_stats) = 0;
1066             // FIXME: implement stats clearing here
1067             log_debug("stats cleared");
1068          }
1069          unlock_setup();
1070       }
1071 
1072       // cleanup MAC table
1073       mac_cleanup();
1074 
1075       // cleanup peers
1076       lock_peers();
1077       for (p = get_first_peer_ptr(); *p; p = &(*p)->next)
1078       {
1079          lock_peer(*p);
1080 
1081          // handle permanent connections
1082          if ((*p)->perm)
1083          {
1084             // sending keepalive
1085             if (act_time - (*p)->time >= KEEPALIVE_TIME)
1086             {
1087                send_keepalive(*p);
1088                (*p)->time = act_time;
1089             }
1090             unlock_peer(*p);
1091          }
1092          // handle temporary connections
1093          else if ((*p)->state && act_time - (*p)->time >= MAX_IDLE_TIME)
1094          {
1095             peer = *p;
1096             *p = peer->next;
1097             log_msg(LOG_INFO | LOG_FCONN, "peer %d timed out, closing.", peer->tcpfd);
1098             oe_close(peer->tcpfd);
1099             unlock_peer(peer);
1100             delete_peer(peer);
1101             if (!(*p))
1102             {
1103                log_debug("last peer in list deleted, breaking loop");
1104                break;
1105             }
1106          }
1107          else
1108             unlock_peer(*p);
1109       }
1110       unlock_peers();
1111    }
1112    return NULL;
1113 }
1114 
1115 
1116 #ifdef WITH_LOOPBACK_RESPONDER
memor(void * dst,const void * src,int n)1117 static void memor(void *dst, const void *src, int n)
1118 {
1119    char *d = dst;
1120    const char *s = src;
1121 
1122    // safety check
1123    if (d == NULL || s == NULL)
1124    {
1125       log_msg(LOG_EMERG, "NULL pointer caught in memor()");
1126       return;
1127    }
1128 
1129    for (; n > 0; n--)
1130       *d++ |= *s++;
1131 }
1132 
1133 
1134 /*! This is the actual loopback loop. It reflects all valid IPv6 packets with
1135  * swapped IP addresses.
1136  * @param fd File descriptor to receive and send packets.
1137  * @return The function always returns 0.
1138  */
loopback_loop(int fd)1139 int loopback_loop(int fd)
1140 {
1141    char buf[FRAME_SIZE];
1142    struct in6_addr addr;
1143    struct ip6_hdr *ip6h = (struct ip6_hdr*) buf;
1144    int len, wlen, maxfd;
1145    fd_set rset;
1146    OcatPeer_t *peer;
1147 
1148    log_debug("starting loopback loop on fd %d", fd);
1149    while (!term_req())
1150    {
1151       FD_ZERO(&rset);
1152       FD_SET(fd, &rset);
1153       log_debug("selecting in fd %d", fd);
1154       if ((maxfd = select(fd + 1, &rset, NULL, NULL, NULL)) == -1)
1155       {
1156          log_msg(LOG_ERR, "select encountered error: \"%s\", restarting", strerror(errno));
1157          continue;
1158       }
1159 
1160       if (!FD_ISSET(fd, &rset))
1161       {
1162          log_msg(LOG_ERR, "fd %d not in fdset, this should not happen");
1163          continue;
1164       }
1165 
1166       // read from pipe
1167       len = read(fd, buf, sizeof(buf));
1168       // check for error
1169       if (len == -1)
1170       {
1171          log_msg(LOG_ERR, "read failed: %s", strerror(errno));
1172          break;
1173       }
1174       if (len == 0)
1175       {
1176          log_msg(LOG_INFO, "socket was closed");
1177          break;
1178       }
1179       log_debug("read %d bytes", len);
1180       // check for minimum length of packet
1181       if (len < IP6HLEN)
1182       {
1183          log_msg(LOG_ERR, "packet too small (%d bytes), dropping", len);
1184          continue;
1185       }
1186       // check for IPv6
1187       if ((buf[0] & 0xf0) != 0x60)
1188       {
1189          log_msg(LOG_ERR, "ill packet, starts with 0x%02x, dropping", buf[0]);
1190          continue;
1191       }
1192 
1193       log_debug("swapping IPs and sending back");
1194       // swapping source and destination address
1195       addr = ip6h->ip6_src;
1196       ip6h->ip6_src = ip6h->ip6_dst;
1197       ip6h->ip6_dst = addr;
1198 
1199       wlen = write(fd, buf, len);
1200       if (wlen == -1)
1201       {
1202          log_msg(LOG_ERR, "write failed: %s", strerror(errno));
1203          break;
1204       }
1205       if (wlen < len)
1206          log_msg(LOG_ERR, "truncated write: %d < %d", wlen, len);
1207    }
1208 
1209    return 0;
1210 }
1211 
1212 
loopback_handler(int fd,const struct in6_addr * laddr)1213 int loopback_handler(int fd, const struct in6_addr *laddr)
1214 {
1215    char buf[FRAME_SIZE];
1216    struct in6_addr addr;
1217    struct ip6_hdr *ip6h = (struct ip6_hdr*) buf;
1218    int len, wlen, uni;
1219    OcatPeer_t *peer;
1220 
1221    log_debug("starting loopback_handler");
1222    memset(ip6h, 0, sizeof(*ip6h));
1223    ip6h->ip6_src = *laddr;
1224    ip6h->ip6_dst = CNF(ocat_addr);
1225    ip6h->ip6_vfc = 0x60;
1226    ip6h->ip6_nxt = IPPROTO_NONE;
1227    ip6h->ip6_hops = 1;
1228    wlen = sizeof(*ip6h);
1229 
1230    log_debug("clearing unidirectional mode and sending packet");
1231    uni = CNF(unidirectional);
1232    CNF(unidirectional) = 0;
1233    len = write(fd, ip6h, wlen);
1234    log_debug("sent %d of %d bytes to fd %d", len, wlen, fd);
1235 
1236    for (peer = NULL; peer == NULL; )
1237    {
1238       lock_peers();
1239       if ((peer = search_peer(laddr)))
1240          lock_peer(peer);
1241       unlock_peers();
1242 
1243       if (peer == NULL)
1244       {
1245          log_debug("peer not found, waiting...");
1246          usleep(100000);
1247       }
1248    }
1249 
1250    // reset unidirectional mode
1251    log_debug("resetting unidirectional mode to %d and setting peer parameters", uni);
1252    CNF(unidirectional) = uni;
1253    //peer->addr = addr;
1254    peer->perm = 1;
1255    unlock_peer(peer);
1256 
1257    set_thread_ready();
1258    log_msg(LOG_INFO, "loopback_handler ready listening on %s", inet_ntop(AF_INET6, laddr, buf, INET6_ADDRSTRLEN));
1259 
1260    loopback_loop(fd);
1261 
1262    return 0;
1263 }
1264 
1265 
1266 /*! This is the local loopback responder thread (the dead-beef-responder). It
1267  * connects locally to the OnionCat TCP port (the acceptor/receiver thread).
1268  * Once connected, it receives IPv6 packets and reflects it with swapped IP
1269  * addresses.
1270  * @return This function always returns NULL.
1271  */
local_loopback_responder(void * ptr)1272 void *local_loopback_responder(void *ptr)
1273 {
1274    struct in6_addr addr = {{{0,0,0,0,0,0,0,0,0,0,0,0,0xde,0xad,0xbe,0xef}}};
1275    int fd;
1276 
1277    log_debug("initializing dead_beef_responder");
1278    if ((fd = socket((*CNF(oc_listen))->sa_family, SOCK_STREAM, 0)) == -1)
1279    {
1280       log_msg(LOG_ERR, "failed to create socket: %s", strerror(errno));
1281       goto loop_exit1;
1282    }
1283 
1284    wait_thread_by_name_ready("acceptor");
1285 
1286    log_debug("connecting...");
1287    if (connect(fd, *CNF(oc_listen), SOCKADDR_SIZE(*CNF(oc_listen))) == -1)
1288    {
1289       log_msg(LOG_ERR, "could not connect(): %s", strerror(errno));
1290       goto loop_exit2;
1291    }
1292 
1293    memor(&addr, &NDESC(prefix), sizeof(addr));
1294    loopback_handler(fd, &addr);
1295 
1296 loop_exit2:
1297    oe_close(fd);
1298 
1299 loop_exit1:
1300    log_msg(LOG_INFO, "local_looback_responder exiting");
1301 
1302    return NULL;
1303 }
1304 
1305 
1306 /*! This is the remote loopback responder thread. It receives IPv6 packets on a
1307  * file descriptor and reflects the packets with swapped IP addresses.
1308  * @param ptr The pointer contains the int file descriptor casted to a pointer.
1309  * @return The function always return NULL.
1310  */
remote_loopback_responder(void * ptr)1311 void *remote_loopback_responder(void *ptr)
1312 {
1313    int fd = (uintptr_t) ptr;
1314 
1315    log_debug("initializing feed_beef_responder");
1316 
1317    detach_thread();
1318    set_thread_ready();
1319 
1320    loopback_loop(fd);
1321 
1322    oe_close(fd);
1323 
1324    log_msg(LOG_INFO, "remote_looback_responder exiting");
1325 
1326    return NULL;
1327 }
1328 
1329 
1330 /*! This function adds a route for remote loopback responder (the
1331  * feed-beef-responder). This is an IPv6 route to itself which can not
1332  * regularly be added.
1333  * @return On success the function returns 0, otherwise -1.
1334  */
add_remote_loopback_route(void)1335 int add_remote_loopback_route(void)
1336 {
1337    IPv6Route_t br;
1338 
1339    br.dest = (struct in6_addr) {{{0,0,0,0,0,0,0,0,0,0,0,0,0xfe,0xed,0xbe,0xef}}};
1340    memor(&br.dest, &NDESC(prefix), sizeof(br.dest));
1341    br.prefixlen = 128;
1342    IN6_ADDR_COPY(&br.gw, &CNF(ocat_addr));
1343 
1344    log_debug("adding feed:beef route");
1345    if (ipv6_add_route(&br))
1346    {
1347       log_msg(LOG_ERR, "ipv6_add_route() failed!");
1348       return -1;
1349    }
1350 
1351    return 0;
1352 }
1353 #endif
1354 
1355