src/ChanUser.c \
src/ModeNode.c \
src/BanNode.c \
+ src/IPNode.c \
src/WHOHandler.c \
src/modcmd.c \
src/mysqlConn.c \
--- /dev/null
+/* IPNode.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "IPNode.h"
+
+#define hex2dec(x) (isxdigit(x) ? (isdigit(x) ? x - '0' : (isupper(x) ? x - 'A' : x - 'a') + 10) : 0)
+
+static struct IPNode *parseIP(struct IPNode *ip, const char *org_ipstr);
+
+struct IPNode *createIPNode(const char *ipstr) {
+ struct IPNode *ip = malloc(sizeof(*ip));
+ if(!ip) return NULL;
+ ip->flags = 0;
+ if(!parseIP(ip, ipstr)) {
+ free(ip);
+ ip = NULL;
+ }
+ return ip;
+}
+
+static struct IPNode *parseIP(struct IPNode *ip, const char *org_ipstr) {
+ char ipstr[strlen(org_ipstr)+1];
+ strcpy(ipstr, org_ipstr);
+ if(strchr(ipstr, ':')) {
+ ip->flags |= IPNODE_IS_IPV6;
+ char *p1 = ipstr;
+ char *p2;
+ int blocks = 1;
+ while(*p1) {
+ if(p1[0] == ':' && p1[1] == ':') {
+ //double ::
+ p1++;
+ }
+ if(*p1 == ':')
+ blocks++;
+ if(*p1 == '/') {
+ *p1 = '\0';
+ break;
+ }
+ p1++;
+ }
+ if(blocks > 8) return 0;
+ char hexa[32];
+ int i;
+ for(i = 0; i < 32; i++)
+ hexa[i] = '0';
+ i = 0;
+ int p = 0;
+ int len;
+ while(*p1) {
+ if(p1[0] == ':' && p1[1] == ':') {
+ i = 8 - blocks;
+ p1 += 2;
+ p = 0;
+ p2 = p1;
+ len = 0;
+ while(*p2 && *p2 != ':') {
+ len++;
+ p2++;
+ }
+ continue;
+ }
+ else if(*p1 == ':') {
+ p1++;
+ i++;
+ p = 0;
+ len = 0;
+ while(*p2 && *p2 != ':') {
+ len++;
+ p2++;
+ }
+ continue;
+ }
+ if(p >= 4 || i >= 8) return NULL;
+ hexa[i*4 + ((4-len) + (p++))] = *p1;
+ p1++;
+ }
+ for(i = 0, p = 0; i < 32; i+=2, p++) {
+ ip->ipdata[p] = hex2dec(hexa[i]) << 4;
+ ip->ipdata[p] |= hex2dec(hexa[i+1]);
+ }
+ } else if(strchr(ipstr, '.')) {
+ char *ippart = ipstr;
+ char *next = strchr(ipstr, '/');
+ int i = 0;
+ if(next) {
+ *next = '\0';
+ next = NULL;
+ }
+ do {
+ next = strchr(ippart, '.');
+ if(next) *next = '\0';
+ if(i >= 4) return NULL;
+ ip->ipdata[12+(i++)] = (unsigned char) atoi(ippart);
+ if(next) {
+ ippart = next+1;
+ continue;
+ }
+ break;
+ } while(1);
+ if(i != 3) return NULL;
+ } else
+ return NULL;
+ return ip;
+}
+
+int ipmatch(struct IPNode *ip1, struct IPNode *ip2, int bits) {
+ if(!bits) return 0;
+ bits = (ip2->flags & IPNODE_IS_IPV6 ? bits : bits + (12*8));
+ if(bits > 128) return 1;
+ int sbit = (bits % 8);
+ int check = (bits / 8) + (sbit ? 1 : 0);
+ int i;
+ for(i = 0; i < check; i++) {
+ if(i == check-1 && sbit) {
+ int bitmask = 0;
+ int j = 0;
+ for(;j < sbit; j++) {
+ bitmask <<= 1;
+ bitmask |= 1;
+ }
+ for(;j < 8; j++) {
+ bitmask <<= 1;
+ bitmask |= 0;
+ }
+ if((ip1->ipdata[i] & bitmask) != (ip2->ipdata[i] & bitmask))
+ return 1;
+ } else if(ip1->ipdata[i] != ip2->ipdata[i])
+ return 1;
+ }
+ return 0;
+}
+
+void freeIPNode(struct IPNode *ip) {
+ free(ip);
+}
+
--- /dev/null
+/* IPNode.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _IPNode_h
+#define _IPNode_h
+#include "main.h"
+
+#define IPNODE_IS_IPV6 0x01
+#define IPNODE_IS_LOCAL 0x02
+
+struct IPNode {
+ unsigned char flags;
+ unsigned char ipdata[16]; // 16 * 8bit = 128bit
+};
+
+struct IPNode *createIPNode(const char *ipstr);
+int ipmatch(struct IPNode *ip1, struct IPNode *ip2, int bits);
+void freeIPNode(struct IPNode *ip);
+
+#endif
\ No newline at end of file
#include "ChanUser.h"
#include "tools.h"
#include "IRCEvents.h"
+#include "IPNode.h"
static struct UserNode **userList;
user->created = time(0);
user->ident[0] = 0;
user->host[0] = 0;
+ user->ip = NULL;
user->realname[0] = 0;
user->flags = 0;
user->channel = NULL;
}
user->ident[0] = 0;
user->host[0] = 0;
+ user->ip = NULL;
user->realname[0] = 0;
user->flags = 0;
user->channel = NULL;
}
user->ident[0] = 0;
user->host[0] = 0;
+ user->ip = NULL;
user->realname[0] = 0;
user->flags = 0;
user->channel = NULL;
user->created = time(0);
user->ident[0] = 0;
user->host[0] = 0;
+ user->ip = NULL;
user->realname[0] = 0;
user->flags = USERFLAG_ISSERVER;
user->channel = NULL;
user->created = time(0);
user->ident[0] = 0;
user->host[0] = 0;
+ user->ip = NULL;
user->realname[0] = 0;
user->flags = 0;
user->channel = NULL;
removeChanUserFromLists(chanUser, 1, 0, freeUser);
}
}
- if(freeUser)
+ if(freeUser) {
+ if(user->ip)
+ freeIPNode(user->ip);
free(user);
- else
+ } else
user->next = NULL;
}
struct ChanUser;
struct language;
+struct IPNode;
struct UserNode {
char nick[NICKLEN+1];
char host[HOSTLEN+1];
char realname[REALLEN+1];
char auth[AUTHLEN+1];
+ struct IPNode *ip;
unsigned int flags;
time_t created, last_who;
struct ChanUser *channel;
#include "ChanUser.h"
#include "ModeNode.h"
#include "ClientSocket.h"
+#include "IPNode.h"
#define WHOQUEUETYPE_ISONQUEUE 0x01
#define WHOQUEUETYPE_USERLIST 0x02
entry->data[0] = data;
for(i = 1; i < MAXCALLBACKS; i++)
entry->data[i] = NULL;
- putsock(bot, "WHO %s,%d %%tuhnaf,%d", chan->name, entry->type, entry->type);
+ putsock(bot, "WHO %s,%d %%tuihnaf,%d", chan->name, entry->type, entry->type);
} else
callback(bot, chan, data);
}
entry->data[0] = data;
for(i = 1; i < MAXCALLBACKS; i++)
entry->data[i] = NULL;
- putsock(bot, "WHO %s,%d d%%tuhnaf,%d", chan->name, entry->type, entry->type);
+ putsock(bot, "WHO %s,%d d%%tuihnaf,%d", chan->name, entry->type, entry->type);
} else
callback(bot, chan, data);
}
//parse flags
int userflags = 0;
int chanuserflags = 0;
- for(i = 0; i < strlen(argv[5]); i++) {
- switch (argv[5][i]) {
+ for(i = 0; i < strlen(argv[6]); i++) {
+ switch (argv[6][i]) {
case '@':
chanuserflags |= CHANUSERFLAG_OPPED;
break;
}
}
- struct UserNode *user = getUserByNick(argv[4]);
+ struct UserNode *user = getUserByNick(argv[5]);
struct ChanUser *chanuser;
if((chanuserflags & CHANUSERFLAG_INVISIBLE) && (!user || !isBot(user))) {
- user = createTempUser(argv[4]);
+ user = createTempUser(argv[5]);
user->flags |= USERFLAG_ISTMPUSER;
chan->flags |= CHANFLAG_HAVE_INVISIBLES;
chanuser = addInvisibleChanUser(chan, user);
chanuser->flags = (chanuser->flags & ~CHANUSERFLAG_OPPED_OR_VOICED) | chanuserflags;
} else {
if(user == NULL) {
- user = addUser(argv[4]);
+ user = addUser(argv[5]);
}
if(!(chanuser = getChanUser(user, chan))) {
chanuser = addChanUser(chan, user);
user->last_who = time(0);
if(!*user->ident)
strcpy(user->ident, argv[2]);
+ if(!user->ip)
+ user->ip = createIPNode(argv[3]);
if(!*user->host)
- strcpy(user->host, argv[3]);
- if(!(user->flags & USERFLAG_ISAUTHED) && strcmp(argv[6], "0")) {
- strcpy(user->auth, argv[6]);
+ strcpy(user->host, argv[4]);
+ if(!(user->flags & USERFLAG_ISAUTHED) && strcmp(argv[7], "0")) {
+ strcpy(user->auth, argv[7]);
user->flags |= USERFLAG_ISAUTHED;
}
} else if((type & WHOQUEUETYPE_USERAUTH) && !(entry->type & WHOQUEUETYPE_FOUND)) {
#include "ChanNode.h"
#include "lang.h"
#include "ClientSocket.h"
+#include "IPNode.h"
static const struct default_language_entry msgtab[] = {
{"TIME_MASK_2_ITEMS", "%s and %s"}, /* {ARGS: "2 days", "1 hour"} */
ident = input;
*p = '\0';
host = p+1;
- } else if((p = strstr(input, "."))) {
+ } else if((p = strstr(input, ".")) || (p = strstr(input, ":"))) {
host = input;
} else if(*input == '*' && input[1] != '\0' && !strstr(input+1, "*")) {
//AUTH MASK
return (strlen(p2+1) > 4);
}
+int mask_match(char *mask, struct UserNode *user) {
+ char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+ char matchmask[strlen(mask)+3];
+ strcpy(matchmask, mask);
+ char *host = strchr(mask, '@');
+ if(host) {
+ struct IPNode *ip = createIPNode(host);
+ int bits = (ip->flags & IPNODE_IS_IPV6 ? 128 : 32);
+ if((host = strchr(host, '/'))) {
+ bits = atoi(host+1);
+ }
+ if(ip && user->ip&& !ipmatch(user->ip, ip, bits)) {
+ host[1] = '*';
+ host[2] = '\0';
+ }
+ }
+ sprintf(usermask, "%s!%s@%s", user->nick, user->ident, user->host);
+ return match(matchmask, usermask);
+}
+
static unsigned long crc_table[256];
static void crc32_init() {
char* make_banmask(char *input, char* buffer);
int isFakeHost(char *host);
+int mask_match(char *mask, struct UserNode *user);
+
unsigned long crc32(const char *text);
void init_tools();