/* * atheme.login * * XML Inputs: * account name, password, source ip (optional) * * XML Outputs: * fault 1 - insufficient parameters * fault 3 - account is not registered * fault 5 - invalid username and password * fault 6 - account is frozen * default - success (authcookie) * * Side Effects: * an authcookie ticket is created for the myuser_t. * the user's lastlogin is updated */ static int xmlrpcmethod_login(void *conn, int parc, char *parv[]) { myuser_t *mu; authcookie_t *ac; const char *sourceip; if (parc < 2) { xmlrpc_generic_error(fault_needmoreparams, "Insufficient parameters."); return 0; } sourceip = parc >= 3 && *parv[2] != '\0' ? parv[2] : NULL; if (!(mu = myuser_find(parv[0]))) { xmlrpc_generic_error(fault_nosuch_source, "The account is not registered."); return 0; } if (metadata_find(mu, "private:freeze:freezer") != NULL) { logcommand_external(nicksvs.me, "xmlrpc", conn, sourceip, NULL, CMDLOG_LOGIN, "failed LOGIN to \2%s\2 (frozen)", entity(mu)->name); xmlrpc_generic_error(fault_noprivs, "The account has been frozen."); return 0; } if (!verify_password(mu, parv[1])) { sourceinfo_t *si; logcommand_external(nicksvs.me, "xmlrpc", conn, sourceip, NULL, CMDLOG_LOGIN, "failed LOGIN to \2%s\2 (bad password)", entity(mu)->name); xmlrpc_generic_error(fault_authfail, "The password is not valid for this account."); si = sourceinfo_create(); si->service = NULL; si->sourcedesc = parv[2] != NULL && *parv[2] ? parv[2] : NULL; si->connection = conn; si->v = &xmlrpc_vtable; si->force_language = language_find("en"); bad_password(si, mu); object_unref(si); return 0; } mu->lastlogin = CURRTIME; ac = authcookie_create(mu); logcommand_external(nicksvs.me, "xmlrpc", conn, sourceip, mu, CMDLOG_LOGIN, "LOGIN"); xmlrpc_send_string(ac->ticket); return 0; }
/* parses a P10 IRC stream */ static void p10_parse(char *line) { sourceinfo_t *si; char *pos; char *origin = NULL; char *command = NULL; char *message = NULL; char *parv[MAXPARC + 1]; static char coreLine[BUFSIZE]; int parc = 0; unsigned int i; pcommand_t *pcmd; /* clear the parv */ for (i = 0; i <= MAXPARC; i++) parv[i] = NULL; si = sourceinfo_create(); si->connection = curr_uplink->conn; si->output_limit = MAX_IRC_OUTPUT_LINES; if (line != NULL) { /* sometimes we'll get a blank line with just a \n on it... * catch those here... they'll core us later on if we don't */ if (*line == '\n') goto cleanup; if (*line == '\000') goto cleanup; /* copy the original line so we know what we crashed on */ memset((char *)&coreLine, '\0', BUFSIZE); mowgli_strlcpy(coreLine, line, BUFSIZE); slog(LG_RAWDATA, "-> %s", line); /* find the first space */ if ((pos = strchr(line, ' '))) { *pos = '\0'; pos++; /* if it starts with a : we have a prefix/origin * pull the origin off into `origin', and have pos for the * command, message will be the part afterwards */ if (*line == ':' || me.recvsvr) { origin = line; if (*origin == ':') { origin++; si->s = server_find(origin); si->su = user_find_named(origin); } else { si->s = server_find(origin); si->su = user_find(origin); } if ((message = strchr(pos, ' '))) { *message = '\0'; message++; command = pos; } else { command = pos; message = NULL; } } else { message = pos; command = line; } } if (!si->s && !si->su && me.recvsvr) { slog(LG_DEBUG, "p10_parse(): got message from nonexistant user or server: %s", origin); goto cleanup; } if (si->s == me.me) { slog(LG_INFO, "p10_parse(): got message supposedly from myself %s: %s", si->s->name, coreLine); goto cleanup; } if (si->su != NULL && si->su->server == me.me) { slog(LG_INFO, "p10_parse(): got message supposedly from my own client %s: %s", si->su->nick, coreLine); goto cleanup; } si->smu = si->su != NULL ? si->su->myuser : NULL; /* okay, the nasty part is over, now we need to make a * parv out of what's left */ if (message) { if (*message == ':') { message++; parv[0] = message; parc = 1; } else parc = tokenize(message, parv); } else parc = 0; /* now we should have origin (or NULL), command, and a parv * with it's accompanying parc... let's make ABSOLUTELY sure */ if (!command) { slog(LG_DEBUG, "p10_parse(): command not found: %s", coreLine); goto cleanup; } /* take the command through the hash table */ if ((pcmd = pcommand_find(command))) { if (si->su && !(pcmd->sourcetype & MSRC_USER)) { slog(LG_INFO, "p10_parse(): user %s sent disallowed command %s", si->su->nick, pcmd->token); goto cleanup; } else if (si->s && !(pcmd->sourcetype & MSRC_SERVER)) { slog(LG_INFO, "p10_parse(): server %s sent disallowed command %s", si->s->name, pcmd->token); goto cleanup; } else if (!me.recvsvr && !(pcmd->sourcetype & MSRC_UNREG)) { slog(LG_INFO, "p10_parse(): unregistered server sent disallowed command %s", pcmd->token); goto cleanup; } if (parc < pcmd->minparc) { slog(LG_INFO, "p10_parse(): insufficient parameters for command %s", pcmd->token); goto cleanup; } if (pcmd->handler) { pcmd->handler(si, parc, parv); } } } cleanup: object_unref(si); }
/* * atheme.command * * XML inputs: * authcookie, account name, source ip, service name, command name, * parameters. * * XML outputs: * depends on command * * Side Effects: * command is executed */ static int xmlrpcmethod_command(void *conn, int parc, char *parv[]) { myuser_t *mu; service_t *svs; command_t *cmd; sourceinfo_t *si; int newparc; char *newparv[20]; struct httpddata *hd = ((connection_t *)conn)->userdata; int i; for (i = 0; i < parc; i++) { if (*parv[i] == '\0' || strchr(parv[i], '\r') || strchr(parv[i], '\n')) { xmlrpc_generic_error(fault_badparams, "Invalid parameters."); return 0; } } if (parc < 5) { xmlrpc_generic_error(fault_needmoreparams, "Insufficient parameters."); return 0; } if (*parv[1] != '\0' && strlen(parv[0]) > 1) { if ((mu = myuser_find(parv[1])) == NULL) { xmlrpc_generic_error(fault_nosuch_source, "Unknown user."); return 0; } if (authcookie_validate(parv[0], mu) == false) { xmlrpc_generic_error(fault_badauthcookie, "Invalid authcookie for this account."); return 0; } } else mu = NULL; /* try literal service name first, then user-configured nickname. */ svs = service_find(parv[3]); if ((svs == NULL && (svs = service_find_nick(parv[3])) == NULL) || svs->commands == NULL) { slog(LG_DEBUG, "xmlrpcmethod_command(): invalid service %s", parv[3]); xmlrpc_generic_error(fault_nosuch_source, "Invalid service name."); return 0; } cmd = command_find(svs->commands, parv[4]); if (cmd == NULL) { xmlrpc_generic_error(fault_nosuch_source, "Invalid command name."); return 0; } memset(newparv, '\0', sizeof newparv); newparc = parc - 5; if (newparc > 20) newparc = 20; if (newparc > 0) memcpy(newparv, parv + 5, newparc * sizeof(parv[0])); si = sourceinfo_create(); si->smu = mu; si->service = svs; si->sourcedesc = parv[2][0] != '\0' ? parv[2] : NULL; si->connection = conn; si->v = &xmlrpc_vtable; si->force_language = language_find("en"); command_exec(svs, si, cmd, newparc, newparv); /* XXX: needs to be fixed up for restartable commands... */ if (!hd->sent_reply) { if (hd->replybuf != NULL) xmlrpc_send_string(hd->replybuf); else xmlrpc_generic_error(fault_unimplemented, "Command did not return a result."); } object_unref(si); return 0; }