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 }
int ssl_handshake(struct Client *cptr) { char *str; int err; cptr->ssl = (struct SSL*) SSL_new (ctx); // cptr->use_ssl=1; CHK_NULL (cptr->ssl); SSL_set_fd ((SSL *)cptr->ssl, cptr->fd); set_non_blocking(cptr->fd); err = ircd_SSL_accept (cptr, cptr->fd); if ((err)==-1) { irclog(L_ERROR,"Lost connection to %s:Error in SSL_accept()", get_client_name(cptr, TRUE)); SSL_shutdown((SSL *)cptr->ssl); SSL_free((SSL *)cptr->ssl); cptr->ssl = NULL; return 0; } /* Get the cipher - opt */ SetSecure(cptr); irclog (L_DEBUG, "SSL connection using %s", SSL_get_cipher ((SSL *)cptr->ssl)); /* Get client's certificate (note: beware of dynamic * allocation) - opt */ cptr->client_cert = (struct X509*)SSL_get_peer_certificate ((SSL *)cptr->ssl); if (cptr->client_cert != NULL) { irclog (L_DEBUG,"Client certificate:"); str = X509_NAME_oneline (X509_get_subject_name ((X509*)cptr->client_cert), 0, 0); CHK_NULL (str); irclog (L_DEBUG, "\t subject: %s", str); // Bejvavalo // Free (str); free(str); str = X509_NAME_oneline (X509_get_issuer_name ((X509*)cptr->client_cert), 0, 0); CHK_NULL (str); irclog (L_DEBUG, "\t issuer: %s", str); // Bejvavalo // Free (str); free(str); /* We could do all sorts of certificate * verification stuff here before * deallocating the certificate. */ X509_free ((X509*)cptr->client_cert); } else irclog (L_DEBUG, "Client does not have certificate."); return 1; }