Annotation of embedaddon/strongswan/src/libpttls/pt_tls_dispatcher.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2012 Martin Willi
! 3: * Copyright (C) 2012 revosec AG
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "pt_tls_dispatcher.h"
! 17: #include "pt_tls_server.h"
! 18:
! 19: #include <threading/thread.h>
! 20: #include <utils/debug.h>
! 21: #include <processing/jobs/callback_job.h>
! 22:
! 23: #include <errno.h>
! 24: #include <string.h>
! 25: #include <unistd.h>
! 26:
! 27: typedef struct private_pt_tls_dispatcher_t private_pt_tls_dispatcher_t;
! 28:
! 29: /**
! 30: * Private data of an pt_tls_dispatcher_t object.
! 31: */
! 32: struct private_pt_tls_dispatcher_t {
! 33:
! 34: /**
! 35: * Public pt_tls_dispatcher_t interface.
! 36: */
! 37: pt_tls_dispatcher_t public;
! 38:
! 39: /**
! 40: * Listening socket
! 41: */
! 42: int fd;
! 43:
! 44: /**
! 45: * Client authentication requirements
! 46: */
! 47: pt_tls_auth_t auth;
! 48:
! 49: /**
! 50: * Server identity
! 51: */
! 52: identification_t *server;
! 53:
! 54: /**
! 55: * Peer identity
! 56: */
! 57: identification_t *peer;
! 58:
! 59: /**
! 60: * TNCCS protocol handler constructor
! 61: */
! 62: pt_tls_tnccs_constructor_t *create;
! 63: };
! 64:
! 65: /**
! 66: * Open listening server socket
! 67: */
! 68: static bool open_socket(private_pt_tls_dispatcher_t *this, host_t *host)
! 69: {
! 70: this->fd = socket(AF_INET, SOCK_STREAM, 0);
! 71: if (this->fd == -1)
! 72: {
! 73: DBG1(DBG_TNC, "opening PT-TLS socket failed: %s", strerror(errno));
! 74: return FALSE;
! 75: }
! 76: if (bind(this->fd, host->get_sockaddr(host),
! 77: *host->get_sockaddr_len(host)) == -1)
! 78: {
! 79: DBG1(DBG_TNC, "binding to PT-TLS socket failed: %s", strerror(errno));
! 80: return FALSE;
! 81: }
! 82: if (listen(this->fd, 5) == -1)
! 83: {
! 84: DBG1(DBG_TNC, "listen on PT-TLS socket failed: %s", strerror(errno));
! 85: return FALSE;
! 86: }
! 87: return TRUE;
! 88: }
! 89:
! 90: /**
! 91: * Handle a single PT-TLS client connection
! 92: */
! 93: static job_requeue_t handle(pt_tls_server_t *connection)
! 94: {
! 95: while (TRUE)
! 96: {
! 97: switch (connection->handle(connection))
! 98: {
! 99: case NEED_MORE:
! 100: continue;
! 101: case FAILED:
! 102: case SUCCESS:
! 103: default:
! 104: break;
! 105: }
! 106: break;
! 107: }
! 108: return JOB_REQUEUE_NONE;
! 109: }
! 110:
! 111: /**
! 112: * Clean up connection state
! 113: */
! 114: static void cleanup(pt_tls_server_t *connection)
! 115: {
! 116: int fd;
! 117:
! 118: fd = connection->get_fd(connection);
! 119: connection->destroy(connection);
! 120: close(fd);
! 121: }
! 122:
! 123: METHOD(pt_tls_dispatcher_t, dispatch, void,
! 124: private_pt_tls_dispatcher_t *this,
! 125: pt_tls_tnccs_constructor_t *create)
! 126: {
! 127: while (TRUE)
! 128: {
! 129: pt_tls_server_t *connection;
! 130: tnccs_t *tnccs;
! 131: bool old;
! 132: int fd;
! 133:
! 134: old = thread_cancelability(TRUE);
! 135: fd = accept(this->fd, NULL, NULL);
! 136: thread_cancelability(old);
! 137: if (fd == -1)
! 138: {
! 139: DBG1(DBG_TNC, "accepting PT-TLS failed: %s", strerror(errno));
! 140: continue;
! 141: }
! 142:
! 143: tnccs = create(this->server, this->peer);
! 144: if (!tnccs)
! 145: {
! 146: close(fd);
! 147: continue;
! 148: }
! 149: connection = pt_tls_server_create(this->server, fd, this->auth, tnccs);
! 150: if (!connection)
! 151: {
! 152: close(fd);
! 153: continue;
! 154: }
! 155: lib->processor->queue_job(lib->processor,
! 156: (job_t*)callback_job_create_with_prio((callback_job_cb_t)handle,
! 157: connection, (void*)cleanup,
! 158: (callback_job_cancel_t)return_false,
! 159: JOB_PRIO_CRITICAL));
! 160: }
! 161: }
! 162:
! 163: METHOD(pt_tls_dispatcher_t, destroy, void,
! 164: private_pt_tls_dispatcher_t *this)
! 165: {
! 166: if (this->fd != -1)
! 167: {
! 168: close(this->fd);
! 169: }
! 170: this->server->destroy(this->server);
! 171: this->peer->destroy(this->peer);
! 172: free(this);
! 173: }
! 174:
! 175: /**
! 176: * See header
! 177: */
! 178: pt_tls_dispatcher_t *pt_tls_dispatcher_create(host_t *address,
! 179: identification_t *id, pt_tls_auth_t auth)
! 180: {
! 181: private_pt_tls_dispatcher_t *this;
! 182:
! 183: INIT(this,
! 184: .public = {
! 185: .dispatch = _dispatch,
! 186: .destroy = _destroy,
! 187: },
! 188: .server = id->clone(id),
! 189: /* we currently don't authenticate the peer, use %any identity */
! 190: .peer = identification_create_from_encoding(ID_ANY, chunk_empty),
! 191: .fd = -1,
! 192: .auth = auth,
! 193: );
! 194:
! 195: if (!open_socket(this, address))
! 196: {
! 197: destroy(this);
! 198: return NULL;
! 199: }
! 200:
! 201: return &this->public;
! 202: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>