/** * Initialize new client and set up the given parameters like client type, * user name, host name, introducing server etc. ... * @return New CLIENT structure. */ static CLIENT * Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, int Type, const char *ID, const char *User, const char *Hostname, const char *Info, int Hops, int Token, const char *Modes, bool Idented) { CLIENT *client; assert(Idx >= NONE); assert(Introducer != NULL); client = New_Client_Struct(); if (!client) return NULL; client->starttime = time(NULL); client->conn_id = Idx; client->introducer = Introducer; client->topserver = TopServer; client->type = Type; if (ID) Client_SetID(client, ID); if (User) { Client_SetUser(client, User, Idented); Client_SetOrigUser(client, User); } if (Hostname) Client_SetHostname(client, Hostname); if (Info) Client_SetInfo(client, Info); client->hops = Hops; client->token = Token; if (Modes) Client_SetModes(client, Modes); if (Type == CLIENT_SERVER) Generate_MyToken(client); if (Client_HasMode(client, 'a')) client->away = strndup(DEFAULT_AWAY_MSG, CLIENT_AWAY_LEN - 1); client->next = (POINTER *)My_Clients; My_Clients = client; Adjust_Counters(client); return client; } /* Init_New_Client */
/** * Handler for the IRC "WEBIRC" command. * * See doc/Protocol.txt, section II.4: * "Update webchat/proxy client information". * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @returns CONNECTED or DISCONNECTED. */ GLOBAL bool IRC_WEBIRC(CLIENT *Client, REQUEST *Req) { /* Exactly 4 parameters are requited */ if (Req->argc != 4) return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0) return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG, Client_ID(Client)); LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s", Client_Conn(Client), Req->argv[1], Req->argv[2], Req->argv[3]); Client_SetUser(Client, Req->argv[1], true); Client_SetOrigUser(Client, Req->argv[1]); Client_SetHostname(Client, Req->argv[2]); return CONNECTED; } /* IRC_WEBIRC */
/** * Handler for the IRC "USER" command. * * See RFC 2812, 3.1.3 "User message". * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @returns CONNECTED or DISCONNECTED. */ GLOBAL bool IRC_USER(CLIENT * Client, REQUEST * Req) { CLIENT *c; char *ptr; assert(Client != NULL); assert(Req != NULL); if (Client_Type(Client) == CLIENT_GOTNICK || #ifndef STRICT_RFC Client_Type(Client) == CLIENT_UNKNOWN || #endif Client_Type(Client) == CLIENT_GOTPASS) { /* New connection */ if (Req->argc != 4) return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); /* User name: only alphanumeric characters and limited punctuation is allowed.*/ ptr = Req->argv[0]; while (*ptr) { if (!isalnum(*ptr) && *ptr != '+' && *ptr != '-' && *ptr != '.' && *ptr != '_') { Conn_Close(Client_Conn(Client), NULL, "Invalid user name", true); return DISCONNECTED; } ptr++; } #ifdef IDENTAUTH ptr = Client_User(Client); if (!ptr || !*ptr || *ptr == '~') Client_SetUser(Client, Req->argv[0], false); #else Client_SetUser(Client, Req->argv[0], false); #endif Client_SetOrigUser(Client, Req->argv[0]); /* "Real name" or user info text: Don't set it to the empty * string, the original ircd can't deal with such "real names" * (e. g. "USER user * * :") ... */ if (*Req->argv[3]) Client_SetInfo(Client, Req->argv[3]); else Client_SetInfo(Client, "-"); LogDebug("Connection %d: got valid USER command ...", Client_Conn(Client)); if (Client_Type(Client) == CLIENT_GOTNICK) return Login_User(Client); else Client_SetType(Client, CLIENT_GOTUSER); return CONNECTED; } else if (Client_Type(Client) == CLIENT_SERVER || Client_Type(Client) == CLIENT_SERVICE) { /* Server/service updating an user */ if (Req->argc != 4) return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); c = Client_Search(Req->prefix); if (!c) return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); Client_SetUser(c, Req->argv[0], true); Client_SetOrigUser(c, Req->argv[0]); Client_SetHostname(c, Req->argv[1]); Client_SetInfo(c, Req->argv[3]); LogDebug("Connection %d: got valid USER command for \"%s\".", Client_Conn(Client), Client_Mask(c)); /* RFC 1459 style user registration? * Introduce client to network: */ if (Client_Type(c) == CLIENT_GOTNICK) Client_Introduce(Client, c, CLIENT_USER); return CONNECTED; } else if (Client_Type(Client) == CLIENT_USER) { /* Already registered connection */ return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG, Client_ID(Client)); } else { /* Unexpected/invalid connection state? */ return IRC_WriteStrClient(Client, ERR_NOTREGISTERED_MSG, Client_ID(Client)); } } /* IRC_USER */