]> arthur.barton.de Git - ngircd.git/blobdiff - src/ngircd/conn.c
S2S-TLS/OpenSSL: Postpone verification of TLS session right before server handshake
[ngircd.git] / src / ngircd / conn.c
index f8c6e2c76fdf45d4269d8c1046626ab42ab6f0d6..fab483e1ab2a288a230a39bce68db553df32d418 100644 (file)
@@ -575,7 +575,7 @@ InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port
 /**
  * Set a socket to "IPv6 only". If the given socket doesn't belong to the
  * AF_INET6 family, or the operating system doesn't support this functionality,
- * this function retruns silently.
+ * this function returns silently.
  *
  * @param af   Address family of the socket.
  * @param sock Socket handle.
@@ -804,7 +804,7 @@ Conn_Handler(void)
  * the result is a valid IRC message (oversized messages are shortened, for
  * example). Then it calls the Conn_Write() function to do the actual sending.
  *
- * @param Idx          Index fo the connection.
+ * @param Idx          Index of the connection.
  * @param Format       Format string, see printf().
  * @returns            true on success, false otherwise.
  */
@@ -1186,7 +1186,7 @@ Conn_CountMax(void)
 } /* Conn_CountMax */
 
 /**
- * Get number of connections accepted since the daemon startet.
+ * Get number of connections accepted since the daemon started.
  *
  * @returns    Number of connections accepted.
  */
@@ -1540,7 +1540,7 @@ Account_Connection(void)
  * a 1:1 mapping today) and enlarge the "connection pool" accordingly.
  *
  * @param Sock Socket handle.
- * @returns    Connecion index or NONE when the pool is too small.
+ * @returns    Connection index or NONE when the pool is too small.
  */
 static CONN_ID
 Socket2Index( int Sock )
@@ -2556,6 +2556,13 @@ cb_listen_ssl(int sock, short irrelevant)
 /**
  * IO callback for new outgoing SSL-enabled server connections.
  *
+ * IMPORTANT: The SSL session has been validated before, but all errors have
+ * been ignored so far! The reason for this is that the generic SSL code has no
+ * idea if the new session actually belongs to a server, as this only becomes
+ * clear when the remote peer sends its PASS command (and we have to handle
+ * invalid client certificates!). Therefore, it is important to check the
+ * status of the SSL session first before continuing the server handshake here!
+ *
  * @param sock         Socket descriptor.
  * @param unused       (ignored IO specification)
  */
@@ -2563,6 +2570,7 @@ static void
 cb_connserver_login_ssl(int sock, short unused)
 {
        CONN_ID idx = Socket2Index(sock);
+       int serveridx;
 
        (void) unused;
 
@@ -2581,10 +2589,30 @@ cb_connserver_login_ssl(int sock, short unused)
                        return;
        }
 
+       serveridx = Conf_GetServer(idx);
+       assert(serveridx >= 0);
+       if (serveridx < 0)
+               goto err;
+
        Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
            My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
 
+       if (!Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_PEERCERT_OK)) {
+               if (Conf_Server[serveridx].SSLVerify) {
+                       Log(LOG_ERR,
+                               "SSLVerify enabled for %d, but peer certificate check failed",
+                               idx);
+                       goto err;
+               }
+               Log(LOG_WARNING,
+                       "Peer certificate check failed for %d, but SSLVerify is disabled, continuing",
+                       idx);
+       }
        server_login(idx);
+       return;
+      err:
+       Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
+       Conn_Close(idx, "Can't connect!", NULL, false);
 }