Changeset b7ec8071a69b07dca745fa521b287c9f4ffec06e

Show
Ignore:
Timestamp:
02/21/08 20:39:44 (6 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1203626384 +0000
git-parent:

[b7d1fe90ade5801d7ff5a7292a5b81478def06b2]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1203626384 +0000
Message:

SSL support that doesn't quite work -- so so so close.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • configure.in

    r37a1f1d rb7ec807  
    6161AC_CHECK_LIB(termcap, tputs, , ) 
    6262AC_CHECK_LIB(curses, clear, , ) 
     63AC_CHECK_LIB(ssl, SSL_library_init, , 
     64        [ 
     65                AC_MSG_ERROR([libssl not found, but required]) 
     66        ] 
     67) 
     68AC_CHECK_LIB(crypto, ERR_load_CRYPTO_strings, , 
     69        [ 
     70                AC_MSG_ERROR([libssl not found, but required]) 
     71        ] 
     72) 
    6373 
    6474AC_MSG_CHECKING([libxml2 cflags]) 
  • src/Makefile.in

    r7b92762 rb7ec807  
    5555        re2c -o $@ noit_tokenizer.re 
    5656 
     57test.key: 
     58        openssl genrsa -out test.key 
     59 
     60test.csr:       test.key 
     61        openssl req -key test.key -days 365 -new -out test.csr 
     62 
     63test.crt:       test.key test.crt 
     64        openssl x509 -req -in test.csr -signkey test.key -out test.crt 
     65 
     66testcerts:      test.key test.crt 
     67 
    5768clean-subdirs: 
    5869        for dir in $(SUBS) ; do \ 
     
    6172 
    6273clean:  clean-subdirs 
    63         rm -f *.o noitd 
     74        rm -f *.o noitd test.key test.csr test.crt 
    6475 
  • src/eventer/Makefile.in

    r3b3b432 rb7ec807  
    1313        eventer_kqueue_impl.o \ 
    1414        eventer_POSIX_fd_opset.o \ 
     15        eventer_SSL_fd_opset.o \ 
    1516        eventer_jobq.o 
    1617 
  • src/eventer/eventer.h

    r3b3b432 rb7ec807  
    2121 
    2222/* All of these functions act like their POSIX couterparts with two 
    23  * additional arguments.  The first is the mask they require o be active 
     23 * additional arguments.  The first is the mask they require to be active 
    2424 * to make progress in the event of an EAGAIN.  The second is a closure 
    2525 * which is the event itself. 
     
    4242 
    4343typedef struct _event *eventer_t; 
     44 
     45#include "eventer/eventer_POSIX_fd_opset.h" 
     46#include "eventer/eventer_SSL_fd_opset.h" 
     47 
    4448typedef int (*eventer_func_t) 
    4549            (eventer_t e, int mask, void *closure, struct timeval *tv); 
     
    5155  int                 mask; 
    5256  eventer_fd_opset_t  opset; 
     57  void               *opset_ctx; 
    5358  void *closure; 
    5459}; 
  • src/eventer/eventer_impl.c

    r3b3b432 rb7ec807  
    5050  int i; 
    5151  eventer_t e; 
     52  eventer_ssl_init(); 
    5253  eventer_jobq_init(&__global_backq); 
    5354  e = eventer_alloc(); 
  • src/noit_console.c

    r624c3f9 rb7ec807  
    252252  int newmask = EVENTER_READ | EVENTER_EXCEPTION; 
    253253  int keep_going; 
    254   noit_console_closure_t ncct = closure; 
     254  acceptor_closure_t *ac = closure; 
     255  noit_console_closure_t ncct = ac->service_ctx; 
    255256 
    256257  if(mask & EVENTER_EXCEPTION || (ncct && ncct->wants_shutdown)) { 
     
    260261    e->opset->close(e->fd, &newmask, e); 
    261262    if(ncct) noit_console_closure_free(ncct); 
     263    free(ac); 
    262264    return 0; 
    263265  } 
    264266 
    265   if(!ncct) { 
     267  if(!ac->service_ctx) { 
     268    ncct = ac->service_ctx = noit_console_closure_alloc(); 
     269  } 
     270  if(!ncct->initialized) { 
    266271    int on = 1; 
    267     ncct = closure = e->closure = noit_console_closure_alloc(); 
    268272    ncct->e = e; 
    269273    if(openpty(&ncct->pty_master, &ncct->pty_slave, NULL, NULL, NULL) || 
     
    273277    } 
    274278    else { 
     279      const char *line_protocol; 
    275280      HistEvent ev; 
    276281      ncct->hist = history_init(); 
     
    280285      el_set(ncct->el, EL_EDITOR, "emacs"); 
    281286      el_set(ncct->el, EL_HIST, history, ncct->hist); 
    282       ncct->telnet = noit_console_telnet_alloc(ncct); 
    283       ncct->output_cooker = nc_telnet_cooker; 
     287      if(!noit_hash_retrieve(ac->config, 
     288                             "line_protocol", strlen("line_protocol"), 
     289                             (void **)&line_protocol)) { 
     290        line_protocol = NULL; 
     291      } 
     292      if(line_protocol && !strcasecmp(line_protocol, "telnet")) { 
     293        ncct->telnet = noit_console_telnet_alloc(ncct); 
     294        ncct->output_cooker = nc_telnet_cooker; 
     295      } 
    284296      noit_console_state_init(ncct); 
    285297    } 
     298    ncct->initialized = 1; 
    286299  } 
    287300 
  • src/noit_console.h

    ra9f9cf2 rb7ec807  
    6161 
    6262typedef struct __noit_console_closure { 
     63  int initialized; 
    6364  eventer_t e;           /* The event it is attached to.  This 
    6465                          * is needed so it can write itself out */ 
  • src/noit_listener.c

    rd936b80 rb7ec807  
    1919#include "noit_listener.h" 
    2020#include "noit_conf.h" 
     21 
     22static int 
     23noit_listener_accept_ssl(eventer_t e, int mask, 
     24                         void *closure, struct timeval *tv) { 
     25  int rv; 
     26  listener_closure_t listener_closure = (listener_closure_t)closure; 
     27  eventer_ssl_ctx_t *ctx; 
     28  if(!closure) goto socketfail; 
     29 
     30  rv = eventer_SSL_accept(e, &mask); 
     31  if(rv > 0) { 
     32    e->callback = listener_closure->dispatch_callback; 
     33    /* We must make a copy of the acceptor_closure_t for each new 
     34     * connection. 
     35     */ 
     36    e->closure = malloc(sizeof(*listener_closure->dispatch_closure)); 
     37    memcpy(e->closure, listener_closure->dispatch_closure, 
     38           sizeof(*listener_closure->dispatch_closure)); 
     39    return e->callback(e, mask, e->closure, tv); 
     40  } 
     41  if(errno == EAGAIN) return mask|EVENTER_EXCEPTION; 
     42  ctx = eventer_get_eventer_ssl_ctx(e); 
     43  eventer_ssl_ctx_free(ctx); 
     44 
     45 socketfail: 
     46  eventer_remove_fd(e->fd); 
     47  close(e->fd); 
     48  return 0; 
     49} 
    2150 
    2251static int 
     
    3362 
    3463  if(mask & EVENTER_EXCEPTION) { 
     64 socketfail: 
    3565    eventer_remove_fd(e->fd); 
    3666    close(e->fd); 
     
    4979    newe->fd = conn; 
    5080    newe->mask = EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION; 
    51     newe->callback = listener_closure->dispatch_callback; 
    52     newe->closure = listener_closure->dispatch_closure; 
     81    if(listener_closure->sslconfig->size) { 
     82      char *cert, *key, *ca, *ciphers; 
     83      eventer_ssl_ctx_t *ctx; 
     84      /* We have an SSL configuration.  While our socket accept is 
     85       * complete, we now have to SSL_accept, which could require 
     86       * several reads and writes and needs its own event callback. 
     87       */ 
     88#define SSLCONFGET(var,name) do { \ 
     89  if(!noit_hash_retrieve(listener_closure->sslconfig, name, strlen(name), \ 
     90                         (void **)&var)) var = NULL; } while(0) 
     91      SSLCONFGET(cert, "certificate_file"); 
     92      SSLCONFGET(key, "key_file"); 
     93      SSLCONFGET(ca, "ca_chain"); 
     94      SSLCONFGET(ciphers, "ciphers"); 
     95      ctx = eventer_ssl_ctx_new(SSL_SERVER, cert, key, ca, ciphers); 
     96      if(!ctx) { 
     97        eventer_free(newe); 
     98        goto socketfail; 
     99      } 
     100      EVENTER_ATTACH_SSL(newe, ctx); 
     101      newe->callback = noit_listener_accept_ssl; 
     102      newe->closure = listener_closure; 
     103    } 
     104    else { 
     105      newe->callback = listener_closure->dispatch_callback; 
     106      /* We must make a copy of the acceptor_closure_t for each new 
     107       * connection. 
     108       */ 
     109      newe->closure = malloc(sizeof(*listener_closure->dispatch_closure)); 
     110      memcpy(newe->closure, listener_closure->dispatch_closure, 
     111             sizeof(*listener_closure->dispatch_closure)); 
     112    } 
    53113    eventer_add(newe); 
    54114  } 
     
    59119int 
    60120noit_listener(char *host, unsigned short port, int type, 
    61               int backlog, eventer_func_t handler, void *closure) { 
     121              int backlog, noit_hash_table *sslconfig, 
     122              noit_hash_table *config, 
     123              eventer_func_t handler, void *service_ctx) { 
    62124  int rv, fd; 
    63125  int8_t family; 
     
    81143        host, port, type, backlog, 
    82144        (event_name = eventer_name_for_callback(handler))?event_name:"??", 
    83         closure); 
     145        service_ctx); 
    84146  if(host[0] == '/') { 
    85147    family = AF_UNIX; 
     
    115177  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 
    116178                 (void*)&reuse, sizeof(reuse)) != 0) { 
    117  
    118179    close(fd); 
    119180    return -1; 
     
    165226  listener_closure->family = family; 
    166227  listener_closure->port = htons(port); 
     228  listener_closure->sslconfig = calloc(1, sizeof(noit_hash_table)); 
     229  noit_hash_merge_as_dict(listener_closure->sslconfig, sslconfig); 
    167230  listener_closure->dispatch_callback = handler; 
    168   listener_closure->dispatch_closure = closure; 
     231 
     232  listener_closure->dispatch_closure = 
     233    calloc(1, sizeof(*listener_closure->dispatch_closure)); 
     234  listener_closure->dispatch_closure->config = config; 
     235  listener_closure->dispatch_closure->service_ctx = service_ctx; 
    169236 
    170237  event = eventer_alloc(); 
     
    179246 
    180247void 
    181 noit_listener_init() { 
     248noit_listener_reconfig() { 
    182249  int i, cnt = 0; 
    183250  noit_conf_section_t *listener_configs; 
    184251 
    185   listener_configs = noit_conf_get_sections(NULL, "/noit/listeners/listener", 
     252  listener_configs = noit_conf_get_sections(NULL, "/noit/listeners//listener", 
    186253                                            &cnt); 
    187254  noitL(noit_stderr, "Found %d /noit/listeners/listener stanzas\n", cnt); 
     
    193260    int backlog; 
    194261    eventer_func_t f; 
     262    noit_hash_table *sslconfig, *config; 
    195263 
    196264    if(!noit_conf_get_stringbuf(listener_configs[i], 
    197                                 "type", type, sizeof(type))) { 
     265                                "ancestor-or-self::node()/@type", 
     266                                type, sizeof(type))) { 
    198267      noitL(noit_stderr, "No type specified in listener stanza %d\n", i+1); 
    199268      continue; 
     
    206275    } 
    207276    if(!noit_conf_get_stringbuf(listener_configs[i], 
    208                                 "address", address, sizeof(address))) { 
     277                                "ancestor-or-self::node()/@address", 
     278                                address, sizeof(address))) { 
    209279      address[0] = '*'; 
    210280      address[1] = '\0'; 
    211281    } 
    212     if(!noit_conf_get_int(listener_configs[i], "port", &portint)) 
     282    if(!noit_conf_get_int(listener_configs[i], 
     283                          "ancestor-or-self::node()/@port", &portint)) 
    213284      portint = 0; 
    214285    port = (unsigned short) portint; 
     
    219290      continue; 
    220291    } 
    221     if(!noit_conf_get_int(listener_configs[i], "backlog", &backlog)) 
     292    if(!noit_conf_get_int(listener_configs[i], 
     293                          "ancestor-or-self::node()/@backlog", &backlog)) 
    222294      backlog = 5; 
    223295 
    224     noit_listener(address, port, SOCK_STREAM, backlog, f, NULL); 
    225   } 
    226 
     296    sslconfig = noit_conf_get_hash(listener_configs[i], "sslconfig/*"); 
     297    config = noit_conf_get_hash(listener_configs[i], "config/*"); 
     298 
     299    noit_listener(address, port, SOCK_STREAM, backlog, 
     300                  sslconfig, config, f, NULL); 
     301  } 
     302
     303void 
     304noit_listener_init() { 
     305  eventer_name_callback("noit_listener_acceptor", noit_listener_acceptor); 
     306  eventer_name_callback("noit_listener_accept_ssl", noit_listener_accept_ssl); 
     307  noit_listener_reconfig(); 
     308
     309 
  • src/noit_listener.h

    rcaa7b86 rb7ec807  
    99#include "noit_defines.h" 
    1010#include "eventer/eventer.h" 
     11#include "utils/noit_hash.h" 
     12 
     13typedef struct { 
     14  noit_hash_table *config; 
     15  void *service_ctx; 
     16} acceptor_closure_t; 
    1117 
    1218typedef struct { 
     
    1420  unsigned short port; 
    1521  eventer_func_t dispatch_callback; 
    16   void *dispatch_closure; 
     22  acceptor_closure_t *dispatch_closure; 
     23  noit_hash_table *sslconfig; 
    1724} * listener_closure_t; 
    1825 
     
    2128API_EXPORT(int) 
    2229noit_listener(char *host, unsigned short port, int type, 
    23               int backlog, eventer_func_t handler, void *closure); 
     30              int backlog, noit_hash_table *sslconfig, 
     31              noit_hash_table *config, 
     32              eventer_func_t handler, void *service_ctx); 
    2433 
    2534#endif 
  • src/sample.conf

    r7b92762 rb7ec807  
    5050  </modules> 
    5151  <listeners> 
    52     <listener> 
    53       <type>noit_console</type> 
    54       <address>/tmp/noit</address> 
    55     </listener> 
    56     <listener> 
    57       <type>noit_console</type> 
    58       <address>*</address> 
    59       <port>32323</port> 
    60     </listener> 
     52    <consoles type="noit_console"> 
     53      <listener address="/tmp/noit"/> 
     54      <listener address="*" port="32323"> 
     55        <config><line_protocol>*telnet</line_protocol></config> 
     56        <sslconfig> 
     57          <certificate_file>test.crt</certificate_file> 
     58          <key_file>test.key</key_file> 
     59        </sslconfig> 
     60      </listener> 
     61    </consoles> 
    6162  </listeners> 
    6263  <checks> 
  • src/utils/noit_hash.c

    r64e4b06 rb7ec807  
    273273} 
    274274 
     275void noit_hash_merge_as_dict(noit_hash_table *dst, noit_hash_table *src) { 
     276  noit_hash_iter iter = NOIT_HASH_ITER_ZERO; 
     277  const char *k; 
     278  int klen; 
     279  void *data; 
     280  if(src == NULL || dst == NULL) return; 
     281  while(noit_hash_next(src, &iter, &k, &klen, &data)) 
     282    noit_hash_store(dst, strdup(k), klen, strdup((char *)data)); 
     283} 
     284 
    275285int noit_hash_next(noit_hash_table *h, noit_hash_iter *iter, 
    276286                const char **k, int *klen, void **data) { 
  • src/utils/noit_hash.h

    r01751d3 rb7ec807  
    8383                       NoitHashFreeFunc datafree); 
    8484 
     85/* This is a convenience function only.  It assumes that all keys and values 
     86 * in the destination hash are strings and allocated with malloc() and 
     87 * assumes that the source contains only keys and values that can be 
     88 * suitably duplicated by strdup(). 
     89 */ 
     90void noit_hash_merge_as_dict(noit_hash_table *dst, noit_hash_table *src); 
     91 
    8592/* This is an iterator and requires the hash to not be written to during the 
    8693   iteration process.