Support different authentication schemes for PT-TLS
authorMartin Willi <martin@revosec.ch>
Thu, 28 Feb 2013 11:03:40 +0000 (12:03 +0100)
committerMartin Willi <martin@revosec.ch>
Thu, 28 Feb 2013 15:46:08 +0000 (16:46 +0100)
src/libpttls/pt_tls.h
src/libpttls/pt_tls_dispatcher.c
src/libpttls/pt_tls_dispatcher.h
src/libpttls/pt_tls_server.c
src/libpttls/pt_tls_server.h

index 2300f85..0031c1e 100644 (file)
@@ -37,6 +37,7 @@
 
 typedef enum pt_tls_message_type_t pt_tls_message_type_t;
 typedef enum pt_tls_sasl_result_t pt_tls_sasl_result_t;
+typedef enum pt_tls_auth_t pt_tls_auth_t;
 
 /**
  * Message types, as defined by NEA PT-TLS
@@ -64,6 +65,22 @@ enum pt_tls_sasl_result_t {
 };
 
 /**
+ * Client authentication to require as PT-TLS server.
+ */
+enum pt_tls_auth_t {
+       /** don't require TLS client certificate or request SASL authentication */
+       PT_TLS_AUTH_NONE,
+       /** require TLS certificate authentication, no SASL */
+       PT_TLS_AUTH_TLS,
+       /** do SASL regardless of TLS certificate authentication */
+       PT_TLS_AUTH_SASL,
+       /* if client does not authenticate with a TLS certificate, request SASL */
+       PT_TLS_AUTH_TLS_OR_SASL,
+       /* require both, TLS certificate authentication and SASL */
+       PT_TLS_AUTH_TLS_AND_SASL,
+};
+
+/**
  * Read a PT-TLS message, create reader over Message Value.
  *
  * @param tls                  TLS socket to read from
index 813580c..4699516 100644 (file)
@@ -42,6 +42,11 @@ struct private_pt_tls_dispatcher_t {
        int fd;
 
        /**
+        * Client authentication requirements
+        */
+       pt_tls_auth_t auth;
+
+       /**
         * Server identity
         */
        identification_t *server;
@@ -141,7 +146,7 @@ METHOD(pt_tls_dispatcher_t, dispatch, void,
                        close(fd);
                        continue;
                }
-               connection = pt_tls_server_create(this->server, fd, tnccs);
+               connection = pt_tls_server_create(this->server, fd, this->auth, tnccs);
                if (!connection)
                {
                        close(fd);
@@ -171,7 +176,7 @@ METHOD(pt_tls_dispatcher_t, destroy, void,
  * See header
  */
 pt_tls_dispatcher_t *pt_tls_dispatcher_create(host_t *address,
-                                                                                         identification_t *id)
+                                                                       identification_t *id, pt_tls_auth_t auth)
 {
        private_pt_tls_dispatcher_t *this;
 
@@ -184,6 +189,7 @@ pt_tls_dispatcher_t *pt_tls_dispatcher_create(host_t *address,
                /* we currently don't authenticate the peer, use %any identity */
                .peer = identification_create_from_encoding(ID_ANY, chunk_empty),
                .fd = -1,
+               .auth = auth,
        );
 
        if (!open_socket(this, address))
index 3c6560b..0801972 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <tnc/tnccs/tnccs.h>
 
+#include "pt_tls.h"
+
 typedef struct pt_tls_dispatcher_t pt_tls_dispatcher_t;
 
 /**
@@ -64,9 +66,10 @@ struct pt_tls_dispatcher_t {
  *
  * @param address              server address with port to listen on, gets owned
  * @param id                   TLS server identity, gets owned
+ * @param auth                 client authentication to perform
  * @return                             dispatcher service
  */
 pt_tls_dispatcher_t *pt_tls_dispatcher_create(host_t *address,
-                                                                                         identification_t *id);
+                                                                       identification_t *id, pt_tls_auth_t auth);
 
 #endif /** PT_TLS_DISPATCHER_H_ @}*/
index 8a58d11..3e134f0 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include "pt_tls_server.h"
-#include "pt_tls.h"
 
 #include <sasl/sasl_mechanism.h>
 
@@ -37,6 +36,11 @@ struct private_pt_tls_server_t {
         */
        tls_socket_t *tls;
 
+       /**
+        * Client authentication requirements
+        */
+       pt_tls_auth_t auth;
+
        enum {
                /* expecting version negotiation */
                PT_TLS_SERVER_VERSION,
@@ -305,6 +309,37 @@ static bool do_sasl(private_pt_tls_server_t *this)
        sasl_mechanism_t *sasl;
        status_t status;
 
+       switch (this->auth)
+       {
+               case PT_TLS_AUTH_NONE:
+                       return TRUE;
+               case PT_TLS_AUTH_TLS:
+                       if (this->tls->get_peer_id(this->tls))
+                       {
+                               return TRUE;
+                       }
+                       DBG1(DBG_TNC, "requiring TLS certificate client authentication");
+                       return FALSE;
+               case PT_TLS_AUTH_SASL:
+                       break;
+               case PT_TLS_AUTH_TLS_OR_SASL:
+                       if (this->tls->get_peer_id(this->tls))
+                       {
+                               DBG1(DBG_TNC, "skipping SASL, client authenticated with TLS "
+                                        "certificate");
+                               return TRUE;
+                       }
+                       break;
+               case PT_TLS_AUTH_TLS_AND_SASL:
+               default:
+                       if (!this->tls->get_peer_id(this->tls))
+                       {
+                               DBG1(DBG_TNC, "requiring TLS certificate client authentication");
+                               return FALSE;
+                       }
+                       break;
+       }
+
        if (!send_sasl_mechs(this))
        {
                return FALSE;
@@ -482,7 +517,7 @@ METHOD(pt_tls_server_t, destroy, void,
  * See header
  */
 pt_tls_server_t *pt_tls_server_create(identification_t *server, int fd,
-                                                                         tnccs_t *tnccs)
+                                                                         pt_tls_auth_t auth, tnccs_t *tnccs)
 {
        private_pt_tls_server_t *this;
 
@@ -495,6 +530,7 @@ pt_tls_server_t *pt_tls_server_create(identification_t *server, int fd,
                .state = PT_TLS_SERVER_VERSION,
                .tls = tls_socket_create(TRUE, server, NULL, fd, NULL),
                .tnccs = (tls_t*)tnccs,
+               .auth = auth,
        );
 
        if (!this->tls)
index 244111b..3e18aee 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <tnc/tnccs/tnccs.h>
 
+#include "pt_tls.h"
+
 typedef struct pt_tls_server_t pt_tls_server_t;
 
 /**
@@ -60,10 +62,11 @@ struct pt_tls_server_t {
  *
  * @param server       TLS server identity
  * @param fd           client connection socket
+ * @param auth         client authentication requirements
  * @param tnccs                inner TNCCS protocol handler to use for this connection
  * @return                     PT-TLS server
  */
 pt_tls_server_t *pt_tls_server_create(identification_t *server, int fd,
-                                                                         tnccs_t *tnccs);
+                                                                         pt_tls_auth_t auth, tnccs_t *tnccs);
 
 #endif /** PT_TLS_SERVER_H_ @}*/