X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Fclient.c;h=2114f84ddbc8bcf6a6761db022524b880c6a1d85;hb=588af510a35b5b28cb8c1063ac865f86c65d7a8a;hp=e203cdd0e79df243089066d09a80eedec5355a46;hpb=7b6b492bdd259c25c4477e33392510872107ca6a;p=ngircd-alex.git diff --git a/src/ngircd/client.c b/src/ngircd/client.c index e203cdd0..2114f84d 100644 --- a/src/ngircd/client.c +++ b/src/ngircd/client.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -331,9 +331,15 @@ Client_SetHostname( CLIENT *Client, const char *Hostname ) assert(Hostname != NULL); if (strlen(Conf_CloakHost)) { + char cloak[GETID_LEN]; + + strlcpy(cloak, Hostname, GETID_LEN); + strlcat(cloak, Conf_CloakHostSalt, GETID_LEN); + snprintf(cloak, GETID_LEN, Conf_CloakHost, Hash(cloak)); + LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"", - Client_ID(Client), Client->host, Conf_CloakHost); - strlcpy(Client->host, Conf_CloakHost, sizeof(Client->host)); + Client_ID(Client), Client->host, cloak); + strlcpy(Client->host, cloak, sizeof(Client->host)); } else { LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"", Client_ID(Client), Client->host, Hostname); @@ -434,18 +440,6 @@ Client_SetFlags( CLIENT *Client, const char *Flags ) } /* Client_SetFlags */ -GLOBAL void -Client_SetPassword( CLIENT *Client, const char *Pwd ) -{ - /* set password sent by client */ - - assert( Client != NULL ); - assert( Pwd != NULL ); - - strlcpy(Client->pwd, Pwd, sizeof(Client->pwd)); -} /* Client_SetPassword */ - - GLOBAL void Client_SetAway( CLIENT *Client, const char *Txt ) { @@ -677,7 +671,6 @@ Client_OrigUser(CLIENT *Client) { #endif - /** * Return the hostname of a client. * @param Client Pointer to client structure @@ -688,33 +681,88 @@ Client_Hostname(CLIENT *Client) { assert (Client != NULL); return Client->host; -} /* Client_Hostname */ +} +/** + * Return the cloaked hostname of a client, if set. + * @param Client Pointer to the client structure. + * @return Pointer to the cloaked hostname or NULL if not set. + */ +GLOBAL char * +Client_HostnameCloaked(CLIENT *Client) +{ + assert(Client != NULL); + return Client->cloaked; +} /** - * Get potentially cloaked hostname of a client. + * Get (potentially cloaked) hostname of a client to display it to other users. + * * If the client has not enabled cloaking, the real hostname is used. + * Please note that this function uses a global static buffer, so you can't + * nest invocations without overwriting earlier results! + * * @param Client Pointer to client structure * @return Pointer to client hostname */ GLOBAL char * -Client_HostnameCloaked(CLIENT *Client) +Client_HostnameDisplayed(CLIENT *Client) { assert(Client != NULL); - if (Client_HasMode(Client, 'x')) - return Client_ID(Client->introducer); - else + + /* Client isn't cloaked at all, return real hostname: */ + if (!Client_HasMode(Client, 'x')) return Client_Hostname(Client); -} /* Client_HostnameCloaked */ + /* Use an already saved cloaked hostname, if there is one */ + if (Client->cloaked[0]) + return Client->cloaked; -GLOBAL char * -Client_Password( CLIENT *Client ) + Client_UpdateCloakedHostname(Client, NULL, NULL); + return Client->cloaked; +} + +/** + * Update (and generate, if necessary) the cloaked hostname of a client. + * + * The newly set cloaked hostname is announced in the network using METADATA + * commands to peers that support this feature. + * + * @param Client The client of which the cloaked hostname should be updated. + * @param Origin The originator of the hostname change, or NULL if this server. + * @param Hostname The new cloaked hostname, or NULL if it should be generated. + */ +GLOBAL void +Client_UpdateCloakedHostname(CLIENT *Client, CLIENT *Origin, + const char *Hostname) { - assert( Client != NULL ); - return Client->pwd; -} /* Client_Password */ + static char Cloak_Buffer[CLIENT_HOST_LEN]; + assert(Client != NULL); + if (!Origin) + Origin = Client_ThisServer(); + + if (!Hostname) { + /* Generate new cloaked hostname */ + if (*Conf_CloakHostModeX) { + strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN); + strlcat(Cloak_Buffer, Conf_CloakHostSalt, + CLIENT_HOST_LEN); + snprintf(Client->cloaked, sizeof(Client->cloaked), + Conf_CloakHostModeX, Hash(Cloak_Buffer)); + } else + strlcpy(Client->cloaked, Client_ID(Client->introducer), + sizeof(Client->cloaked)); + } else + strlcpy(Client->cloaked, Hostname, sizeof(Client->cloaked)); + LogDebug("Cloaked hostname of \"%s\" updated to \"%s\"", + Client_ID(Client), Client->cloaked); + + /* Inform other servers in the network */ + IRC_WriteStrServersPrefixFlag(Client_NextHop(Origin), Origin, 'M', + "METADATA %s cloakhost :%s", + Client_ID(Client), Client->cloaked); +} GLOBAL char * Client_Modes( CLIENT *Client ) @@ -806,10 +854,12 @@ Client_Mask( CLIENT *Client ) /** * Return ID of a client with cloaked hostname: "client!user@server-name" + * * This client ID is used for IRC prefixes, for example. * Please note that this function uses a global static buffer, so you can't * nest invocations without overwriting earlier results! * If the client has not enabled cloaking, the real hostname is used. + * * @param Client Pointer to client structure * @return Pointer to global buffer containing the client ID */ @@ -822,12 +872,11 @@ Client_MaskCloaked(CLIENT *Client) /* Is the client using cloaking at all? */ if (!Client_HasMode(Client, 'x')) - return Client_Mask(Client); + return Client_Mask(Client); + + snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, + Client_HostnameDisplayed(Client)); - snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", - Client->id, Client->user, - *Conf_CloakHostModeX ? Conf_CloakHostModeX - : Client_ID(Client->introducer)); return Mask_Buffer; } /* Client_MaskCloaked */ @@ -871,7 +920,7 @@ Client_Away( CLIENT *Client ) * the appropriate error messages. * * @param Client Client that wants to change the nickname. - * @param Nick New nick name. + * @param Nick New nickname. * @returns true if nickname is valid, false otherwise. */ GLOBAL bool @@ -891,6 +940,16 @@ Client_CheckNick(CLIENT *Client, char *Nick) return false; } + if (Client_Type(Client) != CLIENT_SERVER + && Client_Type(Client) != CLIENT_SERVICE) { + /* Make sure that this isn't a restricted/forbidden nickname */ + if (Conf_NickIsBlocked(Nick)) { + IRC_WriteStrClient(Client, ERR_FORBIDDENNICKNAME_MSG, + Client_ID(Client), Nick); + return false; + } + } + /* Nickname already registered? */ if (Client_Search(Nick)) { IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG, @@ -1161,7 +1220,7 @@ Client_Introduce(CLIENT *From, CLIENT *Client, int Type) Client_SetType(Client, Type); if (From) { - if (Conf_IsService(Conf_GetServer(Client_Conn(From)), + if (Conf_NickIsService(Conf_GetServer(Client_Conn(From)), Client_ID(Client))) Client_SetType(Client, CLIENT_SERVICE); LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).", @@ -1325,7 +1384,7 @@ Client_RegisterWhowas( CLIENT *Client ) sizeof( My_Whowas[slot].id )); strlcpy( My_Whowas[slot].user, Client_User( Client ), sizeof( My_Whowas[slot].user )); - strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ), + strlcpy( My_Whowas[slot].host, Client_HostnameDisplayed( Client ), sizeof( My_Whowas[slot].host )); strlcpy( My_Whowas[slot].info, Client_Info( Client ), sizeof( My_Whowas[slot].info ));