static int me_gcap(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { char *t = LOCAL_COPY(parv[1]); char *s; char *p; if(!IsServer(source_p)) return 0; /* already had GCAPAB?! */ if(!EmptyString(source_p->serv->fullcaps)) { source_p->serv->caps = 0; rb_free(source_p->serv->fullcaps); } source_p->serv->fullcaps = rb_strdup(parv[1]); for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p)) source_p->serv->caps |= capability_get(serv_capindex, s); return 0; }
/* mr_user() * parv[1] = username (login name, account) * parv[2] = client host name (ignored) * parv[3] = server host name (ignored) * parv[4] = users gecos */ static int mr_user(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { static char buf[BUFSIZE]; char *p; if (strlen(client_p->id) == 3) { exit_client(client_p, client_p, client_p, "Mixing client and server protocol"); return 0; } if(source_p->flags & FLAGS_SENTUSER) return 0; if((p = strchr(parv[1], '@'))) *p = '\0'; rb_snprintf(buf, sizeof(buf), "%s %s", parv[2], parv[3]); rb_free(source_p->localClient->fullcaps); source_p->localClient->fullcaps = rb_strdup(buf); do_local_user(client_p, source_p, parv[1], parv[4]); return 0; }
/* * mr_capab - CAPAB message handler * parv[1] = space-separated list of capabilities * */ static int mr_capab(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { int i; char *p; char *s; /* ummm, this shouldn't happen. Could argue this should be logged etc. */ if(client_p->localClient == NULL) return 0; if(client_p->user) return 0; /* CAP_TS6 is set in PASS, so is valid.. */ if((client_p->localClient->caps & ~CAP_TS6) != 0) { exit_client(client_p, client_p, client_p, "CAPAB received twice"); return 0; } else client_p->localClient->caps |= CAP_CAP; rb_free(client_p->localClient->fullcaps); client_p->localClient->fullcaps = rb_strdup(parv[1]); for (i = 1; i < parc; i++) { char *t = LOCAL_COPY(parv[i]); for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p)) client_p->localClient->caps |= capability_get(serv_capindex, s); } return 0; }
void handle_resolve_dns(int parc, char *parv[]) { char *id = rb_strdup(parv[1]); char qtype = *parv[2]; char *record = parv[3]; int aftype = AF_INET; switch(qtype) { case '6': aftype = AF_INET6; case '4': if(!lookup_ip(record, aftype, submit_dns_answer, id)) submit_dns_answer(NULL, false, qtype, NULL); break; case 'S': case 'R': if(!lookup_hostname(record, submit_dns_answer, id)) submit_dns_answer(NULL, false, qtype, NULL); break; default: warn_opers(L_CRIT, "DNS: handle_resolve_dns got an unknown query: %c", qtype); exit(EX_DNS_ERROR); } }
static int me_gcap(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Capability *cap; char *t = LOCAL_COPY(parv[1]); char *s; char *p; if (!IsServer(source_p)) return 0; /* already had GCAPAB?! */ if (!EmptyString(source_p->serv->fullcaps)) { source_p->serv->caps = 0; rb_free(source_p->serv->fullcaps); } source_p->serv->fullcaps = rb_strdup(parv[1]); for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p)) { for (cap = captab; cap->name; cap++) { if (!irccmp(cap->name, s)) { source_p->serv->caps |= cap->cap; break; } } } return 0; }
/* * mr_capab - CAPAB message handler * parv[1] = space-separated list of capabilities * */ static int mr_capab(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Capability *cap; int i; char *p; char *s; /* ummm, this shouldn't happen. Could argue this should be logged etc. */ if (client_p->localClient == NULL) return 0; if (client_p->user) return 0; /* CAP_TS6 is set in PASS, so is valid.. */ if ((client_p->localClient->caps & ~CAP_TS6) != 0) { exit_client(client_p, client_p, client_p, "CAPAB received twice"); return 0; } else client_p->localClient->caps |= CAP_CAP; rb_free(client_p->localClient->fullcaps); client_p->localClient->fullcaps = rb_strdup(parv[1]); for (i = 1; i < parc; i++) { char *t = LOCAL_COPY(parv[i]); for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p)) { for (cap = captab; cap->name; cap++) { if (!irccmp(cap->name, s)) { client_p->localClient->caps |= cap->cap; break; } } } } return 0; }
/* rb_basename * * input - * output - * side effects - */ char * rb_basename(const char *path) { const char *s; if(!(s = strrchr(path, '/'))) s = path; else s++; return rb_strdup(s); }
/* ** me_certfp ** parv[1] = certfp string */ static int me_certfp(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { if (!IsPerson(source_p)) return 0; rb_free(source_p->certfp); source_p->certfp = NULL; if (!EmptyString(parv[1])) source_p->certfp = rb_strdup(parv[1]); return 0; }
static void parse_windows_resolvers(void) { const char *ns = get_windows_nameservers(); char *server; char *p; char *buf = rb_strdup(ns); for(server = rb_strtok_r(buf, " ", &p); server != NULL;server = rb_strtok_r(NULL, " ", &p)) { add_nameserver(server); } rb_free(buf); }
char * rb_dirname (const char *path) { char *s; s = strrchr(path, '/'); if(s == NULL) { return rb_strdup("."); } /* remove extra slashes */ while(s > path && *s == '/') --s; return rb_strndup(path, ((uintptr_t)s - (uintptr_t)path) + 2); }
/* mod_add_cmd * * inputs - command name * - pointer to struct Message * output - none * side effects - load this one command name * msg->count msg->bytes is modified in place, in * modules address space. Might not want to do that... */ void mod_add_cmd(struct Message *msg) { struct MessageHash *ptr; struct MessageHash *last_ptr = NULL; struct MessageHash *new_ptr; int msgindex; s_assert(msg != NULL); if(msg == NULL) return; msgindex = cmd_hash(msg->cmd); for(ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next) { if(strcasecmp(msg->cmd, ptr->cmd) == 0) return; /* Its already added */ last_ptr = ptr; } new_ptr = rb_malloc(sizeof(struct MessageHash)); new_ptr->next = NULL; new_ptr->cmd = rb_strdup(msg->cmd); new_ptr->msg = msg; msg->count = 0; msg->rcount = 0; msg->bytes = 0; if(last_ptr == NULL) msg_hash_table[msgindex] = new_ptr; else last_ptr->next = new_ptr; }
/* ms_ban() * * parv[1] - type * parv[2] - username mask or * * parv[3] - hostname mask * parv[4] - creation TS * parv[5] - duration (relative to creation) * parv[6] - lifetime (relative to creation) * parv[7] - oper or * * parv[8] - reason (possibly with |operreason) */ static int ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { rb_dlink_node *ptr; struct ConfItem *aconf; unsigned int ntype; const char *oper, *stype; time_t now, created, hold, lifetime; char *p; int act; int valid; now = rb_current_time(); if (strlen(parv[1]) != 1) { sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Unknown BAN type %s from %s", parv[1], source_p->name); return 0; } switch (parv[1][0]) { case 'K': ntype = CONF_KILL; stype = "K-Line"; break; case 'X': ntype = CONF_XLINE; stype = "X-Line"; break; case 'R': ntype = IsChannelName(parv[3]) ? CONF_RESV_CHANNEL : CONF_RESV_NICK; stype = "RESV"; break; default: sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Unknown BAN type %s from %s", parv[1], source_p->name); return 0; } created = atol(parv[4]); hold = created + atoi(parv[5]); lifetime = created + atoi(parv[6]); if (!strcmp(parv[7], "*")) oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p); else oper = parv[7]; ptr = find_prop_ban(ntype, parv[2], parv[3]); if (ptr != NULL) { /* We already know about this ban mask. */ aconf = ptr->data; if (aconf->created > created || (aconf->created == created && aconf->lifetime >= lifetime)) { if (IsPerson(source_p)) sendto_one_notice(source_p, ":Your %s [%s%s%s] has been superseded", stype, aconf->user ? aconf->user : "", aconf->user ? "@" : "", aconf->host); return 0; } /* act indicates if something happened (from the oper's * point of view). This is the case if the ban was * previously active (not deleted) or if the new ban * is not a removal and not already expired. */ act = !(aconf->status & CONF_ILLEGAL) || (hold != created && hold > now); if (lifetime > aconf->lifetime) aconf->lifetime = lifetime; /* already expired, hmm */ if (aconf->lifetime <= now) return 0; /* Deactivate, it will be reactivated later if appropriate. */ deactivate_conf(aconf, ptr, now); rb_free(aconf->user); aconf->user = NULL; rb_free(aconf->host); aconf->host = NULL; operhash_delete(aconf->info.oper); aconf->info.oper = NULL; rb_free(aconf->passwd); aconf->passwd = NULL; rb_free(aconf->spasswd); aconf->spasswd = NULL; } else { /* New ban mask. */ aconf = make_conf(); aconf->status = CONF_ILLEGAL | ntype; aconf->lifetime = lifetime; rb_dlinkAddAlloc(aconf, &prop_bans); act = hold != created && hold > now; } aconf->flags &= ~CONF_FLAGS_MYOPER; aconf->flags |= CONF_FLAGS_TEMPORARY; aconf->user = ntype == CONF_KILL ? rb_strdup(parv[2]) : NULL; aconf->host = rb_strdup(parv[3]); aconf->info.oper = operhash_add(oper); aconf->created = created; aconf->hold = hold; if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL) aconf->passwd = rb_strdup(parv[parc - 1]); else { aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1); aconf->spasswd = rb_strdup(p + 1); } /* The ban is fully filled in and in the prop_bans list * but still deactivated. Now determine if it should be activated * and send the server notices. */ /* We only reject *@* and the like here. * Otherwise malformed bans are fairly harmless and can be removed. */ switch (ntype) { case CONF_KILL: valid = valid_wild_card(aconf->user, aconf->host); break; case CONF_RESV_CHANNEL: valid = 1; break; default: valid = valid_wild_card_simple(aconf->host); break; } if (act && hold != created && !valid) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters", (int)((hold - now) / 60), stype, IsServer(source_p) ? source_p->name : get_oper_name(source_p), strcmp(parv[7], "*") ? " on behalf of " : "", strcmp(parv[7], "*") ? parv[7] : "", aconf->user ? aconf->user : "", aconf->user ? "@" : "", aconf->host); if(IsPerson(source_p)) sendto_one_notice(source_p, ":Your %s [%s%s%s] has too few non-wildcard characters", stype, aconf->user ? aconf->user : "", aconf->user ? "@" : "", aconf->host); /* Propagate it, but do not apply it locally. */ } else if (act && hold != created) { /* Keep the notices in sync with modules/m_kline.c etc. */ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s added global %d min. %s%s%s for [%s%s%s] [%s]", IsServer(source_p) ? source_p->name : get_oper_name(source_p), (int)((hold - now) / 60), stype, strcmp(parv[7], "*") ? " from " : "", strcmp(parv[7], "*") ? parv[7] : "", aconf->user ? aconf->user : "", aconf->user ? "@" : "", aconf->host, parv[parc - 1]); ilog(L_KLINE, "%s %s %d %s%s%s %s", parv[1], IsServer(source_p) ? source_p->name : get_oper_name(source_p), (int)((hold - now) / 60), aconf->user ? aconf->user : "", aconf->user ? " " : "", aconf->host, parv[parc - 1]); aconf->status &= ~CONF_ILLEGAL; } else if (act) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has removed the global %s for: [%s%s%s]%s%s", IsServer(source_p) ? source_p->name : get_oper_name(source_p), stype, aconf->user ? aconf->user : "", aconf->user ? "@" : "", aconf->host, strcmp(parv[7], "*") ? " on behalf of " : "", strcmp(parv[7], "*") ? parv[7] : ""); ilog(L_KLINE, "U%s %s %s%s %s", parv[1], IsServer(source_p) ? source_p->name : get_oper_name(source_p), aconf->user ? aconf->user : "", aconf->user ? " " : "", aconf->host); } /* If CONF_ILLEGAL is still set at this point, remove entries from the * reject cache (for klines and xlines). * If CONF_ILLEGAL is not set, add the ban to the type-specific data * structure and take action on matched clients/channels. */ switch (ntype) { case CONF_KILL: if (aconf->status & CONF_ILLEGAL) remove_reject_mask(aconf->user, aconf->host); else { add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf); if(ConfigFileEntry.kline_delay || (IsServer(source_p) && !HasSentEob(source_p))) { if(kline_queued == 0) { rb_event_addonce("check_klines", check_klines_event, NULL, ConfigFileEntry.kline_delay ? ConfigFileEntry.kline_delay : 1); kline_queued = 1; } } else check_klines(); } break; case CONF_XLINE: if (aconf->status & CONF_ILLEGAL) remove_reject_mask(aconf->host, NULL); else { rb_dlinkAddAlloc(aconf, &xline_conf_list); check_xlines(); } break; case CONF_RESV_CHANNEL: if (!(aconf->status & CONF_ILLEGAL)) { add_to_resv_hash(aconf->host, aconf); resv_chan_forcepart(aconf->host, aconf->passwd, hold - now); } break; case CONF_RESV_NICK: if (!(aconf->status & CONF_ILLEGAL)) rb_dlinkAddAlloc(aconf, &resv_conf_list); break; } sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS, ":%s BAN %s %s %s %s %s %s %s :%s", source_p->id, parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[parc - 1]); return 0; }
int main(int argc, char *argv[]) { char *plaintext = NULL; char *repeat_plaintext = NULL; char *crypt_passwd = NULL; int c; char *saltpara = NULL; char *salt; int flag = 0; int length = 0; /* Not Set */ int rounds = 0; /* Not set, since extended DES needs 25 and blowfish needs ** 4 by default, a side effect of this being the encryption ** type parameter must be specified before the rounds ** parameter. */ while((c = getopt(argc, argv, "xymdber:h?l:s:p:")) != -1) { switch (c) { case 'm': flag |= FLAG_MD5; break; case 'd': flag |= FLAG_DES; break; case 'b': flag |= FLAG_BLOWFISH; rounds = 4; break; case 'e': flag |= FLAG_EXT; rounds = 25; break; case 'l': flag |= FLAG_LENGTH; length = atoi(optarg); break; case 'r': flag |= FLAG_ROUNDS; rounds = atoi(optarg); break; case 's': flag |= FLAG_SALT; saltpara = optarg; break; case 'p': flag |= FLAG_PASS; plaintext = optarg; break; case 'x': flag |= FLAG_SHA256; break; case 'y': flag |= FLAG_SHA512; break; case 'h': full_usage(); /* NOT REACHED */ break; case '?': brief_usage(); /* NOT REACHED */ break; default: fprintf(stderr, "Invalid Option: -%c\n", c); break; } } if(flag & FLAG_MD5) { if(length == 0) length = 8; if(flag & FLAG_SALT) salt = make_md5_salt_para(saltpara); else salt = make_md5_salt(length); } else if(flag & FLAG_BLOWFISH) { if(length == 0) length = 22; if(flag & FLAG_SALT) salt = make_bf_salt_para(rounds, saltpara); else salt = make_bf_salt(rounds, length); } else if(flag & FLAG_SHA256) { if(length == 0) length = 16; if(flag & FLAG_SALT) salt = make_sha256_salt_para(saltpara); else salt = make_sha256_salt(length); } else if(flag & FLAG_SHA512) { if(length == 0) length = 16; if(flag & FLAG_SALT) salt = make_sha512_salt_para(saltpara); else salt = make_sha512_salt(length); } else if(flag & FLAG_EXT) { /* XXX - rounds needs to be done */ if(flag & FLAG_SALT) { if((strlen(saltpara) == 4)) { salt = make_ext_salt_para(rounds, saltpara); } else { fprintf(stderr, "Invalid salt, please enter 4 alphanumeric characters\n"); exit(1); } } else { salt = make_ext_salt(rounds); } } else { if(flag & FLAG_SALT) { if((strlen(saltpara) == 2)) { salt = saltpara; } else { fprintf(stderr, "Invalid salt, please enter 2 alphanumeric characters\n"); exit(1); } } else { salt = make_des_salt(); } } if(flag & FLAG_PASS) { if(!plaintext) fprintf(stderr, "Please enter a valid password\n"); } else { plaintext = rb_strdup(getpass("Password: "******"Repeat Password: "******"Password mismatch\n"); return 1; } } crypt_passwd = rb_crypt(plaintext, salt); if(!crypt_passwd) { fprintf(stderr, "Error while encryting password\n"); return 1; } printf("%s\n", crypt_passwd); return 0; }
/* * m_challenge - generate RSA challenge for wouldbe oper * parv[1] = operator to challenge for, or +response * */ static int m_challenge(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct oper_conf *oper_p; char *challenge = NULL; /* to placate gcc */ char chal_line[CHALLENGE_WIDTH]; unsigned char *b_response; size_t cnt; int len = 0; /* if theyre an oper, reprint oper motd and ignore */ if(IsOper(source_p)) { sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name); send_oper_motd(source_p); return 0; } if(*parv[1] == '+') { /* Ignore it if we aren't expecting this... -A1kmm */ if(!source_p->localClient->challenge) return 0; if((rb_current_time() - source_p->localClient->chal_time) > CHALLENGE_EXPIRES) { sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name); ilog(L_FOPER, "EXPIRED CHALLENGE (%s) by (%s!%s@%s) (%s)", source_p->localClient->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Expired CHALLENGE attempt by %s (%s@%s)", source_p->name, source_p->username, source_p->host); cleanup_challenge(source_p); return 0; } parv[1]++; b_response = rb_base64_decode((const unsigned char *)parv[1], strlen(parv[1]), &len); if(len != SHA_DIGEST_LENGTH || memcmp(source_p->localClient->challenge, b_response, SHA_DIGEST_LENGTH)) { sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name); ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s)", source_p->localClient->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Failed CHALLENGE attempt by %s (%s@%s)", source_p->name, source_p->username, source_p->host); rb_free(b_response); cleanup_challenge(source_p); return 0; } rb_free(b_response); oper_p = find_oper_conf(source_p->username, source_p->orighost, source_p->sockhost, source_p->localClient->opername); if(oper_p == NULL) { sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST)); ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)", source_p->localClient->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)", source_p->name, source_p->username, source_p->host); return 0; } cleanup_challenge(source_p); oper_up(source_p, oper_p); ilog(L_OPERED, "OPER %s by %s!%s@%s (%s)", source_p->localClient->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); return 0; } cleanup_challenge(source_p); oper_p = find_oper_conf(source_p->username, source_p->orighost, source_p->sockhost, parv[1]); if(oper_p == NULL) { sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST)); ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)", parv[1], source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)", source_p->name, source_p->username, source_p->host); return 0; } if(!oper_p->rsa_pubkey) { sendto_one_notice(source_p, ":I'm sorry, PK authentication is not enabled for your oper{} block."); return 0; } if(IsOperConfNeedSSL(oper_p) && !IsSSLClient(source_p)) { sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST)); ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s) -- requires SSL/TLS", parv[1], source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Failed CHALLENGE attempt - missing SSL/TLS by %s (%s@%s)", source_p->name, source_p->username, source_p->host); } return 0; } if (oper_p->certfp != NULL) { if (source_p->certfp == NULL || strcasecmp(source_p->certfp, oper_p->certfp)) { sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST)); ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s) -- client certificate fingerprint mismatch", parv[1], source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Failed OPER attempt - client certificate fingerprint mismatch by %s (%s@%s)", source_p->name, source_p->username, source_p->host); } return 0; } } if(!generate_challenge(&challenge, &(source_p->localClient->challenge), oper_p->rsa_pubkey)) { char *chal = challenge; source_p->localClient->chal_time = rb_current_time(); for(;;) { cnt = rb_strlcpy(chal_line, chal, CHALLENGE_WIDTH); sendto_one(source_p, form_str(RPL_RSACHALLENGE2), me.name, source_p->name, chal_line); if(cnt > CHALLENGE_WIDTH) chal += CHALLENGE_WIDTH - 1; else break; } sendto_one(source_p, form_str(RPL_ENDOFRSACHALLENGE2), me.name, source_p->name); rb_free(challenge); source_p->localClient->opername = rb_strdup(oper_p->name); } else sendto_one_notice(source_p, ":Failed to generate challenge."); return 0; }
static int m_displaymsg(struct Client *source_p, const char *channel, int underline, int action, const char *nick, const char *text) { struct Channel *chptr; struct membership *msptr; char nick2[NICKLEN+1]; char *nick3 = rb_strdup(nick); char text2[BUFSIZE]; if((chptr = find_channel(channel)) == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), channel); return 0; } if(!(msptr = find_channel_membership(chptr, source_p))) { sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), chptr->chname); return 0; } if(!(chptr->mode.mode & chmode_flags['N'])) { sendto_one_numeric(source_p, 573, "%s :Roleplay commands are not enabled on this channel.", chptr->chname); return 0; } if(!can_send(chptr, source_p, msptr)) { sendto_one_numeric(source_p, 573, "%s :Cannot send to channel.", chptr->chname); return 0; } /* enforce flood stuff on roleplay commands */ if(flood_attack_channel(0, source_p, chptr, chptr->chname)) return 0; /* enforce target change on roleplay commands */ if(!is_chanop_voiced(msptr) && !IsOper(source_p) && !add_channel_target(source_p, chptr)) { sendto_one(source_p, form_str(ERR_TARGCHANGE), me.name, source_p->name, chptr->chname); return 0; } if(underline) rb_snprintf(nick2, sizeof(nick2), "\x1F%s\x1F", strip_unprintable(nick3)); else rb_snprintf(nick2, sizeof(nick2), "%s", strip_unprintable(nick3)); /* don't allow nicks to be empty after stripping * this prevents nastiness like fake factions, etc. */ if(EmptyString(nick3)) { sendto_one_numeric(source_p, 573, "%s :No visible non-stripped characters in nick.", chptr->chname); return 0; } if(action) rb_snprintf(text2, sizeof(text2), "\1ACTION %s\1", text); else rb_snprintf(text2, sizeof(text2), "%s", text); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected] PRIVMSG %s :%s (%s)", nick2, source_p->name, channel, text2, source_p->name); sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS, "ENCAP * ROLEPLAY %s %s :%s", channel, nick2, text2); return 0; }
/* * m_pass() - Added Sat, 4 March 1989 * * * mr_pass - PASS message handler * parv[0] = sender prefix * parv[1] = password * parv[2] = "TS" if this server supports TS. * parv[3] = optional TS version field -- needed for TS6 */ static int mr_pass(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { if(client_p->localClient->passwd) { memset(client_p->localClient->passwd, 0, strlen(client_p->localClient->passwd)); rb_free(client_p->localClient->passwd); } client_p->localClient->passwd = rb_strndup(parv[1], PASSWDLEN); if(parc > 2) { #ifdef COMPAT_211 /* detected 2.11 protocol? */ if (strlen(parv[2]) == 10 && parc > 4) { if (strchr(parv[4], 'Z')) client_p->localClient->caps |= CAP_ZIP; if (strchr(parv[4], 'T')) client_p->localClient->caps |= CAP_TB; if (strchr(parv[4], 'j')) client_p->localClient->caps |= CAP_JAPANESE; if (!strcmp(parv[2], IRCNET_VERSTRING)) { /* nah, it's just us pretending, we're going to receive CAPAB. Will fill the SID in server stage though. */ client_p->localClient->caps |= CAP_TS6|CAPS_IRCNET; } else { /* True 2.11 */ client_p->localClient->caps |= CAP_211|CAPS_IRCNET; /* As we're never going to receive CAPAB for this one */ client_p->localClient->fullcaps = rb_strdup(send_capabilities(NULL, client_p->localClient->caps)); } return 0; } #endif /* * It looks to me as if orabidoo wanted to have more * than one set of option strings possible here... * i.e. ":AABBTS" as long as TS was the last two chars * however, as we are now using CAPAB, I think we can * safely assume if there is a ":TS" then its a TS server * -Dianora */ if(irccmp(parv[2], "TS") == 0 && client_p->tsinfo == 0) client_p->tsinfo = TS_DOESTS; if(parc == 5 && atoi(parv[3]) >= 6) { /* only mark as TS6 if the SID is valid.. */ if(check_sid(parv[4])) { client_p->localClient->caps |= CAP_TS6; strcpy(client_p->id, parv[4]); } } } return 0; }