Reset partial read only after we've read all of the data
[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 RCSID("$Id$")
26 USES_APPLE_DEPRECATED_API       /* OpenSSL API has been deprecated by Apple */
27
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/process.h>
30 #include <freeradius-devel/rad_assert.h>
31
32 #ifdef HAVE_SYS_STAT_H
33 #include <sys/stat.h>
34 #endif
35
36 #ifdef WITH_TLS
37 #ifdef HAVE_OPENSSL_RAND_H
38 #include <openssl/rand.h>
39 #endif
40
41 #ifdef HAVE_OPENSSL_OCSP_H
42 #include <openssl/ocsp.h>
43 #endif
44
45 #ifdef HAVE_PTHREAD_H
46 #define PTHREAD_MUTEX_LOCK pthread_mutex_lock
47 #define PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock
48 #else
49 #define PTHREAD_MUTEX_LOCK(_x)
50 #define PTHREAD_MUTEX_UNLOCK(_x)
51 #endif
52
53 static void dump_hex(char const *msg, uint8_t const *data, size_t data_len)
54 {
55         size_t i;
56
57         if (debug_flag < 3) return;
58
59         printf("%s %d\n", msg, (int) data_len);
60         if (data_len > 256) data_len = 256;
61
62         for (i = 0; i < data_len; i++) {
63                 if ((i & 0x0f) == 0x00) printf ("%02x: ", (unsigned int) i);
64                 printf("%02x ", data[i]);
65                 if ((i & 0x0f) == 0x0f) printf ("\n");
66         }
67         printf("\n");
68         fflush(stdout);
69 }
70
71 static void tls_socket_close(rad_listen_t *listener)
72 {
73         listen_socket_t *sock = listener->data;
74
75         listener->status = RAD_LISTEN_STATUS_EOL;
76         listener->tls = NULL; /* parent owns this! */
77
78         if (sock->parent) {
79                 /*
80                  *      Decrement the number of connections.
81                  */
82                 if (sock->parent->limit.num_connections > 0) {
83                         sock->parent->limit.num_connections--;
84                 }
85                 if (sock->client->limit.num_connections > 0) {
86                         sock->client->limit.num_connections--;
87                 }
88         }
89
90         /*
91          *      Tell the event handler that an FD has disappeared.
92          */
93         event_new_fd(listener);
94
95         /*
96          *      Do NOT free the listener here.  It's in use by
97          *      a request, and will need to hang around until
98          *      all of the requests are done.
99          *
100          *      It is instead free'd in remove_from_request_hash()
101          */
102 }
103
104 static int tls_socket_write(rad_listen_t *listener, REQUEST *request)
105 {
106         uint8_t *p;
107         ssize_t rcode;
108         listen_socket_t *sock = listener->data;
109
110         p = sock->ssn->dirty_out.data;
111
112         while (p < (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used)) {
113                 RDEBUG3("Writing to socket %d", request->packet->sockfd);
114                 rcode = write(request->packet->sockfd, p,
115                               (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used) - p);
116                 if (rcode <= 0) {
117                         RDEBUG("Error writing to TLS socket: %s", fr_syserror(errno));
118
119                         tls_socket_close(listener);
120                         return 0;
121                 }
122                 p += rcode;
123         }
124
125         sock->ssn->dirty_out.used = 0;
126
127         return 1;
128 }
129
130
131 static int tls_socket_recv(rad_listen_t *listener)
132 {
133         bool doing_init = false;
134         ssize_t rcode;
135         RADIUS_PACKET *packet;
136         REQUEST *request;
137         listen_socket_t *sock = listener->data;
138         fr_tls_status_t status;
139         RADCLIENT *client = sock->client;
140
141         if (!sock->packet) {
142                 sock->packet = rad_alloc(sock, 0);
143                 if (!sock->packet) return 0;
144
145                 sock->packet->sockfd = listener->fd;
146                 sock->packet->src_ipaddr = sock->other_ipaddr;
147                 sock->packet->src_port = sock->other_port;
148                 sock->packet->dst_ipaddr = sock->my_ipaddr;
149                 sock->packet->dst_port = sock->my_port;
150
151                 if (sock->request) {
152                         (void) talloc_steal(sock->request, sock->packet);
153                         sock->request->packet = sock->packet;
154                 }
155         }
156
157         /*
158          *      Allocate a REQUEST for debugging.
159          */
160         if (!sock->request) {
161                 sock->request = request = request_alloc(NULL);
162                 if (!sock->request) {
163                         ERROR("Out of memory");
164                         return 0;
165                 }
166
167                 rad_assert(request->packet == NULL);
168                 rad_assert(sock->packet != NULL);
169                 request->packet = sock->packet;
170
171                 request->component = "<core>";
172                 request->component = "<tls-connect>";
173
174                 /*
175                  *      Not sure if we should do this on every packet...
176                  */
177                 request->reply = rad_alloc(request, 0);
178                 if (!request->reply) return 0;
179
180                 rad_assert(sock->ssn == NULL);
181
182                 sock->ssn = tls_new_session(listener->tls, sock->request,
183                                             listener->tls->require_client_cert);
184                 if (!sock->ssn) {
185                         request_free(&sock->request);
186                         sock->packet = NULL;
187                         return 0;
188                 }
189
190                 (void) talloc_steal(sock, sock->ssn);
191                 SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_REQUEST, (void *)request);
192                 SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_CERTS, (void *)&request->packet->vps);
193
194                 doing_init = true;
195         }
196
197         rad_assert(sock->request != NULL);
198         rad_assert(sock->request->packet != NULL);
199         rad_assert(sock->packet != NULL);
200         rad_assert(sock->ssn != NULL);
201
202         request = sock->request;
203
204         RDEBUG3("Reading from socket %d", request->packet->sockfd);
205         PTHREAD_MUTEX_LOCK(&sock->mutex);
206         rcode = read(request->packet->sockfd,
207                      sock->ssn->dirty_in.data,
208                      sizeof(sock->ssn->dirty_in.data));
209         if ((rcode < 0) && (errno == ECONNRESET)) {
210         do_close:
211                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
212                 DEBUG("Closing TLS socket from client");
213                 tls_socket_close(listener);
214                 return 0;
215         }
216
217         if (rcode < 0) {
218                 RDEBUG("Error reading TLS socket: %s", fr_syserror(errno));
219                 goto do_close;
220         }
221
222         /*
223          *      Normal socket close.
224          */
225         if (rcode == 0) goto do_close;
226
227         sock->ssn->dirty_in.used = rcode;
228
229         dump_hex("READ FROM SSL", sock->ssn->dirty_in.data, sock->ssn->dirty_in.used);
230
231         /*
232          *      Catch attempts to use non-SSL.
233          */
234         if (doing_init && (sock->ssn->dirty_in.data[0] != handshake)) {
235                 RDEBUG("Non-TLS data sent to TLS socket: closing");
236                 goto do_close;
237         }
238
239         /*
240          *      Skip ahead to reading application data.
241          */
242         if (SSL_is_init_finished(sock->ssn->ssl)) goto app;
243
244         if (!tls_handshake_recv(request, sock->ssn)) {
245                 RDEBUG("FAILED in TLS handshake receive");
246                 goto do_close;
247         }
248
249         if (sock->ssn->dirty_out.used > 0) {
250                 tls_socket_write(listener, request);
251                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
252                 return 0;
253         }
254
255 app:
256         /*
257          *      FIXME: Run the packet through a virtual server in
258          *      order to see if we like the certificate presented by
259          *      the client.
260          */
261
262         status = tls_application_data(sock->ssn, request);
263         RDEBUG("Application data status %d", status);
264
265         if (status == FR_TLS_MORE_FRAGMENTS) {
266                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
267                 return 0;
268         }
269
270         if (sock->ssn->clean_out.used == 0) {
271                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
272                 return 0;
273         }
274
275         dump_hex("TUNNELED DATA", sock->ssn->clean_out.data, sock->ssn->clean_out.used);
276
277         /*
278          *      If the packet is a complete RADIUS packet, return it to
279          *      the caller.  Otherwise...
280          */
281         if ((sock->ssn->clean_out.used < 20) ||
282             (((sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]) != (int) sock->ssn->clean_out.used)) {
283                 RDEBUG("Received bad packet: Length %d contents %d",
284                        sock->ssn->clean_out.used,
285                        (sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]);
286                 goto do_close;
287         }
288
289         packet = sock->packet;
290         packet->data = talloc_array(packet, uint8_t, sock->ssn->clean_out.used);
291         packet->data_len = sock->ssn->clean_out.used;
292         sock->ssn->record_minus(&sock->ssn->clean_out, packet->data, packet->data_len);
293         packet->vps = NULL;
294         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
295
296         if (!rad_packet_ok(packet, 0)) {
297                 RDEBUG("Received bad packet: %s", fr_strerror());
298                 DEBUG("Closing TLS socket from client");
299                 tls_socket_close(listener);
300                 return 0;       /* do_close unlocks the mutex */
301         }
302
303         /*
304          *      Copied from src/lib/radius.c, rad_recv();
305          */
306         if (fr_debug_flag) {
307                 char host_ipaddr[128];
308
309                 if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
310                         RDEBUG("tls_recv: %s packet from host %s port %d, id=%d, length=%d",
311                                fr_packet_codes[packet->code],
312                                inet_ntop(packet->src_ipaddr.af,
313                                          &packet->src_ipaddr.ipaddr,
314                                          host_ipaddr, sizeof(host_ipaddr)),
315                                packet->src_port,
316                                packet->id, (int) packet->data_len);
317                 } else {
318                         RDEBUG("tls_recv: Packet from host %s port %d code=%d, id=%d, length=%d",
319                                inet_ntop(packet->src_ipaddr.af,
320                                          &packet->src_ipaddr.ipaddr,
321                                          host_ipaddr, sizeof(host_ipaddr)),
322                                packet->src_port,
323                                packet->code,
324                                packet->id, (int) packet->data_len);
325                 }
326         }
327
328         FR_STATS_INC(auth, total_requests);
329
330         return 1;
331 }
332
333
334 int dual_tls_recv(rad_listen_t *listener)
335 {
336         RADIUS_PACKET *packet;
337         REQUEST *request;
338         RAD_REQUEST_FUNP fun = NULL;
339         listen_socket_t *sock = listener->data;
340         RADCLIENT       *client = sock->client;
341
342         if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
343
344         if (!tls_socket_recv(listener)) {
345                 return 0;
346         }
347
348         rad_assert(sock->request != NULL);
349         rad_assert(sock->request->packet != NULL);
350         rad_assert(sock->packet != NULL);
351         rad_assert(sock->ssn != NULL);
352         rad_assert(client != NULL);
353
354         request = sock->request;
355         packet = sock->packet;
356
357         /*
358          *      Some sanity checks, based on the packet code.
359          *
360          *      "auth+acct" are marked as "auth", with the "dual" flag
361          *      set.
362          */
363         switch(packet->code) {
364         case PW_AUTHENTICATION_REQUEST:
365                 if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
366                 FR_STATS_INC(auth, total_requests);
367                 fun = rad_authenticate;
368                 break;
369
370 #ifdef WITH_ACCOUNTING
371         case PW_ACCOUNTING_REQUEST:
372                 if (listener->type != RAD_LISTEN_ACCT) {
373                         /*
374                          *      Allow auth + dual.  Disallow
375                          *      everything else.
376                          */
377                         if (!((listener->type == RAD_LISTEN_AUTH) &&
378                               (listener->dual))) {
379                                     goto bad_packet;
380                         }
381                 }
382                 FR_STATS_INC(acct, total_requests);
383                 fun = rad_accounting;
384                 break;
385 #endif
386
387         case PW_STATUS_SERVER:
388                 if (!mainconfig.status_server) {
389                         FR_STATS_INC(auth, total_unknown_types);
390                         WDEBUG("Ignoring Status-Server request due to security configuration");
391                         rad_free(&sock->packet);
392                         request->packet = NULL;
393                         return 0;
394                 }
395                 fun = rad_status_server;
396                 break;
397
398         default:
399         bad_packet:
400                 FR_STATS_INC(auth, total_unknown_types);
401
402                 DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED",
403                       packet->code, client->shortname, packet->src_port);
404                 rad_free(&sock->packet);
405                 request->packet = NULL;
406                 return 0;
407         } /* switch over packet types */
408
409         if (!request_receive(listener, packet, client, fun)) {
410                 FR_STATS_INC(auth, total_packets_dropped);
411                 rad_free(&sock->packet);
412                 request->packet = NULL;
413                 return 0;
414         }
415
416         sock->packet = NULL;    /* we have no need for more partial reads */
417         request->packet = NULL;
418
419         return 1;
420 }
421
422
423 /*
424  *      Send a response packet
425  */
426 int dual_tls_send(rad_listen_t *listener, REQUEST *request)
427 {
428         listen_socket_t *sock = listener->data;
429
430         rad_assert(request->listener == listener);
431         rad_assert(listener->send == dual_tls_send);
432
433         if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
434
435         /*
436          *      Accounting reject's are silently dropped.
437          *
438          *      We do it here to avoid polluting the rest of the
439          *      code with this knowledge
440          */
441         if (request->reply->code == 0) return 0;
442
443         /*
444          *      Pack the VPs
445          */
446         if (rad_encode(request->reply, request->packet,
447                        request->client->secret) < 0) {
448                 RERROR("Failed encoding packet: %s", fr_strerror());
449                 return 0;
450         }
451
452         /*
453          *      Sign the packet.
454          */
455         if (rad_sign(request->reply, request->packet,
456                        request->client->secret) < 0) {
457                 RERROR("Failed signing packet: %s", fr_strerror());
458                 return 0;
459         }
460
461         PTHREAD_MUTEX_LOCK(&sock->mutex);
462         /*
463          *      Write the packet to the SSL buffers.
464          */
465         sock->ssn->record_plus(&sock->ssn->clean_in,
466                                request->reply->data, request->reply->data_len);
467
468         /*
469          *      Do SSL magic to get encrypted data.
470          */
471         tls_handshake_send(request, sock->ssn);
472
473         /*
474          *      And finally write the data to the socket.
475          */
476         if (sock->ssn->dirty_out.used > 0) {
477                 dump_hex("WRITE TO SSL", sock->ssn->dirty_out.data, sock->ssn->dirty_out.used);
478
479                 tls_socket_write(listener, request);
480         }
481         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
482
483         return 0;
484 }
485
486
487 #ifdef WITH_PROXY
488 /*
489  *      Read from the SSL socket.  Safe with either blocking or
490  *      non-blocking IO.  This level of complexity is probably not
491  *      necessary, as each packet gets put into one SSL application
492  *      record.  When SSL has a full record, we should be able to read
493  *      the entire packet via one SSL_read().
494  *
495  *      When SSL has a partial record, SSL_read() will return
496  *      WANT_READ or WANT_WRITE, and zero application data.
497  *
498  *      Called with the mutex held.
499  */
500 static int proxy_tls_read(rad_listen_t *listener)
501 {
502         int rcode;
503         size_t length;
504         uint8_t *data;
505         listen_socket_t *sock = listener->data;
506
507         /*
508          *      Get the maximum size of data to receive.
509          */
510         if (!sock->data) sock->data = talloc_array(sock, uint8_t,
511                                                    sock->ssn->offset);
512
513         data = sock->data;
514
515         if (sock->partial < 4) {
516                 rcode = SSL_read(sock->ssn->ssl, data + sock->partial,
517                                  4 - sock->partial);
518                 if (rcode <= 0) {
519                         int err = SSL_get_error(sock->ssn->ssl, rcode);
520                         switch (err) {
521                         case SSL_ERROR_WANT_READ:
522                         case SSL_ERROR_WANT_WRITE:
523                                 return 0; /* do some more work later */
524
525                         case SSL_ERROR_ZERO_RETURN:
526                                 /* remote end sent close_notify, send one back */
527                                 SSL_shutdown(sock->ssn->ssl);
528
529                         case SSL_ERROR_SYSCALL:
530                         do_close:
531                                 return -1;
532
533                         default:
534                                 while ((err = ERR_get_error())) {
535                                         DEBUG("proxy recv says %s",
536                                               ERR_error_string(err, NULL));
537                                 }
538                                 
539                                 goto do_close;
540                         }
541                 }
542
543                 sock->partial = rcode;
544         } /* try reading the packet header */
545
546         if (sock->partial < 4) return 0; /* read more data */
547
548         length = (data[2] << 8) | data[3];
549
550         /*
551          *      Do these checks only once, when we read the header.
552          */
553         if (sock->partial == 4) {
554                 DEBUG3("Proxy received header saying we have a packet of %u bytes",
555                        (unsigned int) length);
556
557                 /*
558                  *      FIXME: allocate a RADIUS_PACKET, and set
559                  *      "data" to be as large as necessary.
560                  */
561                 if (length > sock->ssn->offset) {
562                         INFO("Received packet will be too large! Set \"fragment_size = %u\"",
563                              (data[2] << 8) | data[3]);
564                         goto do_close;
565                 }
566         }
567
568         /*
569          *      Try to read some more.
570          */
571         if (sock->partial < length) {
572                 rcode = SSL_read(sock->ssn->ssl, data + sock->partial,
573                                  length - sock->partial);
574                 if (rcode <= 0) {
575                         switch (SSL_get_error(sock->ssn->ssl, rcode)) {
576                         case SSL_ERROR_WANT_READ:
577                         case SSL_ERROR_WANT_WRITE:
578                                 return 0;
579
580                         case SSL_ERROR_ZERO_RETURN:
581                                 /* remote end sent close_notify, send one back */
582                                 SSL_shutdown(sock->ssn->ssl);
583                                 goto do_close;
584                         default:
585                                 goto do_close;
586                         }
587                 }
588
589                 sock->partial += rcode;
590         }
591
592         /*
593          *      If we're not done, say so.
594          *
595          *      Otherwise, reset the partially read data flag, and say
596          *      we have a packet.
597          */
598         if (sock->partial < length) {
599                 return 0;
600         }
601
602         return 1;
603 }
604
605
606 int proxy_tls_recv(rad_listen_t *listener)
607 {
608         int rcode;
609         listen_socket_t *sock = listener->data;
610         char buffer[256];
611         RADIUS_PACKET *packet;
612         uint8_t *data;
613
614         if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
615
616         DEBUG3("Proxy SSL socket has data to read");
617         PTHREAD_MUTEX_LOCK(&sock->mutex);
618         rcode = proxy_tls_read(listener);
619         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
620
621         if (rcode < 0) {
622                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
623                 DEBUG("Closing TLS socket to home server");
624                 tls_socket_close(listener);
625                 return 0;
626         }
627
628         if (rcode == 0) return 0; /* no data to read */
629
630         data = sock->data;
631         sock->partial = 0;      /* we've now read the packet */
632
633         packet = rad_alloc(sock, 0);
634         packet->sockfd = listener->fd;
635         packet->src_ipaddr = sock->other_ipaddr;
636         packet->src_port = sock->other_port;
637         packet->dst_ipaddr = sock->my_ipaddr;
638         packet->dst_port = sock->my_port;
639         packet->code = data[0];
640         packet->id = data[1];
641         packet->data_len = (data[2] << 8) | data[3];
642         packet->data = talloc_array(packet, uint8_t, packet->data_len);
643         memcpy(packet->data, data, packet->data_len);
644         memcpy(packet->vector, packet->data + 4, 16);
645
646         /*
647          *      FIXME: Client MIB updates?
648          */
649         switch(packet->code) {
650         case PW_AUTHENTICATION_ACK:
651         case PW_ACCESS_CHALLENGE:
652         case PW_AUTHENTICATION_REJECT:
653                 break;
654
655 #ifdef WITH_ACCOUNTING
656         case PW_ACCOUNTING_RESPONSE:
657                 break;
658 #endif
659
660         default:
661                 /*
662                  *      FIXME: Update MIB for packet types?
663                  */
664                 ERROR("Invalid packet code %d sent to a proxy port "
665                        "from home server %s port %d - ID %d : IGNORED",
666                        packet->code,
667                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
668                        packet->src_port, packet->id);
669                 rad_free(&packet);
670                 return 0;
671         }
672
673         if (!request_proxy_reply(packet)) {
674                 rad_free(&packet);
675                 return 0;
676         }
677
678         return 1;
679 }
680
681
682 int proxy_tls_send(rad_listen_t *listener, REQUEST *request)
683 {
684         int rcode;
685         listen_socket_t *sock = listener->data;
686
687         if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
688
689         /*
690          *      Normal proxying calls us with the data already
691          *      encoded.  The "ping home server" code does not.  So,
692          *      if there's no packet, encode it here.
693          */
694         if (!request->proxy->data) {
695                 request->proxy_listener->encode(request->proxy_listener,
696                                                 request);
697         }
698
699         DEBUG3("Proxy is writing %u bytes to SSL",
700                (unsigned int) request->proxy->data_len);
701         PTHREAD_MUTEX_LOCK(&sock->mutex);
702         while ((rcode = SSL_write(sock->ssn->ssl, request->proxy->data,
703                                   request->proxy->data_len)) < 0) {
704                 int err;
705
706                 err = ERR_get_error();
707                 switch (err) {
708                 case SSL_ERROR_WANT_READ:
709                 case SSL_ERROR_WANT_WRITE:
710                         DEBUG("Retrying proxy TLS write");
711                         break;
712
713                 default:
714                         DEBUG("proxy SSL_write says %s",
715                               ERR_error_string(err, NULL));
716                         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
717                         DEBUG("Closing TLS socket to home server");
718                         tls_socket_close(listener);
719                         return 0;
720                 }
721         }
722         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
723
724         return 1;
725 }
726 #endif  /* WITH_PROXY */
727
728 #endif  /* WITH_TLS */