diff --git a/src/ngircd/class.c b/src/ngircd/class.c index b7a5cbc0..0a8ae241 100644 --- a/src/ngircd/class.c +++ b/src/ngircd/class.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. * * 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 @@ -26,12 +26,15 @@ #include "client.h" #include "lists.h" #include "match.h" +#include "stdio.h" #include "exp.h" #include "class.h" struct list_head My_Classes[CLASS_COUNT]; +char Reject_Reason[COMMAND_LEN]; + GLOBAL void Class_Init(void) { @@ -46,15 +49,61 @@ Class_Exit(void) for (i = 0; i < CLASS_COUNT; Lists_Free(&My_Classes[i++])); } -GLOBAL bool -Class_IsMember(const int Class, CLIENT *Client) +GLOBAL char * +Class_GetMemberReason(const int Class, CLIENT *Client) { + char *reason; + assert(Class < CLASS_COUNT); assert(Client != NULL); - return Lists_Check(&My_Classes[Class], Client); + reason = Lists_CheckReason(&My_Classes[Class], Client); + if (!reason) + return NULL; + + if (!*reason) + reason = "listed"; + + switch(Class) { + case CLASS_GLINE: + snprintf(Reject_Reason, sizeof(Reject_Reason), + "\"%s\" (G-Line)", reason); + return Reject_Reason; + case CLASS_KLINE: + snprintf(Reject_Reason, sizeof(Reject_Reason), + "\"%s\" (K-Line)", reason); + return Reject_Reason; + } + return reason; } +/** + * Check if a client is banned from this server: GLINE, KLINE. + * + * If a client isn't allowed to connect, it will be disconnected again. + * + * @param Client The client to check. + * @return CONNECTED if client is allowed to join, DISCONNECTED if not. + */ +GLOBAL bool +Class_HandleServerBans(CLIENT *Client) +{ + char *rejectptr; + + assert(Client != NULL); + + rejectptr = Class_GetMemberReason(CLASS_GLINE, Client); + if (!rejectptr) + rejectptr = Class_GetMemberReason(CLASS_KLINE, Client); + if (rejectptr) { + Client_Reject(Client, rejectptr, true); + return DISCONNECTED; + } + + return CONNECTED; +} + + GLOBAL bool Class_AddMask(const int Class, const char *Mask, time_t ValidUntil, const char *Reason) diff --git a/src/ngircd/class.h b/src/ngircd/class.h index 8c06c2e2..2a9dbba7 100644 --- a/src/ngircd/class.h +++ b/src/ngircd/class.h @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. * * 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 @@ -29,7 +29,8 @@ GLOBAL bool Class_AddMask PARAMS((const int Class, const char *Mask, const time_t ValidUntil, const char *Reason)); GLOBAL void Class_DeleteMask PARAMS((const int Class, const char *Mask)); -GLOBAL bool Class_IsMember PARAMS((const int Class, CLIENT *Client)); +GLOBAL char *Class_GetMemberReason PARAMS((const int Class, CLIENT *Client)); +GLOBAL bool Class_HandleServerBans PARAMS((CLIENT *Client)); GLOBAL struct list_head *Class_GetList PARAMS((const int Class)); diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index bbb2f0d5..54818fe4 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -47,7 +47,6 @@ static bool Hello_User PARAMS(( CLIENT *Client )); static bool Hello_User_PostAuth PARAMS(( CLIENT *Client )); static void Kill_Nick PARAMS(( char *Nick, char *Reason )); static void Introduce_Client PARAMS((CLIENT *To, CLIENT *Client, int Type)); -static void Reject_Client PARAMS((CLIENT *Client, const char *InternalReason)); static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix, void *i)); @@ -945,7 +944,7 @@ Hello_User(CLIENT * Client) * passwords supplied are classified as "wrong". */ if(Client_Password(Client)[0] == '\0') return Hello_User_PostAuth(Client); - Reject_Client(Client, "non-empty password"); + Client_Reject(Client, "Non-empty password", false); return DISCONNECTED; } @@ -981,7 +980,7 @@ Hello_User(CLIENT * Client) /* Check global server password ... */ if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) { /* Bad password! */ - Reject_Client(Client, "bad server password"); + Client_Reject(Client, "Bad server password", false); return DISCONNECTED; } return Hello_User_PostAuth(Client); @@ -1026,7 +1025,7 @@ cb_Read_Auth_Result(int r_fd, UNUSED short events) if (len != sizeof(result)) { Log(LOG_CRIT, "Auth: Got malformed result!"); - Reject_Client(client, "internal error"); + Client_Reject(client, "Internal error", false); return; } @@ -1034,31 +1033,12 @@ cb_Read_Auth_Result(int r_fd, UNUSED short events) Client_SetUser(client, Client_OrigUser(client), true); (void)Hello_User_PostAuth(client); } else - Reject_Client(client, "bad password"); + Client_Reject(client, "Bad password", false); } #endif -/** - * Reject a client because of wrong password. - * - * This function is called either when the global server password or a password - * checked using PAM has been wrong. - * - * @param Client The client to reject. - */ -static void -Reject_Client(CLIENT *Client, const char *InternalReason) -{ - Log(LOG_ERR, - "User \"%s\" rejected (connection %d): %s!", - Client_Mask(Client), Client_Conn(Client), InternalReason); - Conn_Close(Client_Conn(Client), InternalReason, - "Access denied! Bad password?", true); -} - - /** * Finish client registration. * @@ -1071,14 +1051,10 @@ Reject_Client(CLIENT *Client, const char *InternalReason) static bool Hello_User_PostAuth(CLIENT *Client) { - if (Class_IsMember(CLASS_GLINE, Client)) { - Reject_Client(Client, "G-Line'd"); + assert(Client != NULL); + + if (Class_HandleServerBans(Client) != CONNECTED) return DISCONNECTED; - } - if (Class_IsMember(CLASS_KLINE, Client)) { - Reject_Client(Client, "K-Line'd"); - return DISCONNECTED; - } Introduce_Client(NULL, Client, CLIENT_USER);