aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libpttls/pt_tls.h17
-rw-r--r--src/libpttls/pt_tls_dispatcher.c10
-rw-r--r--src/libpttls/pt_tls_dispatcher.h5
-rw-r--r--src/libpttls/pt_tls_server.c40
-rw-r--r--src/libpttls/pt_tls_server.h5
5 files changed, 71 insertions, 6 deletions
diff --git a/src/libpttls/pt_tls.h b/src/libpttls/pt_tls.h
index 2300f8516..0031c1ebd 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
@@ -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
diff --git a/src/libpttls/pt_tls_dispatcher.c b/src/libpttls/pt_tls_dispatcher.c
index 813580cd0..469951616 100644
--- a/src/libpttls/pt_tls_dispatcher.c
+++ b/src/libpttls/pt_tls_dispatcher.c
@@ -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))
diff --git a/src/libpttls/pt_tls_dispatcher.h b/src/libpttls/pt_tls_dispatcher.h
index 3c6560baa..080197263 100644
--- a/src/libpttls/pt_tls_dispatcher.h
+++ b/src/libpttls/pt_tls_dispatcher.h
@@ -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_ @}*/
diff --git a/src/libpttls/pt_tls_server.c b/src/libpttls/pt_tls_server.c
index 8a58d1107..3e134f0dd 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 <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)
diff --git a/src/libpttls/pt_tls_server.h b/src/libpttls/pt_tls_server.h
index 244111b43..3e18aee8f 100644
--- a/src/libpttls/pt_tls_server.h
+++ b/src/libpttls/pt_tls_server.h
@@ -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_ @}*/