Move server-specific code to tls_listen.c
[freeradius.git] / src / main / tls_listen.c
1 /*
2  * tls.c
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
21  * Copyright 2003  Alan DeKok <aland@freeradius.org>
22  * Copyright 2006  The FreeRADIUS server project
23  */
24
25 #include <freeradius-devel/ident.h>
26 RCSID("$Id$")
27
28 #include <freeradius-devel/autoconf.h>
29 #include <freeradius-devel/radiusd.h>
30 #include <freeradius-devel/process.h>
31 #include <freeradius-devel/rad_assert.h>
32
33 #ifdef HAVE_SYS_STAT_H
34 #include <sys/stat.h>
35 #endif
36
37 #ifdef WITH_TLS
38 #ifdef HAVE_OPENSSL_RAND_H
39 #include <openssl/rand.h>
40 #endif
41
42 #ifdef HAVE_OPENSSL_OCSP_H
43 #include <openssl/ocsp.h>
44 #endif
45
46 #ifdef HAVE_PTHREAD_H
47 #define PTHREAD_MUTEX_LOCK pthread_mutex_lock
48 #define PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock
49 #else
50 #define PTHREAD_MUTEX_LOCK(_x)
51 #define PTHREAD_MUTEX_UNLOCK(_x)
52 #endif
53
54 static void tls_socket_close(rad_listen_t *listener)
55 {
56         listen_socket_t *sock = listener->data;
57
58         listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
59         listener->tls = NULL; /* parent owns this! */
60         
61         if (sock->parent) {
62                 /*
63                  *      Decrement the number of connections.
64                  */
65                 if (sock->parent->num_connections > 0) {
66                         sock->parent->num_connections--;
67                 }
68                 if (sock->client->num_connections > 0) {
69                         sock->client->num_connections--;
70                 }
71         }
72         
73         /*
74          *      Tell the event handler that an FD has disappeared.
75          */
76         DEBUG("Client has closed connection");
77         event_new_fd(listener);
78         
79         /*
80          *      Do NOT free the listener here.  It's in use by
81          *      a request, and will need to hang around until
82          *      all of the requests are done.
83          *
84          *      It is instead free'd in remove_from_request_hash()
85          */
86 }
87
88 static int tls_socket_write(rad_listen_t *listener, REQUEST *request)
89 {
90         uint8_t *p;
91         ssize_t rcode;
92         listen_socket_t *sock = listener->data;
93
94         p = sock->ssn->dirty_out.data;
95         
96         while (p < (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used)) {
97                 RDEBUG3("Writing to socket %d", request->packet->sockfd);
98                 rcode = write(request->packet->sockfd, p,
99                               (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used) - p);
100                 if (rcode <= 0) {
101                         RDEBUG("Error writing to TLS socket: %s", strerror(errno));
102                         
103                         tls_socket_close(listener);
104                         return 0;
105                 }
106                 p += rcode;
107         }
108
109         sock->ssn->dirty_out.used = 0;
110         
111         return 1;
112 }
113
114
115 static int tls_socket_recv(rad_listen_t *listener)
116 {
117         int doing_init = FALSE;
118         ssize_t rcode;
119         RADIUS_PACKET *packet;
120         REQUEST *request;
121         listen_socket_t *sock = listener->data;
122         fr_tls_status_t status;
123         RADCLIENT *client = sock->client;
124
125         if (!sock->packet) {
126                 sock->packet = rad_alloc(0);
127                 if (!sock->packet) return 0;
128
129                 sock->packet->sockfd = listener->fd;
130                 sock->packet->src_ipaddr = sock->other_ipaddr;
131                 sock->packet->src_port = sock->other_port;
132                 sock->packet->dst_ipaddr = sock->my_ipaddr;
133                 sock->packet->dst_port = sock->my_port;
134
135                 if (sock->request) sock->request->packet = sock->packet;
136         }
137
138         /*
139          *      Allocate a REQUEST for debugging.
140          */
141         if (!sock->request) {
142                 sock->request = request = request_alloc();
143                 if (!sock->request) {
144                         radlog(L_ERR, "Out of memory");
145                         return 0;
146                 }
147
148                 rad_assert(request->packet == NULL);
149                 rad_assert(sock->packet != NULL);
150                 request->packet = sock->packet;
151
152                 request->component = "<core>";
153                 request->component = "<tls-connect>";
154
155                 /*
156                  *      Not sure if we should do this on every packet...
157                  */
158                 request->reply = rad_alloc(0);
159                 if (!request->reply) return 0;
160
161                 request->options = RAD_REQUEST_OPTION_DEBUG2;
162
163                 rad_assert(sock->ssn == NULL);
164
165                 sock->ssn = tls_new_session(listener->tls, sock->request,
166                                             listener->tls->require_client_cert);
167                 if (!sock->ssn) {
168                         request_free(&sock->request);
169                         sock->packet = NULL;
170                         return 0;
171                 }
172
173                 SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_REQUEST, (void *)request);
174                 SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_CERTS, (void *)&request->packet->vps);
175
176                 doing_init = TRUE;
177         }
178
179         rad_assert(sock->request != NULL);
180         rad_assert(sock->request->packet != NULL);
181         rad_assert(sock->packet != NULL);
182         rad_assert(sock->ssn != NULL);
183
184         request = sock->request;
185
186         RDEBUG3("Reading from socket %d", request->packet->sockfd);
187         PTHREAD_MUTEX_LOCK(&sock->mutex);
188         rcode = read(request->packet->sockfd,
189                      sock->ssn->dirty_in.data,
190                      sizeof(sock->ssn->dirty_in.data));
191         if ((rcode < 0) && (errno == ECONNRESET)) {
192         do_close:
193                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
194                 tls_socket_close(listener);
195                 return 0;
196         }
197         
198         if (rcode < 0) {
199                 RDEBUG("Error reading TLS socket: %s", strerror(errno));
200                 goto do_close;
201         }
202
203         /*
204          *      Normal socket close.
205          */
206         if (rcode == 0) goto do_close;
207         
208         sock->ssn->dirty_in.used = rcode;
209         memset(sock->ssn->dirty_in.data + sock->ssn->dirty_in.used,
210                0, 16);
211
212         dump_hex("READ FROM SSL", sock->ssn->dirty_in.data, sock->ssn->dirty_in.used);
213
214         /*
215          *      Catch attempts to use non-SSL.
216          */
217         if (doing_init && (sock->ssn->dirty_in.data[0] != handshake)) {
218                 RDEBUG("Non-TLS data sent to TLS socket: closing");
219                 goto do_close;
220         }
221         
222         /*
223          *      Skip ahead to reading application data.
224          */
225         if (SSL_is_init_finished(sock->ssn->ssl)) goto app;
226
227         if (!tls_handshake_recv(request, sock->ssn)) {
228                 RDEBUG("FAILED in TLS handshake receive");
229                 goto do_close;
230         }
231         
232         if (sock->ssn->dirty_out.used > 0) {
233                 tls_socket_write(listener, request);
234                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
235                 return 0;
236         }
237
238 app:
239         /*
240          *      FIXME: Run the packet through a virtual server in
241          *      order to see if we like the certificate presented by
242          *      the client.
243          */
244
245         status = tls_application_data(sock->ssn, request);
246         RDEBUG("Application data status %d", status);
247
248         if (status == FR_TLS_MORE_FRAGMENTS) {
249                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
250                 return 0;
251         }
252
253         if (sock->ssn->clean_out.used == 0) {
254                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
255                 return 0;
256         }
257
258         dump_hex("TUNNELED DATA", sock->ssn->clean_out.data, sock->ssn->clean_out.used);
259
260         /*
261          *      If the packet is a complete RADIUS packet, return it to
262          *      the caller.  Otherwise...
263          */
264         if ((sock->ssn->clean_out.used < 20) ||
265             (((sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]) != (int) sock->ssn->clean_out.used)) {
266                 RDEBUG("Received bad packet: Length %d contents %d",
267                        sock->ssn->clean_out.used,
268                        (sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]);
269                 goto do_close;
270         }
271
272         packet = sock->packet;
273         packet->data = rad_malloc(sock->ssn->clean_out.used);
274         packet->data_len = sock->ssn->clean_out.used;
275         record_minus(&sock->ssn->clean_out, packet->data, packet->data_len);
276         packet->vps = NULL;
277         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
278
279         if (!rad_packet_ok(packet, 0)) {
280                 RDEBUG("Received bad packet: %s", fr_strerror());
281                 tls_socket_close(listener);
282                 return 0;       /* do_close unlocks the mutex */
283         }
284
285         /*
286          *      Copied from src/lib/radius.c, rad_recv();
287          */
288         if (fr_debug_flag) {
289                 char host_ipaddr[128];
290
291                 if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
292                         RDEBUG("tls_recv: %s packet from host %s port %d, id=%d, length=%d",
293                                fr_packet_codes[packet->code],
294                                inet_ntop(packet->src_ipaddr.af,
295                                          &packet->src_ipaddr.ipaddr,
296                                          host_ipaddr, sizeof(host_ipaddr)),
297                                packet->src_port,
298                                packet->id, (int) packet->data_len);
299                 } else {
300                         RDEBUG("tls_recv: Packet from host %s port %d code=%d, id=%d, length=%d",
301                                inet_ntop(packet->src_ipaddr.af,
302                                          &packet->src_ipaddr.ipaddr,
303                                          host_ipaddr, sizeof(host_ipaddr)),
304                                packet->src_port,
305                                packet->code,
306                                packet->id, (int) packet->data_len);
307                 }
308         }
309
310         FR_STATS_INC(auth, total_requests);
311
312         return 1;
313 }
314
315
316 int dual_tls_recv(rad_listen_t *listener)
317 {
318         RADIUS_PACKET *packet;
319         REQUEST *request;
320         RAD_REQUEST_FUNP fun = NULL;
321         listen_socket_t *sock = listener->data;
322         RADCLIENT       *client = sock->client;
323
324         if (!tls_socket_recv(listener)) {
325                 return 0;
326         }
327
328         rad_assert(sock->request != NULL);
329         rad_assert(sock->request->packet != NULL);
330         rad_assert(sock->packet != NULL);
331         rad_assert(sock->ssn != NULL);
332
333         request = sock->request;
334         packet = sock->packet;
335
336         /*
337          *      Some sanity checks, based on the packet code.
338          */
339         switch(packet->code) {
340         case PW_AUTHENTICATION_REQUEST:
341                 if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
342                 FR_STATS_INC(auth, total_requests);
343                 fun = rad_authenticate;
344                 break;
345
346         case PW_ACCOUNTING_REQUEST:
347                 if (listener->type != RAD_LISTEN_ACCT) goto bad_packet;
348                 FR_STATS_INC(acct, total_requests);
349                 fun = rad_accounting;
350                 break;
351
352         case PW_STATUS_SERVER:
353                 if (!mainconfig.status_server) {
354                         FR_STATS_INC(auth, total_unknown_types);
355                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
356                         rad_free(&sock->packet);
357                         request->packet = NULL;
358                         return 0;
359                 }
360                 fun = rad_status_server;
361                 break;
362
363         default:
364         bad_packet:
365                 FR_STATS_INC(auth, total_unknown_types);
366
367                 DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED",
368                       packet->code, client->shortname, packet->src_port);
369                 rad_free(&sock->packet);
370                 request->packet = NULL;
371                 return 0;
372         } /* switch over packet types */
373
374         if (!request_receive(listener, packet, client, fun)) {
375                 FR_STATS_INC(auth, total_packets_dropped);
376                 rad_free(&sock->packet);
377                 request->packet = NULL;
378                 return 0;
379         }
380
381         sock->packet = NULL;    /* we have no need for more partial reads */
382         request->packet = NULL;
383
384         return 1;
385 }
386
387
388 /*
389  *      Send a response packet
390  */
391 int dual_tls_send(rad_listen_t *listener, REQUEST *request)
392 {
393         listen_socket_t *sock = listener->data;
394
395         rad_assert(request->listener == listener);
396         rad_assert(listener->send == dual_tls_send);
397
398         /*
399          *      Accounting reject's are silently dropped.
400          *
401          *      We do it here to avoid polluting the rest of the
402          *      code with this knowledge
403          */
404         if (request->reply->code == 0) return 0;
405
406         /*
407          *      Pack the VPs
408          */
409         if (rad_encode(request->reply, request->packet,
410                        request->client->secret) < 0) {
411                 RDEBUG("Failed encoding packet: %s", fr_strerror());
412                 return 0;
413         }
414
415         /*
416          *      Sign the packet.
417          */
418         if (rad_sign(request->reply, request->packet,
419                        request->client->secret) < 0) {
420                 RDEBUG("Failed signing packet: %s", fr_strerror());
421                 return 0;
422         }
423         
424         PTHREAD_MUTEX_LOCK(&sock->mutex);
425         /*
426          *      Write the packet to the SSL buffers.
427          */
428         record_plus(&sock->ssn->clean_in,
429                     request->reply->data, request->reply->data_len);
430
431         /*
432          *      Do SSL magic to get encrypted data.
433          */
434         tls_handshake_send(request, sock->ssn);
435
436         /*
437          *      And finally write the data to the socket.
438          */
439         if (sock->ssn->dirty_out.used > 0) {
440                 dump_hex("WRITE TO SSL", sock->ssn->dirty_out.data, sock->ssn->dirty_out.used);
441
442                 tls_socket_write(listener, request);
443         }
444         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
445
446         return 0;
447 }
448
449
450 int proxy_tls_recv(rad_listen_t *listener)
451 {
452         int rcode;
453         size_t length;
454         listen_socket_t *sock = listener->data;
455         char buffer[256];
456         uint8_t data[1024];
457         RADIUS_PACKET *packet;
458         RAD_REQUEST_FUNP fun = NULL;
459
460         DEBUG3("Proxy SSL socket has data to read");
461         PTHREAD_MUTEX_LOCK(&sock->mutex);
462 redo:
463         rcode = SSL_read(sock->ssn->ssl, data, 4);
464         if (rcode <= 0) {
465                 int err = SSL_get_error(sock->ssn->ssl, rcode);
466                 switch (err) {
467                 case SSL_ERROR_WANT_READ:
468                 case SSL_ERROR_WANT_WRITE:
469                         rcode = 0;
470                         goto redo;
471                 case SSL_ERROR_ZERO_RETURN:
472                         /* remote end sent close_notify, send one back */
473                         SSL_shutdown(sock->ssn->ssl);
474
475                 case SSL_ERROR_SYSCALL:
476                 do_close:
477                         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
478                         tls_socket_close(listener);
479                         return 0;
480
481                 default:
482                         while ((err = ERR_get_error())) {
483                                 DEBUG("proxy recv says %s",
484                                       ERR_error_string(err, NULL));
485                         }
486                         
487                         goto do_close;
488                 }
489         }
490
491         length = (data[2] << 8) | data[3];
492         DEBUG3("Proxy received header saying we have a packet of %u bytes",
493                (unsigned int) length);
494
495         if (length > sizeof(data)) {
496                 DEBUG("Received packet will be too large! (%u)",
497                       (data[2] << 8) | data[3]);
498                 goto do_close;
499         }
500         
501         rcode = SSL_read(sock->ssn->ssl, data + 4, length);
502         if (rcode <= 0) {
503                 switch (SSL_get_error(sock->ssn->ssl, rcode)) {
504                 case SSL_ERROR_WANT_READ:
505                 case SSL_ERROR_WANT_WRITE:
506                         rcode = 0;
507                         break;
508
509                 case SSL_ERROR_ZERO_RETURN:
510                         /* remote end sent close_notify, send one back */
511                         SSL_shutdown(sock->ssn->ssl);
512                         goto do_close;
513                 default:
514                         goto do_close;
515                 }
516         }
517         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
518
519         packet = rad_alloc(0);
520         packet->sockfd = listener->fd;
521         packet->src_ipaddr = sock->other_ipaddr;
522         packet->src_port = sock->other_port;
523         packet->dst_ipaddr = sock->my_ipaddr;
524         packet->dst_port = sock->my_port;
525         packet->code = data[0];
526         packet->id = data[1];
527         packet->data_len = length;
528         packet->data = rad_malloc(packet->data_len);
529         memcpy(packet->data, data, packet->data_len);
530         memcpy(packet->vector, packet->data + 4, 16);
531
532         /*
533          *      FIXME: Client MIB updates?
534          */
535         switch(packet->code) {
536         case PW_AUTHENTICATION_ACK:
537         case PW_ACCESS_CHALLENGE:
538         case PW_AUTHENTICATION_REJECT:
539                 fun = rad_authenticate;
540                 break;
541
542 #ifdef WITH_ACCOUNTING
543         case PW_ACCOUNTING_RESPONSE:
544                 fun = rad_accounting;
545                 break;
546 #endif
547
548         default:
549                 /*
550                  *      FIXME: Update MIB for packet types?
551                  */
552                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
553                        "from home server %s port %d - ID %d : IGNORED",
554                        packet->code,
555                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
556                        packet->src_port, packet->id);
557                 rad_free(&packet);
558                 return 0;
559         }
560
561         if (!request_proxy_reply(packet)) {
562                 rad_free(&packet);
563                 return 0;
564         }
565
566         return 1;
567 }
568
569 int proxy_tls_send(rad_listen_t *listener, REQUEST *request)
570 {
571         int rcode;
572         listen_socket_t *sock = listener->data;
573
574         /*
575          *      Normal proxying calls us with the data already
576          *      encoded.  The "ping home server" code does not.  So,
577          *      if there's no packet, encode it here.
578          */
579         if (!request->proxy->data) {
580                 request->proxy_listener->encode(request->proxy_listener,
581                                                 request);
582         }
583
584         DEBUG3("Proxy is writing %u bytes to SSL",
585                (unsigned int) request->proxy->data_len);
586         PTHREAD_MUTEX_LOCK(&sock->mutex);
587         while ((rcode = SSL_write(sock->ssn->ssl, request->proxy->data,
588                                   request->proxy->data_len)) < 0) {
589                 int err;
590                 while ((err = ERR_get_error())) {
591                         DEBUG("proxy SSL_write says %s",
592                               ERR_error_string(err, NULL));
593                 }
594                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
595                 tls_socket_close(listener);
596                 return 0;
597         }
598         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
599
600         return 1;
601 }
602
603 #endif  /* WITH_TLS */