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; }
static void me_sasl(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p, *agent_p; /* Let propagate if not addressed to us, or if broadcast. * Only SASL agents can answer global requests. */ if(strncmp(parv[2], me.id, 3)) return; if((target_p = find_id(parv[2])) == NULL) return; if((agent_p = find_id(parv[1])) == NULL) return; if(source_p != agent_p->servptr) /* WTF?! */ return; /* We only accept messages from SASL agents; these must have umode +S * (so the server must be listed in a service{} block). */ if(!IsService(agent_p)) return; /* Reject if someone has already answered. */ if(*target_p->localClient->sasl_agent && strncmp(parv[1], target_p->localClient->sasl_agent, IDLEN)) return; else if(!*target_p->localClient->sasl_agent) rb_strlcpy(target_p->localClient->sasl_agent, parv[1], IDLEN); if(*parv[3] == 'C') { sendto_one(target_p, "AUTHENTICATE %s", parv[4]); target_p->localClient->sasl_messages++; } else if(*parv[3] == 'D') { if(*parv[4] == 'F') { sendto_one(target_p, form_str(ERR_SASLFAIL), me.name, EmptyString(target_p->name) ? "*" : target_p->name); /* Failures with zero messages are just "unknown mechanism" errors; don't count those. */ if(target_p->localClient->sasl_messages > 0) { if(*target_p->name) { target_p->localClient->sasl_failures++; target_p->localClient->sasl_next_retry = rb_current_time() + (1 << MIN(target_p->localClient->sasl_failures + 5, 13)); } else if(throttle_add((struct sockaddr*)&target_p->localClient->ip)) { exit_client(target_p, target_p, &me, "Too many failed authentication attempts"); return; } } } else if(*parv[4] == 'S') { sendto_one(target_p, form_str(RPL_SASLSUCCESS), me.name, EmptyString(target_p->name) ? "*" : target_p->name); target_p->localClient->sasl_failures = 0; target_p->localClient->sasl_complete = 1; ServerStats.is_ssuc++; } *target_p->localClient->sasl_agent = '\0'; /* Blank the stored agent so someone else can answer */ target_p->localClient->sasl_messages = 0; } else if(*parv[3] == 'M') sendto_one(target_p, form_str(RPL_SASLMECHS), me.name, EmptyString(target_p->name) ? "*" : target_p->name, parv[4]); }