Annotation of embedaddon/strongswan/src/libpttls/pt_tls_dispatcher.c, revision 1.1.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>