/*! \brief CAPAB command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = space-separated list of capabilities */ static int mr_capab(struct Client *source_p, int parc, char *parv[]) { unsigned int cap = 0; char *p = NULL; char *s = NULL; for (s = strtok_r(parv[1], " ", &p); s; s = strtok_r(NULL, " ", &p)) if ((cap = find_capability(s))) SetCapable(source_p, cap); return 0; }
/* * m_pass() - Added Sat, 4 March 1989 * * * mr_pass - PASS message handler * parv[0] = sender prefix * parv[1] = password * parv[2] = optional extra version information */ static void mr_pass(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char *password = parv[1]; if (EmptyString(password)) { sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS), me.name, EmptyString(parv[0]) ? "*" : parv[0], "PASS"); return; } MyFree(client_p->localClient->passwd); if (strlen(password) > PASSWDLEN) password[PASSWDLEN] = '\0'; DupString(client_p->localClient->passwd, password); if (parc > 2) { /* 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") && client_p->tsinfo == 0) client_p->tsinfo = TS_DOESTS; } /* only do this stuff if we are doing ts6 */ if (parc > 4 && me.id[0]) { if (atoi(parv[3]) >= 6 && valid_sid(parv[4])) { strlcpy(client_p->id, parv[4], sizeof(client_p->id)); SetCapable(client_p, CAP_TS6); } } }
/*! \brief PASS command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = password * - parv[2] = optional extra version information * - parv[3] = TS protocol version * - parv[4] = server ID (SID) */ static int mr_pass(struct Client *source_p, int parc, char *parv[]) { assert(MyConnect(source_p)); if (EmptyString(parv[1])) { sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "PASS"); return 0; } MyFree(source_p->connection->password); source_p->connection->password = xstrndup(parv[1], IRCD_MIN(strlen(parv[1]), PASSWDLEN)); if (parc > 2) { /* * 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 it's a TS server * -Dianora */ if (!irccmp(parv[2], "TS") && source_p->tsinfo == 0) source_p->tsinfo = TS_DOESTS; } /* Only do this stuff if we are doing ts6 */ if (parc > 4) { if (atoi(parv[3]) >= 6 && valid_sid(parv[4])) { strlcpy(source_p->id, parv[4], sizeof(source_p->id)); SetCapable(source_p, CAP_TS6); } } return 0; }
/* * mr_capab - CAPAB message handler * parv[0] = sender prefix * parv[1] = space-separated list of capabilities * */ static void mr_capab(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { int i; int cap; char *p; char *s; #ifdef HAVE_LIBCRYPTO struct EncCapability *ecap; unsigned int cipher = 0; #endif /* ummm, this shouldn't happen. Could argue this should be logged etc. */ if (client_p->localClient == NULL) return; if (client_p->localClient->caps && !(IsCapable(client_p, CAP_TS6))) { exit_client(client_p, client_p, "CAPAB received twice"); return; } else SetCapable(client_p, CAP_CAP); for (i = 1; i < parc; i++) { for (s = strtoken(&p, parv[i], " "); s; s = strtoken(&p, NULL, " ")) { #ifdef HAVE_LIBCRYPTO if ((strncmp(s, "ENC:", 4) == 0)) { /* Skip the "ENC:" portion */ s += 4; /* Check the remaining portion against the list of ciphers we * have available (CipherTable). */ for (ecap = CipherTable; ecap->name; ecap++) { if ((irccmp(ecap->name, s) == 0) && (ecap->cap & CAP_ENC_MASK)) { cipher = ecap->cap; break; } } /* Since the name and capabilities matched, use it. */ if (cipher != 0) { SetCapable(client_p, CAP_ENC); client_p->localClient->enc_caps |= cipher; } else { /* cipher is still zero; we didn't find a matching entry. */ exit_client(client_p, client_p, "Cipher selected is not available here."); return; } } else /* normal capab */ #endif if ((cap = find_capability(s)) != 0) SetCapable(client_p, cap); } } }