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>