static inline int tls_setup_process(shout_tls_t *tls) { if (SSL_is_init_finished(tls->ssl)) return tls_check_cert(tls); tls->ssl_ret = SSL_connect(tls->ssl); if (SSL_is_init_finished(tls->ssl)) return tls_check_cert(tls); return SHOUTERR_BUSY; }
int tls_start(tls_t *tls, int fd, const char *hostname, int no_certcheck, tls_cert_info_t *tci, char **errstr) { #ifdef HAVE_LIBGNUTLS int error_code; gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr_t)fd); do { error_code = gnutls_handshake(tls->session); } while (error_code < 0 && gnutls_error_is_fatal(error_code) == 0); if (error_code != 0) { *errstr = xasprintf(_("TLS handshake failed: %s"), gnutls_strerror(error_code)); gnutls_deinit(tls->session); gnutls_certificate_free_credentials(tls->cred); return TLS_EHANDSHAKE; } if (tci) { if ((error_code = tls_cert_info_get(tls, tci, errstr)) != TLS_EOK) { gnutls_deinit(tls->session); gnutls_certificate_free_credentials(tls->cred); return error_code; } } if (!no_certcheck) { if ((error_code = tls_check_cert(tls, hostname, errstr)) != TLS_EOK) { gnutls_deinit(tls->session); gnutls_certificate_free_credentials(tls->cred); return error_code; } } tls->is_active = 1; return TLS_EOK; #endif /* HAVE_LIBGNUTLS */ #ifdef HAVE_LIBSSL int error_code; if (!SSL_set_fd(tls->ssl, fd)) { *errstr = xasprintf(_("cannot set the file descriptor for TLS: %s"), ERR_error_string(ERR_get_error(), NULL)); SSL_free(tls->ssl); SSL_CTX_free(tls->ssl_ctx); return TLS_ELIBFAILED; } if ((error_code = SSL_connect(tls->ssl)) < 1) { if (errno == EINTR && (SSL_get_error(tls->ssl, error_code) == SSL_ERROR_WANT_READ || SSL_get_error(tls->ssl, error_code) == SSL_ERROR_WANT_WRITE)) { *errstr = xasprintf(_("operation aborted")); } else { *errstr = openssl_io_error(error_code, SSL_get_error(tls->ssl, error_code), _("TLS handshake failed")); } SSL_free(tls->ssl); SSL_CTX_free(tls->ssl_ctx); return TLS_EIO; } if (tci) { if ((error_code = tls_cert_info_get(tls, tci, errstr)) != TLS_EOK) { SSL_free(tls->ssl); SSL_CTX_free(tls->ssl_ctx); return error_code; } } if (!no_certcheck) { if ((error_code = tls_check_cert(tls, hostname, errstr)) != TLS_EOK) { SSL_free(tls->ssl); SSL_CTX_free(tls->ssl_ctx); return error_code; } } tls->is_active = 1; return TLS_EOK; #endif /* HAVE_LIBSSL */ }