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; }
/* * mo_connect - CONNECT command handler * * Added by Jto 11 Feb 1989 * * m_connect * parv[1] = servername * parv[2] = port number * parv[3] = remote server */ static int mo_connect(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { int port; int tmpport; struct server_conf *server_p; struct Client *target_p; /* always privileged with handlers */ if(MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "remote"); return 0; } if(hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME) return 0; if((target_p = find_server(source_p, parv[1]))) { sendto_one_notice(source_p, ":Connect: Server %s already exists from %s.", parv[1], target_p->from->name); return 0; } /* * try to find the name, then host, if both fail notify ops and bail */ if((server_p = find_server_conf(parv[1])) == NULL) { sendto_one_notice(source_p, ":Connect: Host %s not listed in ircd.conf", parv[1]); return 0; } if(ServerConfSSL(server_p) && (!ssl_ok || !get_ssld_count())) { sendto_one_notice(source_p, ":Connect: Server %s is set to use SSL/TLS but SSL/TLS is not configured.", parv[1]); return 0; } /* * Get port number from user, if given. If not specified, * use the default form configuration structure. If missing * from there, then use the precompiled default. */ tmpport = port = 0; if(parc > 2 && !EmptyString(parv[2])) port = atoi(parv[2]); if(port == 0 && server_p->port) port = server_p->port; else if(port <= 0) { sendto_one_notice(source_p, ":Connect: illegal port number"); return 0; } /* * Notify all operators about remote connect requests */ ilog(L_SERVER, "CONNECT From %s : %s %s", source_p->name, parv[1], parc > 2 ? parv[2] : ""); server_p->port = port; /* * at this point we should be calling connect_server with a valid * C:line and a valid port in the C:line */ if(serv_connect(server_p, source_p)) { sendto_one_notice(source_p, ":*** Connecting to %s.%d", server_p->name, server_p->port); } else { sendto_one_notice(source_p, ":*** Couldn't connect to %s.%d", server_p->name, server_p->port); } /* * client is either connecting with all the data it needs or has been * destroyed */ server_p->port = tmpport; return 0; }
static int accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data) { struct Listener *listener = (struct Listener *)data; char buf[BUFSIZE]; struct ConfItem *aconf; static time_t last_oper_notice = 0; int len; if(listener->ssl && (!ssl_ok || !get_ssld_count())) { rb_close(F); return 0; } if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus */ { ++ServerStats.is_ref; /* * slow down the whining to opers bit */ if((last_oper_notice + 20) <= rb_current_time()) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "All connections in use. (%s)", get_listener_name(listener)); last_oper_notice = rb_current_time(); } rb_write(F, "ERROR :All connections in use\r\n", 32); rb_close(F); /* Re-register a new IO request for the next accept .. */ return 0; } aconf = find_dline(addr, addr->sa_family); if(aconf != NULL && (aconf->status & CONF_EXEMPTDLINE)) return 1; /* Do an initial check we aren't connecting too fast or with too many * from this IP... */ if(aconf != NULL) { ServerStats.is_ref++; if(ConfigFileEntry.dline_with_reason) { len = rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", get_user_ban_reason(aconf)); if (len >= (int)(sizeof(buf)-1)) { buf[sizeof(buf) - 3] = '\r'; buf[sizeof(buf) - 2] = '\n'; buf[sizeof(buf) - 1] = '\0'; } } else strcpy(buf, "ERROR :You have been D-lined.\r\n"); rb_write(F, buf, strlen(buf)); rb_close(F); return 0; } if(check_reject(F, addr)) return 0; if(throttle_add(addr)) { rb_write(F, toofast, strlen(toofast)); rb_close(F); return 0; } return 1; }
/* * ms_connect - CONNECT command handler * * Added by Jto 11 Feb 1989 * * m_connect * parv[1] = servername * parv[2] = port number * parv[3] = remote server */ static int ms_connect(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { int port; int tmpport; struct server_conf *server_p; struct Client *target_p; if(hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME) return 0; if((target_p = find_server(NULL, parv[1]))) { sendto_one_notice(source_p, ":Connect: Server %s already exists from %s.", parv[1], target_p->from->name); return 0; } /* * try to find the name, then host, if both fail notify ops and bail */ if((server_p = find_server_conf(parv[1])) == NULL) { sendto_one_notice(source_p, ":Connect: Host %s not listed in ircd.conf", parv[1]); return 0; } if(ServerConfSSL(server_p) && (!ssl_ok || !get_ssld_count())) { sendto_one_notice(source_p, ":Connect: Server %s is set to use SSL/TLS but SSL/TLS is not configured.", parv[1]); return 0; } /* * Get port number from user, if given. If not specified, * use the default form configuration structure. If missing * from there, then use the precompiled default. */ tmpport = server_p->port; port = atoi(parv[2]); /* if someone sends port 0, and we have a config port.. use it */ if(port == 0 && server_p->port) port = server_p->port; else if(port <= 0) { sendto_one_notice(source_p, ":Connect: Illegal port number"); return 0; } /* * Notify all operators about remote connect requests */ sendto_wallops_flags(UMODE_WALLOP, &me, "Remote CONNECT %s %d from %s", parv[1], port, source_p->name); sendto_server(NULL, NULL, CAP_TS6, NOCAPS, ":%s WALLOPS :Remote CONNECT %s %d from %s", me.id, parv[1], port, source_p->name); ilog(L_SERVER, "CONNECT From %s : %s %d", source_p->name, parv[1], port); server_p->port = port; /* * at this point we should be calling connect_server with a valid * C:line and a valid port in the C:line */ if(serv_connect(server_p, source_p)) sendto_one_notice(source_p, ":*** Connecting to %s.%d", server_p->name, server_p->port); else sendto_one_notice(source_p, ":*** Couldn't connect to %s.%d", server_p->name, server_p->port); /* * client is either connecting with all the data it needs or has been * destroyed */ server_p->port = tmpport; return 0; }