]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
Optionally validate certificates on TLS server links
[ngircd-alex.git] / src / ngircd / conn.c
index 62561544866413f5abb1534da27caac1e2aa2218..418728e3c39b1ab202dcf8266052fededa105abc 100644 (file)
@@ -269,6 +269,7 @@ server_login(CONN_ID idx)
                      Conf_ServerName, Conf_ServerInfo);
 }
 
+
 /**
  * IO callback for established non-SSL client and server connections.
  *
@@ -335,6 +336,48 @@ Conn_Init( void )
                Init_Conn_Struct(i);
 } /* Conn_Init */
 
+
+/*
+ * create protocol and server identification.
+ * The syntax used by ngIRCd in PASS commands and the extended flags
+ * are described in doc/Protocol.txt
+ *
+ * @param i connection index, may be < 0 to get compile-time constants
+ * @return pointer to static buffer with the connection flags matching i.
+ */
+GLOBAL const char*
+Conn_BuildProtoID(CONN_ID i)
+{
+       static char proto[256];
+#ifdef IRCPLUS
+       snprintf(proto, sizeof(proto), "%s%s %s|%s:%s", PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS);
+#ifdef ZLIB
+       /* don't bother with link compression if ssl already does it */
+#ifdef SSL_SUPPORT
+       if (i < 0 || !Conn_OPTION_ISSET(&My_Connections[i], CONN_SSL_COMPRESSION))
+#else
+       if (i < 0)
+#endif
+               strlcat(proto, "Z", sizeof(proto));
+#endif
+       if (Conf_OperCanMode)
+               strlcat(proto, "o", sizeof(proto));
+#else
+       snprintf(proto, sizeof(proto), "%s%s %s|%s", PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION);
+#endif
+       strlcat(proto, " P", sizeof(proto));
+#ifdef ZLIB
+#ifdef SSL_SUPPORT
+       if (i < 0 || !Conn_OPTION_ISSET(&My_Connections[i], CONN_SSL_COMPRESSION))
+#else
+       if (i < 0)
+#endif
+               strlcat(proto, "Z", sizeof(proto));
+#endif
+       return proto;
+}
+
+
 /**
  * Clean up connection module.
  */
@@ -2523,6 +2566,7 @@ static void
 cb_connserver_login_ssl(int sock, short unused)
 {
        CONN_ID idx = Socket2Index(sock);
+       int serveridx;
 
        assert(idx >= 0);
        if (idx < 0) {
@@ -2540,10 +2584,25 @@ 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 (Conf_Server[serveridx].SSLVerify &&
+                       !Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_PEERCERT_OK))
+       {
+               Log(LOG_ERR, "SSLVerify enabled for %d, but peer certificate check failed", idx);
+               goto err;
+       }
        server_login(idx);
+       return;
+ err:
+       Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
+       Conn_Close(idx, "Can't connect!", NULL, false);
 }