From: Martin Willi Date: Thu, 28 Feb 2013 11:03:40 +0000 (+0100) Subject: Support different authentication schemes for PT-TLS X-Git-Tag: 5.0.3dr3~4^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61f1693df1d260055ab696e1894251b8f5cc3197;p=thirdparty%2Fstrongswan.git Support different authentication schemes for PT-TLS --- diff --git a/src/libpttls/pt_tls.h b/src/libpttls/pt_tls.h index 2300f8516d..0031c1ebd3 100644 --- a/src/libpttls/pt_tls.h +++ b/src/libpttls/pt_tls.h @@ -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. * diff --git a/src/libpttls/pt_tls_dispatcher.c b/src/libpttls/pt_tls_dispatcher.c index 813580cd07..4699516164 100644 --- a/src/libpttls/pt_tls_dispatcher.c +++ b/src/libpttls/pt_tls_dispatcher.c @@ -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)) diff --git a/src/libpttls/pt_tls_dispatcher.h b/src/libpttls/pt_tls_dispatcher.h index 3c6560baa4..0801972631 100644 --- a/src/libpttls/pt_tls_dispatcher.h +++ b/src/libpttls/pt_tls_dispatcher.h @@ -26,6 +26,8 @@ #include +#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_ @}*/ diff --git a/src/libpttls/pt_tls_server.c b/src/libpttls/pt_tls_server.c index 8a58d1107e..3e134f0dd8 100644 --- a/src/libpttls/pt_tls_server.c +++ b/src/libpttls/pt_tls_server.c @@ -14,7 +14,6 @@ */ #include "pt_tls_server.h" -#include "pt_tls.h" #include @@ -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) diff --git a/src/libpttls/pt_tls_server.h b/src/libpttls/pt_tls_server.h index 244111b430..3e18aee8fa 100644 --- a/src/libpttls/pt_tls_server.h +++ b/src/libpttls/pt_tls_server.h @@ -25,6 +25,8 @@ #include +#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_ @}*/