#include #include #include #include #include #include #include "librez.h" #include "myserv.h" #include "rezssl.h" void librez_ssl_private(t_rez *d_rez, t_librez_fd rezid, int (*ssl_func)()) { int ret; ret = ssl_func(d_rez->ssl[rezid]); if (ret == 0) { librez_myserv_hup(d_rez->tl_rezid_2_ifds[rezid], d_rez); return ; } if (ret < 0) { ret = SSL_get_error(d_rez->ssl[rezid], ret); if (ret == SSL_ERROR_WANT_READ) { d_rez->fds[d_rez->tl_rezid_2_ifds[rezid]].events = POLLRDNORM; return ; } if (ret == SSL_ERROR_WANT_WRITE) { d_rez->fds[d_rez->tl_rezid_2_ifds[rezid]].events = POLLWRNORM; return ; } librez_myserv_hup(d_rez->tl_rezid_2_ifds[rezid], d_rez); return ; } d_rez->fds[d_rez->tl_rezid_2_ifds[rezid]].events = d_rez->ssl_saved_events[rezid]; d_rez->ssl_negociation[rezid] = NULL; if (d_rez->notify[d_rez->tl_rezid_2_ifds[rezid]][LIBREZ_SSL_VALID]) (*d_rez->notify[d_rez->tl_rezid_2_ifds[rezid]][LIBREZ_SSL_VALID])(rezid, d_rez->data); } void librez_ssl_accept(t_rez *d_rez, t_librez_fd rezid, void (*f_notify_user)()) { d_rez->ssl_negociation[rezid] = SSL_accept; d_rez->ssl_saved_events[rezid] = d_rez->fds[d_rez->tl_rezid_2_ifds[rezid]].events; d_rez->notify[d_rez->tl_rezid_2_ifds[rezid]][LIBREZ_SSL_VALID] = f_notify_user; librez_ssl_private(d_rez, rezid, SSL_accept); } void librez_ssl_connect(t_rez *d_rez, t_librez_fd rezid, void (*f_notify_user)()) { d_rez->ssl_negociation[rezid] = SSL_connect; d_rez->ssl_saved_events[rezid] = d_rez->fds[d_rez->tl_rezid_2_ifds[rezid]].events; d_rez->notify[d_rez->tl_rezid_2_ifds[rezid]][LIBREZ_SSL_VALID] = f_notify_user; librez_ssl_private(d_rez, rezid, SSL_connect); } void librez_ssl_new(t_rez *d_rez, SSL_CTX *ctx, t_librez_fd rezid) { BIO *bio; int fd; d_rez->ssl[rezid] = SSL_new(ctx); if (d_rez->ssl[rezid] == NULL) { ERR_print_errors_fp(stderr); errx(1, "librez: librez_ssl_new(); -> d_rez->ssl[rezid] == NULL"); } fd = d_rez->fds[d_rez->tl_rezid_2_ifds[rezid]].fd; fcntl(fd, F_SETFL, O_NONBLOCK); bio = BIO_new_socket(fd, BIO_NOCLOSE); SSL_set_bio(d_rez->ssl[rezid], bio, bio); } char *librez_ssl_certname(t_rez *d_rez, t_librez_fd rezid) { X509 *x509; static char peer_CN[256]; x509 = SSL_get_peer_certificate(d_rez->ssl[rezid]); X509_NAME_get_text_by_NID(X509_get_subject_name(x509), NID_commonName, peer_CN, 256); X509_free(x509); return (peer_CN); }