DLLFUNC CMD_FUNC(m_starttls) { if (!MyConnect(sptr) || !IsUnknown(sptr)) return 0; #ifndef USE_SSL /* sendnotice(sptr, "This server does not support SSL"); */ /* or numeric 691? */ /* actually... it's probably best to just act like we don't know this command...? */ sendto_one(sptr, err_str(ERR_NOTREGISTERED), me.name, "STARTTLS"); return 0; #else if (iConf.ssl_options & SSLFLAG_NOSTARTTLS) { sendto_one(sptr, err_str(ERR_NOTREGISTERED), me.name, "STARTTLS"); return 0; } if (IsSecure(sptr)) { sendto_one(sptr, err_str(ERR_STARTTLS), me.name, !BadPtr(sptr->name) ? sptr->name : "*", "STARTTLS failed. Already using TLS."); return 0; } dbuf_delete(&sptr->recvQ, 1000000); /* Clear up any remaining plaintext commands */ sendto_one(sptr, rpl_str(RPL_STARTTLS), me.name, !BadPtr(sptr->name) ? sptr->name : "*"); send_queued(sptr); SetSSLStartTLSHandshake(sptr); Debug((DEBUG_DEBUG, "Starting SSL handshake (due to STARTTLS) for %s", sptr->sockhost)); if ((sptr->ssl = SSL_new(ctx_server)) == NULL) goto fail; sptr->flags |= FLAGS_SSL; SSL_set_fd(sptr->ssl, sptr->fd); SSL_set_nonblocking(sptr->ssl); if (!ircd_SSL_accept(sptr, sptr->fd)) { Debug((DEBUG_DEBUG, "Failed SSL accept handshake in instance 1: %s", sptr->sockhost)); SSL_set_shutdown(sptr->ssl, SSL_RECEIVED_SHUTDOWN); SSL_smart_shutdown(sptr->ssl); SSL_free(sptr->ssl); goto fail; } /* HANDSHAKE IN PROGRESS */ return 0; fail: /* Failure */ sendto_one(sptr, err_str(ERR_STARTTLS), me.name, !BadPtr(sptr->name) ? sptr->name : "*", "STARTTLS failed"); sptr->ssl = NULL; sptr->flags &= ~FLAGS_SSL; SetUnknown(sptr); return 0; #endif }
void conn_destroy(Connection *conn) { int ret; if (conn == NULL) return; /* No locking done here. conn_destroy should not be called * if any thread might still be interested in the connection. */ if (conn->registered) { fdset_unregister(conn->registered, conn->fd); /* call data destroyer if any */ if (conn->callback_data != NULL && conn->callback_data_destroyer != NULL) conn->callback_data_destroyer(conn->callback_data); } if (conn->fd >= 0) { /* Try to flush any remaining data */ unlocked_try_write(conn); #ifdef HAVE_LIBSSL if (conn->ssl != NULL) { SSL_smart_shutdown(conn->ssl); SSL_free(conn->ssl); if (conn->peer_certificate != NULL) X509_free(conn->peer_certificate); } #endif /* HAVE_LIBSSL */ ret = close(conn->fd); if (ret < 0) error(errno, "conn_destroy: error on close"); conn->fd = -1; } octstr_destroy(conn->outbuf); octstr_destroy(conn->inbuf); mutex_destroy(conn->inlock); mutex_destroy(conn->outlock); gw_free(conn); }