From: Kern Sibbald Date: Wed, 23 May 2007 10:38:53 +0000 (+0000) Subject: kes Reduce bat connect timeout from 30 to 15 seconds. X-Git-Tag: Release-7.0.0~6261 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=8de83aab28ad5cbdc6a2455622ff5cdbce3d63d4;p=bacula%2Fbacula kes Reduce bat connect timeout from 30 to 15 seconds. kes More restructuring and implementing BSOCK class in place of old bnet.c code. kes Remove a few unnecessary malloc() tests in crypto code. kes Turn off crypto calls for > 128 bits in crypto.c if HAVE_SHA2 not defined. Bug reported by Allan Black kes Remove duplicate HAVE_CRYPTO definition in config.h.in git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4884 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/autoconf/config.h.in b/bacula/autoconf/config.h.in index 34bca4c309..d29d9229fa 100644 --- a/bacula/autoconf/config.h.in +++ b/bacula/autoconf/config.h.in @@ -293,9 +293,6 @@ /* Set if Bacula conio support enabled */ #undef HAVE_CONIO -/* Define if encryption support should be enabled */ -#undef HAVE_CRYPTO - /* Define to 1 if you have the header file. */ #undef HAVE_CURSES_H @@ -817,9 +814,9 @@ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if the `S_IS*' macros in do not work properly. */ diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 1856e48ee5..16736a7b7e 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -341,29 +341,7 @@ bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) */ int bnet_wait_data(BSOCK * bsock, int sec) { - fd_set fdset; - struct timeval tv; - - FD_ZERO(&fdset); - FD_SET((unsigned)bsock->m_fd, &fdset); - for (;;) { - tv.tv_sec = sec; - tv.tv_usec = 0; - switch (select(bsock->m_fd + 1, &fdset, NULL, NULL, &tv)) { - case 0: /* timeout */ - bsock->b_errno = 0; - return 0; - case -1: - bsock->b_errno = errno; - if (errno == EINTR) { - continue; - } - return -1; /* error return */ - default: - bsock->b_errno = 0; - return 1; - } - } + return bsock->wait_data(sec); } /* @@ -371,24 +349,7 @@ int bnet_wait_data(BSOCK * bsock, int sec) */ int bnet_wait_data_intr(BSOCK * bsock, int sec) { - fd_set fdset; - struct timeval tv; - - FD_ZERO(&fdset); - FD_SET((unsigned)bsock->m_fd, &fdset); - tv.tv_sec = sec; - tv.tv_usec = 0; - switch (select(bsock->m_fd + 1, &fdset, NULL, NULL, &tv)) { - case 0: /* timeout */ - bsock->b_errno = 0; - return 0; - case -1: - bsock->b_errno = errno; - return -1; /* error return */ - default: - bsock->b_errno = 0; - } - return 1; + return bsock->wait_data_intr(sec); } #ifndef NETDB_INTERNAL @@ -550,171 +511,24 @@ dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr) } /* - * Open a TCP connection to the UPS network server - * Returns NULL - * Returns BSOCK * pointer on success - * - */ -static BSOCK *bnet_open(JCR *jcr, const char *name, char *host, char *service, - int port, utime_t heart_beat, int *fatal) -{ - int sockfd = -1; - dlist *addr_list; - IPADDR *ipaddr; - bool connected = false; - int turnon = 1; - const char *errstr; - int save_errno = 0; - - /* - * Fill in the structure serv_addr with the address of - * the server that we want to connect with. - */ - if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) { - /* Note errstr is not malloc'ed */ - Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"), - host, errstr); - Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n", - host, errstr); - *fatal = 1; - return NULL; - } - - foreach_dlist(ipaddr, addr_list) { - ipaddr->set_port_net(htons(port)); - char allbuf[256 * 10]; - char curbuf[256]; - Dmsg2(100, "Current %sAll %s\n", - ipaddr->build_address_str(curbuf, sizeof(curbuf)), - build_addresses_str(addr_list, allbuf, sizeof(allbuf))); - /* Open a TCP socket */ - if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) { - berrno be; - save_errno = errno; - *fatal = 1; - Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"), - ipaddr->get_family(), ipaddr->get_port_host_order(), be.bstrerror()); - continue; - } - /* - * Keep socket from timing out from inactivity - */ - if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { - berrno be; - Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), - be.bstrerror()); - } -#if defined(TCP_KEEPIDLE) - if (heart_beat) { - int opt = heart_beat - if (setsockopt(sockfd, IPPROTO_IP, TCP_KEEPIDLE, (sockopt_val_t)&opt, sizeof(opt)) < 0) { - berrno be; - Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPIDLE on socket: %s\n"), - be.bstrerror()); - } - } -#endif - - /* connect to server */ - if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) { - save_errno = errno; - socketClose(sockfd); - continue; - } - *fatal = 0; - connected = true; - break; - } - - if (!connected) { - free_addresses(addr_list); - errno = save_errno | b_errno_win32; - return NULL; - } - /* - * Keep socket from timing out from inactivity - * Do this a second time out of paranoia - */ - if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { - berrno be; - Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), - be.bstrerror()); - } - BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr()); - free_addresses(addr_list); - return ret; -} - - -#ifdef xxx + * This is the "old" way of opening a connection. The preferred way is + * now to do what this subroutine does, but inline. That allows the + * connect() call to return error status, ... + */ BSOCK *bnet_connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, int verbose) { - BSOCK *bsock = new BSOCK(); + BSOCK *bsock = new_bsock(); if (!bsock->connect(jcr, retry_interval, max_retry_time, heart_beat, name, host, service, port, verbose)) { - delete bsock; + bsock->destroy(); bsock = NULL; } return bsock; } -#endif - - -/* - * Try to connect to host for max_retry_time at retry_time intervals. - */ -BSOCK *bnet_connect(JCR * jcr, int retry_interval, utime_t max_retry_time, - utime_t heart_beat, - const char *name, char *host, char *service, int port, - int verbose) -{ - int i; - BSOCK *bsock; - int fatal = 0; - time_t begin_time = time(NULL); - time_t now; - btimer_t *tid = NULL; - - /* Try to trap out of OS call when time expires */ - if (max_retry_time) { - tid = start_thread_timer(pthread_self(), (uint32_t)max_retry_time); - } - - for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, heart_beat, &fatal)) == NULL; - i -= retry_interval) { - berrno be; - if (fatal || (jcr && job_canceled(jcr))) { - bsock = NULL; - goto bail_out; - } - Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n", - name, host, port, be.bstrerror()); - if (i < 0) { - i = 60 * 5; /* complain again in 5 minutes */ - if (verbose) - Qmsg4(jcr, M_WARNING, 0, _( - "Could not connect to %s on %s:%d. ERR=%s\n" - "Retrying ...\n"), name, host, port, be.bstrerror()); - } - bmicrosleep(retry_interval, 0); - now = time(NULL); - if (begin_time + max_retry_time <= now) { - Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"), - name, host, port, be.bstrerror()); - bsock = NULL; - goto bail_out; - } - } -bail_out: - if (tid) { - stop_thread_timer(tid); - } - return bsock; -} /* @@ -723,12 +537,7 @@ bail_out: */ const char *bnet_strerror(BSOCK * bsock) { - berrno be; - if (bsock->errmsg == NULL) { - bsock->errmsg = get_pool_memory(PM_MESSAGE); - } - pm_strcpy(bsock->errmsg, be.bstrerror(bsock->b_errno)); - return bsock->errmsg; + return bsock->bstrerror(); } /* @@ -848,7 +657,6 @@ const char *bnet_sig_to_ascii(BSOCK * bs) } } - /* Initialize internal socket structure. * This probably should be done in net_open */ @@ -897,7 +705,7 @@ BSOCK *dup_bsock(BSOCK * osock) /* Close the network connection */ void bnet_close(BSOCK * bsock) { - bsock->close(); /* this calls destroy */ + bsock->close(); } void term_bsock(BSOCK * bsock) diff --git a/bacula/src/lib/bsock.c b/bacula/src/lib/bsock.c index 87ea2e5aca..96e7f182f6 100644 --- a/bacula/src/lib/bsock.c +++ b/bacula/src/lib/bsock.c @@ -30,7 +30,7 @@ * * by Kern Sibbald * - * Version $Id: bnet.c 3670 2006-11-21 16:13:58Z kerns $ + * Version $Id: $ */ @@ -52,18 +52,43 @@ #define socketClose(fd) ::close(fd) #endif -BSOCK::BSOCK() +/* + * This is a non-class BSOCK "constructor" because we want to + * call the Bacula smartalloc routines instead of new. + */ +BSOCK *new_bsock() +{ + BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK)); + bsock->init(); + return bsock; +} + +void BSOCK::init() { memset(this, 0, sizeof(BSOCK)); + m_blocking = 1; + msg = get_pool_memory(PM_MESSAGE); + errmsg = get_pool_memory(PM_MESSAGE); + /* + * ****FIXME**** reduce this to a few hours once + * heartbeats are implemented + */ + timeout = 60 * 60 * 6 * 24; /* 6 days timeout */ } -BSOCK::~BSOCK() +/* + * This is our "class destructor" that ensures that we use + * smartalloc rather than the system free(). + */ +void BSOCK::free_bsock() { destroy(); } /* * Try to connect to host for max_retry_time at retry_time intervals. + * Note, you must have called the constructor prior to calling + * this routine. */ bool BSOCK::connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, @@ -115,34 +140,23 @@ bail_out: } -/* Initialize internal socket structure. - * This probably should be done in net_open +/* + * Finish initialization of the pocket structure. */ -void BSOCK::init(JCR * jcr, int sockfd, const char *who, const char *host, int port, +void BSOCK::fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr) { Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port); m_fd = sockfd; - tls = NULL; - errors = 0; - m_blocking = 1; - msg = get_pool_memory(PM_MESSAGE); - errmsg = get_pool_memory(PM_MESSAGE); set_who(bstrdup(who)); set_host(bstrdup(host)); set_port(port); - memset(&peer_addr, 0, sizeof(peer_addr)); memcpy(&client_addr, lclient_addr, sizeof(client_addr)); - /* - * ****FIXME**** reduce this to a few hours once - * heartbeats are implemented - */ - timeout = 60 * 60 * 6 * 24; /* 6 days timeout */ set_jcr(jcr); } /* - * Open a TCP connection to the UPS network server + * Open a TCP connection to the server * Returns NULL * Returns BSOCK * pointer on success * @@ -232,7 +246,7 @@ bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service, Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), be.bstrerror()); } - init(jcr, sockfd, name, host, port, ipaddr->get_sockaddr()); + fin_init(jcr, sockfd, name, host, port, ipaddr->get_sockaddr()); free_addresses(addr_list); return true; } @@ -289,7 +303,7 @@ bool BSOCK::send() Qmsg5(m_jcr, M_ERROR, 0, _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), msglen, m_who, - m_host, m_port, bnet_strerror(this)); + m_host, m_port, this->bstrerror()); } } else { Qmsg5(m_jcr, M_ERROR, 0, @@ -427,7 +441,7 @@ int32_t BSOCK::recv() } errors++; Qmsg4(m_jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"), - m_who, m_host, m_port, bnet_strerror(this)); + m_who, m_host, m_port, this->bstrerror()); return BNET_ERROR; } timer_start = 0; /* clear timer */ @@ -706,7 +720,70 @@ void BSOCK::restore_blocking (int flags) #endif } +/* + * Wait for a specified time for data to appear on + * the BSOCK connection. + * + * Returns: 1 if data available + * 0 if timeout + * -1 if error + */ +int BSOCK::wait_data(int sec) +{ + fd_set fdset; + struct timeval tv; + + FD_ZERO(&fdset); + FD_SET((unsigned)m_fd, &fdset); + for (;;) { + tv.tv_sec = sec; + tv.tv_usec = 0; + switch (select(m_fd + 1, &fdset, NULL, NULL, &tv)) { + case 0: /* timeout */ + b_errno = 0; + return 0; + case -1: + b_errno = errno; + if (errno == EINTR) { + continue; + } + return -1; /* error return */ + default: + b_errno = 0; + return 1; + } + } +} + +/* + * As above, but returns on interrupt + */ +int BSOCK::wait_data_intr(int sec) +{ + fd_set fdset; + struct timeval tv; + + FD_ZERO(&fdset); + FD_SET((unsigned)m_fd, &fdset); + tv.tv_sec = sec; + tv.tv_usec = 0; + switch (select(m_fd + 1, &fdset, NULL, NULL, &tv)) { + case 0: /* timeout */ + b_errno = 0; + return 0; + case -1: + b_errno = errno; + return -1; /* error return */ + default: + b_errno = 0; + } + return 1; +} +/* + * Note, this routine closes and destroys all the sockets + * that are open including the duped ones. + */ void BSOCK::close() { BSOCK *bsock = this; @@ -715,20 +792,18 @@ void BSOCK::close() for (; bsock; bsock = next) { next = bsock->m_next; /* get possible pointer to next before destoryed */ if (!bsock->m_duped) { -#ifdef HAVE_TLS /* Shutdown tls cleanly. */ if (bsock->tls) { tls_bsock_shutdown(bsock); free_tls_connection(bsock->tls); bsock->tls = NULL; } -#endif /* HAVE_TLS */ if (bsock->is_timed_out()) { shutdown(bsock->m_fd, 2); /* discard any pending I/O */ } socketClose(bsock->m_fd); /* normal close */ } - bsock->destroy(); /* free the packet */ + bsock->destroy(); } return; } diff --git a/bacula/src/lib/bsock.h b/bacula/src/lib/bsock.h index 2bf6a7f38e..0cfe61203e 100644 --- a/bacula/src/lib/bsock.h +++ b/bacula/src/lib/bsock.h @@ -50,7 +50,7 @@ private: char *m_host; /* Host name/IP */ int m_port; /* desired port */ - void init(JCR * jcr, int sockfd, const char *who, const char *host, int port, + void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr); bool open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal); @@ -80,8 +80,8 @@ public: struct sockaddr_in peer_addr; /* peer's IP address */ /* methods -- in bsock.c */ - BSOCK(); - ~BSOCK(); + void init(); + void free_bsock(); bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, int verbose); @@ -98,6 +98,8 @@ public: int set_nonblocking(); int set_blocking(); void restore_blocking(int flags); + int wait_data(int sec); + int wait_data_intr(int sec); /* Inline functions */ void set_jcr(JCR *jcr) { m_jcr = jcr; }; @@ -171,3 +173,5 @@ enum { int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes); int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes); + +BSOCK *new_bsock(); diff --git a/bacula/src/lib/cram-md5.c b/bacula/src/lib/cram-md5.c index 22e999812e..83c43059e9 100644 --- a/bacula/src/lib/cram-md5.c +++ b/bacula/src/lib/cram-md5.c @@ -1,16 +1,7 @@ -/* - * Challenge Response Authentication Method using MD5 (CRAM-MD5) - * - * cram-md5 is based on RFC2104. - * - * Written for Bacula by Kern E. Sibbald, May MMI. - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2006 Free Software Foundation Europe e.V. + Copyright (C) 2001-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -34,6 +25,15 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Challenge Response Authentication Method using MD5 (CRAM-MD5) + * + * cram-md5 is based on RFC2104. + * + * Written for Bacula by Kern E. Sibbald, May MMI. + * + * Version $Id$ + */ #include "bacula.h" @@ -69,22 +69,22 @@ bool cram_md5_challenge(BSOCK *bs, char *password, int tls_local_need, int compa bsnprintf(chal, sizeof(chal), "<%u.%u@%s>", (uint32_t)random(), (uint32_t)time(NULL), host); if (compatible) { Dmsg2(50, "send: auth cram-md5 %s ssl=%d\n", chal, tls_local_need); - if (!bnet_fsend(bs, "auth cram-md5 %s ssl=%d\n", chal, tls_local_need)) { - Dmsg1(50, "Bnet send challenge error.\n", bnet_strerror(bs)); + if (!bs->fsend("auth cram-md5 %s ssl=%d\n", chal, tls_local_need)) { + Dmsg1(50, "Bnet send challenge error.\n", bs->bstrerror()); return false; } } else { /* Old non-compatible system */ Dmsg2(50, "send: auth cram-md5 %s ssl=%d\n", chal, tls_local_need); - if (!bnet_fsend(bs, "auth cram-md5 %s ssl=%d\n", chal, tls_local_need)) { - Dmsg1(50, "Bnet send challenge error.\n", bnet_strerror(bs)); + if (!bs->fsend("auth cram-md5 %s ssl=%d\n", chal, tls_local_need)) { + Dmsg1(50, "Bnet send challenge error.\n", bs->bstrerror()); return false; } } /* Read hashed response to challenge */ - if (bnet_wait_data(bs, 180) <= 0 || bnet_recv(bs) <= 0) { - Dmsg1(50, "Bnet receive challenge response error.\n", bnet_strerror(bs)); + if (bs->wait_data(180) <= 0 || bs->recv() <= 0) { + Dmsg1(50, "Bnet receive challenge response error.\n", bs->bstrerror()); bmicrosleep(5, 0); return false; } @@ -103,10 +103,10 @@ bool cram_md5_challenge(BSOCK *bs, char *password, int tls_local_need, int compa } } if (ok) { - bnet_fsend(bs, "1000 OK auth\n"); + bs->fsend("1000 OK auth\n"); } else { Dmsg1(50, "Auth failed PW: %s\n", password); - bnet_fsend(bs, _("1999 Authorization failed.\n")); + bs->fsend(_("1999 Authorization failed.\n")); bmicrosleep(5, 0); } return ok; @@ -119,7 +119,7 @@ bool cram_md5_respond(BSOCK *bs, char *password, int *tls_remote_need, int *comp uint8_t hmac[20]; *compatible = false; - if (bnet_recv(bs) <= 0) { + if (bs->recv() <= 0) { bmicrosleep(5, 0); return false; } @@ -134,7 +134,7 @@ bool cram_md5_respond(BSOCK *bs, char *password, int *tls_remote_need, int *comp } else if (sscanf(bs->msg, "auth cram-md5 %s ssl=%d", chal, tls_remote_need) != 2) { if (sscanf(bs->msg, "auth cram-md5 %s\n", chal) != 1) { Dmsg1(50, "Cannot scan challenge: %s", bs->msg); - bnet_fsend(bs, _("1999 Authorization failed.\n")); + bs->fsend(_("1999 Authorization failed.\n")); bmicrosleep(5, 0); return false; } @@ -143,13 +143,13 @@ bool cram_md5_respond(BSOCK *bs, char *password, int *tls_remote_need, int *comp hmac_md5((uint8_t *)chal, strlen(chal), (uint8_t *)password, strlen(password), hmac); bs->msglen = bin_to_base64(bs->msg, 50, (char *)hmac, 16, *compatible) + 1; // Dmsg3(100, "get_auth: chal=%s pw=%s hmac=%s\n", chal, password, bs->msg); - if (!bnet_send(bs)) { - Dmsg1(50, "Send challenge failed. ERR=%s\n", bnet_strerror(bs)); + if (!bs->send()) { + Dmsg1(50, "Send challenge failed. ERR=%s\n", bs->bstrerror()); return false; } Dmsg1(99, "sending resp to challenge: %s\n", bs->msg); - if (bnet_wait_data(bs, 180) <= 0 || bnet_recv(bs) <= 0) { - Dmsg1(50, "Receive chanllenge response failed. ERR=%s\n", bnet_strerror(bs)); + if (bs->wait_data(180) <= 0 || bs->recv() <= 0) { + Dmsg1(50, "Receive chanllenge response failed. ERR=%s\n", bs->bstrerror()); bmicrosleep(5, 0); return false; } diff --git a/bacula/src/lib/crypto.c b/bacula/src/lib/crypto.c index b4db253e16..ce1dd97daf 100644 --- a/bacula/src/lib/crypto.c +++ b/bacula/src/lib/crypto.c @@ -362,14 +362,12 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) { * Returns: A pointer to a X509 KEYPAIR object on success. * NULL on failure. */ -X509_KEYPAIR *crypto_keypair_new(void) { +X509_KEYPAIR *crypto_keypair_new(void) +{ X509_KEYPAIR *keypair; /* Allocate our keypair structure */ - keypair = (X509_KEYPAIR *) malloc(sizeof(X509_KEYPAIR)); - if (!keypair) { - return NULL; - } + keypair = (X509_KEYPAIR *)malloc(sizeof(X509_KEYPAIR)); /* Initialize our keypair structure */ keypair->keyid = NULL; @@ -966,6 +964,8 @@ void crypto_sign_free(SIGNATURE *sig) * Create a new encryption session. * Returns: A pointer to a CRYPTO_SESSION object on success. * NULL on failure. + * + * Note! Bacula malloc() fails if out of memory. */ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) { @@ -976,10 +976,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) int iv_len; /* Allocate our session description structures */ - cs = (CRYPTO_SESSION *) malloc(sizeof(CRYPTO_SESSION)); - if (!cs) { - return NULL; - } + cs = (CRYPTO_SESSION *)malloc(sizeof(CRYPTO_SESSION)); /* Initialize required fields */ cs->session_key = NULL; @@ -1005,6 +1002,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_128_cbc); ec = EVP_aes_128_cbc(); break; +#ifdef HAVE_SHA2 case CRYPTO_CIPHER_AES_192_CBC: /* AES 192 bit CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_192_cbc); @@ -1015,6 +1013,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_256_cbc); ec = EVP_aes_256_cbc(); break; +#endif case CRYPTO_CIPHER_BLOWFISH_CBC: /* Blowfish CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_bf_cbc); @@ -1037,12 +1036,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) /* Generate an IV if possible */ if ((iv_len = EVP_CIPHER_iv_length(ec))) { - iv = (unsigned char *) malloc(iv_len); - if (!iv) { - /* Malloc failure */ - crypto_session_free(cs); - return NULL; - } + iv = (unsigned char *)malloc(iv_len); /* Generate random IV */ if (RAND_bytes(iv, iv_len) <= 0) { @@ -1090,12 +1084,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) ri->keyEncryptionAlgorithm = OBJ_nid2obj(NID_rsaEncryption); /* Encrypt the session key */ - ekey = (unsigned char *) malloc(EVP_PKEY_size(keypair->pubkey)); - if (!ekey) { - RecipientInfo_free(ri); - crypto_session_free(cs); - return NULL; - } + ekey = (unsigned char *)malloc(EVP_PKEY_size(keypair->pubkey)); if ((ekey_len = EVP_PKEY_encrypt(ekey, cs->session_key, cs->session_key_len, keypair->pubkey)) <= 0) { /* OpenSSL failure */ @@ -1170,10 +1159,7 @@ crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist return CRYPTO_ERROR_NORECIPIENT; } - cs = (CRYPTO_SESSION *) malloc(sizeof(CRYPTO_SESSION)); - if (!cs) { - return CRYPTO_ERROR_INTERNAL; - } + cs = (CRYPTO_SESSION *)malloc(sizeof(CRYPTO_SESSION)); /* Initialize required fields */ cs->session_key = NULL; @@ -1222,7 +1208,7 @@ crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist /* Decrypt the session key */ /* Allocate sufficient space for the largest possible decrypted data */ - cs->session_key = (unsigned char *) malloc(EVP_PKEY_size(keypair->privkey)); + cs->session_key = (unsigned char *)malloc(EVP_PKEY_size(keypair->privkey)); cs->session_key_len = EVP_PKEY_decrypt(cs->session_key, M_ASN1_STRING_data(ri->encryptedKey), M_ASN1_STRING_length(ri->encryptedKey), keypair->privkey); @@ -1250,7 +1236,7 @@ err: /* * Free memory associated with a crypto session object. */ -void crypto_session_free (CRYPTO_SESSION *cs) +void crypto_session_free(CRYPTO_SESSION *cs) { if (cs->cryptoData) { CryptoData_free(cs->cryptoData); @@ -1271,10 +1257,7 @@ CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *bl CIPHER_CONTEXT *cipher_ctx; const EVP_CIPHER *ec; - cipher_ctx = (CIPHER_CONTEXT *) malloc(sizeof(CIPHER_CONTEXT)); - if (!cipher_ctx) { - return NULL; - } + cipher_ctx = (CIPHER_CONTEXT *)malloc(sizeof(CIPHER_CONTEXT)); /* * Acquire a cipher instance for the given ASN.1 cipher NID diff --git a/bacula/src/lib/tls.c b/bacula/src/lib/tls.c index 141771d76a..807a6f4dc0 100644 --- a/bacula/src/lib/tls.c +++ b/bacula/src/lib/tls.c @@ -693,4 +693,16 @@ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, } void free_tls_context(TLS_CONTEXT *ctx) { } +void tls_bsock_shutdown(BSOCK *bsock) { } + +void free_tls_connection(TLS_CONNECTION *tls) +{ + if (tls) { + if (tls->openssl) { + SSL_free(tls->openssl); + } + free(tls); + } +} + #endif /* HAVE_TLS */ diff --git a/bacula/src/lib/tls.h b/bacula/src/lib/tls.h index 5c088fffc3..9d3e52eccd 100644 --- a/bacula/src/lib/tls.h +++ b/bacula/src/lib/tls.h @@ -1,28 +1,7 @@ -/* - * tls.h TLS support functions - * - * Author: Landon Fuller - * - * Version $Id$ - * - * This file was contributed to the Bacula project by Landon Fuller - * and Three Rings Design, Inc. - * - * Three Rings Design, Inc. has been granted a perpetual, worldwide, - * non-exclusive, no-charge, royalty-free, irrevocable copyright - * license to reproduce, prepare derivative works of, publicly - * display, publicly perform, sublicense, and distribute the original - * work contributed by Three Rings Design, Inc. and its employees to - * the Bacula project in source or object form. - * - * If you wish to license contributions from Three Rings Design, Inc, - * under an alternate open source license please contact - * Landon Fuller . - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2005-2006 Free Software Foundation Europe e.V. + Copyright (C) 2005-2007 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -46,6 +25,27 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * tls.h TLS support functions + * + * Author: Landon Fuller + * + * Version $Id$ + * + * This file was contributed to the Bacula project by Landon Fuller + * and Three Rings Design, Inc. + * + * Three Rings Design, Inc. has been granted a perpetual, worldwide, + * non-exclusive, no-charge, royalty-free, irrevocable copyright + * license to reproduce, prepare derivative works of, publicly + * display, publicly perform, sublicense, and distribute the original + * work contributed by Three Rings Design, Inc. and its employees to + * the Bacula project in source or object form. + * + * If you wish to license contributions from Three Rings Design, Inc, + * under an alternate open source license please contact + * Landon Fuller . + */ #ifndef __TLS_H_ #define __TLS_H_ diff --git a/bacula/src/qt-console/console/authenticate.cpp b/bacula/src/qt-console/console/authenticate.cpp index d702e2ce85..e934e6e73b 100644 --- a/bacula/src/qt-console/console/authenticate.cpp +++ b/bacula/src/qt-console/console/authenticate.cpp @@ -79,7 +79,6 @@ bool Console::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, tls_local_need = BNET_TLS_OK; } } - tls_ctx = cons->tls_ctx; } else { bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name)); @@ -95,8 +94,8 @@ bool Console::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, tls_ctx = director->tls_ctx; } - /* Timeout Hello after 30 secs */ - btimer_t *tid = start_bsock_timer(dir, 30); + /* Timeout Hello after 15 secs */ + btimer_t *tid = start_bsock_timer(dir, 15); dir->fsend(hello, bashed_name); /* respond to Dir challenge */ diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index fee97325ef..ae7ba36629 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,14 @@ Technical notes on version 2.1 General: +23May07 +kes Reduce bat connect timeout from 30 to 15 seconds. +kes More restructuring and implementing BSOCK class in place of + old bnet.c code. +kes Remove a few unnecessary malloc() tests in crypto code. +kes Turn off crypto calls for > 128 bits in crypto.c if HAVE_SHA2 + not defined. Bug reported by Allan Black +kes Remove duplicate HAVE_CRYPTO definition in config.h.in 22May07 kes Fix Verify InitCatalog mysql_escape_string() trashing memory. Make buffer bigger.