Skip to content
This repository
Browse code

Merge pull request #79 from EmericBr/StudClientMode

Stud client mode
  • Loading branch information...
commit 84797cc9604c7360868709f9bfb1ee29e7e5ad09 2 parents a9b5aca + 7330881
Jamie Turner authored June 01, 2012
10  configuration.c
@@ -111,6 +111,7 @@ stud_config * config_new (void) {
111 111
   // set default values
112 112
 
113 113
   r->ETYPE              = ENC_TLS;
  114
+  r->PMODE              = SSL_SERVER;
114 115
   r->WRITE_IP_OCTET     = 0;
115 116
   r->WRITE_PROXY_LINE   = 0;
116 117
   r->CHROOT             = NULL;
@@ -856,6 +857,7 @@ void config_print_usage_fd (char *prog, stud_config *cfg, FILE *out) {
856 857
   fprintf(out, "\n");
857 858
   fprintf(out, "SOCKET:\n");
858 859
   fprintf(out, "\n");
  860
+  fprintf(out, "  --client                    Enable client proxy mode\n");
859 861
   fprintf(out, "  -b  --backend=HOST,PORT     Backend [connect] (default is \"%s\")\n", config_disp_hostport(cfg->BACK_IP, cfg->BACK_PORT));
860 862
   fprintf(out, "  -f  --frontend=HOST,PORT    Frontend [bind] (default is \"%s\")\n", config_disp_hostport(cfg->FRONT_IP, cfg->FRONT_PORT));
861 863
 
@@ -1096,6 +1098,7 @@ void config_print_usage (char *prog, stud_config *cfg) {
1096 1098
 
1097 1099
 void config_parse_cli(int argc, char **argv, stud_config *cfg) {
1098 1100
   static int tls = 0, ssl = 0;
  1101
+  static int client = 0;
1099 1102
   int c;
1100 1103
   int test_only = 0;
1101 1104
   char *prog;
@@ -1108,6 +1111,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) {
1108 1111
     
1109 1112
     { "tls", 0, &tls, 1},
1110 1113
     { "ssl", 0, &ssl, 1},    
  1114
+    { "client", 0, &client, 1},    
1111 1115
     { CFG_CIPHERS, 1, NULL, 'c' },
1112 1116
     { CFG_PREFER_SERVER_CIPHERS, 0, NULL, 'O' },
1113 1117
     { CFG_BACKEND, 1, NULL, 'b' },
@@ -1245,6 +1249,10 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) {
1245 1249
       cfg->ETYPE = ENC_TLS;
1246 1250
   }
1247 1251
 
  1252
+  if (client) {
  1253
+      cfg->PMODE = SSL_CLIENT;
  1254
+  }
  1255
+
1248 1256
   if (cfg->WRITE_IP_OCTET && cfg->WRITE_PROXY_LINE)
1249 1257
     config_die("Options --write-ip and --write-proxy are mutually exclusive.");
1250 1258
 
@@ -1263,7 +1271,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) {
1263 1271
   argv += optind;
1264 1272
   if (argv != NULL && argv[0] != NULL)
1265 1273
     config_param_validate(CFG_PEM_FILE, argv[0], cfg, NULL, 0);
1266  
-  else if (cfg->CERT_FILE == NULL || strlen(cfg->CERT_FILE) < 1)
  1274
+  else if ((cfg->PMODE == SSL_SERVER) && (cfg->CERT_FILE == NULL || strlen(cfg->CERT_FILE) < 1))
1267 1275
     config_die("No x509 certificate PEM file specified!");
1268 1276
   
1269 1277
   // was this only a test?
6  configuration.h
@@ -26,9 +26,15 @@ typedef enum {
26 26
     ENC_SSL
27 27
 } ENC_TYPE;
28 28
 
  29
+typedef enum {
  30
+    SSL_SERVER,
  31
+    SSL_CLIENT
  32
+} PROXY_MODE;
  33
+
29 34
 /* configuration structure */
30 35
 struct __stud_config {
31 36
     ENC_TYPE ETYPE;
  37
+    PROXY_MODE PMODE;
32 38
     int WRITE_IP_OCTET;
33 39
     int WRITE_PROXY_LINE;
34 40
     char *CHROOT;
475  stud.c
@@ -89,6 +89,7 @@ static int listener_socket;
89 89
 static int child_num;
90 90
 static pid_t *child_pids;
91 91
 static SSL_CTX *ssl_ctx;
  92
+static SSL_SESSION *client_session;
92 93
 
93 94
 #ifdef USE_SHARED_CACHE
94 95
 static ev_io shcupd_listener;
@@ -113,8 +114,8 @@ static char tcp_proxy_line[128] = "";
113 114
  * handling */
114 115
 typedef enum _SHUTDOWN_REQUESTOR {
115 116
     SHUTDOWN_HARD,
116  
-    SHUTDOWN_DOWN,
117  
-    SHUTDOWN_UP
  117
+    SHUTDOWN_CLEAR,
  118
+    SHUTDOWN_SSL
118 119
 } SHUTDOWN_REQUESTOR;
119 120
 
120 121
 /*
@@ -123,23 +124,26 @@ typedef enum _SHUTDOWN_REQUESTOR {
123 124
  * All state associated with one proxied connection
124 125
  */
125 126
 typedef struct proxystate {
126  
-    ringbuffer ring_down; /* pushing bytes from client to backend */
127  
-    ringbuffer ring_up;   /* pushing bytes from backend to client */
  127
+    ringbuffer ring_ssl2clear; /* pushing bytes from secure to clear stream */
  128
+    ringbuffer ring_clear2ssl; /* pushing bytes from clear to secure stream */
128 129
 
129  
-    ev_io ev_r_up;        /* Upstream write event */
130  
-    ev_io ev_w_up;        /* Upstream read event */
  130
+    ev_io ev_r_ssl;        /* secure stream write event */
  131
+    ev_io ev_w_ssl;        /* secure stream read event */
131 132
 
132  
-    ev_io ev_r_handshake; /* Downstream write event */
133  
-    ev_io ev_w_handshake; /* Downstream read event */
  133
+    ev_io ev_r_handshake; /* secure stream handshake write event */
  134
+    ev_io ev_w_handshake; /* secure stream handshake read event */
134 135
 
135  
-    ev_io ev_r_down;      /* Downstream write event */
136  
-    ev_io ev_w_down;      /* Downstream read event */
  136
+    ev_io ev_w_connect;    /* backend connect event */
  137
+
  138
+    ev_io ev_r_clear;      /* clear stream write event */
  139
+    ev_io ev_w_clear;      /* clear stream read event */
137 140
 
138 141
     int fd_up;            /* Upstream (client) socket */
139 142
     int fd_down;          /* Downstream (backend) socket */
140 143
 
141 144
     int want_shutdown:1;  /* Connection is half-shutdown */
142 145
     int handshaked:1;     /* Initial handshake happened */
  146
+    int clear_connected:1; /* clear stream is connected  */
143 147
     int renegotiation:1;  /* Renegotation is occuring */
144 148
 
145 149
     SSL *ssl;             /* OpenSSL SSL state */
@@ -541,9 +545,9 @@ SSL_CTX * init_openssl() {
541 545
             SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
542 546
 
543 547
     if (CONFIG->ETYPE == ENC_TLS)
544  
-        ctx = SSL_CTX_new(TLSv1_server_method());
  548
+        ctx = SSL_CTX_new((CONFIG->PMODE == SSL_CLIENT) ? TLSv1_client_method() : TLSv1_server_method());
545 549
     else if (CONFIG->ETYPE == ENC_SSL)
546  
-        ctx = SSL_CTX_new(SSLv23_server_method());
  550
+        ctx = SSL_CTX_new((CONFIG->PMODE == SSL_CLIENT) ? SSLv23_client_method() : SSLv23_server_method());
547 551
     else
548 552
         assert(CONFIG->ETYPE == ENC_TLS || CONFIG->ETYPE == ENC_SSL);
549 553
 
@@ -554,26 +558,6 @@ SSL_CTX * init_openssl() {
554 558
     SSL_CTX_set_options(ctx, ssloptions);
555 559
     SSL_CTX_set_info_callback(ctx, info_callback);
556 560
 
557  
-    if (SSL_CTX_use_certificate_chain_file(ctx, CONFIG->CERT_FILE) <= 0) {
558  
-        ERR_print_errors_fp(stderr);
559  
-        exit(1);
560  
-    }
561  
-
562  
-    rsa = load_rsa_privatekey(ctx, CONFIG->CERT_FILE);
563  
-    if(!rsa) {
564  
-       ERR("Error loading rsa private key\n");
565  
-       exit(1);
566  
-    }
567  
-
568  
-    if (SSL_CTX_use_RSAPrivateKey(ctx,rsa) <= 0) {
569  
-        ERR_print_errors_fp(stderr);
570  
-        exit(1);
571  
-    }
572  
-
573  
-#ifndef OPENSSL_NO_DH
574  
-    init_dh(ctx, CONFIG->CERT_FILE);
575  
-#endif /* OPENSSL_NO_DH */
576  
-
577 561
     if (CONFIG->ENGINE) {
578 562
         ENGINE *e = NULL;
579 563
         ENGINE_load_builtin_engines();
@@ -599,6 +583,31 @@ SSL_CTX * init_openssl() {
599 583
     if (CONFIG->PREFER_SERVER_CIPHERS)
600 584
         SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
601 585
 
  586
+
  587
+    if (CONFIG->PMODE == SSL_CLIENT)
  588
+        return ctx;
  589
+
  590
+    /* SSL_SERVER Mode stuff */
  591
+    if (SSL_CTX_use_certificate_chain_file(ctx, CONFIG->CERT_FILE) <= 0) {
  592
+        ERR_print_errors_fp(stderr);
  593
+        exit(1);
  594
+    }
  595
+
  596
+    rsa = load_rsa_privatekey(ctx, CONFIG->CERT_FILE);
  597
+    if(!rsa) {
  598
+       ERR("Error loading rsa private key\n");
  599
+       exit(1);
  600
+    }
  601
+
  602
+    if (SSL_CTX_use_RSAPrivateKey(ctx,rsa) <= 0) {
  603
+        ERR_print_errors_fp(stderr);
  604
+        exit(1);
  605
+    }
  606
+
  607
+#ifndef OPENSSL_NO_DH
  608
+    init_dh(ctx, CONFIG->CERT_FILE);
  609
+#endif /* OPENSSL_NO_DH */
  610
+
602 611
 #ifdef USE_SHARED_CACHE
603 612
     if (CONFIG->SHARED_CACHE) {
604 613
         if (shared_context_init(ctx, CONFIG->SHARED_CACHE) < 0) {
@@ -712,16 +721,9 @@ static int create_back_socket() {
712 721
     if (ret == -1) {
713 722
       perror("Couldn't setsockopt to backend (TCP_NODELAY)\n");
714 723
     }
715  
-
716  
-    int t = 1;
717 724
     setnonblocking(s);
718  
-    t = connect(s, backaddr->ai_addr, backaddr->ai_addrlen);
719  
-    if (t == 0 || errno == EINPROGRESS || errno == EINTR)
720  
-        return s;
721  
-
722  
-    perror("{backend-connect}");
723 725
 
724  
-    return -1;
  726
+    return s;
725 727
 }
726 728
 
727 729
 /* Only enable a libev ev_io event if the proxied connection still
@@ -735,12 +737,13 @@ static void safe_enable_io(proxystate *ps, ev_io *w) {
735 737
  * has both up and down connected */
736 738
 static void shutdown_proxy(proxystate *ps, SHUTDOWN_REQUESTOR req) {
737 739
     if (ps->want_shutdown || req == SHUTDOWN_HARD) {
738  
-        ev_io_stop(loop, &ps->ev_w_up);
739  
-        ev_io_stop(loop, &ps->ev_r_up);
  740
+        ev_io_stop(loop, &ps->ev_w_ssl);
  741
+        ev_io_stop(loop, &ps->ev_r_ssl);
740 742
         ev_io_stop(loop, &ps->ev_w_handshake);
741 743
         ev_io_stop(loop, &ps->ev_r_handshake);
742  
-        ev_io_stop(loop, &ps->ev_w_down);
743  
-        ev_io_stop(loop, &ps->ev_r_down);
  744
+        ev_io_stop(loop, &ps->ev_w_connect);
  745
+        ev_io_stop(loop, &ps->ev_w_clear);
  746
+        ev_io_stop(loop, &ps->ev_r_clear);
744 747
 
745 748
         close(ps->fd_up);
746 749
         close(ps->fd_down);
@@ -752,94 +755,105 @@ static void shutdown_proxy(proxystate *ps, SHUTDOWN_REQUESTOR req) {
752 755
     }
753 756
     else {
754 757
         ps->want_shutdown = 1;
755  
-        if (req == SHUTDOWN_DOWN && ringbuffer_is_empty(&ps->ring_up))
  758
+        if (req == SHUTDOWN_CLEAR && ringbuffer_is_empty(&ps->ring_clear2ssl))
756 759
             shutdown_proxy(ps, SHUTDOWN_HARD);
757  
-        else if (req == SHUTDOWN_UP && ringbuffer_is_empty(&ps->ring_down))
  760
+        else if (req == SHUTDOWN_SSL && ringbuffer_is_empty(&ps->ring_ssl2clear))
758 761
             shutdown_proxy(ps, SHUTDOWN_HARD);
759 762
     }
760 763
 }
761 764
 
762 765
 /* Handle various socket errors */
763  
-static void handle_socket_errno(proxystate *ps) {
  766
+static void handle_socket_errno(proxystate *ps, int backend) {
764 767
     if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
765 768
         return;
766 769
 
767 770
     if (errno == ECONNRESET)
768  
-        ERR("{backend} Connection reset by peer\n");
  771
+        ERR("{%s} Connection reset by peer\n", backend ? "backend" : "client");
769 772
     else if (errno == ETIMEDOUT)
770  
-        ERR("{backend} Connection to backend timed out\n");
  773
+        ERR("{%s} Connection to backend timed out\n", backend ? "backend" : "client");
771 774
     else if (errno == EPIPE)
772  
-        ERR("{backend} Broken pipe to backend (EPIPE)\n");
  775
+        ERR("{%s} Broken pipe to backend (EPIPE)\n", backend ? "backend" : "client");
773 776
     else
774 777
         perror("{backend} [errno]");
775  
-    shutdown_proxy(ps, SHUTDOWN_DOWN);
  778
+    shutdown_proxy(ps, SHUTDOWN_CLEAR);
  779
+}
  780
+/* Start connect to backend */
  781
+static void start_connect(proxystate *ps) {
  782
+    int t = 1;
  783
+    t = connect(ps->fd_down, backaddr->ai_addr, backaddr->ai_addrlen);
  784
+    if (t == 0 || errno == EINPROGRESS || errno == EINTR) {
  785
+        ev_io_start(loop, &ps->ev_w_connect);
  786
+        return ;
  787
+    }
  788
+    perror("{backend-connect}");
  789
+    shutdown_proxy(ps, SHUTDOWN_HARD);
776 790
 }
777 791
 
778 792
 /* Read some data from the backend when libev says data is available--
779 793
  * write it into the upstream buffer and make sure the write event is
780 794
  * enabled for the upstream socket */
781  
-static void back_read(struct ev_loop *loop, ev_io *w, int revents) {
  795
+static void clear_read(struct ev_loop *loop, ev_io *w, int revents) {
782 796
     (void) revents;
783 797
     int t;
784 798
     proxystate *ps = (proxystate *)w->data;
785 799
     if (ps->want_shutdown) {
786  
-        ev_io_stop(loop, &ps->ev_r_down);
  800
+        ev_io_stop(loop, &ps->ev_r_clear);
787 801
         return;
788 802
     }
789 803
     int fd = w->fd;
790  
-    char * buf = ringbuffer_write_ptr(&ps->ring_up);
  804
+    char * buf = ringbuffer_write_ptr(&ps->ring_clear2ssl);
791 805
     t = recv(fd, buf, RING_DATA_LEN, 0);
792 806
 
793 807
     if (t > 0) {
794  
-        ringbuffer_write_append(&ps->ring_up, t);
795  
-        if (ringbuffer_is_full(&ps->ring_up))
796  
-            ev_io_stop(loop, &ps->ev_r_down);
  808
+        ringbuffer_write_append(&ps->ring_clear2ssl, t);
  809
+        if (ringbuffer_is_full(&ps->ring_clear2ssl))
  810
+            ev_io_stop(loop, &ps->ev_r_clear);
797 811
         if (ps->handshaked)
798  
-            safe_enable_io(ps, &ps->ev_w_up);
  812
+            safe_enable_io(ps, &ps->ev_w_ssl);
799 813
     }
800 814
     else if (t == 0) {
801  
-        LOG("{backend} Connection closed\n");
802  
-        shutdown_proxy(ps, SHUTDOWN_DOWN);
  815
+        LOG("{%s} Connection closed\n", fd == ps->fd_down ? "backend" : "client");
  816
+        shutdown_proxy(ps, SHUTDOWN_CLEAR);
803 817
     }
804 818
     else {
805 819
         assert(t == -1);
806  
-        handle_socket_errno(ps);
  820
+        handle_socket_errno(ps, fd == ps->fd_down ? 1 : 0);
807 821
     }
808 822
 }
809 823
 /* Write some data, previously received on the secure upstream socket,
810 824
  * out of the downstream buffer and onto the backend socket */
811  
-static void back_write(struct ev_loop *loop, ev_io *w, int revents) {
  825
+static void clear_write(struct ev_loop *loop, ev_io *w, int revents) {
812 826
     (void) revents;
813 827
     int t;
814 828
     proxystate *ps = (proxystate *)w->data;
815 829
     int fd = w->fd;
816 830
     int sz;
817 831
 
818  
-    assert(!ringbuffer_is_empty(&ps->ring_down));
  832
+    assert(!ringbuffer_is_empty(&ps->ring_ssl2clear));
819 833
 
820  
-    char *next = ringbuffer_read_next(&ps->ring_down, &sz);
  834
+    char *next = ringbuffer_read_next(&ps->ring_ssl2clear, &sz);
821 835
     t = send(fd, next, sz, MSG_NOSIGNAL);
822 836
 
823 837
     if (t > 0) {
824 838
         if (t == sz) {
825  
-            ringbuffer_read_pop(&ps->ring_down);
  839
+            ringbuffer_read_pop(&ps->ring_ssl2clear);
826 840
             if (ps->handshaked)
827  
-                safe_enable_io(ps, &ps->ev_r_up);
828  
-            if (ringbuffer_is_empty(&ps->ring_down)) {
  841
+                safe_enable_io(ps, &ps->ev_r_ssl);
  842
+            if (ringbuffer_is_empty(&ps->ring_ssl2clear)) {
829 843
                 if (ps->want_shutdown) {
830 844
                     shutdown_proxy(ps, SHUTDOWN_HARD);
831 845
                     return; // dealloc'd
832 846
                 }
833  
-                ev_io_stop(loop, &ps->ev_w_down);
  847
+                ev_io_stop(loop, &ps->ev_w_clear);
834 848
             }
835 849
         }
836 850
         else {
837  
-            ringbuffer_read_skip(&ps->ring_down, t);
  851
+            ringbuffer_read_skip(&ps->ring_ssl2clear, t);
838 852
         }
839 853
     }
840 854
     else {
841 855
         assert(t == -1);
842  
-        handle_socket_errno(ps);
  856
+        handle_socket_errno(ps, fd == ps->fd_down ? 1 : 0);
843 857
     }
844 858
 }
845 859
 
@@ -851,57 +865,25 @@ static void handle_connect(struct ev_loop *loop, ev_io *w, int revents) {
851 865
     (void) revents;
852 866
     int t;
853 867
     proxystate *ps = (proxystate *)w->data;
854  
-    char tcp6_address_string[INET6_ADDRSTRLEN];
855  
-    size_t written = 0;
856 868
     t = connect(ps->fd_down, backaddr->ai_addr, backaddr->ai_addrlen);
857 869
     if (!t || errno == EISCONN || !errno) {
858  
-        /* INIT */
859  
-        ev_io_stop(loop, &ps->ev_w_down);
860  
-        ev_io_init(&ps->ev_r_down, back_read, ps->fd_down, EV_READ);
861  
-        ev_io_init(&ps->ev_w_down, back_write, ps->fd_down, EV_WRITE);
862  
-        start_handshake(ps, SSL_ERROR_WANT_READ); /* for client-first handshake */
863  
-        ev_io_start(loop, &ps->ev_r_down);
864  
-        if (CONFIG->WRITE_PROXY_LINE) {
865  
-            char *ring_pnt = ringbuffer_write_ptr(&ps->ring_down);
866  
-            assert(ps->remote_ip.ss_family == AF_INET ||
867  
-		   ps->remote_ip.ss_family == AF_INET6);
868  
-	    if(ps->remote_ip.ss_family == AF_INET) {
869  
-	      struct sockaddr_in* addr = (struct sockaddr_in*)&ps->remote_ip;
870  
-	      written = snprintf(ring_pnt,
871  
-				 RING_DATA_LEN,
872  
-				 tcp_proxy_line,
873  
-				 "TCP4",
874  
-				 inet_ntoa(addr->sin_addr),
875  
-				 ntohs(addr->sin_port));
876  
-	    }
877  
-	    else if (ps->remote_ip.ss_family == AF_INET6) {
878  
-	      struct sockaddr_in6* addr = (struct sockaddr_in6*)&ps->remote_ip;
879  
-	      inet_ntop(AF_INET6,&(addr->sin6_addr),tcp6_address_string,INET6_ADDRSTRLEN);
880  
-	      written = snprintf(ring_pnt,
881  
-				 RING_DATA_LEN,
882  
-				 tcp_proxy_line,
883  
-				 "TCP6",
884  
-				 tcp6_address_string,
885  
-				 ntohs(addr->sin6_port));
886  
-	    }   
887  
-            ringbuffer_write_append(&ps->ring_down, written);
888  
-            ev_io_start(loop, &ps->ev_w_down);
  870
+        ev_io_stop(loop, &ps->ev_w_connect);
  871
+
  872
+        if (!ps->clear_connected) {
  873
+            ps->clear_connected = 1;
  874
+
  875
+            /* if incoming buffer is not full */
  876
+            if (!ringbuffer_is_full(&ps->ring_clear2ssl))
  877
+                safe_enable_io(ps, &ps->ev_r_clear);
  878
+
  879
+            /* if outgoing buffer is not empty */
  880
+            if (!ringbuffer_is_empty(&ps->ring_ssl2clear))
  881
+                // not safe.. we want to resume stream even during half-closed
  882
+                ev_io_start(loop, &ps->ev_w_clear);
889 883
         }
890  
-        else if (CONFIG->WRITE_IP_OCTET) {
891  
-            char *ring_pnt = ringbuffer_write_ptr(&ps->ring_down);
892  
-            assert(ps->remote_ip.ss_family == AF_INET ||
893  
-                   ps->remote_ip.ss_family == AF_INET6);
894  
-            *ring_pnt++ = (unsigned char) ps->remote_ip.ss_family;
895  
-            if (ps->remote_ip.ss_family == AF_INET6) {
896  
-                memcpy(ring_pnt, &((struct sockaddr_in6 *) &ps->remote_ip)
897  
-                       ->sin6_addr.s6_addr, 16U);
898  
-                ringbuffer_write_append(&ps->ring_down, 1U + 16U);
899  
-            } else {
900  
-                memcpy(ring_pnt, &((struct sockaddr_in *) &ps->remote_ip)
901  
-                       ->sin_addr.s_addr, 4U);
902  
-                ringbuffer_write_append(&ps->ring_down, 1U + 4U);
903  
-            }
904  
-            ev_io_start(loop, &ps->ev_w_down);
  884
+        else {
  885
+            /* Clear side already connected so connect is on secure side: perform handshake */
  886
+            start_handshake(ps, SSL_ERROR_WANT_WRITE);
905 887
         }
906 888
     }
907 889
     else if (errno == EINPROGRESS || errno == EINTR || errno == EALREADY) {
@@ -916,8 +898,8 @@ static void handle_connect(struct ev_loop *loop, ev_io *w, int revents) {
916 898
 /* Upon receiving a signal from OpenSSL that a handshake is required, re-wire
917 899
  * the read/write events to hook up to the handshake handlers */
918 900
 static void start_handshake(proxystate *ps, int err) {
919  
-    ev_io_stop(loop, &ps->ev_r_up);
920  
-    ev_io_stop(loop, &ps->ev_w_up);
  901
+    ev_io_stop(loop, &ps->ev_r_ssl);
  902
+    ev_io_stop(loop, &ps->ev_w_ssl);
921 903
 
922 904
     ps->handshaked = 0;
923 905
 
@@ -930,6 +912,8 @@ static void start_handshake(proxystate *ps, int err) {
930 912
 /* After OpenSSL is done with a handshake, re-wire standard read/write handlers
931 913
  * for data transmission */
932 914
 static void end_handshake(proxystate *ps) {
  915
+    char tcp6_address_string[INET6_ADDRSTRLEN];
  916
+    size_t written = 0;
933 917
     ev_io_stop(loop, &ps->ev_r_handshake);
934 918
     ev_io_stop(loop, &ps->ev_w_handshake);
935 919
 
@@ -939,14 +923,69 @@ static void end_handshake(proxystate *ps) {
939 923
     }
940 924
     ps->handshaked = 1;
941 925
 
  926
+    /* Check if clear side is connected */
  927
+    if (!ps->clear_connected) {
  928
+        if (CONFIG->WRITE_PROXY_LINE) {
  929
+            char *ring_pnt = ringbuffer_write_ptr(&ps->ring_ssl2clear);
  930
+            assert(ps->remote_ip.ss_family == AF_INET ||
  931
+                   ps->remote_ip.ss_family == AF_INET6);
  932
+            if(ps->remote_ip.ss_family == AF_INET) {
  933
+               struct sockaddr_in* addr = (struct sockaddr_in*)&ps->remote_ip;
  934
+               written = snprintf(ring_pnt,
  935
+                                  RING_DATA_LEN,
  936
+                                  tcp_proxy_line,
  937
+                                  "TCP4",
  938
+                                  inet_ntoa(addr->sin_addr),
  939
+                                  ntohs(addr->sin_port));
  940
+               }
  941
+               else if (ps->remote_ip.ss_family == AF_INET6) {
  942
+                        struct sockaddr_in6* addr = (struct sockaddr_in6*)&ps->remote_ip;
  943
+                        inet_ntop(AF_INET6,&(addr->sin6_addr),tcp6_address_string,INET6_ADDRSTRLEN);
  944
+                        written = snprintf(ring_pnt,
  945
+                                  RING_DATA_LEN,
  946
+                                  tcp_proxy_line,
  947
+                                  "TCP6",
  948
+                                  tcp6_address_string,
  949
+                                  ntohs(addr->sin6_port));
  950
+            }   
  951
+            ringbuffer_write_append(&ps->ring_ssl2clear, written);
  952
+        }
  953
+        else if (CONFIG->WRITE_IP_OCTET) {
  954
+            char *ring_pnt = ringbuffer_write_ptr(&ps->ring_ssl2clear);
  955
+            assert(ps->remote_ip.ss_family == AF_INET ||
  956
+                   ps->remote_ip.ss_family == AF_INET6);
  957
+            *ring_pnt++ = (unsigned char) ps->remote_ip.ss_family;
  958
+            if (ps->remote_ip.ss_family == AF_INET6) {
  959
+                memcpy(ring_pnt, &((struct sockaddr_in6 *) &ps->remote_ip)
  960
+                       ->sin6_addr.s6_addr, 16U);
  961
+                ringbuffer_write_append(&ps->ring_ssl2clear, 1U + 16U);
  962
+            }
  963
+            else {
  964
+                memcpy(ring_pnt, &((struct sockaddr_in *) &ps->remote_ip)
  965
+                       ->sin_addr.s_addr, 4U);
  966
+                ringbuffer_write_append(&ps->ring_ssl2clear, 1U + 4U);
  967
+            }
  968
+        }
  969
+	/* start connect now */
  970
+        start_connect(ps);
  971
+    }
  972
+    else {
  973
+        /* stud used in client mode, keep client session ) */
  974
+        if (!SSL_session_reused(ps->ssl)) {
  975
+            if (client_session)
  976
+                SSL_SESSION_free(client_session);
  977
+            client_session = SSL_get1_session(ps->ssl);
  978
+        }
  979
+    }
  980
+
942 981
     /* if incoming buffer is not full */
943  
-    if (!ringbuffer_is_full(&ps->ring_down))
944  
-        safe_enable_io(ps, &ps->ev_r_up);
  982
+    if (!ringbuffer_is_full(&ps->ring_ssl2clear))
  983
+        safe_enable_io(ps, &ps->ev_r_ssl);
945 984
 
946 985
     /* if outgoing buffer is not empty */
947  
-    if (!ringbuffer_is_empty(&ps->ring_up))
  986
+    if (!ringbuffer_is_empty(&ps->ring_clear2ssl))
948 987
         // not safe.. we want to resume stream even during half-closed
949  
-        ev_io_start(loop, &ps->ev_w_up);
  988
+        ev_io_start(loop, &ps->ev_w_ssl);
950 989
 }
951 990
 
952 991
 /* The libev I/O handler during the OpenSSL handshake phase.  Basically, just
@@ -972,54 +1011,55 @@ static void client_handshake(struct ev_loop *loop, ev_io *w, int revents) {
972 1011
             ev_io_start(loop, &ps->ev_w_handshake);
973 1012
         }
974 1013
         else if (err == SSL_ERROR_ZERO_RETURN) {
975  
-            LOG("{client} Connection closed (in handshake)\n");
976  
-            shutdown_proxy(ps, SHUTDOWN_UP);
  1014
+            LOG("{%s} Connection closed (in handshake)\n", w->fd == ps->fd_up ? "client" : "backend");
  1015
+            shutdown_proxy(ps, SHUTDOWN_SSL);
977 1016
         }
978 1017
         else {
979  
-            LOG("{client} Unexpected SSL error (in handshake): %d\n", err);
980  
-            shutdown_proxy(ps, SHUTDOWN_UP);
  1018
+            LOG("{%s} Unexpected SSL error (in handshake): %d\n", w->fd == ps->fd_up ? "client" : "backend", err);
  1019
+            shutdown_proxy(ps, SHUTDOWN_SSL);
981 1020
         }
982 1021
     }
983 1022
 }
984 1023
 
985 1024
 /* Handle a socket error condition passed to us from OpenSSL */
986  
-static void handle_fatal_ssl_error(proxystate *ps, int err) {
  1025
+static void handle_fatal_ssl_error(proxystate *ps, int err, int backend) {
987 1026
     if (err == SSL_ERROR_ZERO_RETURN)
988  
-        ERR("{client} Connection closed (in data)\n");
  1027
+        ERR("{%s} Connection closed (in data)\n", backend ? "backend" : "client");
989 1028
     else if (err == SSL_ERROR_SYSCALL)
990 1029
         if (errno == 0)
991  
-            ERR("{client} Connection closed (in data)\n");
  1030
+            ERR("{%s} Connection closed (in data)\n", backend ? "backend" : "client");
992 1031
         else
993  
-            perror("{client} [errno] ");
  1032
+            perror(backend ? "{backend} [errno] " : "{client} [errno] ");
994 1033
     else
995  
-        ERR("{client} Unexpected SSL_read error: %d\n", err);
996  
-    shutdown_proxy(ps, SHUTDOWN_UP);
  1034
+        ERR("{%s} Unexpected SSL_read error: %d\n", backend ? "backend" : "client" , err);
  1035
+    shutdown_proxy(ps, SHUTDOWN_SSL);
997 1036
 }
998 1037
 
999 1038
 /* Read some data from the upstream secure socket via OpenSSL,
1000 1039
  * and buffer anything we get for writing to the backend */
1001  
-static void client_read(struct ev_loop *loop, ev_io *w, int revents) {
  1040
+static void ssl_read(struct ev_loop *loop, ev_io *w, int revents) {
1002 1041
     (void) revents;
1003 1042
     int t;    
1004 1043
     proxystate *ps = (proxystate *)w->data;
1005 1044
     if (ps->want_shutdown) {
1006  
-        ev_io_stop(loop, &ps->ev_r_up);
  1045
+        ev_io_stop(loop, &ps->ev_r_ssl);
1007 1046
         return;
1008 1047
     }
1009  
-    char * buf = ringbuffer_write_ptr(&ps->ring_down);
  1048
+    char * buf = ringbuffer_write_ptr(&ps->ring_ssl2clear);
1010 1049
     t = SSL_read(ps->ssl, buf, RING_DATA_LEN);
1011 1050
 
1012 1051
     /* Fix CVE-2009-3555. Disable reneg if started by client. */
1013 1052
     if (ps->renegotiation) {
1014  
-        shutdown_proxy(ps, SHUTDOWN_UP);
  1053
+        shutdown_proxy(ps, SHUTDOWN_SSL);
1015 1054
         return;
1016 1055
     }
1017 1056
 
1018 1057
     if (t > 0) {
1019  
-        ringbuffer_write_append(&ps->ring_down, t);
1020  
-        if (ringbuffer_is_full(&ps->ring_down))
1021  
-            ev_io_stop(loop, &ps->ev_r_up);
1022  
-        safe_enable_io(ps, &ps->ev_w_down);
  1058
+        ringbuffer_write_append(&ps->ring_ssl2clear, t);
  1059
+        if (ringbuffer_is_full(&ps->ring_ssl2clear))
  1060
+            ev_io_stop(loop, &ps->ev_r_ssl);
  1061
+        if (ps->clear_connected)
  1062
+            safe_enable_io(ps, &ps->ev_w_clear);
1023 1063
     }
1024 1064
     else {
1025 1065
         int err = SSL_get_error(ps->ssl, t);
@@ -1028,34 +1068,35 @@ static void client_read(struct ev_loop *loop, ev_io *w, int revents) {
1028 1068
         }
1029 1069
         else if (err == SSL_ERROR_WANT_READ) { } /* incomplete SSL data */
1030 1070
         else
1031  
-            handle_fatal_ssl_error(ps, err);
  1071
+            handle_fatal_ssl_error(ps, err, w->fd == ps->fd_up ? 0 : 1);
1032 1072
     }
1033 1073
 }
1034 1074
 
1035 1075
 /* Write some previously-buffered backend data upstream on the
1036 1076
  * secure socket using OpenSSL */
1037  
-static void client_write(struct ev_loop *loop, ev_io *w, int revents) {
  1077
+static void ssl_write(struct ev_loop *loop, ev_io *w, int revents) {
1038 1078
     (void) revents;
1039 1079
     int t;
1040 1080
     int sz;
1041 1081
     proxystate *ps = (proxystate *)w->data;
1042  
-    assert(!ringbuffer_is_empty(&ps->ring_up));
1043  
-    char * next = ringbuffer_read_next(&ps->ring_up, &sz);
  1082
+    assert(!ringbuffer_is_empty(&ps->ring_clear2ssl));
  1083
+    char * next = ringbuffer_read_next(&ps->ring_clear2ssl, &sz);
1044 1084
     t = SSL_write(ps->ssl, next, sz);
1045 1085
     if (t > 0) {
1046 1086
         if (t == sz) {
1047  
-            ringbuffer_read_pop(&ps->ring_up);
1048  
-            safe_enable_io(ps, &ps->ev_r_down); // can be re-enabled b/c we've popped
1049  
-            if (ringbuffer_is_empty(&ps->ring_up)) {
  1087
+            ringbuffer_read_pop(&ps->ring_clear2ssl);
  1088
+            if (ps->clear_connected)
  1089
+                safe_enable_io(ps, &ps->ev_r_clear); // can be re-enabled b/c we've popped
  1090
+            if (ringbuffer_is_empty(&ps->ring_clear2ssl)) {
1050 1091
                 if (ps->want_shutdown) {
1051 1092
                     shutdown_proxy(ps, SHUTDOWN_HARD);
1052 1093
                     return;
1053 1094
                 }
1054  
-                ev_io_stop(loop, &ps->ev_w_up);
  1095
+                ev_io_stop(loop, &ps->ev_w_ssl);
1055 1096
             }
1056 1097
         }
1057 1098
         else {
1058  
-            ringbuffer_read_skip(&ps->ring_up, t);
  1099
+            ringbuffer_read_skip(&ps->ring_clear2ssl, t);
1059 1100
         }
1060 1101
     }
1061 1102
     else {
@@ -1065,7 +1106,7 @@ static void client_write(struct ev_loop *loop, ev_io *w, int revents) {
1065 1106
         }
1066 1107
         else if (err == SSL_ERROR_WANT_WRITE) {} /* incomplete SSL data */
1067 1108
         else
1068  
-            handle_fatal_ssl_error(ps, err);
  1109
+            handle_fatal_ssl_error(ps, err,  w->fd == ps->fd_up ? 0 : 1);
1069 1110
     }
1070 1111
 }
1071 1112
 
@@ -1074,6 +1115,7 @@ static void client_write(struct ev_loop *loop, ev_io *w, int revents) {
1074 1115
  * connecting to the backend */
1075 1116
 static void handle_accept(struct ev_loop *loop, ev_io *w, int revents) {
1076 1117
     (void) revents;
  1118
+    (void) loop;
1077 1119
     struct sockaddr_storage addr;
1078 1120
     socklen_t sl = sizeof(addr);
1079 1121
     int client = accept(w->fd, (struct sockaddr *) &addr, &sl);
@@ -1114,7 +1156,7 @@ static void handle_accept(struct ev_loop *loop, ev_io *w, int revents) {
1114 1156
 
1115 1157
     if (back == -1) {
1116 1158
         close(client);
1117  
-        perror("{backend-connect}");
  1159
+        perror("{backend-socket}");
1118 1160
         return;
1119 1161
     }
1120 1162
 
@@ -1134,33 +1176,37 @@ static void handle_accept(struct ev_loop *loop, ev_io *w, int revents) {
1134 1176
     ps->fd_down = back;
1135 1177
     ps->ssl = ssl;
1136 1178
     ps->want_shutdown = 0;
  1179
+    ps->clear_connected = 0;
1137 1180
     ps->handshaked = 0;
1138 1181
     ps->renegotiation = 0;
1139 1182
     ps->remote_ip = addr;
1140  
-    ringbuffer_init(&ps->ring_up);
1141  
-    ringbuffer_init(&ps->ring_down);
  1183
+    ringbuffer_init(&ps->ring_clear2ssl);
  1184
+    ringbuffer_init(&ps->ring_ssl2clear);
1142 1185
 
1143 1186
     /* set up events */
1144  
-    ev_io_init(&ps->ev_r_up, client_read, client, EV_READ);
1145  
-    ev_io_init(&ps->ev_w_up, client_write, client, EV_WRITE);
  1187
+    ev_io_init(&ps->ev_r_ssl, ssl_read, client, EV_READ);
  1188
+    ev_io_init(&ps->ev_w_ssl, ssl_write, client, EV_WRITE);
1146 1189
 
1147 1190
     ev_io_init(&ps->ev_r_handshake, client_handshake, client, EV_READ);
1148 1191
     ev_io_init(&ps->ev_w_handshake, client_handshake, client, EV_WRITE);
1149 1192
 
1150  
-    ev_io_init(&ps->ev_w_down, handle_connect, back, EV_WRITE);
1151  
-    ev_io_init(&ps->ev_r_down, back_read, back, EV_READ);
  1193
+    ev_io_init(&ps->ev_w_connect, handle_connect, back, EV_WRITE);
1152 1194
 
1153  
-    ev_io_start(loop, &ps->ev_w_down);
  1195
+    ev_io_init(&ps->ev_w_clear, clear_write, back, EV_WRITE);
  1196
+    ev_io_init(&ps->ev_r_clear, clear_read, back, EV_READ);
1154 1197
 
1155  
-    ps->ev_r_up.data = ps;
1156  
-    ps->ev_w_up.data = ps;
1157  
-    ps->ev_r_down.data = ps;
1158  
-    ps->ev_w_down.data = ps;
  1198
+    ps->ev_r_ssl.data = ps;
  1199
+    ps->ev_w_ssl.data = ps;
  1200
+    ps->ev_r_clear.data = ps;
  1201
+    ps->ev_w_clear.data = ps;
  1202
+    ps->ev_w_connect.data = ps;
1159 1203
     ps->ev_r_handshake.data = ps;
1160 1204
     ps->ev_w_handshake.data = ps;
1161 1205
 
1162 1206
     /* Link back proxystate to SSL state */
1163 1207
     SSL_set_app_data(ssl, ps);
  1208
+
  1209
+    start_handshake(ps, SSL_ERROR_WANT_READ); /* for client-first handshake */
1164 1210
 }
1165 1211
 
1166 1212
 
@@ -1176,6 +1222,105 @@ static void check_ppid(struct ev_loop *loop, ev_timer *w, int revents) {
1176 1222
 
1177 1223
 }
1178 1224
 
  1225
+static void handle_clear_accept(struct ev_loop *loop, ev_io *w, int revents) {
  1226
+    (void) revents;
  1227
+    (void) loop;
  1228
+    struct sockaddr_storage addr;
  1229
+    socklen_t sl = sizeof(addr);
  1230
+    int client = accept(w->fd, (struct sockaddr *) &addr, &sl);
  1231
+    if (client == -1) {
  1232
+        switch (errno) {
  1233
+        case EMFILE:
  1234
+            ERR("{client} accept() failed; too many open files for this process\n");
  1235
+            break;
  1236
+
  1237
+        case ENFILE:
  1238
+            ERR("{client} accept() failed; too many open files for this system\n");
  1239
+            break;
  1240
+
  1241
+        default:
  1242
+            assert(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN);
  1243
+            break;
  1244
+        }
  1245
+        return;
  1246
+    }
  1247
+
  1248
+    int flag = 1;
  1249
+    int ret = setsockopt(client, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) );
  1250
+    if (ret == -1) {
  1251
+      perror("Couldn't setsockopt on client (TCP_NODELAY)\n");
  1252
+    }
  1253
+#ifdef TCP_CWND
  1254
+    int cwnd = 10;
  1255
+    ret = setsockopt(client, IPPROTO_TCP, TCP_CWND, &cwnd, sizeof(cwnd));
  1256
+    if (ret == -1) {
  1257
+      perror("Couldn't setsockopt on client (TCP_CWND)\n");
  1258
+    }
  1259
+#endif
  1260
+
  1261
+    setnonblocking(client);
  1262
+    settcpkeepalive(client);
  1263
+
  1264
+    int back = create_back_socket();
  1265
+
  1266
+    if (back == -1) {
  1267
+        close(client);
  1268
+        perror("{backend-socket}");
  1269
+        return;
  1270
+    }
  1271
+
  1272
+    SSL_CTX * ctx = (SSL_CTX *)w->data;
  1273
+    SSL *ssl = SSL_new(ctx);
  1274
+    long mode = SSL_MODE_ENABLE_PARTIAL_WRITE;
  1275
+#ifdef SSL_MODE_RELEASE_BUFFERS
  1276
+    mode |= SSL_MODE_RELEASE_BUFFERS;
  1277
+#endif
  1278
+    SSL_set_mode(ssl, mode);
  1279
+    SSL_set_connect_state(ssl);
  1280
+    SSL_set_fd(ssl, back);
  1281
+    if (client_session)
  1282
+        SSL_set_session(ssl, client_session);
  1283
+
  1284
+    proxystate *ps = (proxystate *)malloc(sizeof(proxystate));
  1285
+
  1286
+    ps->fd_up = client;
  1287
+    ps->fd_down = back;
  1288
+    ps->ssl = ssl;
  1289
+    ps->want_shutdown = 0;
  1290
+    ps->clear_connected = 1;
  1291
+    ps->handshaked = 0;
  1292
+    ps->renegotiation = 0;
  1293
+    ps->remote_ip = addr;
  1294
+    ringbuffer_init(&ps->ring_clear2ssl);
  1295
+    ringbuffer_init(&ps->ring_ssl2clear);
  1296
+
  1297
+    /* set up events */
  1298
+    ev_io_init(&ps->ev_r_clear, clear_read, client, EV_READ);
  1299
+    ev_io_init(&ps->ev_w_clear, clear_write, client, EV_WRITE);
  1300
+
  1301
+    ev_io_init(&ps->ev_w_connect, handle_connect, back, EV_WRITE);
  1302
+
  1303
+    ev_io_init(&ps->ev_r_handshake, client_handshake, back, EV_READ);
  1304
+    ev_io_init(&ps->ev_w_handshake, client_handshake, back, EV_WRITE);
  1305
+
  1306
+
  1307
+    ev_io_init(&ps->ev_w_ssl, ssl_write, back, EV_WRITE);
  1308
+    ev_io_init(&ps->ev_r_ssl, ssl_read, back, EV_READ);
  1309
+
  1310
+    ps->ev_r_ssl.data = ps;
  1311
+    ps->ev_w_ssl.data = ps;
  1312
+    ps->ev_r_clear.data = ps;
  1313
+    ps->ev_w_clear.data = ps;
  1314
+    ps->ev_w_connect.data = ps;
  1315
+    ps->ev_r_handshake.data = ps;
  1316
+    ps->ev_w_handshake.data = ps;
  1317
+
  1318
+    /* Link back proxystate to SSL state */
  1319
+    SSL_set_app_data(ssl, ps);
  1320
+
  1321
+    ev_io_start(loop, &ps->ev_r_clear);
  1322
+    start_connect(ps); /* start connect */
  1323
+}
1179 1324
 
1180 1325
 /* Set up the child (worker) process including libev event loop, read event
1181 1326
  * on the bound socket, etc */
@@ -1204,7 +1349,7 @@ static void handle_connections() {
1204 1349
     ev_timer_init(&timer_ppid_check, check_ppid, 1.0, 1.0);
1205 1350
     ev_timer_start(loop, &timer_ppid_check);
1206 1351
 
1207  
-    ev_io_init(&listener, handle_accept, listener_socket, EV_READ);
  1352
+    ev_io_init(&listener, (CONFIG->PMODE == SSL_CLIENT) ? handle_clear_accept : handle_accept, listener_socket, EV_READ);
1208 1353
     listener.data = ssl_ctx;
1209 1354
     ev_io_start(loop, &listener);
1210 1355
 

0 notes on commit 84797cc

Please sign in to comment.
Something went wrong with that request. Please try again.