Hi list,

attached is the announced patch to support ssl-enabled inter-box
connections and various ssl specific (potential) bug fixes.

General changes:

  * supporing ssl-enabled connections between bearerbox and
[smsbox|wapbox]
  * various additional ssl configuration checking
  * changed the status page to show also ssl-enabled connections
 
(for details have a look in the ChangeLog section, as far as you have
time :))

Could the SSL coders around have a review on this, please. If there
are no objections, I will commit the patch to CVS in a coupld of
hours.

Stipe

[EMAIL PROTECTED]
-------------------------------------------------------------------
Wapme Systems AG

Münsterstr. 248
40470 Düsseldorf

Tel: +49-211-74845-0
Fax: +49-211-74845-299

E-Mail: [EMAIL PROTECTED]
Internet: http://www.wapme-systems.de
-------------------------------------------------------------------
wapme.net - wherever you are
diff -urN gateway/ChangeLog gateway-new/ChangeLog
--- gateway/ChangeLog   Thu Dec 20 15:46:29 2001
+++ gateway-new/ChangeLog       Thu Dec 20 19:21:38 2001
@@ -1,3 +1,45 @@
+2001-12-20  Stipe Tolj  <[EMAIL PROTECTED]>
+    * doc/userguide/userguide.xml: added documentation for the introduced
+      configuration directives "smsbox-port-ssl" and "wapbox-port-ssl" in
+      the core group.
+    * gw/bb_boxc.c: added parameters for calling ssl-enabled box connection
+      using boolean configuration directives "smsbox-port-ssl" for bearerbox
+      to smsbox communication and "wapbox-port-ssl" for bearerbox to wapbox
+      communication. Changed the way boxc_status() displays the current 
+      status of kannel's boxes, including ssl information for internal conn.
+    * gw/bb_http.c: Commented out call to use_global_server_certkey_file()
+      within httpadmin_start(), this is now done globaly by conn_config_ssl().    
+    * gw/bearerbox.c: added checking in starter() if corresponding cert and 
+      key files are specified in the conf file for ssl-enabled inter-box 
+      connections. Changed the way the status is displayed.
+    * gw/shared.c: added OpenSSL version string within widely used 
+      version_report_string(). Added information that established inter-box
+      connections are ssl-enabled if so.
+    * gw/shared.h: changed declaration of connect_to_bearerbox() to include
+      ssl flag.
+    * gw/smsbox.c: added handling for "smsbox-port-ssl" conf directive.
+    * gw/wapbox.c: added handling for "wapbox-port-ssl" conf directive.
+    * gwlib/cfg.def: added "smsbox-port-ssl" and "wapbox-port-ssl" to allow
+      boolean configuration of ssl-enabled internal box connections.
+    * gwlib/conn.c: changed the way ssl connections are established in 
+      conn_wrap_fd() and checked. Fixes also a not previosly detected bug,
+      that causes non-ssl enabled connections on the same port as wanted 
+      for ssl, hence SSL_accept() = -1 was not handled correctly. Fixed
+      a potential (non-reported) bug in conn_destroy() that causes errors
+      if we call unlocked_write() in case of ssl-enabled connection.
+      Added function conn_get_ssl() to return the corresponding pointer.
+    * gwlib/conn.h: included declaration of conn_config_ssl() and 
+      conn_get_ssl().
+    * gwlib/gwlib.h: added header file inlusion for ssl.h.
+    * gwlib/http.c: added information to display if HTTP clients are using
+      ssl to connect to an ssl-enabled HTTP server.
+      Fixed potential bug if client_create() is called, but the previous
+      ssl-enabled conn_wrap_fd() has failed, now we check.
+    * gwlib/http.h: added response code for HTTP_BAD_REQUEST.
+    * gwlib/ssl.c: added file to hold all ssl specific code.
+    * gwlib/ssl.h: added file for declaration of all code implemented 
+      in ssl.c. 
+
 2001-12-20: Andreas Fink <[EMAIL PROTECTED]>
    * gw/smsc_emi2.c: fixed a problem resulting in timing out at high load.
    *gw/bb_smscconn.c, gw/msg-decl.h, gw/smsbox.c:
diff -urN gateway/doc/userguide/userguide.xml gateway-new/doc/userguide/userguide.xml
--- gateway/doc/userguide/userguide.xml Thu Dec 20 15:46:30 2001
+++ gateway-new/doc/userguide/userguide.xml     Thu Dec 20 16:47:28 2001
@@ -968,12 +968,34 @@
         As with admin-port, this can be anything you want. Must be set
         if you want to handle any SMS traffic.
      </entry></row>
+         
+        <row><entry><literal>smsbox-port-ssl (o)</literal></entry>
+     <entry>bool</entry>
+     <entry valign=bottom>
+            If set to true, the smsbox connection module will be SSL-enabled.
+                 Your smsboxes will have to connect using SSL to the bearerbox
+                 then. This is used to secure communication between bearerbox
+                 and smsboxes in case they are in seperate networks operated and
+                 the TCP communication is not secured on a lower network layer.
+                 Defaults to "no".
+     </entry></row>
 
     <row><entry><literal>wapbox-port (c)</literal></entry>
      <entry>port-number</entry>
      <entry valign=bottom>
         Like smsbox-port, but for wapbox-connections. If not set,
         Kannel cannot handle WAP traffic
+     </entry></row>
+
+        <row><entry><literal>wapbox-port-ssl (o)</literal></entry>
+     <entry>bool</entry>
+     <entry valign=bottom>
+            If set to true, the wapbox connection module will be SSL-enabled.
+                 Your wapboxes will have to connect using SSL to the bearerbox
+                 then. This is used to secure communication between bearerbox
+                 and wapboxes in case they are in seperate networks operated and
+                 the TCP communication is not secured on a lower network layer.
+                 Defaults to "no".
      </entry></row>
 
     <row><entry><literal>box-deny-ip</literal></entry>
diff -urN gateway/gw/bb_boxc.c gateway-new/gw/bb_boxc.c
--- gateway/gw/bb_boxc.c        Fri Oct 19 02:44:21 2001
+++ gateway-new/gw/bb_boxc.c    Thu Dec 20 18:11:30 2001
@@ -42,7 +42,9 @@
 static List    *smsbox_list = NULL;
 
 static long    smsbox_port;
+static int smsbox_port_ssl = 0;
 static long    wapbox_port;
+static int wapbox_port_ssl = 0;
 
 static Octstr *box_allow_ip;
 static Octstr *box_deny_ip;
@@ -250,14 +252,14 @@
  */
 
 
-static Boxc *boxc_create(int fd, Octstr *ip)
+static Boxc *boxc_create(int fd, Octstr *ip, int ssl)
 {
     Boxc *boxc;
     
     boxc = gw_malloc(sizeof(Boxc));
     boxc->is_wap = 0;
     boxc->load = 0;
-    boxc->conn = conn_wrap_fd(fd, 0);
+    boxc->conn = conn_wrap_fd(fd, ssl);
     boxc->id = boxid++;                /* XXX  MUTEX! fix later... */
     boxc->client_ip = ip;
     boxc->alive = 1;
@@ -280,7 +282,7 @@
 
 
 
-static Boxc *accept_boxc(int fd)
+static Boxc *accept_boxc(int fd, int ssl)
 {
     Boxc *newconn;
     Octstr *ip;
@@ -303,9 +305,20 @@
        octstr_destroy(ip);
        return NULL;
     }
-    newconn = boxc_create(newfd, ip);
+    newconn = boxc_create(newfd, ip, ssl);
     
-    info(0, "Client connected from <%s>", octstr_get_cstr(ip));
+    /*
+     * check if the SSL handshake was successfull, otherwise
+     * this is no valid box connection any more
+     */
+    if (ssl && !conn_get_ssl(newconn->conn))
+        return NULL;
+
+    if (ssl)
+        info(0, "Client connected from <%s> using SSL", octstr_get_cstr(ip));
+    else
+        info(0, "Client connected from <%s>", octstr_get_cstr(ip));
+        
 
     /* XXX TODO: do the hand-shake, baby, yeah-yeah! */
 
@@ -322,7 +335,7 @@
     
     list_add_producer(flow_threads);
     fd = (int)arg;
-    newconn = accept_boxc(fd);
+    newconn = accept_boxc(fd, smsbox_port_ssl);
     if (newconn == NULL) {
        list_remove_producer(flow_threads);
        return;
@@ -363,7 +376,7 @@
 
     list_add_producer(flow_threads);
     fd = (int)arg;
-    newconn = accept_boxc(fd);
+    newconn = accept_boxc(fd, wapbox_port_ssl);
     if (newconn == NULL) {
        list_remove_producer(flow_threads);
        return;
@@ -721,6 +734,13 @@
        error(0, "Missing smsbox-port variable, cannot start smsboxes");
        return -1;
     }
+#ifdef HAVE_LIBSSL
+    cfg_get_bool(&smsbox_port_ssl, grp, octstr_imm("smsbox-port-ssl"));
+#endif /* HAVE_LIBSSL */
+
+    if (smsbox_port_ssl)
+        debug("bb", 0, "smsbox connection module is SSL-enabled");
+
     
     smsbox_list = list_create();       /* have a list of connections */
     list_add_producer(outgoing_sms);
@@ -761,6 +781,10 @@
        error(0, "Missing wapbox-port variable, cannot start WAP");
        return -1;
     }
+#ifdef HAVE_LIBSSL
+    cfg_get_bool(&wapbox_port_ssl, grp, octstr_imm("wapbox-port-ssl"));
+#endif /* HAVE_LIBSSL */
+  
     box_allow_ip = cfg_get(grp, octstr_imm("box-allow-ip"));
     if (box_allow_ip == NULL)
        box_allow_ip = octstr_create("");
@@ -830,15 +854,28 @@
            t = orig - bi->connect_time;
             if (status_type == BBSTATUS_XML)
                octstr_format_append(tmp,
-                   "<box>\n\t\t<type>wapbox</type>\n\t\t<IP>%s</IP>\n\t\t<status>"
-                                 "on-line %ldd %ldh %ldm %lds</status>\n\t</box>\n",
+                   "<box>\n\t\t<type>wapbox</type>\n\t\t<IP>%s</IP>\n"
+            "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
+            "\t\t<ssl>%s</ssl>\n\t</box>\n",
                                 octstr_get_cstr(bi->client_ip),
-                                t/3600/24, t/3600%24, t/60%60, t%60);
+                                t/3600/24, t/3600%24, t/60%60, t%60,
+#ifdef HAVE_LIBSSL
+                 conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
+#else 
+                 "not installed"
+#endif
+                 );
             else
                octstr_format_append(tmp,
-                   "%swapbox %s (on-line %ldd %ldh %ldm %lds)%s",
+                   "%swapbox, IP %s (on-line %ldd %ldh %ldm %lds) %s %s",
                                 ws, octstr_get_cstr(bi->client_ip),
-                                t/3600/24, t/3600%24, t/60%60, t%60, lb);
+                                t/3600/24, t/3600%24, t/60%60, t%60, 
+#ifdef HAVE_LIBSSL
+                 conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
+#else
+                 "",
+#endif 
+                 lb);
            boxes++;
        }
        list_unlock(wapbox_list);
@@ -851,14 +888,27 @@
                continue;
            t = orig - bi->connect_time;
             if (status_type == BBSTATUS_XML)
-               octstr_format_append(tmp, 
"<box>\n\t\t<type>smsbox</type>\n\t\t<IP>%s</IP>\n\t\t<status>"
-                    "on-line %ldd %ldh %ldm %lds</status>\n\t\t</box>",
+               octstr_format_append(tmp, 
+"<box>\n\t\t<type>smsbox</type>\n\t\t<IP>%s</IP>\n"
+                    "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
+                    "\t\t<ssl>%s</ssl>\n\t</box>",
                    octstr_get_cstr(bi->client_ip),
-                   t/3600/24, t/3600%24, t/60%60, t%60);
+                   t/3600/24, t/3600%24, t/60%60, t%60,
+#ifdef HAVE_LIBSSL
+                 conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
+#else 
+                 "not installed"
+#endif
+            );
             else
-               octstr_format_append(tmp, "%ssmsbox %s (on-line %ldd %ldh %ldm 
%lds)%s",
+               octstr_format_append(tmp, "%ssmsbox, IP %s (on-line %ldd %ldh %ldm 
+%lds) %s %s",
                    ws, octstr_get_cstr(bi->client_ip),
-                   t/3600/24, t/3600%24, t/60%60, t%60, lb);
+                   t/3600/24, t/3600%24, t/60%60, t%60, 
+#ifdef HAVE_LIBSSL
+                 conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
+#else
+                 "",
+#endif 
+            lb);
            boxes++;
        }
        list_unlock(smsbox_list);
diff -urN gateway/gw/bb_http.c gateway-new/gw/bb_http.c
--- gateway/gw/bb_http.c        Fri Oct 19 02:44:21 2001
+++ gateway-new/gw/bb_http.c    Thu Dec 20 18:44:31 2001
@@ -316,10 +316,14 @@
     ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file"));
     ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file"));
     if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
+        /* we are fine here, the following call is now in conn_config_ssl(),
+         * so there is no reason to do this twice.
+
         use_global_server_certkey_file(ssl_server_cert_file, 
             ssl_server_key_file);
+        */
     } else if (ssl) {
-          panic(0, "You MUST specify cert and key files within core group for SSL!");
+          panic(0, "You MUST specify cert and key files within core group for 
+SSL-enabled HTTP servers!");
     }
 
     octstr_destroy(ssl_server_cert_file);
diff -urN gateway/gw/bearerbox.c gateway-new/gw/bearerbox.c
--- gateway/gw/bearerbox.c      Thu Dec  6 16:22:53 2001
+++ gateway-new/gw/bearerbox.c  Thu Dec 20 18:37:47 2001
@@ -273,7 +273,12 @@
     CfgGroup *grp;
     Octstr *log, *val;
     long loglevel;
-    
+#ifdef HAVE_LIBSSL
+    Octstr *ssl_server_cert_file;
+    Octstr *ssl_server_key_file;
+    int ssl_enabled = 0;
+#endif /* HAVE_LIBSSL */
+ 
        
     grp = cfg_get_single_group(cfg, octstr_imm("core"));
 
@@ -306,6 +311,27 @@
     }
 
     conn_config_ssl (grp);
+
+    /* 
+     * Make sure we have "ssl-server-cert-file" and "ssl-server-key-file" specified
+     * in the core group since we need it to run SSL-enabled internal box 
+     * connections configured via "smsbox-port-ssl = yes" and "wapbox-port-ssl = yes".
+     * Check only these, because for "admin-port-ssl" and "sendsms-port-ssl" for the 
+     * SSL-enabled HTTP servers are probed within gw/bb_http.c:httpadmin_start()
+     */
+#ifdef HAVE_LIBSSL
+    ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file"));
+    ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file"));
+    if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
+       /* we are fine, at least files are specified in the configuration */
+    } else {
+        cfg_get_bool(&ssl_enabled, grp, octstr_imm("smsbox-port-ssl"));
+        cfg_get_bool(&ssl_enabled, grp, octstr_imm("wapbox-port-ssl"));
+        if (ssl_enabled) {
+              panic(0, "You MUST specify cert and key files within core group for 
+SSL-enabled inter-box connections!");
+        }
+    }
+#endif /* HAVE_LIBSSL */
        
     /* if all seems to be OK by the first glimpse, real start-up */
     
@@ -600,11 +626,11 @@
     else
        s = "going down";
 
-    version = version_report_string("");
+    version = version_report_string("bearerbox");
 
     if (status_type == BBSTATUS_HTML) {
        frmt = "%s</p>\n\n"
-           " <p>Status: uptime %ldd %ldh %ldm %lds, %s</p>\n\n"
+           " <p>Status: %s, uptime %ldd %ldh %ldm %lds</p>\n\n"
            " <p>WDP: received %ld (%ld queued), sent %ld "
            "(%ld queued)</p>\n\n"
            " <p>SMS: received %ld (%ld queued), sent %ld "
@@ -612,7 +638,7 @@
        footer = "<p>";
     } else if (status_type == BBSTATUS_WML) {
        frmt = "%s</p>\n\n"
-           "   <p>Status: uptime %ldd %ldh %ldm %lds, %s</p>\n\n"
+           "   <p>Status: %s, uptime %ldd %ldh %ldm %lds</p>\n\n"
            "   <p>WDP: received %ld (%ld queued)<br/>\n"
            "      WDP: sent %ld (%ld queued)</p>\n\n"
            "   <p>SMS: received %ld (%ld queued)<br/>\n"
@@ -621,14 +647,14 @@
        footer = "<p>";
     } else if (status_type == BBSTATUS_XML) {
        frmt = "<version>%s</version>\n"
-           "<status>uptime %ldd %ldh %ldm %lds, %s</status>\n"
+           "<status>%s, uptime %ldd %ldh %ldm %lds</status>\n"
            
"\t<wdp>\n\t\t<received><total>%ld</total><queued>%ld</queued></received>\n\t\t<sent><total>%ld"
            "</total><queued>%ld</queued></sent>\n\t</wdp>\n"
            
"\t<sms>\n\t\t<received><total>%ld</total><queued>%ld</queued></received>\n\t\t<sent><total>%ld"
            
"</total><queued>%ld</queued></sent>\n\t\t<storesize>%ld</storesize>\n\t</sms>\n";
        footer = "";
     } else {
-       frmt = "%s\n\nStatus: uptime %ldd %ldh %ldm %lds, %s\n\n"
+       frmt = "%s\n\nStatus: %s, uptime %ldd %ldh %ldm %lds\n\n"
            "WDP: received %ld (%ld queued), sent %ld (%ld queued)\n\n"
            "SMS: received %ld (%ld queued), sent %ld (%ld queued), "
            "store size %ld\n\n";
@@ -637,7 +663,7 @@
     
     sprintf(buf, frmt,
            octstr_get_cstr(version),
-           t/3600/24, t/3600%24, t/60%60, t%60, s,
+           s, t/3600/24, t/3600%24, t/60%60, t%60,
            counter_value(incoming_wdp_counter),
            list_len(incoming_wdp) + boxc_incoming_wdp_queue(),
            counter_value(outgoing_wdp_counter),
diff -urN gateway/gw/shared.c gateway-new/gw/shared.c
--- gateway/gw/shared.c Thu Oct 11 18:18:33 2001
+++ gateway-new/gw/shared.c     Thu Dec 20 16:47:28 2001
@@ -6,6 +6,9 @@
 
 #include <sys/utsname.h>
 #include <xmlversion.h>
+#ifdef HAVE_LIBSSL 
+#include <openssl/opensslv.h>
+#endif
 
 #include "gwlib/gwlib.h"
 #include "shared.h"
@@ -34,13 +37,19 @@
                         "System %s, release %s, version %s, machine %s.\n"
                         "Hostname %s, IP %s.\n"
                         "Libxml version %s.\n"
-                         "Using %s malloc.\n",
+#ifdef HAVE_LIBSSL
+             "Using %s.\n"
+#endif
+             "Using %s malloc.\n",
                         boxname, VERSION,
                         u.sysname, u.release, u.version, u.machine,
                         octstr_get_cstr(get_official_name()),
                         octstr_get_cstr(get_official_ip()),
                         LIBXML_VERSION_STRING,
-                         octstr_get_cstr(gwmem_type()));
+#ifdef HAVE_LIBSSL
+             OPENSSL_VERSION_TEXT,
+#endif
+             octstr_get_cstr(gwmem_type()));
 }
 
 
@@ -52,13 +61,23 @@
 static Connection *bb_conn;
 
 
-void connect_to_bearerbox(Octstr *host, int port, Octstr *our_host)
+void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
 {
+#ifdef HAVE_LIBSSL
+       if (ssl) 
+           bb_conn = conn_open_ssl(host, port, NULL, our_host);
+        /* XXX add certkeyfile to be given to conn_open_ssl */
+       else
+#endif /* HAVE_LIBSSL */
     bb_conn = conn_open_tcp(host, port, our_host);
     if (bb_conn == NULL)
        panic(0, "Couldn't connect to the bearerbox.");
-    info(0, "Connected to bearerbox at %s port %d.",
-        octstr_get_cstr(host), port);
+    if (ssl)
+        info(0, "Connected to bearerbox at %s port %d using SSL.",
+                octstr_get_cstr(host), port);
+    else
+        info(0, "Connected to bearerbox at %s port %d.",
+                octstr_get_cstr(host), port);
 }
 
 
diff -urN gateway/gw/shared.h gateway-new/gw/shared.h
--- gateway/gw/shared.h Mon Oct  8 20:43:04 2001
+++ gateway-new/gw/shared.h     Thu Dec 20 16:47:28 2001
@@ -45,7 +45,7 @@
 /*
  * Open a connection to the bearerbox.
  */
-void connect_to_bearerbox(Octstr *host, int port, Octstr *our_host);
+void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host);
 
 
 /*
diff -urN gateway/gw/smsbox.c gateway-new/gw/smsbox.c
--- gateway/gw/smsbox.c Thu Dec 20 15:46:30 2001
+++ gateway-new/gw/smsbox.c     Thu Dec 20 16:47:28 2001
@@ -36,6 +36,7 @@
 
 static Cfg *cfg;
 static long bb_port;
+static int bb_ssl = 0;
 static long sendsms_port = 0;
 static Octstr *bb_host;
 static char *pid_file;
@@ -1894,6 +1895,7 @@
     int ssl = 0;
 
     bb_port = BB_DEFAULT_SMSBOX_PORT;
+    bb_ssl = 0;
     bb_host = octstr_create(BB_DEFAULT_HOST);
     heartbeat_freq = BB_DEFAULT_HEARTBEAT;
     logfile = NULL;
@@ -1908,6 +1910,9 @@
     
     if (cfg_get_integer(&bb_port, grp, octstr_imm("smsbox-port")) == -1)
        panic(0, "Missing or bad 'smsbox-port' in core group");
+#ifdef HAVE_LIBSSL
+    cfg_get_bool(&bb_ssl, grp, octstr_imm("smsbox-port-ssl"));
+#endif /* HAVE_LIBSSL */
 
     cfg_get_integer(&http_proxy_port, grp, octstr_imm("http-proxy-port"));
 
@@ -2077,7 +2082,7 @@
     gwthread_create(obey_request_thread, NULL);
     gwthread_create(url_result_thread, NULL);
 
-    connect_to_bearerbox(bb_host, bb_port, NULL /* bb_our_host */);
+    connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL /* bb_our_host */);
        /* XXX add our_host if required */
 
     heartbeat_thread = heartbeat_start(write_to_bearerbox, heartbeat_freq,
diff -urN gateway/gw/wapbox.c gateway-new/gw/wapbox.c
--- gateway/gw/wapbox.c Thu Dec 13 11:25:57 2001
+++ gateway-new/gw/wapbox.c     Thu Dec 20 17:56:33 2001
@@ -38,6 +38,7 @@
 
 static Octstr *bearerbox_host;
 static long bearerbox_port = BB_DEFAULT_WAPBOX_PORT;
+static int bearerbox_ssl = 0;
 static long heartbeat_freq = BB_DEFAULT_HEARTBEAT;
 static long heartbeat_thread;
 static Counter *sequence_counter = NULL;
@@ -78,6 +79,10 @@
     
     if (cfg_get_integer(&bearerbox_port,grp,octstr_imm("wapbox-port")) == -1)
        panic(0, "No 'wapbox-port' in core group");
+#ifdef HAVE_LIBSSL
+    cfg_get_bool(&bearerbox_ssl, grp, octstr_imm("wapbox-port-ssl"));
+#endif /* HAVE_LIBSSL */
+
     
     http_proxy_host = cfg_get(grp, octstr_imm("http-proxy-host"));
     http_proxy_port =  -1;
@@ -429,7 +434,7 @@
     
     if (bearerbox_host == NULL)
        bearerbox_host = octstr_create(BB_DEFAULT_HOST);
-    connect_to_bearerbox(bearerbox_host, bearerbox_port, NULL
+    connect_to_bearerbox(bearerbox_host, bearerbox_port, bearerbox_ssl, NULL
                    /* bearerbox_our_port */);
 
     wap_push_ota_bb_address_set(bearerbox_host);
diff -urN gateway/gwlib/cfg.def gateway-new/gwlib/cfg.def
--- gateway/gwlib/cfg.def       Tue Dec 18 08:05:40 2001
+++ gateway-new/gwlib/cfg.def   Thu Dec 20 16:47:28 2001
@@ -26,7 +26,9 @@
     OCTSTR(admin-deny-ip)
     OCTSTR(admin-allow-ip)
     OCTSTR(smsbox-port)
+    OCTSTR(smsbox-port-ssl)
     OCTSTR(wapbox-port)
+    OCTSTR(wapbox-port-ssl)
     OCTSTR(box-deny-ip)
     OCTSTR(box-allow-ip)
     OCTSTR(udp-deny-ip)
diff -urN gateway/gwlib/conn.c gateway-new/gwlib/conn.c
--- gateway/gwlib/conn.c        Thu Dec 13 11:59:24 2001
+++ gateway-new/gwlib/conn.c    Thu Dec 20 19:31:55 2001
@@ -26,6 +26,7 @@
 
 #ifdef HAVE_LIBSSL
 #include <openssl/ssl.h>
+#include <openssl/err.h>
 
 SSL_CTX *global_ssl_context = NULL;
 SSL_CTX *global_server_ssl_context = NULL;
@@ -423,6 +424,7 @@
 {
     Connection *conn;
     unsigned long err;
+    int rc;
 
     if (socket_set_blocking(fd, 0) < 0)
         return NULL;
@@ -461,14 +463,94 @@
         BIO_set_nbio(SSL_get_wbio(conn->ssl), 0);
 
         conn->ssl_mutex = mutex_create();
-        if (!SSL_accept(conn->ssl)) {
-               if ((err = ERR_get_error())) {
-                error(0, "SSL: Access failed: %.256s", ERR_error_string(err, NULL));
-           }
-            error(0, "SSL: disconnected.");
-            SSL_free(conn->ssl);
-            goto error;
-        }
+
+        /* 
+         * now enter the SSL handshake phase
+         */    
+     
+        /*
+         * For non-blocking BIO we may return from SSL_accept(). In this 
+         * case we check for SSL_get_error() = SSL_ERROR_WANT_[READ|WRITE]
+         * and loop the SSL_accept() until we have come through.
+         */
+        while (((rc = SSL_accept(conn->ssl)) <= 0) && 
+               ((SSL_get_error(conn->ssl, rc) == SSL_ERROR_WANT_READ) ||
+               (SSL_get_error(conn->ssl, rc) == SSL_ERROR_WANT_WRITE))) 
+            {}
+                    
+        /*
+         * If SSL_accept() has failed then check which reason it may 
+         * have been and log the error.
+         */
+        if (rc <= 0) {
+             
+            if (SSL_get_error(conn->ssl, rc) == SSL_ERROR_ZERO_RETURN) {
+                /*
+                 * The case where the connection was closed before any data
+                 * was transferred. That's not a real error and can occur
+                 * sporadically with some clients.
+                 */
+                warning(0, "SSL: handshake stopped: connection was closed");
+                warning(0, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), 
+NULL));
+
+                SSL_set_shutdown(conn->ssl, SSL_RECEIVED_SHUTDOWN);
+                SSL_smart_shutdown(conn->ssl);
+             }
+             else if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) {
+                /*
+                 * The case where OpenSSL has recognized a HTTP request:
+                 * This means the client speaks plain HTTP on our HTTPS
+                 * port. Hmmmm...  At least for this error we can be more friendly
+                 * and try to provide him with a HTML error page. We have only one
+                 * problem: OpenSSL has already read some bytes from the HTTP
+                 * request. So we have to skip the request line manually.
+                 */
+                char ca[2];
+                int rv;
+
+                warning(0, "SSL: handshake failed: HTTP spoken on HTTPS port");
+                warning(0, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), 
+NULL));
+                    
+                /* first: skip the remaining bytes of the request line */
+                do {
+                    do {
+                        rv = read(conn->fd, ca, 1);
+                    } while (rv == -1 && errno == EINTR);
+                } while (rv > 0 && ca[0] != '\012' /*LF*/);
+
+                /* second: kick away the SSL stuff */
+                SSL_set_shutdown(conn->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+                SSL_smart_shutdown(conn->ssl);
+
+                /* tell the user how to access using the HTTPS scheme */
+                //SSL_http_hint(conn, HTTP_BAD_REQUEST);
+             }   
+             else if (SSL_get_error(conn->ssl, rc) == SSL_ERROR_SYSCALL) {
+                if (errno > 0)
+                    warning(0, "SSL: handshake interrupted by system (stop button 
+pressed in browser?!)");
+                else
+                    warning(0, "SSL: spurious handshake interrupt (one of OpenSSL 
+confusions?!)");
+                error(0, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), 
+NULL));
+
+                SSL_set_shutdown(conn->ssl, SSL_RECEIVED_SHUTDOWN);
+                SSL_smart_shutdown(conn->ssl);
+             } 
+             else {
+                /*
+                 * ok, anything else is a fatal error
+                 */
+                warning(0, "SSL: handshake failed with fatal error");
+                warning(0, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), 
+NULL));
+                
+                SSL_set_shutdown(conn->ssl, SSL_RECEIVED_SHUTDOWN);
+                SSL_smart_shutdown(conn->ssl);
+             }
+
+             warning(0, "SSL: disconnecting.");
+             goto error;
+
+        } /* SSL error */
+     
     } else {
         conn->ssl = NULL;
         conn->peer_certificate = NULL;
@@ -497,8 +579,10 @@
         fdset_unregister(conn->registered, conn->fd);
 
     if (conn->fd >= 0) {
-        /* Try to flush any remaining data */
-        unlocked_write(conn);
+        /* Try to flush any remaining data, only in case this is
+         * not a SSL connection. Otherwise this crashes the bearerbox
+         * at least on the Cygwin platform
+         */
 #ifdef HAVE_LIBSSL
         if (conn->ssl != NULL) {
             mutex_lock(conn->ssl_mutex);
@@ -508,8 +592,11 @@
                 X509_free(conn->peer_certificate);
             mutex_unlock(conn->ssl_mutex);
             mutex_destroy(conn->ssl_mutex);
-       }
+           }
+        else
 #endif /* HAVE_LIBSSL */
+        unlocked_write(conn);
+
         ret = close(conn->fd);
         if (ret < 0)
             error(errno, "conn_destroy: error on close");
@@ -1188,8 +1275,7 @@
     return preverify_ok;
 }
 
-void
-conn_config_ssl (CfgGroup *grp)
+void conn_config_ssl (CfgGroup *grp)
 {
     Octstr *ssl_client_certkey_file = NULL;
     Octstr *ssl_server_cert_file    = NULL;
@@ -1240,10 +1326,17 @@
     octstr_destroy(ssl_trusted_ca_file);
 }
 
+SSL *conn_get_ssl(Connection *conn)
+{
+    if (conn != NULL)
+        return conn->ssl;
+    else 
+        return NULL;
+}
+
 #else
 
-void
-conn_config_ssl (CfgGroup *grp)
+void conn_config_ssl (CfgGroup *grp)
 {
     info(0, "SSL not supported, no SSL initialization done.");
 }
diff -urN gateway/gwlib/conn.h gateway-new/gwlib/conn.h
--- gateway/gwlib/conn.h        Thu Dec  6 16:22:53 2001
+++ gateway-new/gwlib/conn.h    Thu Dec 20 16:47:28 2001
@@ -197,6 +197,7 @@
 #ifdef HAVE_LIBSSL
 
 #include <openssl/x509.h>
+#include <openssl/ssl.h>
 
 /* Returns the SSL peer certificate for the given Connection or NULL
  * if none. 
@@ -230,4 +231,16 @@
  * key matches with the certificate and will panic if it doesn't.
  */
 void use_global_server_certkey_file(Octstr *certfile, Octstr *keyfile); 
+
+/* Configures all global variables for client and server SSL mode 
+ * from the values specified within the configuration file.
+ */
+void conn_config_ssl(CfgGroup *grp);
+
+/* Returns the pointer to the SSL structure of the Connection given.
+ * This should be used for determining if certain connections are 
+ * SSL enabled outside of the scope of conn.c.
+ */
+SSL *conn_get_ssl(Connection *conn);
+  
 #endif /* HAVE_LIBSSL */
diff -urN gateway/gwlib/gwlib.h gateway-new/gwlib/gwlib.h
--- gateway/gwlib/gwlib.h       Fri Jan 26 16:18:07 2001
+++ gateway-new/gwlib/gwlib.h   Thu Dec 20 16:47:28 2001
@@ -35,6 +35,7 @@
 #include "counter.h"
 #include "charset.h"
 #include "conn.h"
+#include "ssl.h"
 #include "parse.h"
 #include "protected.h"
 #include "accesslog.h"
diff -urN gateway/gwlib/http.c gateway-new/gwlib/http.c
--- gateway/gwlib/http.c        Fri Oct 19 02:45:12 2001
+++ gateway-new/gwlib/http.c    Thu Dec 20 16:47:28 2001
@@ -1370,6 +1370,12 @@
 {
     HTTPClient *p;
     
+#ifdef HAVE_LIBSSL
+    if (conn_get_ssl(conn)) 
+        debug("gwlib.http", 0, "HTTP: Creating SSL-enabled HTTPClient for `%s', using 
+cipher '%s'.",
+             octstr_get_cstr(ip), SSL_get_cipher_version(conn_get_ssl(conn)));
+    else
+#endif    
     debug("gwlib.http", 0, "HTTP: Creating HTTPClient for `%s'.",
          octstr_get_cstr(ip));
     p = gw_malloc(sizeof(*p));
@@ -1710,10 +1716,18 @@
                    ports[i] = -1;
             ssl[i] = 0;
                } else {
-                   conn = conn_wrap_fd(fd, ssl[i]);
-           client = client_create(ports[i], conn, host_ip(addr));
-                   conn_register(conn, server_fdset, receive_request, 
-                                 client);
+            /*
+             * Be aware that conn_wrap_fd() will return NULL if SSL handshake
+             * has failed, so we only client_create() if there is an conn.
+             */             
+            if ((conn = conn_wrap_fd(fd, ssl[i]))) {
+               client = client_create(ports[i], conn, host_ip(addr));
+                       conn_register(conn, server_fdset, receive_request, 
+                                     client);
+            } else {
+                error(0, "HTTP: unsuccessfull SSL handshake for client `%s'",
+                      octstr_get_cstr(host_ip(addr)));
+            }
                }
            }
        }
diff -urN gateway/gwlib/http.h gateway-new/gwlib/http.h
--- gateway/gwlib/http.h        Fri Oct 19 02:45:12 2001
+++ gateway-new/gwlib/http.h    Thu Dec 20 16:47:29 2001
@@ -92,6 +92,7 @@
        HTTP_SEE_OTHER                  = 303,
        HTTP_NOT_MODIFIED               = 304,
        HTTP_TEMPORARY_REDIRECT         = 307,
+    HTTP_BAD_REQUEST        = 400,
        HTTP_NOT_FOUND                  = 404,
        HTTP_REQUEST_ENTITY_TOO_LARGE   = 413,
        HTTP_INTERNAL_SERVER_ERROR      = 500,
diff -urN gateway/gwlib/ssl.c gateway-new/gwlib/ssl.c
--- gateway/gwlib/ssl.c Thu Jan  1 00:00:00 1970
+++ gateway-new/gwlib/ssl.c     Thu Dec 20 20:08:32 2001
@@ -0,0 +1,41 @@
+/*  
+ * ssl.c - implements SSL specific routines and types 
+ * 
+ * This file implements the secure socket layer (SSL) specific  
+ * routines and types. 
+ * 
+ * This product includes software developed by Ralf S. Engelschall  
+ * <[EMAIL PROTECTED]> for use in the mod_ssl project  
+ * (http://www.modssl.org/). 
+ * 
+ * Stipe Tolj <[EMAIL PROTECTED]>  
+ * for Kannel Project and Wapme Systems AG 
+ */ 
+ 
+#include "gwlib/gwlib.h" 
+ 
+#ifdef HAVE_LIBSSL 
+  
+#include <openssl/ssl.h> 
+ 
+int SSL_smart_shutdown(SSL *ssl) 
+{ 
+    int i; 
+    int rc; 
+ 
+    /* 
+     * Repeat the calls, because SSL_shutdown internally dispatches through a 
+     * little state machine. Usually only one or two interation should be 
+     * needed, so we restrict the total number of restrictions in order to 
+     * avoid process hangs in case the client played bad with the socket 
+     * connection and OpenSSL cannot recognize it. 
+     */ 
+    rc = 0; 
+    for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) { 
+        if ((rc = SSL_shutdown(ssl))) 
+            break; 
+    } 
+    return rc; 
+} 
+ 
+#endif /* HAVE_LIBSSL */
diff -urN gateway/gwlib/ssl.h gateway-new/gwlib/ssl.h
--- gateway/gwlib/ssl.h Thu Jan  1 00:00:00 1970
+++ gateway-new/gwlib/ssl.h     Thu Dec 20 20:09:03 2001
@@ -0,0 +1,15 @@
+/*  
+ * ssl.h - declares SSL specific routines and types 
+ * 
+ * This file defines the secure socket layer (SSL) specific  
+ * routines and types. 
+ * 
+ * Stipe Tolj <[EMAIL PROTECTED]>  
+ * for Kannel Project and Wapme Systems AG 
+ */ 
+ 
+#ifdef HAVE_LIBSSL 
+ 
+int SSL_smart_shutdown(SSL *ssl); 
+ 
+#endif /* HAVE_LIBSSL */

Reply via email to