root/src/noit_listener.c

Revision 5c3b2beac55664af9541cf140da10ab73a8ef00e, 19.1 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 months ago)

Support spefication of SSL layer (SSLv3, SSLv2, TLSv1, TLSv1.1 and TLSv1.2).

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34
35 #include <unistd.h>
36 #include <errno.h>
37 #include <sys/time.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <sys/un.h>
42 #include <arpa/inet.h>
43 #include <assert.h>
44
45 #include "eventer/eventer.h"
46 #include "utils/noit_log.h"
47 #include "noit_listener.h"
48 #include "noit_conf.h"
49
50 static noit_log_stream_t nlerr = NULL;
51 static noit_log_stream_t nldeb = NULL;
52 static noit_hash_table listener_commands = NOIT_HASH_EMPTY;
53 noit_hash_table *
54 noit_listener_commands() {
55   return &listener_commands;
56 }
57
58 void
59 acceptor_closure_free(acceptor_closure_t *ac) {
60   if(ac->remote_cn) free(ac->remote_cn);
61   if(ac->service_ctx_free && ac->service_ctx)
62     ac->service_ctx_free(ac->service_ctx);
63   free(ac);
64 }
65
66 static struct avoid_listener {
67   char *address;
68   int port;
69   struct avoid_listener *next;
70 } *listener_avoid_list;
71 void
72 noit_listener_skip(const char *address, int port) {
73   struct avoid_listener *al;
74   al = calloc(1, sizeof(*al));
75   al->address = address ? strdup(address) : NULL;
76   al->port = port;
77   al->next = listener_avoid_list;
78   listener_avoid_list = al;
79 }
80 static noit_boolean
81 noit_listener_should_skip(const char *address, int port) {
82   struct avoid_listener *al;
83   for(al = listener_avoid_list; al; al = al->next)
84     if(al->port == port &&
85        (al->address == NULL || !strcmp(address, al->address)))
86       return noit_true;
87   return noit_false;
88 }
89
90 static int
91 noit_listener_accept_ssl(eventer_t e, int mask,
92                          void *closure, struct timeval *tv) {
93   int rv;
94   listener_closure_t listener_closure = (listener_closure_t)closure;
95   acceptor_closure_t *ac = NULL;
96   if(!closure) goto socketfail;
97   ac = listener_closure->dispatch_closure;
98
99   rv = eventer_SSL_accept(e, &mask);
100   if(rv > 0) {
101     eventer_ssl_ctx_t *sslctx;
102     e->callback = listener_closure->dispatch_callback;
103     /* We must make a copy of the acceptor_closure_t for each new
104      * connection.
105      */
106     if((sslctx = eventer_get_eventer_ssl_ctx(e)) != NULL) {
107       const char *cn, *end;
108       cn = eventer_ssl_get_peer_subject(sslctx);
109       if(cn && (cn = strstr(cn, "CN=")) != NULL) {
110         cn += 3;
111         end = cn;
112         while(*end && *end != '/') end++;
113         ac->remote_cn = malloc(end - cn + 1);
114         memcpy(ac->remote_cn, cn, end - cn);
115         ac->remote_cn[end-cn] = '\0';
116       }
117     }
118     e->closure = ac;
119     noitL(nldeb, "noit_listener[%s] SSL_accept on fd %d [%s]\n",
120           eventer_name_for_callback_e(e->callback, e),
121           e->fd, ac->remote_cn ? ac->remote_cn : "anonymous");
122     if(listener_closure) free(listener_closure);
123     return e->callback(e, mask, e->closure, tv);
124   }
125   if(errno == EAGAIN) return mask|EVENTER_EXCEPTION;
126
127  socketfail:
128   if(listener_closure) free(listener_closure);
129   if(ac) acceptor_closure_free(ac);
130   eventer_remove_fd(e->fd);
131   e->opset->close(e->fd, &mask, e);
132   return 0;
133 }
134
135 static void
136 noit_listener_details(char *buf, int buflen, eventer_t e, void *closure) {
137   char sbuf[128];
138   const char *sbufptr;
139   struct _event stub;
140   listener_closure_t listener_closure = e->closure;
141
142   stub.callback = listener_closure->dispatch_callback;
143   stub.closure = listener_closure->dispatch_closure;
144   sbufptr = eventer_name_for_callback_e(stub.callback, &stub);
145   strlcpy(sbuf, sbufptr, sizeof(sbuf));
146   snprintf(buf, buflen, "listener(%s)", sbuf);
147 }
148
149 static int
150 noit_listener_acceptor(eventer_t e, int mask,
151                        void *closure, struct timeval *tv) {
152   int conn, newmask = EVENTER_READ;
153   socklen_t salen;
154   listener_closure_t listener_closure = (listener_closure_t)closure;
155   acceptor_closure_t *ac = NULL;
156
157   if(mask & EVENTER_EXCEPTION) {
158  socketfail:
159     if(ac) acceptor_closure_free(ac);
160     /* We don't shut down the socket, it's out listener! */
161     return EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION;
162   }
163
164   do {
165     ac = malloc(sizeof(*ac));
166     memcpy(ac, listener_closure->dispatch_closure, sizeof(*ac));
167     salen = sizeof(ac->remote);
168     conn = e->opset->accept(e->fd, &ac->remote.remote_addr, &salen, &newmask, e);
169     if(conn >= 0) {
170       eventer_t newe;
171       noitL(nldeb, "noit_listener[%s] accepted fd %d\n",
172             eventer_name_for_callback(listener_closure->dispatch_callback),
173             conn);
174       if(eventer_set_fd_nonblocking(conn)) {
175         close(conn);
176         free(ac);
177         goto accept_bail;
178       }
179       newe = eventer_alloc();
180       newe->fd = conn;
181       newe->mask = EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION;
182  
183       if(listener_closure->sslconfig->size) {
184         const char *layer, *cert, *key, *ca, *ciphers, *crl;
185         eventer_ssl_ctx_t *ctx;
186         /* We have an SSL configuration.  While our socket accept is
187          * complete, we now have to SSL_accept, which could require
188          * several reads and writes and needs its own event callback.
189          */
190   #define SSLCONFGET(var,name) do { \
191     if(!noit_hash_retr_str(listener_closure->sslconfig, name, strlen(name), \
192                            &var)) var = NULL; } while(0)
193         SSLCONFGET(layer, "layer");
194         SSLCONFGET(cert, "certificate_file");
195         SSLCONFGET(key, "key_file");
196         SSLCONFGET(ca, "ca_chain");
197         SSLCONFGET(ciphers, "ciphers");
198         ctx = eventer_ssl_ctx_new(SSL_SERVER, layer, cert, key, ca, ciphers);
199         if(!ctx) {
200           newe->opset->close(newe->fd, &newmask, e);
201           eventer_free(newe);
202           goto socketfail;
203         }
204         SSLCONFGET(crl, "crl");
205         if(crl) {
206           if(!eventer_ssl_use_crl(ctx, crl)) {
207             noitL(noit_error, "Failed to load CRL from %s\n", crl);
208             eventer_ssl_ctx_free(ctx);
209             newe->opset->close(newe->fd, &newmask, e);
210             eventer_free(newe);
211             goto socketfail;
212           }
213         }
214
215         eventer_ssl_ctx_set_verify(ctx, eventer_ssl_verify_cert,
216                                    listener_closure->sslconfig);
217         EVENTER_ATTACH_SSL(newe, ctx);
218         newe->callback = noit_listener_accept_ssl;
219         newe->closure = malloc(sizeof(*listener_closure));
220         memcpy(newe->closure, listener_closure, sizeof(*listener_closure));
221         ((listener_closure_t)newe->closure)->dispatch_closure = ac;
222       }
223       else {
224         newe->callback = listener_closure->dispatch_callback;
225         /* We must make a copy of the acceptor_closure_t for each new
226          * connection.
227          */
228         newe->closure = ac;
229       }
230       eventer_add(newe);
231     }
232     else {
233       if(errno == EAGAIN) {
234         if(ac) acceptor_closure_free(ac);
235       }
236       else if(errno != EINTR) {
237         noitL(noit_error, "accept socket error: %s\n", strerror(errno));
238         goto socketfail;
239       }
240     }
241   } while(conn >= 0);
242  accept_bail:
243   return newmask | EVENTER_EXCEPTION;
244 }
245
246 int
247 noit_listener(char *host, unsigned short port, int type,
248               int backlog, noit_hash_table *sslconfig,
249               noit_hash_table *config,
250               eventer_func_t handler, void *service_ctx) {
251   int rv, fd;
252   int8_t family;
253   int sockaddr_len;
254   socklen_t reuse;
255   listener_closure_t listener_closure;
256   eventer_t event;
257   union {
258     struct in_addr addr4;
259     struct in6_addr addr6;
260   } a;
261   union {
262     struct sockaddr_in addr4;
263     struct sockaddr_in6 addr6;
264     struct sockaddr_un addru;
265   } s;
266   const char *event_name;
267
268   noitL(nldeb, "noit_listener(%s, %d, %d, %d, %s, %p)\n",
269         host, port, type, backlog,
270         (event_name = eventer_name_for_callback(handler))?event_name:"??",
271         service_ctx);
272   if(host[0] == '/') {
273     family = AF_UNIX;
274   }
275   else {
276     family = AF_INET;
277     rv = inet_pton(family, host, &a);
278     if(rv != 1) {
279       family = AF_INET6;
280       rv = inet_pton(family, host, &a);
281       if(rv != 1) {
282         if(!strcmp(host, "*")) {
283           family = AF_INET;
284           a.addr4.s_addr = INADDR_ANY;
285         } else {
286           noitL(noit_error, "Cannot translate '%s' to IP\n", host);
287           return -1;
288         }
289       }
290     }
291   }
292
293   fd = socket(family, NE_SOCK_CLOEXEC|type, 0);
294   if(fd < 0) {
295     noitL(noit_error, "Cannot create socket: %s\n", strerror(errno));
296     return -1;
297   }
298
299   if(eventer_set_fd_nonblocking(fd)) {
300     close(fd);
301     noitL(noit_error, "Cannot make socket non-blocking: %s\n",
302           strerror(errno));
303     return -1;
304   }
305
306   reuse = 1;
307   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
308                  (void*)&reuse, sizeof(reuse)) != 0) {
309     close(fd);
310     noitL(noit_error, "Cannot set SO_REUSEADDR: %s\n", strerror(errno));
311     return -1;
312   }
313
314   memset(&s, 0, sizeof(s));
315   if(family == AF_UNIX) {
316     struct stat sb;
317     /* unlink the path if it is a socket */
318     /* coverity[fs_check_call] */
319     if(stat(host, &sb) == -1) {
320       if(errno != ENOENT) {
321         noitL(noit_error, "%s: %s\n", host, strerror(errno));
322         close(fd);
323         return -1;
324       }
325     }
326     else {
327       if(sb.st_mode & S_IFSOCK) {
328         /* coverity[toctou] */
329         unlink(host);
330       }
331       else {
332         noitL(noit_error, "unlink %s failed: %s\n", host, strerror(errno));
333         close(fd);
334         return -1;
335       }
336     }
337     s.addru.sun_family = AF_UNIX;
338     strncpy(s.addru.sun_path, host, sizeof(s.addru.sun_path)-1);
339     sockaddr_len = sizeof(s.addru);
340   }
341   else {
342     if(family == AF_INET6) {
343       s.addr6.sin6_family = family;
344       s.addr6.sin6_port = htons(port);
345       memcpy(&s.addr6.sin6_addr, &a.addr6, sizeof(a.addr6));
346     }
347     else {
348       s.addr4.sin_family = family;
349       s.addr4.sin_port = htons(port);
350       memcpy(&s.addr4.sin_addr, &a.addr4, sizeof(a.addr4));
351     }
352     sockaddr_len = (family == AF_INET) ?  sizeof(s.addr4) : sizeof(s.addr6);
353   }
354   if(bind(fd, (struct sockaddr *)&s, sockaddr_len) < 0) {
355     noitL(noit_error, "bind failed[%s]: %s\n", host, strerror(errno));
356     close(fd);
357     return -1;
358   }
359
360   if(type == SOCK_STREAM) {
361     if(listen(fd, backlog) < 0) {
362       close(fd);
363       return -1;
364     }
365   }
366
367   listener_closure = calloc(1, sizeof(*listener_closure));
368   listener_closure->family = family;
369   listener_closure->port = htons(port);
370   listener_closure->sslconfig = calloc(1, sizeof(noit_hash_table));
371   noit_hash_merge_as_dict(listener_closure->sslconfig, sslconfig);
372   listener_closure->dispatch_callback = handler;
373
374   listener_closure->dispatch_closure =
375     calloc(1, sizeof(*listener_closure->dispatch_closure));
376   listener_closure->dispatch_closure->config = config;
377   listener_closure->dispatch_closure->dispatch = handler;
378   listener_closure->dispatch_closure->service_ctx = service_ctx;
379
380   event = eventer_alloc();
381   event->fd = fd;
382   event->mask = EVENTER_READ | EVENTER_EXCEPTION;
383   event->callback = noit_listener_acceptor;
384   event->closure = listener_closure;
385
386   eventer_add(event);
387   return 0;
388 }
389
390 void
391 noit_listener_reconfig(const char *toplevel) {
392   int i, cnt = 0;
393   noit_conf_section_t *listener_configs;
394   char path[256];
395
396   snprintf(path, sizeof(path), "/%s/listeners//listener",
397            toplevel ? toplevel : "*");
398   listener_configs = noit_conf_get_sections(NULL, path, &cnt);
399   noitL(noit_debug, "Found %d %s stanzas\n", cnt, path);
400   for(i=0; i<cnt; i++) {
401     char address[256];
402     char type[256];
403     unsigned short port;
404     int portint;
405     int backlog;
406     eventer_func_t f;
407     noit_boolean ssl;
408     noit_hash_table *sslconfig, *config;
409
410     if(!noit_conf_get_stringbuf(listener_configs[i],
411                                 "ancestor-or-self::node()/@type",
412                                 type, sizeof(type))) {
413       noitL(noit_error, "No type specified in listener stanza %d\n", i+1);
414       continue;
415     }
416     f = eventer_callback_for_name(type);
417     if(!f) {
418       noitL(noit_error,
419             "Cannot find handler for listener type: '%s'\n", type);
420       continue;
421     }
422     if(!noit_conf_get_stringbuf(listener_configs[i],
423                                 "ancestor-or-self::node()/@address",
424                                 address, sizeof(address))) {
425       address[0] = '*';
426       address[1] = '\0';
427     }
428     if(!noit_conf_get_int(listener_configs[i],
429                           "ancestor-or-self::node()/@port", &portint))
430       portint = 0;
431     port = (unsigned short) portint;
432     if(address[0] != '/' && (portint == 0 || (port != portint))) {
433       /* UNIX sockets don't require a port (they'll ignore it if specified */
434       noitL(noit_error,
435             "Invalid port [%d] specified in stanza %d\n", port, i+1);
436       continue;
437     }
438     if(noit_listener_should_skip(address, port)) {
439       if(port)
440         noitL(noit_error, "Operator forced skipping listener %s:%d\n", address, port);
441       else
442         noitL(noit_error, "Operator forced skipping listener %s\n", address);
443       continue;
444     }
445     if(!noit_conf_get_int(listener_configs[i],
446                           "ancestor-or-self::node()/@backlog", &backlog))
447       backlog = 5;
448
449     if(!noit_conf_get_boolean(listener_configs[i],
450                               "ancestor-or-self::node()/@ssl", &ssl))
451      ssl = noit_false;
452
453     sslconfig = ssl ?
454                   noit_conf_get_hash(listener_configs[i], "sslconfig") :
455                   NULL;
456     config = noit_conf_get_hash(listener_configs[i], "config");
457
458     if(noit_listener(address, port, SOCK_STREAM, backlog,
459                      sslconfig, config, f, NULL) != 0) {
460       noit_hash_destroy(config,free,free);
461       free(config);
462     }
463     if(sslconfig) {
464       /* A copy of this is made within noit_listener */
465       noit_hash_destroy(sslconfig,free,free);
466       free(sslconfig);
467     }
468   }
469   free(listener_configs);
470 }
471 int
472 noit_control_dispatch(eventer_t e, int mask, void *closure,
473                       struct timeval *now) {
474   u_int32_t cmd;
475   int len = 0, callmask = mask;
476   void *vdelegation_table;
477   noit_hash_table *delegation_table = NULL;
478   acceptor_closure_t *ac = closure;
479
480   assert(ac->rlen >= 0);
481   while(len >= 0 && ac->rlen < sizeof(cmd)) {
482     len = e->opset->read(e->fd, ((char *)&cmd) + ac->rlen,
483                          sizeof(cmd) - ac->rlen, &mask, e);
484     if(len == -1 && errno == EAGAIN)
485       return EVENTER_READ | EVENTER_EXCEPTION;
486
487     if(len > 0) ac->rlen += len;
488   }
489   assert(ac->rlen >= 0 && ac->rlen <= sizeof(cmd));
490
491   if(callmask & EVENTER_EXCEPTION || ac->rlen != sizeof(cmd)) {
492     int newmask;
493 socket_error:
494     /* Exceptions cause us to simply snip the connection */
495     eventer_remove_fd(e->fd);
496     e->opset->close(e->fd, &newmask, e);
497     acceptor_closure_free(ac);
498     return 0;
499   }
500
501   ac->cmd = ntohl(cmd);
502   /* Lookup cmd and dispatch */
503   if(noit_hash_retrieve(&listener_commands,
504                         (char *)&ac->dispatch, sizeof(ac->dispatch),
505                         (void **)&vdelegation_table)) {
506     void *vfunc;
507     delegation_table = (noit_hash_table *)vdelegation_table;
508     if(noit_hash_retrieve(delegation_table,
509                           (char *)&ac->cmd, sizeof(ac->cmd), &vfunc)) {
510       e->callback = *((eventer_func_t *)vfunc);
511       return e->callback(e, callmask, closure, now);
512     }
513     else {
514     const char *event_name;
515       noitL(noit_error, "listener (%s %p) has no command: 0x%08x\n",
516             (event_name = eventer_name_for_callback(ac->dispatch))?event_name:"???",
517             delegation_table, cmd);
518     }
519   }
520   else {
521     const char *event_name;
522     noitL(noit_error, "No delegation table for listener (%s %p)\n",
523           (event_name = eventer_name_for_callback(ac->dispatch))?event_name:"???",
524           delegation_table);
525   }
526   goto socket_error;
527 }
528 void
529 noit_control_dispatch_delegate(eventer_func_t listener_dispatch,
530                                u_int32_t cmd,
531                                eventer_func_t delegate_dispatch) {
532   u_int32_t *cmd_copy;
533   eventer_func_t *handler_copy;
534   void *vdelegation_table;
535   noit_hash_table *delegation_table;
536   if(!noit_hash_retrieve(&listener_commands,
537                          (char *)&listener_dispatch, sizeof(listener_dispatch),
538                          &vdelegation_table)) {
539     delegation_table = calloc(1, sizeof(*delegation_table));
540     handler_copy = malloc(sizeof(*handler_copy));
541     *handler_copy = listener_dispatch;
542     noit_hash_store(&listener_commands,
543                     (char *)handler_copy, sizeof(*handler_copy),
544                     delegation_table);
545   }
546   else
547     delegation_table = (noit_hash_table *)vdelegation_table;
548
549   cmd_copy = malloc(sizeof(*cmd_copy));
550   *cmd_copy = cmd;
551   handler_copy = malloc(sizeof(*handler_copy));
552   *handler_copy = delegate_dispatch;
553   noit_hash_replace(delegation_table,
554                     (char *)cmd_copy, sizeof(*cmd_copy),
555                     handler_copy,
556                     free, free);
557 }
558
559 int
560 noit_convert_sockaddr_to_buff(char *buff, int blen, struct sockaddr *remote) {
561   char name[128] = "";
562   buff[0] = '\0';
563   if(remote) {
564     int len = 0;
565     switch(remote->sa_family) {
566       case AF_INET:
567         len = sizeof(struct sockaddr_in);
568         inet_ntop(remote->sa_family, &((struct sockaddr_in *)remote)->sin_addr,
569                   name, len);
570         break;
571       case AF_INET6:
572        len = sizeof(struct sockaddr_in6);
573         inet_ntop(remote->sa_family, &((struct sockaddr_in6 *)remote)->sin6_addr,
574                   name, len);
575        break;
576       case AF_UNIX:
577         snprintf(name, sizeof(name), "%s", ((struct sockaddr_un *)remote)->sun_path);
578         break;
579       default: return 0;
580     }
581   }
582   strlcpy(buff, name, blen);
583   return strlen(buff);
584 }
585
586 void
587 noit_listener_init(const char *toplevel) {
588   nlerr = noit_log_stream_find("error/listener");
589   nldeb = noit_log_stream_find("debug/listener");
590   if(!nlerr) nlerr = noit_error;
591   if(!nldeb) nldeb = noit_debug;
592   eventer_name_callback_ext("noit_listener_acceptor", noit_listener_acceptor,
593                             noit_listener_details, NULL);
594   eventer_name_callback("noit_listener_accept_ssl", noit_listener_accept_ssl);
595   eventer_name_callback("control_dispatch", noit_control_dispatch);
596   noit_listener_reconfig(toplevel);
597 }
598
Note: See TracBrowser for help on using the browser.