]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
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 2300f8516da9de99a8eb7af8b184acf4fec5e004..0031c1ebd344c521969e6b61f7a810153542aa45 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
@@ -63,6 +64,22 @@ enum pt_tls_sasl_result_t {
        PT_TLS_SASL_RESULT_MECH_FAILURE = 3,
 };
 
+/**
+ * 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.
  *
index 813580cd07e906b3222e7a0fd5fb9eb0b773209d..4699516164c2b50cca7f87a1524b2aba730dedf9 100644 (file)
@@ -41,6 +41,11 @@ struct private_pt_tls_dispatcher_t {
         */
        int fd;
 
+       /**
+        * Client authentication requirements
+        */
+       pt_tls_auth_t auth;
+
        /**
         * Server identity
         */
@@ -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 3c6560baa4dc869fa7bf2685fdcc565e4708e9d2..080197263157c0953e9c06cb043fb30109aabf3f 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 8a58d1107eb25ad6dae25a2613a80efb1f4b9523..3e134f0dd89548872cda6206942f7d07a452f14c 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 244111b43088b170eb79b5f8d6f9e7fda5530d1b..3e18aee8fa53ef70aa6d3149c589b091a474aaa8 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_ @}*/