static int mr_starttls(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { #ifdef HAVE_LIBCRYPTO ssl_ctl_t *ctl; rb_fde_t *F[2]; if (!MyConnect(client_p)) return 0; if (IsSSL(client_p)) { sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "Nested TLS handshake not allowed"); return 1; } if (!ssl_ok || !get_ssld_count()) { sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "TLS is not configured"); return 1; } if (rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &F[0], &F[1], "STARTTLS ssld session") == -1) { ilog_error("error creating SSL/TLS socketpair for ssld slave"); sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "Unable to create SSL/TLS socketpair for ssld offload slave"); return 1; } s_assert(client_p->localClient != NULL); /* clear out any remaining plaintext lines */ rb_linebuf_donebuf(&client_p->localClient->buf_recvq); sendto_one_numeric(client_p, RPL_STARTTLS, form_str(RPL_STARTTLS)); send_queued(client_p); ctl = start_ssld_accept(client_p->localClient->F, F[1], rb_get_fd(F[0])); if (ctl != NULL) { client_p->localClient->F = F[0]; client_p->localClient->ssl_ctl = ctl; SetSSL(client_p); } else return 1; #else sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "TLS is not configured"); #endif return 0; }
static void accept_ssld(rb_fde_t *F, struct sockaddr *addr, struct sockaddr *laddr, struct Listener *listener) { ssl_ctl_t *ctl; rb_fde_t *xF[2]; if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection") == -1) { ilog_error("creating SSL/TLS socket pairs"); rb_close(F); return; } ctl = start_ssld_accept(F, xF[1], rb_get_fd(xF[0])); /* this will close F for us */ add_connection(listener, xF[0], addr, laddr, ctl); }
static int inetport(struct Listener *listener) { rb_fde_t *F; int ret; int opt = 1; /* * At first, open a new socket */ F = rb_socket(GET_SS_FAMILY(&listener->addr), SOCK_STREAM, 0, "Listener socket"); #ifdef RB_IPV6 if(listener->addr.ss_family == AF_INET6) { struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&listener->addr; if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any)) { rb_inet_ntop(AF_INET6, &in6->sin6_addr, listener->vhost, sizeof(listener->vhost)); listener->name = listener->vhost; } } else #endif { struct sockaddr_in *in = (struct sockaddr_in *)&listener->addr; if(in->sin_addr.s_addr != INADDR_ANY) { rb_inet_ntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost)); listener->name = listener->vhost; } } if(F == NULL) { ilog_error("opening listener socket"); return 0; } else if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus*/ { ilog_error("no more connections left for listener"); rb_close(F); return 0; } /* * XXX - we don't want to do all this crap for a listener * set_sock_opts(listener); */ if(setsockopt(rb_get_fd(F), SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt))) { ilog_error("setting SO_REUSEADDR for listener"); rb_close(F); return 0; } /* * Bind a port to listen for new connections if port is non-null, * else assume it is already open and try get something from it. */ if(bind(rb_get_fd(F), (struct sockaddr *) &listener->addr, GET_SS_LEN(&listener->addr))) { ilog_error("binding listener socket"); rb_close(F); return 0; } if((ret = rb_listen(F, RATBOX_SOMAXCONN))) { ilog_error("listen()"); rb_close(F); return 0; } listener->F = F; rb_accept_tcp(listener->F, accept_precallback, accept_callback, listener); return 1; }
static int inetport(struct Listener *listener) { rb_fde_t *F; int opt = 1; const char *errstr; /* * At first, open a new socket */ F = rb_socket(GET_SS_FAMILY(&listener->addr), SOCK_STREAM, 0, "Listener socket"); #ifdef RB_IPV6 if(listener->addr.ss_family == AF_INET6) { struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&listener->addr; if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any)) { rb_inet_ntop(AF_INET6, &in6->sin6_addr, listener->vhost, sizeof(listener->vhost)); listener->name = listener->vhost; } } else #endif { struct sockaddr_in *in = (struct sockaddr_in *)&listener->addr; if(in->sin_addr.s_addr != INADDR_ANY) { rb_inet_ntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost)); listener->name = listener->vhost; } } if(F == NULL) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Cannot open socket for listener on port %d", get_listener_port(listener)); ilog(L_MAIN, "Cannot open socket for listener %s", get_listener_name(listener)); return 0; } else if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus*/ { ilog_error("no more connections left for listener"); sendto_realops_snomask(SNO_GENERAL, L_ALL, "No more connections left for listener on port %d", get_listener_port(listener)); ilog(L_MAIN, "No more connections left for listener %s", get_listener_name(listener)); rb_close(F); return 0; } /* * XXX - we don't want to do all this crap for a listener * set_sock_opts(listener); */ if(setsockopt(rb_get_fd(F), SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt))) { errstr = strerror(rb_get_sockerr(F)); sendto_realops_snomask(SNO_GENERAL, L_ALL, "Cannot set SO_REUSEADDR for listener on port %d: %s", get_listener_port(listener), errstr); ilog(L_MAIN, "Cannot set SO_REUSEADDR for listener %s: %s", get_listener_name(listener), errstr); rb_close(F); return 0; } /* * Bind a port to listen for new connections if port is non-null, * else assume it is already open and try get something from it. */ if(bind(rb_get_fd(F), (struct sockaddr *) &listener->addr, GET_SS_LEN(&listener->addr))) { errstr = strerror(rb_get_sockerr(F)); sendto_realops_snomask(SNO_GENERAL, L_ALL, "Cannot bind for listener on port %d: %s", get_listener_port(listener), errstr); ilog(L_MAIN, "Cannot bind for listener %s: %s", get_listener_name(listener), errstr); rb_close(F); return 0; } if(rb_listen(F, CHARYBDIS_SOMAXCONN, listener->defer_accept)) { errstr = strerror(rb_get_sockerr(F)); sendto_realops_snomask(SNO_GENERAL, L_ALL, "Cannot listen() for listener on port %d: %s", get_listener_port(listener), errstr); ilog(L_MAIN, "Cannot listen() for listener %s: %s", get_listener_name(listener), errstr); rb_close(F); return 0; } listener->F = F; rb_accept_tcp(listener->F, accept_precallback, accept_callback, listener); return 1; }