From 66f0dc137cea9a925a0b35d148aa3fb3011443cd Mon Sep 17 00:00:00 2001 From: pk910 Date: Sun, 8 Jan 2012 06:04:04 +0100 Subject: [PATCH] fixed temporary user management --- src/IRCParser.c | 12 ++--- src/UserNode.c | 113 +++++++++++++++++++++++++++------------ src/UserNode.h | 3 +- src/cmd_neonserv_unban.c | 2 +- 4 files changed, 89 insertions(+), 41 deletions(-) diff --git a/src/IRCParser.c b/src/IRCParser.c index 6e6c613..750ac7b 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -395,7 +395,7 @@ static IRC_CMD(raw_kick) { int keep_channel = 1; if(isUserOnChan(target, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) { if(user == NULL) { - user = createTempUser(from); + user = createTempUserMask(from); if(!user) return 0; user->flags |= USERFLAG_ISTMPUSER; } @@ -425,7 +425,7 @@ static IRC_CMD(raw_topic) { if(chan == NULL) return 0; if(chan->chanbot != client->user) return 1; //just ignore it to prevent event duplicates if(user == NULL) { - user = createTempUser(from); + user = createTempUserMask(from); if(!user) return 0; user->flags |= USERFLAG_ISTMPUSER; } @@ -438,7 +438,7 @@ static IRC_CMD(raw_privmsg) { if(from == NULL || argc < 2) return 0; struct UserNode *user = getUserByMask(from); if(user == NULL) { - user = createTempUser(from); + user = createTempUserMask(from); if(!user) return 0; user->flags |= USERFLAG_ISTMPUSER; } @@ -496,7 +496,7 @@ static IRC_CMD(raw_notice) { if(from == NULL || argc < 2) return 0; struct UserNode *user = getUserByMask(from); if(user == NULL) { - user = createTempUser(from); + user = createTempUserMask(from); if(!user) return 0; user->flags |= USERFLAG_ISTMPUSER; } @@ -551,7 +551,7 @@ static IRC_CMD(raw_invite) { if(from == NULL || argc < 2) return 0; struct UserNode *user = getUserByMask(from); if(user == NULL) { - user = createTempUser(from); + user = createTempUserMask(from); if(!user) return 0; user->flags |= USERFLAG_ISTMPUSER; } @@ -563,7 +563,7 @@ static IRC_CMD(raw_mode) { if(from == NULL || argc < 2) return 0; struct UserNode *user = getUserByMask(from); if(user == NULL) { - user = createTempUser(from); + user = createTempUserMask(from); if(!user) return 0; user->flags |= USERFLAG_ISTMPUSER; } diff --git a/src/UserNode.c b/src/UserNode.c index 739722a..3f20a13 100644 --- a/src/UserNode.c +++ b/src/UserNode.c @@ -122,7 +122,7 @@ struct UserNode* searchUserByNick(const char *nick) { //case insensitive int countUsersWithHost(char *host) { int i, count = 0; struct UserNode *user; - for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN+1; i++) { + for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) { for(user = userList[i]; user; user = user->next) { if(!strcmp(user->host, host)) { count++; @@ -135,7 +135,7 @@ int countUsersWithHost(char *host) { char *getAuthFakehost(char *auth) { int i; struct UserNode *user; - for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN+1; i++) { + for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) { for(user = userList[i]; user; user = user->next) { if((user->flags & USERFLAG_ISAUTHED) && !strcmp(user->auth, auth) && isFakeHost(user->host)) { return user->host; @@ -152,7 +152,7 @@ struct UserNode* getAllUsers(struct UserNode *last) { cindex = 0; else cindex = get_nicklist_entry(last->nick[0]) + 1; - while(userList[cindex] == NULL && cindex <= VALID_NICK_CHARS_FIRST_LEN) + while(userList[cindex] == NULL && cindex < VALID_NICK_CHARS_FIRST_LEN) cindex++; if(cindex > VALID_NICK_CHARS_FIRST_LEN) return NULL; return userList[cindex]; @@ -177,7 +177,7 @@ struct UserNode* getUsersWithAuth(const char *auth, struct UserNode *last) { int getUserCount() { int i, count = 0; struct UserNode *user; - for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN+1; i++) { + for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) { for(user = userList[i]; user; user = user->next) { count++; } @@ -235,32 +235,80 @@ struct UserNode* addUserMask(const char *mask) { return user; } -struct UserNode* createTempUser(const char *mask) { +struct UserNode* createTempUser(const char *nick) { + int already_on_list = 0; + struct UserNode *user = NULL; + if(!is_valid_nick(nick)) { + return NULL; + } + for(user = userList[TEMPUSER_LIST_INDEX]; user; user = user->next) { + if(!stricmp(user->nick, nick)) { + already_on_list = 1; + break; + } + } + if(!user) { + user = malloc(sizeof(*user)); + if (!user) { + perror("malloc() failed"); + return NULL; + } + user->ident[0] = 0; + user->host[0] = 0; + user->realname[0] = 0; + user->flags = 0; + user->channel = NULL; + user->last_who = 0; + } else + user->flags &= ~USERFLAG_FREETMPUSER; + user->created = time(0); + if(user->created - user->last_who > REWHO_TIMEOUT) + user->flags &= ~USERFLAG_ISAUTHED; //remove authed flag (security reasons) + strcpy(user->nick, nick); + if(!already_on_list) { + user->next = userList[TEMPUSER_LIST_INDEX]; + userList[TEMPUSER_LIST_INDEX] = user; + } + return user; +} + +struct UserNode* createTempUserMask(const char *mask) { //note: it could also be a server we have to create a temponary user for... char cmask[strlen(mask)+1]; strcpy(cmask, mask); int i, ii = 0; + int already_on_list = 0; struct UserNode *user = NULL; for(i = 0; i < strlen(mask)+1; i++) { if(cmask[i] == '!') { cmask[i] = 0; - if(!is_valid_nick(cmask)) { - return NULL; - } - user = malloc(sizeof(*user)); - if (!user) - { - perror("malloc() failed"); + if(!is_valid_nick(cmask)) { return NULL; } - strcpy(user->nick, cmask); + for(user = userList[TEMPUSER_LIST_INDEX]; user; user = user->next) { + if(!stricmp(user->nick, cmask)) { + already_on_list = 1; + break; + } + } + if(!user) { + user = malloc(sizeof(*user)); + if (!user) { + perror("malloc() failed"); + return NULL; + } + user->ident[0] = 0; + user->host[0] = 0; + user->realname[0] = 0; + user->flags = 0; + user->channel = NULL; + user->last_who = 0; + } else + user->flags &= ~USERFLAG_FREETMPUSER; user->created = time(0); - user->ident[0] = 0; - user->host[0] = 0; - user->realname[0] = 0; - user->flags = 0; - user->channel = NULL; - user->last_who = 0; + if(user->created - user->last_who > REWHO_TIMEOUT) + user->flags &= ~USERFLAG_ISAUTHED; //remove authed flag (security reasons) + strcpy(user->nick, cmask); ii = i+1; } else if(cmask[i] == '.' && !user) { //it's a server @@ -301,11 +349,15 @@ struct UserNode* createTempUser(const char *mask) { user->flags = 0; user->channel = NULL; user->last_who = 0; - return user; + break; } strcpy(user->host, &cmask[ii]); } } + if(!already_on_list) { + user->next = userList[TEMPUSER_LIST_INDEX]; + userList[TEMPUSER_LIST_INDEX] = user; + } return user; } @@ -340,7 +392,7 @@ int renameUser(struct UserNode* user, const char *new_nick) { } void delUser(struct UserNode* user, int freeUser) { - int userListIndex = get_nicklist_entry(user->nick[0]); + int userListIndex = ((user->flags & USERFLAG_ISTMPUSER) ? TEMPUSER_LIST_INDEX : get_nicklist_entry(user->nick[0])); if(userListIndex == -1) return; event_freeuser(user); struct UserNode *cuser, *last_user = NULL; @@ -354,10 +406,10 @@ void delUser(struct UserNode* user, int freeUser) { } else last_user = cuser; } - if(freeUser && (user->flags & USERFLAG_IS_ON_WHO_QUEUE)) { - user->flags |= USERFLAG_FREE_AFTER_WHO; - freeUser = 0; - } + if(freeUser && (user->flags & USERFLAG_IS_ON_WHO_QUEUE)) { + user->flags |= USERFLAG_FREE_AFTER_WHO; + freeUser = 0; + } if(user->channel) { struct ChanUser *chanUser, *next; for(chanUser = user->channel; chanUser; chanUser = next) { @@ -373,17 +425,12 @@ void delUser(struct UserNode* user, int freeUser) { void clearTempUsers() { int userListIndex = TEMPUSER_LIST_INDEX; - struct UserNode *cuser, *last_user = NULL, *next; + struct UserNode *cuser, *next; time_t now = time(0); for(cuser = userList[userListIndex]; cuser; cuser = next) { next = cuser->next; if(cuser->flags & USERFLAG_FREETMPUSER || now - cuser->created >= 300) { - if(last_user) - last_user->next = cuser->next; - else - userList[userListIndex] = cuser->next; - break; - } else - last_user = cuser; + delUser(cuser, 1); + } } } diff --git a/src/UserNode.h b/src/UserNode.h index 699c539..bb794b7 100644 --- a/src/UserNode.h +++ b/src/UserNode.h @@ -70,7 +70,8 @@ struct UserNode* getUsersWithAuth(const char *auth, struct UserNode *last); int getUserCount(); struct UserNode* addUser(const char *nick); struct UserNode* addUserMask(const char *mask); -struct UserNode* createTempUser(const char *mask); +struct UserNode* createTempUser(const char *nick); +struct UserNode* createTempUserMask(const char *mask); int renameUser(struct UserNode* user, const char *new_nick); void delUser(struct UserNode* user, int freeUser); void clearTempUsers(); diff --git a/src/cmd_neonserv_unban.c b/src/cmd_neonserv_unban.c index 3df5150..f88033b 100644 --- a/src/cmd_neonserv_unban.c +++ b/src/cmd_neonserv_unban.c @@ -63,7 +63,7 @@ CMD_BIND(neonserv_cmd_unban) { if(is_valid_nick(mask)) { struct UserNode *cuser = getUserByNick(mask); if(!cuser) { - cuser = createTempUser(mask); + cuser = createTempUserMask(mask); if(!cuser) { break; //internal bot error } -- 2.20.1