mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-10-31 22:13:00 +00:00 
			
		
		
		
	Improved client announcement
Move Announce_User() to client.c and rename it to Client_Announce(). Use this in cb_introduceClient() instead of duplicating the code. This fix the certificate fingerprint announcement for new clients. Also ensure the certificate fingerprint is only announced if the client supports it (`M' flag).
This commit is contained in:
		| @@ -1513,9 +1513,6 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool | |||||||
| /** | /** | ||||||
|  * Introduce a new user or service client to a remote server. |  * Introduce a new user or service client to a remote server. | ||||||
|  * |  * | ||||||
|  * This function differentiates between RFC1459 and RFC2813 server links and |  | ||||||
|  * generates the appropriate commands to register the new user or service. |  | ||||||
|  * |  | ||||||
|  * @param To		The remote server to inform. |  * @param To		The remote server to inform. | ||||||
|  * @param Prefix	Prefix for the generated commands. |  * @param Prefix	Prefix for the generated commands. | ||||||
|  * @param data		CLIENT structure of the new client. |  * @param data		CLIENT structure of the new client. | ||||||
| @@ -1524,43 +1521,92 @@ static void | |||||||
| cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data) | cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data) | ||||||
| { | { | ||||||
| 	CLIENT *c = (CLIENT *)data; | 	CLIENT *c = (CLIENT *)data; | ||||||
|  |  | ||||||
|  | 	(void)Client_Announce(To, Prefix, c); | ||||||
|  |  | ||||||
|  | } /* cb_introduceClient */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Announce an user or service to a server. | ||||||
|  |  * | ||||||
|  |  * This function differentiates between RFC1459 and RFC2813 server links and | ||||||
|  |  * generates the appropriate commands to register the user or service. | ||||||
|  |  * | ||||||
|  |  * @param Client	Server | ||||||
|  |  * @param Prefix	Prefix for the generated commands | ||||||
|  |  * @param User		User to announce | ||||||
|  |  */ | ||||||
|  | GLOBAL bool | ||||||
|  | Client_Announce(CLIENT * Client, CLIENT * Prefix, CLIENT * User) | ||||||
|  | { | ||||||
| 	CONN_ID conn; | 	CONN_ID conn; | ||||||
| 	char *modes, *user, *host; | 	char *modes, *user, *host; | ||||||
|  |  | ||||||
| 	modes = Client_Modes(c); | 	modes = Client_Modes(User); | ||||||
| 	user = Client_User(c) ? Client_User(c) : "-"; | 	user = Client_User(User) ? Client_User(User) : "-"; | ||||||
| 	host = Client_Hostname(c) ? Client_Hostname(c) : "-"; | 	host = Client_Hostname(User) ? Client_Hostname(User) : "-"; | ||||||
|  |  | ||||||
| 	conn = Client_Conn(To); | 	conn = Client_Conn(Client); | ||||||
| 	if (Conn_Options(conn) & CONN_RFC1459) { | 	if (Conn_Options(conn) & CONN_RFC1459) { | ||||||
| 		/* RFC 1459 mode: separate NICK and USER commands */ | 		/* RFC 1459 mode: separate NICK and USER commands */ | ||||||
| 		Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c), | 		if (! Conn_WriteStr(conn, "NICK %s :%d", | ||||||
| 			      Client_Hops(c) + 1); | 				    Client_ID(User), Client_Hops(User) + 1)) | ||||||
| 		Conn_WriteStr(conn, ":%s USER %s %s %s :%s", | 			return DISCONNECTED; | ||||||
| 			      Client_ID(c), user, host, | 		if (! Conn_WriteStr(conn, ":%s USER %s %s %s :%s", | ||||||
| 			      Client_ID(Client_Introducer(c)), Client_Info(c)); | 				     Client_ID(User), user, host, | ||||||
| 		if (modes[0]) | 				     Client_ID(Client_Introducer(User)), | ||||||
| 			Conn_WriteStr(conn, ":%s MODE %s +%s", | 				     Client_Info(User))) | ||||||
| 				      Client_ID(c), Client_ID(c), modes); | 			return DISCONNECTED; | ||||||
|  | 		if (modes[0]) { | ||||||
|  | 			if (! Conn_WriteStr(conn, ":%s MODE %s +%s", | ||||||
|  | 				     Client_ID(User), Client_ID(User), | ||||||
|  | 				     modes)) | ||||||
|  | 				return DISCONNECTED; | ||||||
|  | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		/* RFC 2813 mode: one combined NICK or SERVICE command */ | 		/* RFC 2813 mode: one combined NICK or SERVICE command */ | ||||||
| 		if (Client_Type(c) == CLIENT_SERVICE | 		if (Client_Type(User) == CLIENT_SERVICE | ||||||
| 		    && strchr(Client_Flags(To), 'S')) | 		    && strchr(Client_Flags(Client), 'S')) { | ||||||
| 			IRC_WriteStrClientPrefix(To, Prefix, | 			if (!IRC_WriteStrClientPrefix(Client, Prefix, | ||||||
| 						 "SERVICE %s %d * +%s %d :%s", | 					"SERVICE %s %d * +%s %d :%s", | ||||||
| 						 Client_Mask(c), | 					Client_Mask(User), | ||||||
| 						 Client_MyToken(Client_Introducer(c)), | 					Client_MyToken(Client_Introducer(User)), | ||||||
| 						 Client_Modes(c), Client_Hops(c) + 1, | 					modes, Client_Hops(User) + 1, | ||||||
| 						 Client_Info(c)); | 					Client_Info(User))) | ||||||
| 		else | 				return DISCONNECTED; | ||||||
| 			IRC_WriteStrClientPrefix(To, Prefix, | 		} else { | ||||||
| 						 "NICK %s %d %s %s %d +%s :%s", | 			if (!IRC_WriteStrClientPrefix(Client, Prefix, | ||||||
| 						 Client_ID(c), Client_Hops(c) + 1, | 					"NICK %s %d %s %s %d +%s :%s", | ||||||
| 						 user, host, | 					Client_ID(User), Client_Hops(User) + 1, | ||||||
| 						 Client_MyToken(Client_Introducer(c)), | 					user, host, | ||||||
| 						 modes, Client_Info(c)); | 					Client_MyToken(Client_Introducer(User)), | ||||||
|  | 					modes, Client_Info(User))) | ||||||
|  | 				return DISCONNECTED; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } /* cb_introduceClient */ |  | ||||||
|  | 	if (strchr(Client_Flags(Client), 'M')) { | ||||||
|  | 		/* Synchronize metadata */ | ||||||
|  | 		if (Client_HostnameCloaked(User)) { | ||||||
|  | 			if (!IRC_WriteStrClientPrefix(Client, Prefix, | ||||||
|  | 					"METADATA %s cloakhost :%s", | ||||||
|  | 					Client_ID(User), | ||||||
|  | 					Client_HostnameCloaked(User))) | ||||||
|  | 				return DISCONNECTED; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (Conn_GetFingerprint(Client_Conn(User))) { | ||||||
|  | 			if (!IRC_WriteStrClientPrefix(Client, Prefix, | ||||||
|  | 					"METADATA %s certfp :%s", | ||||||
|  | 					Client_ID(User), | ||||||
|  | 					Conn_GetFingerprint(Client_Conn(User)))) | ||||||
|  | 				return DISCONNECTED; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return CONNECTED; | ||||||
|  | } /* Client_Announce */ | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
|   | |||||||
| @@ -93,6 +93,8 @@ GLOBAL CLIENT *Client_ThisServer PARAMS(( void )); | |||||||
|  |  | ||||||
| GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, int Token )); | GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, int Token )); | ||||||
|  |  | ||||||
|  | GLOBAL bool Client_Announce PARAMS(( CLIENT *Client, CLIENT *Prefix, CLIENT *User )); | ||||||
|  |  | ||||||
| GLOBAL CLIENT *Client_Search PARAMS(( const char *ID )); | GLOBAL CLIENT *Client_Search PARAMS(( const char *ID )); | ||||||
| GLOBAL CLIENT *Client_SearchServer PARAMS(( const char *ID )); | GLOBAL CLIENT *Client_SearchServer PARAMS(( const char *ID )); | ||||||
| GLOBAL CLIENT *Client_First PARAMS(( void )); | GLOBAL CLIENT *Client_First PARAMS(( void )); | ||||||
|   | |||||||
| @@ -150,80 +150,6 @@ Announce_Server(CLIENT * Client, CLIENT * Server) | |||||||
| } /* Announce_Server */ | } /* Announce_Server */ | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Announce existing user to a new server |  | ||||||
|  * @param Client New server |  | ||||||
|  * @param User Existing user in the network |  | ||||||
|  */ |  | ||||||
| static bool |  | ||||||
| Announce_User(CLIENT * Client, CLIENT * User) |  | ||||||
| { |  | ||||||
| 	CONN_ID conn; |  | ||||||
| 	char *modes; |  | ||||||
|  |  | ||||||
| 	conn = Client_Conn(Client); |  | ||||||
| 	if (Conn_Options(conn) & CONN_RFC1459) { |  | ||||||
| 		/* RFC 1459 mode: separate NICK and USER commands */ |  | ||||||
| 		if (! Conn_WriteStr(conn, "NICK %s :%d", |  | ||||||
| 				    Client_ID(User), Client_Hops(User) + 1)) |  | ||||||
| 			return DISCONNECTED; |  | ||||||
| 		if (! Conn_WriteStr(conn, ":%s USER %s %s %s :%s", |  | ||||||
| 				     Client_ID(User), Client_User(User), |  | ||||||
| 				     Client_Hostname(User), |  | ||||||
| 				     Client_ID(Client_Introducer(User)), |  | ||||||
| 				     Client_Info(User))) |  | ||||||
| 			return DISCONNECTED; |  | ||||||
| 		modes = Client_Modes(User); |  | ||||||
| 		if (modes[0]) { |  | ||||||
| 			return Conn_WriteStr(conn, ":%s MODE %s +%s", |  | ||||||
| 				     Client_ID(User), Client_ID(User), |  | ||||||
| 				     modes); |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		/* RFC 2813 mode: one combined NICK or SERVICE command */ |  | ||||||
| 		if (Client_Type(User) == CLIENT_SERVICE |  | ||||||
| 		    && strchr(Client_Flags(Client), 'S')) { |  | ||||||
| 			if (!IRC_WriteStrClient(Client, |  | ||||||
| 					"SERVICE %s %d * +%s %d :%s", |  | ||||||
| 					Client_Mask(User), |  | ||||||
| 					Client_MyToken(Client_Introducer(User)), |  | ||||||
| 					Client_Modes(User), Client_Hops(User) + 1, |  | ||||||
| 					Client_Info(User))) |  | ||||||
| 				return DISCONNECTED; |  | ||||||
| 		} else { |  | ||||||
| 			if (!IRC_WriteStrClient(Client, |  | ||||||
| 					"NICK %s %d %s %s %d +%s :%s", |  | ||||||
| 					Client_ID(User), Client_Hops(User) + 1, |  | ||||||
| 					Client_User(User), Client_Hostname(User), |  | ||||||
| 					Client_MyToken(Client_Introducer(User)), |  | ||||||
| 					Client_Modes(User), Client_Info(User))) |  | ||||||
| 				return DISCONNECTED; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (strchr(Client_Flags(Client), 'M')) { |  | ||||||
| 		/* Synchronize metadata */ |  | ||||||
| 		if (Client_HostnameCloaked(User)) { |  | ||||||
| 			if (!IRC_WriteStrClient(Client, |  | ||||||
| 						"METADATA %s cloakhost :%s", |  | ||||||
| 						Client_ID(User), |  | ||||||
| 						Client_HostnameCloaked(User))) |  | ||||||
| 				return DISCONNECTED; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (Conn_GetFingerprint(conn)) { |  | ||||||
| 		if (!IRC_WriteStrClient(Client, |  | ||||||
| 					"METADATA %s certfp :%s", |  | ||||||
| 					Client_ID(User), |  | ||||||
| 					Conn_GetFingerprint(conn))) |  | ||||||
| 			return DISCONNECTED; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return CONNECTED; |  | ||||||
| } /* Announce_User */ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef IRCPLUS | #ifdef IRCPLUS | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -380,7 +306,7 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req) | |||||||
| 	while (c) { | 	while (c) { | ||||||
| 		if (Client_Type(c) == CLIENT_USER || | 		if (Client_Type(c) == CLIENT_USER || | ||||||
| 		    Client_Type(c) == CLIENT_SERVICE) { | 		    Client_Type(c) == CLIENT_SERVICE) { | ||||||
| 			if (!Announce_User(Client, c)) | 			if (!Client_Announce(Client, Client_ThisServer(), c)) | ||||||
| 				return DISCONNECTED; | 				return DISCONNECTED; | ||||||
| 		} | 		} | ||||||
| 		c = Client_Next(c); | 		c = Client_Next(c); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Federico G. Schwindt
					Federico G. Schwindt