Replace all radlog/radlog_request calls with macros
[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_REMOVE_FD;
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         DEBUG("Client has closed connection");
94         event_new_fd(listener);
95         
96         /*
97          *      Do NOT free the listener here.  It's in use by
98          *      a request, and will need to hang around until
99          *      all of the requests are done.
100          *
101          *      It is instead free'd in remove_from_request_hash()
102          */
103 }
104
105 static int tls_socket_write(rad_listen_t *listener, REQUEST *request)
106 {
107         uint8_t *p;
108         ssize_t rcode;
109         listen_socket_t *sock = listener->data;
110
111         p = sock->ssn->dirty_out.data;
112         
113         while (p < (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used)) {
114                 RDEBUG3("Writing to socket %d", request->packet->sockfd);
115                 rcode = write(request->packet->sockfd, p,
116                               (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used) - p);
117                 if (rcode <= 0) {
118                         RDEBUG("Error writing to TLS socket: %s", strerror(errno));
119                         
120                         tls_socket_close(listener);
121                         return 0;
122                 }
123                 p += rcode;
124         }
125
126         sock->ssn->dirty_out.used = 0;
127         
128         return 1;
129 }
130
131
132 static int tls_socket_recv(rad_listen_t *listener)
133 {
134         int doing_init = false;
135         ssize_t rcode;
136         RADIUS_PACKET *packet;
137         REQUEST *request;
138         listen_socket_t *sock = listener->data;
139         fr_tls_status_t status;
140         RADCLIENT *client = sock->client;
141
142         if (!sock->packet) {
143                 sock->packet = rad_alloc(NULL, 0);
144                 if (!sock->packet) return 0;
145
146                 sock->packet->sockfd = listener->fd;
147                 sock->packet->src_ipaddr = sock->other_ipaddr;
148                 sock->packet->src_port = sock->other_port;
149                 sock->packet->dst_ipaddr = sock->my_ipaddr;
150                 sock->packet->dst_port = sock->my_port;
151
152                 if (sock->request) {
153                         (void) talloc_steal(sock->request, sock->packet);
154                         sock->request->packet = sock->packet;
155                 }
156         }
157
158         /*
159          *      Allocate a REQUEST for debugging.
160          */
161         if (!sock->request) {
162                 sock->request = request = request_alloc();
163                 if (!sock->request) {
164                         ERROR("Out of memory");
165                         return 0;
166                 }
167
168                 rad_assert(request->packet == NULL);
169                 rad_assert(sock->packet != NULL);
170                 request->packet = sock->packet;
171
172                 request->component = "<core>";
173                 request->component = "<tls-connect>";
174
175                 /*
176                  *      Not sure if we should do this on every packet...
177                  */
178                 request->reply = rad_alloc(request, 0);
179                 if (!request->reply) return 0;
180
181                 request->options = RAD_REQUEST_OPTION_DEBUG2;
182
183                 rad_assert(sock->ssn == NULL);
184
185                 sock->ssn = tls_new_session(listener->tls, sock->request,
186                                             listener->tls->require_client_cert);
187                 if (!sock->ssn) {
188                         request_free(&sock->request);
189                         sock->packet = NULL;
190                         return 0;
191                 }
192
193                 (void) talloc_steal(sock, sock->ssn);
194                 SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_REQUEST, (void *)request);
195                 SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_CERTS, (void *)&request->packet->vps);
196
197                 doing_init = true;
198         }
199
200         rad_assert(sock->request != NULL);
201         rad_assert(sock->request->packet != NULL);
202         rad_assert(sock->packet != NULL);
203         rad_assert(sock->ssn != NULL);
204
205         request = sock->request;
206
207         RDEBUG3("Reading from socket %d", request->packet->sockfd);
208         PTHREAD_MUTEX_LOCK(&sock->mutex);
209         rcode = read(request->packet->sockfd,
210                      sock->ssn->dirty_in.data,
211                      sizeof(sock->ssn->dirty_in.data));
212         if ((rcode < 0) && (errno == ECONNRESET)) {
213         do_close:
214                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
215                 tls_socket_close(listener);
216                 return 0;
217         }
218         
219         if (rcode < 0) {
220                 RDEBUG("Error reading TLS socket: %s", strerror(errno));
221                 goto do_close;
222         }
223
224         /*
225          *      Normal socket close.
226          */
227         if (rcode == 0) goto do_close;
228         
229         sock->ssn->dirty_in.used = rcode;
230
231         dump_hex("READ FROM SSL", sock->ssn->dirty_in.data, sock->ssn->dirty_in.used);
232
233         /*
234          *      Catch attempts to use non-SSL.
235          */
236         if (doing_init && (sock->ssn->dirty_in.data[0] != handshake)) {
237                 RDEBUG("Non-TLS data sent to TLS socket: closing");
238                 goto do_close;
239         }
240         
241         /*
242          *      Skip ahead to reading application data.
243          */
244         if (SSL_is_init_finished(sock->ssn->ssl)) goto app;
245
246         if (!tls_handshake_recv(request, sock->ssn)) {
247                 RDEBUG("FAILED in TLS handshake receive");
248                 goto do_close;
249         }
250         
251         if (sock->ssn->dirty_out.used > 0) {
252                 tls_socket_write(listener, request);
253                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
254                 return 0;
255         }
256
257 app:
258         /*
259          *      FIXME: Run the packet through a virtual server in
260          *      order to see if we like the certificate presented by
261          *      the client.
262          */
263
264         status = tls_application_data(sock->ssn, request);
265         RDEBUG("Application data status %d", status);
266
267         if (status == FR_TLS_MORE_FRAGMENTS) {
268                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
269                 return 0;
270         }
271
272         if (sock->ssn->clean_out.used == 0) {
273                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
274                 return 0;
275         }
276
277         dump_hex("TUNNELED DATA", sock->ssn->clean_out.data, sock->ssn->clean_out.used);
278
279         /*
280          *      If the packet is a complete RADIUS packet, return it to
281          *      the caller.  Otherwise...
282          */
283         if ((sock->ssn->clean_out.used < 20) ||
284             (((sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]) != (int) sock->ssn->clean_out.used)) {
285                 RDEBUG("Received bad packet: Length %d contents %d",
286                        sock->ssn->clean_out.used,
287                        (sock->ssn->clean_out.data[2] << 8) | sock->ssn->clean_out.data[3]);
288                 goto do_close;
289         }
290
291         packet = sock->packet;
292         packet->data = talloc_array(packet, uint8_t, sock->ssn->clean_out.used);
293         packet->data_len = sock->ssn->clean_out.used;
294         sock->ssn->record_minus(&sock->ssn->clean_out, packet->data, packet->data_len);
295         packet->vps = NULL;
296         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
297
298         if (!rad_packet_ok(packet, 0)) {
299                 RDEBUG("Received bad packet: %s", fr_strerror());
300                 tls_socket_close(listener);
301                 return 0;       /* do_close unlocks the mutex */
302         }
303
304         /*
305          *      Copied from src/lib/radius.c, rad_recv();
306          */
307         if (fr_debug_flag) {
308                 char host_ipaddr[128];
309
310                 if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
311                         RDEBUG("tls_recv: %s packet from host %s port %d, id=%d, length=%d",
312                                fr_packet_codes[packet->code],
313                                inet_ntop(packet->src_ipaddr.af,
314                                          &packet->src_ipaddr.ipaddr,
315                                          host_ipaddr, sizeof(host_ipaddr)),
316                                packet->src_port,
317                                packet->id, (int) packet->data_len);
318                 } else {
319                         RDEBUG("tls_recv: Packet from host %s port %d code=%d, id=%d, length=%d",
320                                inet_ntop(packet->src_ipaddr.af,
321                                          &packet->src_ipaddr.ipaddr,
322                                          host_ipaddr, sizeof(host_ipaddr)),
323                                packet->src_port,
324                                packet->code,
325                                packet->id, (int) packet->data_len);
326                 }
327         }
328
329         FR_STATS_INC(auth, total_requests);
330
331         return 1;
332 }
333
334
335 int dual_tls_recv(rad_listen_t *listener)
336 {
337         RADIUS_PACKET *packet;
338         REQUEST *request;
339         RAD_REQUEST_FUNP fun = NULL;
340         listen_socket_t *sock = listener->data;
341         RADCLIENT       *client = sock->client;
342
343         if (!tls_socket_recv(listener)) {
344                 return 0;
345         }
346
347         rad_assert(sock->request != NULL);
348         rad_assert(sock->request->packet != NULL);
349         rad_assert(sock->packet != NULL);
350         rad_assert(sock->ssn != NULL);
351
352         request = sock->request;
353         packet = sock->packet;
354
355         /*
356          *      Some sanity checks, based on the packet code.
357          */
358         switch(packet->code) {
359         case PW_AUTHENTICATION_REQUEST:
360                 if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
361                 FR_STATS_INC(auth, total_requests);
362                 fun = rad_authenticate;
363                 break;
364
365         case PW_ACCOUNTING_REQUEST:
366                 if (listener->type != RAD_LISTEN_ACCT) goto bad_packet;
367                 FR_STATS_INC(acct, total_requests);
368                 fun = rad_accounting;
369                 break;
370
371         case PW_STATUS_SERVER:
372                 if (!mainconfig.status_server) {
373                         FR_STATS_INC(auth, total_unknown_types);
374                         WDEBUG("Ignoring Status-Server request due to security configuration");
375                         rad_free(&sock->packet);
376                         request->packet = NULL;
377                         return 0;
378                 }
379                 fun = rad_status_server;
380                 break;
381
382         default:
383         bad_packet:
384                 FR_STATS_INC(auth, total_unknown_types);
385
386                 DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED",
387                       packet->code, client->shortname, packet->src_port);
388                 rad_free(&sock->packet);
389                 request->packet = NULL;
390                 return 0;
391         } /* switch over packet types */
392
393         if (!request_receive(listener, packet, client, fun)) {
394                 FR_STATS_INC(auth, total_packets_dropped);
395                 rad_free(&sock->packet);
396                 request->packet = NULL;
397                 return 0;
398         }
399
400         sock->packet = NULL;    /* we have no need for more partial reads */
401         request->packet = NULL;
402
403         return 1;
404 }
405
406
407 /*
408  *      Send a response packet
409  */
410 int dual_tls_send(rad_listen_t *listener, REQUEST *request)
411 {
412         listen_socket_t *sock = listener->data;
413
414         rad_assert(request->listener == listener);
415         rad_assert(listener->send == dual_tls_send);
416
417         /*
418          *      Accounting reject's are silently dropped.
419          *
420          *      We do it here to avoid polluting the rest of the
421          *      code with this knowledge
422          */
423         if (request->reply->code == 0) return 0;
424
425         /*
426          *      Pack the VPs
427          */
428         if (rad_encode(request->reply, request->packet,
429                        request->client->secret) < 0) {
430                 RDEBUG("Failed encoding packet: %s", fr_strerror());
431                 return 0;
432         }
433
434         /*
435          *      Sign the packet.
436          */
437         if (rad_sign(request->reply, request->packet,
438                        request->client->secret) < 0) {
439                 RDEBUG("Failed signing packet: %s", fr_strerror());
440                 return 0;
441         }
442         
443         PTHREAD_MUTEX_LOCK(&sock->mutex);
444         /*
445          *      Write the packet to the SSL buffers.
446          */
447         sock->ssn->record_plus(&sock->ssn->clean_in,
448                                request->reply->data, request->reply->data_len);
449
450         /*
451          *      Do SSL magic to get encrypted data.
452          */
453         tls_handshake_send(request, sock->ssn);
454
455         /*
456          *      And finally write the data to the socket.
457          */
458         if (sock->ssn->dirty_out.used > 0) {
459                 dump_hex("WRITE TO SSL", sock->ssn->dirty_out.data, sock->ssn->dirty_out.used);
460
461                 tls_socket_write(listener, request);
462         }
463         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
464
465         return 0;
466 }
467
468
469 int proxy_tls_recv(rad_listen_t *listener)
470 {
471         int rcode;
472         size_t length;
473         listen_socket_t *sock = listener->data;
474         char buffer[256];
475         RADIUS_PACKET *packet;
476         uint8_t *data;
477
478         /*
479          *      Get the maximum size of data to receive.
480          */
481         if (!sock->data) sock->data = talloc_array(sock, uint8_t,
482                                                    sock->ssn->offset);
483         data = sock->data;
484
485         DEBUG3("Proxy SSL socket has data to read");
486         PTHREAD_MUTEX_LOCK(&sock->mutex);
487 redo:
488         rcode = SSL_read(sock->ssn->ssl, data, 4);
489         if (rcode <= 0) {
490                 int err = SSL_get_error(sock->ssn->ssl, rcode);
491                 switch (err) {
492                 case SSL_ERROR_WANT_READ:
493                 case SSL_ERROR_WANT_WRITE:
494                         goto redo;
495
496                 case SSL_ERROR_ZERO_RETURN:
497                         /* remote end sent close_notify, send one back */
498                         SSL_shutdown(sock->ssn->ssl);
499
500                 case SSL_ERROR_SYSCALL:
501                 do_close:
502                         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
503                         tls_socket_close(listener);
504                         return 0;
505
506                 default:
507                         while ((err = ERR_get_error())) {
508                                 DEBUG("proxy recv says %s",
509                                       ERR_error_string(err, NULL));
510                         }
511                         
512                         goto do_close;
513                 }
514         }
515
516         length = (data[2] << 8) | data[3];
517         DEBUG3("Proxy received header saying we have a packet of %u bytes",
518                (unsigned int) length);
519
520         if (length > sock->ssn->offset) {
521                 INFO("Received packet will be too large! Set \"fragment_size=%u\"",
522                        (data[2] << 8) | data[3]);
523                 goto do_close;
524         }
525         
526         rcode = SSL_read(sock->ssn->ssl, data + 4, length);
527         if (rcode <= 0) {
528                 switch (SSL_get_error(sock->ssn->ssl, rcode)) {
529                 case SSL_ERROR_WANT_READ:
530                 case SSL_ERROR_WANT_WRITE:
531                         break;
532
533                 case SSL_ERROR_ZERO_RETURN:
534                         /* remote end sent close_notify, send one back */
535                         SSL_shutdown(sock->ssn->ssl);
536                         goto do_close;
537                 default:
538                         goto do_close;
539                 }
540         }
541         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
542
543         packet = rad_alloc(NULL, 0);
544         packet->sockfd = listener->fd;
545         packet->src_ipaddr = sock->other_ipaddr;
546         packet->src_port = sock->other_port;
547         packet->dst_ipaddr = sock->my_ipaddr;
548         packet->dst_port = sock->my_port;
549         packet->code = data[0];
550         packet->id = data[1];
551         packet->data_len = length;
552         packet->data = talloc_array(packet, uint8_t, packet->data_len);
553         memcpy(packet->data, data, packet->data_len);
554         memcpy(packet->vector, packet->data + 4, 16);
555
556         /*
557          *      FIXME: Client MIB updates?
558          */
559         switch(packet->code) {
560         case PW_AUTHENTICATION_ACK:
561         case PW_ACCESS_CHALLENGE:
562         case PW_AUTHENTICATION_REJECT:
563                 break;
564
565 #ifdef WITH_ACCOUNTING
566         case PW_ACCOUNTING_RESPONSE:
567                 break;
568 #endif
569
570         default:
571                 /*
572                  *      FIXME: Update MIB for packet types?
573                  */
574                 ERROR("Invalid packet code %d sent to a proxy port "
575                        "from home server %s port %d - ID %d : IGNORED",
576                        packet->code,
577                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
578                        packet->src_port, packet->id);
579                 rad_free(&packet);
580                 return 0;
581         }
582
583         if (!request_proxy_reply(packet)) {
584                 rad_free(&packet);
585                 return 0;
586         }
587
588         return 1;
589 }
590
591 int proxy_tls_send(rad_listen_t *listener, REQUEST *request)
592 {
593         int rcode;
594         listen_socket_t *sock = listener->data;
595
596         /*
597          *      Normal proxying calls us with the data already
598          *      encoded.  The "ping home server" code does not.  So,
599          *      if there's no packet, encode it here.
600          */
601         if (!request->proxy->data) {
602                 request->proxy_listener->encode(request->proxy_listener,
603                                                 request);
604         }
605
606         DEBUG3("Proxy is writing %u bytes to SSL",
607                (unsigned int) request->proxy->data_len);
608         PTHREAD_MUTEX_LOCK(&sock->mutex);
609         while ((rcode = SSL_write(sock->ssn->ssl, request->proxy->data,
610                                   request->proxy->data_len)) < 0) {
611                 int err;
612                 while ((err = ERR_get_error())) {
613                         DEBUG("proxy SSL_write says %s",
614                               ERR_error_string(err, NULL));
615                 }
616                 PTHREAD_MUTEX_UNLOCK(&sock->mutex);
617                 tls_socket_close(listener);
618                 return 0;
619         }
620         PTHREAD_MUTEX_UNLOCK(&sock->mutex);
621
622         return 1;
623 }
624
625 #endif  /* WITH_TLS */