ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/server.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/server.c (file contents):
Revision 6602 by michael, Thu Oct 22 18:07:38 2015 UTC vs.
Revision 7105 by michael, Sat Jan 23 20:11:27 2016 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2015 ircd-hybrid development team
4 > *  Copyright (c) 1997-2016 ircd-hybrid development team
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
# Line 25 | Line 25
25   */
26  
27   #include "stdinc.h"
28 #ifdef HAVE_LIBCRYPTO
29 #include <openssl/rsa.h>
30 #include "rsa.h"
31 #endif
28   #include "list.h"
29   #include "client.h"
30   #include "event.h"
# Line 82 | Line 78 | write_links_file(void *unused)
78    DLINK_FOREACH_SAFE(node, node_next, flatten_links.head)
79    {
80      dlinkDelete(node, &flatten_links);
81 <    MyFree(node->data);
81 >    xfree(node->data);
82      free_dlink_node(node);
83    }
84  
# Line 256 | Line 252 | try_connections(void *unused)
252   {
253    dlink_node *node = NULL;
254  
259  /* TODO: change this to set active flag to 0 when added to event! --Habeeb */
255    if (GlobalSetOptions.autoconn == 0)
256      return;
257  
# Line 266 | Line 261 | try_connections(void *unused)
261  
262      assert(conf->type == CONF_SERVER);
263  
264 <    /* Also when already connecting! (update holdtimes) --SRB
270 <     */
264 >    /* Also when already connecting! (update holdtimes) --SRB */
265      if (!conf->port || !IsConfAllowAutoConn(conf))
266        continue;
267  
268 <
269 <    /* Skip this entry if the use of it is still on hold until
268 >    /*
269 >     * Skip this entry if the use of it is still on hold until
270       * future. Otherwise handle this entry (and set it on hold
271       * until next time). Will reset only hold times, if already
272       * made one successfull connection... [this algorithm is
# Line 367 | Line 361 | check_server(const char *name, struct Cl
361  
362      error = -3;
363  
370    /* XXX: Fix me for IPv6                    */
371    /* XXX sockhost is the IPv4 ip as a string */
364      if (!match(conf->host, client_p->host) ||
365          !match(conf->host, client_p->sockhost))
366      {
# Line 425 | Line 417 | check_server(const char *name, struct Cl
417   void
418   add_capability(const char *name, unsigned int flag)
419   {
420 <  struct Capability *cap = MyCalloc(sizeof(*cap));
420 >  struct Capability *cap = xcalloc(sizeof(*cap));
421  
422    cap->name = xstrdup(name);
423    cap->cap = flag;
# Line 450 | Line 442 | delete_capability(const char *name)
442      if (!irccmp(cap->name, name))
443      {
444        dlinkDelete(node, &server_capabilities_list);
445 <      MyFree(cap->name);
446 <      MyFree(cap);
445 >      xfree(cap->name);
446 >      xfree(cap);
447      }
448    }
449   }
# Line 546 | Line 538 | struct Server *
538   make_server(struct Client *client_p)
539   {
540    if (client_p->serv == NULL)
541 <    client_p->serv = MyCalloc(sizeof(struct Server));
541 >    client_p->serv = xcalloc(sizeof(struct Server));
542  
543    return client_p->serv;
544   }
# Line 606 | Line 598 | serv_connect(struct MaskItem *conf, stru
598      return 0;
599    }
600  
601 <  /* Make sure this server isn't already connected
602 <   * Note: conf should ALWAYS be a valid C: line
601 >  /*
602 >   * Make sure this server isn't already connected.
603 >   * Note: conf should ALWAYS be a valid connect {} block
604     */
605    if ((client_p = hash_find_server(conf->name)))
606    {
# Line 633 | Line 626 | serv_connect(struct MaskItem *conf, stru
626    /* We already converted the ip once, so lets use it - stu */
627    strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost));
628  
629 <  /* create a socket for the server connection */
629 >  /* Create a socket for the server connection */
630    if (comm_open(&client_p->connection->fd, conf->addr.ss.ss_family, SOCK_STREAM, 0, NULL) < 0)
631    {
632      /* Eek, failure to create the socket */
# Line 644 | Line 637 | serv_connect(struct MaskItem *conf, stru
637      return 0;
638    }
639  
640 <  /* servernames are always guaranteed under HOSTLEN chars */
641 <  fd_note(&client_p->connection->fd, "Server: %s", conf->name);
640 >  /* Server names are always guaranteed under HOSTLEN chars */
641 >  fd_note(&client_p->connection->fd, "Server: %s", client_p->name);
642  
643 <  /* Attach config entries to client here rather than in
644 <   * serv_connect_callback(). This to avoid null pointer references.
643 >  /*
644 >   * Attach config entries to client here rather than in serv_connect_callback().
645 >   * This to avoid null pointer references.
646     */
647    if (!attach_connect_block(client_p, conf->name, conf->host))
648    {
# Line 663 | Line 657 | serv_connect(struct MaskItem *conf, stru
657      return 0;
658    }
659  
660 <  /* at this point we have a connection in progress and C/N lines
661 <   * attached to the client, the socket info should be saved in the
662 <   * client and it should either be resolved or have a valid address.
660 >  /*
661 >   * At this point we have a connection in progress and a connect {} block
662 >   * attached to the client, the socket info should be saved in the client
663 >   * and it should either be resolved or have a valid address.
664     *
665     * The socket has been connected or connect is in progress.
666     */
# Line 759 | Line 754 | serv_connect(struct MaskItem *conf, stru
754    return 1;
755   }
756  
757 < #ifdef HAVE_LIBCRYPTO
757 > #ifdef HAVE_TLS
758   static void
759   finish_ssl_server_handshake(struct Client *client_p)
760   {
# Line 808 | Line 803 | static void
803   ssl_server_handshake(fde_t *fd, void *data)
804   {
805    struct Client *client_p = data;
806 <  X509 *cert = NULL;
807 <  int ret = 0;
806 >  int res = 0;
807 >  const char *sslerr = NULL;
808  
809 <  if ((ret = SSL_connect(client_p->connection->fd.ssl)) <= 0)
809 >  tls_handshake_status_t ret = tls_handshake(&client_p->connection->fd.ssl, TLS_ROLE_CLIENT, &sslerr);
810 >  if (ret != TLS_HANDSHAKE_DONE)
811    {
812      if ((CurrentTime - client_p->connection->firsttime) > CONNECTTIMEOUT)
813      {
814 <      exit_client(client_p, "Timeout during SSL handshake");
814 >      exit_client(client_p, "Timeout during TLS handshake");
815        return;
816      }
817  
818 <    switch (SSL_get_error(client_p->connection->fd.ssl, ret))
818 >    switch (ret)
819      {
820 <      case SSL_ERROR_WANT_WRITE:
820 >      case TLS_HANDSHAKE_WANT_WRITE:
821          comm_setselect(&client_p->connection->fd, COMM_SELECT_WRITE,
822                         ssl_server_handshake, client_p, CONNECTTIMEOUT);
823          return;
824 <      case SSL_ERROR_WANT_READ:
824 >      case TLS_HANDSHAKE_WANT_READ:
825          comm_setselect(&client_p->connection->fd, COMM_SELECT_READ,
826                         ssl_server_handshake, client_p, CONNECTTIMEOUT);
827          return;
828        default:
829        {
834        const char *sslerr = ERR_error_string(ERR_get_error(), NULL);
830          sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
831                               "Error connecting to %s: %s", client_p->name,
832 <                             sslerr ? sslerr : "unknown SSL error");
833 <        exit_client(client_p, "Error during SSL handshake");
832 >                             sslerr ? sslerr : "unknown TLS error");
833 >        exit_client(client_p, "Error during TLS handshake");
834          return;
835        }
836      }
# Line 843 | Line 838 | ssl_server_handshake(fde_t *fd, void *da
838  
839    comm_settimeout(&client_p->connection->fd, 0, NULL, NULL);
840  
841 <  if ((cert = SSL_get_peer_certificate(client_p->connection->fd.ssl)))
842 <  {
843 <    int res = SSL_get_verify_result(client_p->connection->fd.ssl);
849 <    char buf[EVP_MAX_MD_SIZE * 2 + 1] = "";
850 <    unsigned char md[EVP_MAX_MD_SIZE] = "";
851 <
852 <    if (res == X509_V_OK || res == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
853 <        res == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE ||
854 <        res == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
855 <    {
856 <      unsigned int n = 0;
857 <
858 <      if (X509_digest(cert, ConfigServerInfo.message_digest_algorithm, md, &n))
859 <      {
860 <        binary_to_hex(md, buf, n);
861 <        client_p->certfp = xstrdup(buf);
862 <      }
863 <    }
864 <    else
865 <      ilog(LOG_TYPE_IRCD, "Server %s!%s@%s gave bad SSL client certificate: %d",
866 <           client_p->name, client_p->username, client_p->host, res);
867 <    X509_free(cert);
868 <  }
841 >  if (!tls_verify_cert(&client_p->connection->fd.ssl, ConfigServerInfo.message_digest_algorithm, &client_p->certfp, &res))
842 >    ilog(LOG_TYPE_IRCD, "Server %s!%s@%s gave bad TLS client certificate: %d",
843 >         client_p->name, client_p->username, client_p->host, res);
844  
845    finish_ssl_server_handshake(client_p);
846   }
# Line 873 | Line 848 | ssl_server_handshake(fde_t *fd, void *da
848   static void
849   ssl_connect_init(struct Client *client_p, const struct MaskItem *conf, fde_t *fd)
850   {
851 <  if ((client_p->connection->fd.ssl = SSL_new(ConfigServerInfo.client_ctx)) == NULL)
851 >  if (!tls_new(&client_p->connection->fd.ssl, fd->fd, TLS_ROLE_CLIENT))
852    {
878    ilog(LOG_TYPE_IRCD, "SSL_new() ERROR! -- %s",
879         ERR_error_string(ERR_get_error(), NULL));
853      SetDead(client_p);
854 <    exit_client(client_p, "SSL_new failed");
854 >    exit_client(client_p, "TLS context initialization failed");
855      return;
856    }
857  
885  SSL_set_fd(fd->ssl, fd->fd);
886
858    if (!EmptyString(conf->cipher_list))
859 <    SSL_set_cipher_list(client_p->connection->fd.ssl, conf->cipher_list);
859 >    tls_set_ciphers(&client_p->connection->fd.ssl, conf->cipher_list);
860  
861    ssl_server_handshake(NULL, client_p);
862   }
# Line 950 | Line 921 | serv_connect_callback(fde_t *fd, int sta
921    /* Next, send the initial handshake */
922    SetHandshake(client_p);
923  
924 < #ifdef HAVE_LIBCRYPTO
924 > #ifdef HAVE_TLS
925    if (IsConfSSL(conf))
926    {
927      ssl_connect_init(client_p, conf, fd);

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)