2 * trojanscan.c version 2
4 * Trojanscan copyright (C) Chris Porter 2002-2004
5 * Newserv bits copyright (C) David Mansell 2002-2003
8 * - Put bots in channels
9 - On kick stuff (different to normal handling)
10 - select the correct user to join >= TROJANSCAN_WATCHCLONE_MAX
12 * - Steal hosts from users
13 * - Poke splidge about +r'ing bots
16 #include "trojanscan.h"
19 trojanscan_cmds
= newcommandtree();
21 addcommandtotree(trojanscan_cmds
, "showcommands", TROJANSCAN_ACL_UNAUTHED
, 0, &trojanscan_showcommands
);
22 addcommandtotree(trojanscan_cmds
, "help", TROJANSCAN_ACL_UNAUTHED
, 1, &trojanscan_help
);
23 addcommandtotree(trojanscan_cmds
, "hello", TROJANSCAN_ACL_UNAUTHED
| TROJANSCAN_ACL_OPER
, 1, &trojanscan_hello
);
25 addcommandtotree(trojanscan_cmds
, "join", TROJANSCAN_ACL_STAFF
, 1, &trojanscan_userjoin
);
26 addcommandtotree(trojanscan_cmds
, "chanlist", TROJANSCAN_ACL_STAFF
, 0, &trojanscan_chanlist
);
27 addcommandtotree(trojanscan_cmds
, "whois", TROJANSCAN_ACL_STAFF
, 1, &trojanscan_whois
);
29 addcommandtotree(trojanscan_cmds
, "changelev", TROJANSCAN_ACL_STAFF
| TROJANSCAN_ACL_OPER
, 2, &trojanscan_changelev
);
30 addcommandtotree(trojanscan_cmds
, "deluser", TROJANSCAN_ACL_TEAMLEADER
| TROJANSCAN_ACL_OPER
, 2, &trojanscan_deluser
);
31 addcommandtotree(trojanscan_cmds
, "mew", TROJANSCAN_ACL_STAFF
| TROJANSCAN_ACL_OPER
, 2, &trojanscan_mew
);
32 addcommandtotree(trojanscan_cmds
, "status", TROJANSCAN_ACL_STAFF
| TROJANSCAN_ACL_OPER
, 0, &trojanscan_status
);
33 addcommandtotree(trojanscan_cmds
, "listusers", TROJANSCAN_ACL_TEAMLEADER
, 0, &trojanscan_listusers
);
35 addcommandtotree(trojanscan_cmds
, "rehash", TROJANSCAN_ACL_WEBSITE
, 0, &trojanscan_rehash
);
37 addcommandtotree(trojanscan_cmds
, "cat", TROJANSCAN_ACL_CAT
| TROJANSCAN_ACL_OPER
, 1, &trojanscan_cat
);
39 addcommandtotree(trojanscan_cmds
, "reschedule", TROJANSCAN_ACL_DEVELOPER
| TROJANSCAN_ACL_OPER
, 0, &trojanscan_reschedule
);
41 srand((int)time(NULL
));
43 trojanscan_connect_schedule
= scheduleoneshot(time(NULL
) + 1, &trojanscan_connect
, NULL
);
48 struct trojanscan_realchannels
*rp
= trojanscan_realchanlist
, *oldrp
;
49 struct trojanscan_rejoinlist
*rj
= trojanscan_schedulerejoins
, *oldrj
;
52 deregisterlocaluser(trojanscan_nick
, NULL
);
54 if (trojanscan_connect_schedule
)
55 deleteschedule(trojanscan_connect_schedule
, &trojanscan_connect
, NULL
);
57 if(trojanscan_schedule
)
58 deleteschedule(trojanscan_schedule
, &trojanscan_dojoin
, NULL
);
60 if(trojanscan_poolschedule
)
61 deleteschedule(trojanscan_poolschedule
, &trojanscan_repool
, NULL
);
63 if(trojanscan_cloneschedule
)
64 deleteschedule(trojanscan_poolschedule
, &trojanscan_registerclones
, NULL
);
67 deleteschedule(rp
->schedule
, &trojanscan_dopart
, (void *)rp
);
74 deleteschedule(rj
->schedule
, &trojanscan_rejoin_channel
, (void *)rj
);
75 freesstring(rj
->channel
);
81 if(trojanscan_initialschedule
)
82 deleteschedule(trojanscan_initialschedule
, &trojanscan_fill_channels
, NULL
);
84 deleteschedule(trojanscan_rehashschedule
, &trojanscan_rehash_schedule
, NULL
);
86 for (i
=0;i
<TROJANSCAN_CLONE_TOTAL
;i
++)
87 if(trojanscan_swarm
[i
].clone
) {
88 deregisterlocaluser(trojanscan_swarm
[i
].clone
, NULL
);
89 trojanscan_swarm
[i
].clone
= NULL
;
91 trojanscan_free_database();
92 trojanscan_free_channels();
94 for (i
=0;i
<trojanscan_hostpoolsize
;i
++)
95 freesstring(trojanscan_hostpool
[i
]);
97 for (i
=0;i
<trojanscan_tailpoolsize
;i
++)
98 freesstring(trojanscan_tailpool
[i
]);
99 trojanscan_database_close();
102 void trojanscan_connect(void *arg
) {
103 sstring
*mnick
, *myident
, *myhost
, *myrealname
, *myauthname
;
104 sstring
*dbhost
, *dbuser
, *dbpass
, *db
, *dbport
, *temp
;
109 trojanscan_connect_schedule
= NULL
;
111 for(i
=0;i
<TROJANSCAN_CLONE_TOTAL
;i
++)
112 trojanscan_swarm
[i
].index
= i
; /* sure this could be done with pointer arithmetic... */
114 trojanscan_hostpoolsize
= 0;
115 trojanscan_tailpoolsize
= 0;
116 trojanscan_hostmode
= 0;
117 trojanscan_poolschedule
= NULL
;
118 trojanscan_cloneschedule
= NULL
;
119 trojanscan_realchanlist
= NULL
;
120 trojanscan_database
.glines
= 0;
121 trojanscan_database
.detections
= 0;
123 mnick
= getcopyconfigitem("trojanscan", "nick", "T", NICKLEN
);
124 myident
= getcopyconfigitem("trojanscan", "ident", "trojanscan", NICKLEN
);
125 myhost
= getcopyconfigitem("trojanscan", "hostname", "trojanscan.slug.netsplit.net", HOSTLEN
);
126 myrealname
= getcopyconfigitem("trojanscan", "realname", "Trojanscan v" TROJANSCAN_VERSION
, REALLEN
);
127 myauthname
= getcopyconfigitem("trojanscan", "authname", "T", ACCOUNTLEN
);
129 dbhost
= getcopyconfigitem("trojanscan", "dbhost", "localhost", HOSTLEN
);
130 dbuser
= getcopyconfigitem("trojanscan", "dbuser", "", NICKLEN
);
131 dbpass
= getcopyconfigitem("trojanscan", "dbpass", "", REALLEN
);
132 db
= getcopyconfigitem("trojanscan", "db", "", NICKLEN
);
134 dbport
= getcopyconfigitem("trojanscan", "dbport", "3306", ACCOUNTLEN
);
136 length
= snprintf(buf
, sizeof(buf
) - 1, "%d", TROJANSCAN_DEFAULT_MAXCHANS
);
137 temp
= getcopyconfigitem("trojanscan", "maxchans", buf
, length
);
139 trojanscan_maxchans
= atoi(temp
->content
);
142 length
= snprintf(buf
, sizeof(buf
) - 1, "%d", TROJANSCAN_DEFAULT_CYCLETIME
);
143 temp
= getcopyconfigitem("trojanscan", "cycletime", buf
, length
);
145 trojanscan_cycletime
= atoi(temp
->content
);
148 length
= snprintf(buf
, sizeof(buf
) - 1, "%d", TROJANSCAN_DEFAULT_PARTTIME
);
149 temp
= getcopyconfigitem("trojanscan", "parttime", buf
, length
);
150 trojanscan_part_time
= atoi(temp
->content
);
153 length
= snprintf(buf
, sizeof(buf
) - 1, "%d", TROJANSCAN_DEFAULT_MAXUSERS
);
154 temp
= getcopyconfigitem("trojanscan", "maxusers", buf
, length
);
155 trojanscan_maxusers
= atoi(temp
->content
);
158 if ((trojanscan_cycletime
/ trojanscan_maxchans
) < 1) {
159 Error("trojanscan", ERR_FATAL
, "Cycletime / maxchans < 1!!");
160 return; /* PPA: splidge: do something here 8]! */
163 length
= snprintf(buf
, sizeof(buf
) - 1, "%d", TROJANSCAN_DEFAULT_MINIMUM_CHANNEL_SIZE
);
164 temp
= getcopyconfigitem("trojanscan", "minchansize", buf
, length
);
165 trojanscan_minchansize
= atoi(temp
->content
);
168 trojanscan_nick
= registerlocaluser(mnick
->content
, myident
->content
, myhost
->content
, myrealname
->content
, myauthname
->content
, UMODE_SERVICE
| UMODE_DEAF
|
169 UMODE_OPER
| UMODE_INV
|
171 &trojanscan_handlemessages
);
173 if (trojanscan_database_connect(dbhost
->content
, dbuser
->content
, dbpass
->content
, db
->content
, atoi(dbport
->content
)) < 0) {
174 Error("trojanscan", ERR_FATAL
, "Cannot connect to database host!");
175 return; /* PPA: splidge: do something here 8]! */
178 trojanscan_database_query("CREATE TABLE phrases (id INT(10) PRIMARY KEY AUTO_INCREMENT, wormid INT(10) NOT NULL, phrase TEXT NOT NULL, priority INT(10) DEFAULT 0 NOT NULL)");
179 trojanscan_database_query("CREATE TABLE worms (id INT(10) PRIMARY KEY AUTO_INCREMENT, wormname TEXT NOT NULL, glinetype INT DEFAULT 0, data text, hitmsgs BOOL DEFAULT 1, hitchans BOOL DEFAULT 0)");
180 trojanscan_database_query("CREATE TABLE logs (id INT(10) PRIMARY KEY AUTO_INCREMENT, userid INT(10) NOT NULL, act TEXT NOT NULL, description TEXT NOT NULL, ts TIMESTAMP)");
181 trojanscan_database_query("CREATE TABLE channels (id INT(10) PRIMARY KEY AUTO_INCREMENT, channel VARCHAR(%d) NOT NULL, exempt BOOL DEFAULT 0)", CHANNELLEN
);
182 trojanscan_database_query("CREATE TABLE users (id INT(10) PRIMARY KEY AUTO_INCREMENT, authname VARCHAR(%d) NOT NULL, authlevel TINYINT(4) NOT NULL)", ACCOUNTLEN
);
183 trojanscan_database_query("CREATE TABLE hits (id INT(10) PRIMARY KEY AUTO_INCREMENT, nickname VARCHAR(%d) NOT NULL, ident VARCHAR(%d) NOT NULL, host VARCHAR(%d) NOT NULL, phrase INT(10) NOT NULL, ts TIMESTAMP, messagetype VARCHAR(1) NOT NULL DEFAULT 'm', glined BOOL DEFAULT 1)", NICKLEN
, USERLEN
, HOSTLEN
);
184 trojanscan_database_query("CREATE TABLE settings (id INT(10) PRIMARY KEY AUTO_INCREMENT, setting VARCHAR(15) NOT NULL, value VARCHAR(15) NOT NULL)");
185 trojanscan_database_query("CREATE TABLE wwwlogs (id INT(10) PRIMARY KEY AUTO_INCREMENT, authid INT(10) NOT NULL, ip VARCHAR(15), action TEXT, ts TIMESTAMP)");
186 trojanscan_database_query("CREATE TABLE unknownlog (id INT(10) PRIMARY KEY AUTO_INCREMENT, data TEXT, user VARCHAR(%d) NOT NULL, ts TIMESTAMP)", NICKLEN
+USERLEN
+HOSTLEN
+3);
188 trojanscan_database_query("DELETE FROM settings WHERE setting = 'rehash'");
189 trojanscan_database_query("INSERT INTO settings (setting, value) VALUES ('rehash','0')");
190 trojanscan_database_query("INSERT INTO settings (setting, value) VALUES ('changed','0')");
192 trojanscan_read_database(1);
194 cp
= findchannel(TROJANSCAN_OPERCHANNEL
);
196 localcreatechannel(trojanscan_nick
, TROJANSCAN_OPERCHANNEL
);
198 localjoinchannel(trojanscan_nick
, cp
);
199 localgetops(trojanscan_nick
, cp
);
202 cp
= findchannel(TROJANSCAN_CHANNEL
);
204 localcreatechannel(trojanscan_nick
, TROJANSCAN_CHANNEL
);
206 localjoinchannel(trojanscan_nick
, cp
);
207 localgetops(trojanscan_nick
, cp
);
211 freesstring(myident
);
213 freesstring(myrealname
);
214 freesstring(myauthname
);
220 trojanscan_registerclones(NULL
);
222 trojanscan_initialschedule
= scheduleoneshot(time(NULL
) + 300, &trojanscan_fill_channels
, NULL
);
223 trojanscan_rehashschedule
= scheduleoneshot(time(NULL
) + 60, &trojanscan_rehash_schedule
, NULL
);
227 void trojanscan_rehash_schedule(void *arg
) {
228 trojanscan_rehashschedule
= scheduleoneshot(time(NULL
) + 60, &trojanscan_rehash_schedule
, NULL
);
229 if (!(trojanscan_database_query("SELECT value FROM settings WHERE setting = 'rehash'"))) {
230 trojanscan_database_res
*res
;
231 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
232 if (trojanscan_database_num_rows(res
) > 0) {
233 trojanscan_database_row sqlrow
= trojanscan_database_fetch_row(res
);
234 if (sqlrow
&& (sqlrow
[0][0] == '1')) {
235 trojanscan_mainchanmsg("n: rehash initiated by website. . .");
236 trojanscan_read_database(0);
239 trojanscan_database_free_result(res
);
245 void trojanscan_free_database(void) {
247 for(i
=0;i
<trojanscan_database
.total_channels
;i
++)
248 freesstring(trojanscan_database
.channels
[i
].name
);
249 free(trojanscan_database
.channels
);
250 for(i
=0;i
<trojanscan_database
.total_phrases
;i
++)
251 if (trojanscan_database
.phrases
[i
].phrase
) {
252 free(trojanscan_database
.phrases
[i
].phrase
);
253 free(trojanscan_database
.phrases
[i
].hint
);
255 free(trojanscan_database
.phrases
);
256 for(i
=0;i
<trojanscan_database
.total_worms
;i
++)
257 freesstring(trojanscan_database
.worms
[i
].name
);
258 free(trojanscan_database
.worms
);
259 trojanscan_database
.total_channels
= 0;
260 trojanscan_database
.total_phrases
= 0;
261 trojanscan_database
.total_worms
= 0;
265 sstring
*trojanscan_getsstring(char *string
, int length
) {
268 for(i
=0;i
<length
;i
++) {
269 if ((string
[i
] == '\r') || (string
[i
] == '\n')) {
270 Error("trojanscan", ERR_WARNING
, "Error reading %s at position %d, set to ERROR!", string
, i
+1);
271 return getsstring("ERROR", sizeof("ERROR"));
275 return getsstring(string
, length
);
278 int trojanscan_strip_codes(char *buf
, size_t max
, char *original
) {
279 int i
, j
, length
= TROJANSCAN_MMIN(strlen(original
), max
-1);
280 char *p2
= original
, *p3
, flag
= 0;
282 for(i
=0;i
<length
+1;i
++) {
291 if ((i
+ 1) > length
)
293 if ((j
== 4) && flag
)
297 if ((j
== 0) && (!((*p2
>= '0') && (*p2
<= '9'))))
302 if ((i
+ 1) > length
)
304 if (!((*(p2
+ 1) >= '0') && (*(p2
+ 1) <= '9')))
307 } else if ((*p2
>= '0') && (*p2
<= '9')) {
315 if (!((*p2
>= '0') && (*p2
<= '9')))
321 if ((i
+ 1) > length
)
323 if (!((*(p2
+ 1) >= '0') && (*(p2
+ 1) <= '9')))
328 if ((j
== 3) && (!((*p2
>= '0') && (*p2
<= '9'))))
330 if ((j
== 4) && (!((*p2
>= '0') && (*p2
<= '9'))))
347 struct trojanscan_worms
*trojanscan_find_worm_by_id(int id
) {
349 for(i
=0;i
<trojanscan_database
.total_worms
;i
++)
350 if ((trojanscan_database
.worms
[i
].id
== id
))
351 return &trojanscan_database
.worms
[i
];
355 void trojanscan_read_database(int first_time
) {
357 int erroroffset
, i
, tempresult
;
359 trojanscan_database_res
*res
;
360 trojanscan_database_row sqlrow
;
363 trojanscan_free_database();
365 trojanscan_database
.total_channels
= 0;
366 trojanscan_database
.total_phrases
= 0;
367 trojanscan_database
.total_worms
= 0;
370 if (!(trojanscan_database_query("SELECT channel, exempt FROM channels"))) {
371 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
372 trojanscan_database
.total_channels
= trojanscan_database_num_rows(res
);
373 if (trojanscan_database
.total_channels
> 0) {
374 if ((trojanscan_database
.channels
= (trojanscan_channels
*)malloc(sizeof(trojanscan_channels
) * trojanscan_database
.total_channels
))) {
375 if ((trojanscan_database
.total_channels
>0) && trojanscan_database
.channels
) {
377 while((sqlrow
= trojanscan_database_fetch_row(res
))) {
378 trojanscan_database
.channels
[i
].name
= trojanscan_getsstring(sqlrow
[0], strlen(sqlrow
[0]));
379 trojanscan_database
.channels
[i
].exempt
= (sqlrow
[1][0] == '1');
385 trojanscan_database_free_result(res
);
389 if (!(trojanscan_database_query("SELECT id, wormname, glinetype, length(data), hitmsgs, hitchans FROM worms"))) {
390 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
391 trojanscan_database
.total_worms
= trojanscan_database_num_rows(res
);
392 if (trojanscan_database
.total_worms
> 0) {
393 if ((trojanscan_database
.worms
= (trojanscan_worms
*)malloc(sizeof(trojanscan_worms
) * trojanscan_database
.total_worms
))) {
395 while((sqlrow
= trojanscan_database_fetch_row(res
))) {
396 trojanscan_database
.worms
[i
].id
= atoi(sqlrow
[0]);
397 trojanscan_database
.worms
[i
].name
= trojanscan_getsstring(sqlrow
[1], strlen(sqlrow
[1]));
398 tempresult
= atoi(sqlrow
[2]);
399 trojanscan_database
.worms
[i
].glineuser
= (tempresult
== 0);
400 trojanscan_database
.worms
[i
].glinehost
= (tempresult
== 1);
401 trojanscan_database
.worms
[i
].monitor
= (tempresult
== 2);
403 trojanscan_database
.worms
[i
].datalen
= ((atoi(sqlrow
[3]) == 0) ? 0 : 1);
405 trojanscan_database
.worms
[i
].datalen
= 0;
408 trojanscan_database
.worms
[i
].hitpriv
= (atoi(sqlrow
[4]) == 1);
409 trojanscan_database
.worms
[i
].hitchans
= (atoi(sqlrow
[5]) == 1);
415 trojanscan_database_free_result(res
);
419 if (!(trojanscan_database_query("SELECT id, phrase, wormid FROM phrases ORDER BY priority DESC"))) {
420 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
421 trojanscan_database
.total_phrases
= trojanscan_database_num_rows(res
);
422 if (trojanscan_database
.total_phrases
> 0) {
423 if ((trojanscan_database
.phrases
= (trojanscan_phrases
*)malloc(sizeof(trojanscan_phrases
) * trojanscan_database
.total_phrases
))) {
425 while((sqlrow
= trojanscan_database_fetch_row(res
))) {
426 trojanscan_database
.phrases
[i
].id
= atoi(sqlrow
[0]);
427 trojanscan_database
.phrases
[i
].worm
= trojanscan_find_worm_by_id(atoi(sqlrow
[2]));
428 if (!(trojanscan_database
.phrases
[i
].phrase
= pcre_compile(sqlrow
[1], PCRE_CASELESS
, &error
, &erroroffset
, NULL
))) {
429 Error("trojanscan", ERR_WARNING
, "Error compiling expression %s at offset %d: %s", sqlrow
[1], erroroffset
, error
);
431 if ((trojanscan_database
.phrases
[i
].hint
= pcre_study(trojanscan_database
.phrases
[i
].phrase
, 0, &error
))) {
432 Error("trojanscan", ERR_WARNING
, "Error studying expression %s: %s", sqlrow
[1], error
);
433 free(trojanscan_database
.phrases
[i
].phrase
);
434 trojanscan_database
.phrases
[i
].phrase
= NULL
;
441 trojanscan_database_free_result(res
);
445 trojanscan_database_query("UPDATE settings SET value = '0' where setting = 'rehash'");
449 void trojanscan_log(nick
*np
, char *event
, char *details
, ...) {
451 char eevent
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], edetails
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], buf
[513];
454 va_start(va
, details
);
455 vsnprintf(buf
, sizeof(buf
) - 1, details
, va
);
460 nickid
= trojanscan_user_id_by_authname(np
->authname
);
462 trojanscan_database_escape_string(eevent
, event
, strlen(event
));
463 trojanscan_database_escape_string(edetails
, buf
, strlen(buf
));
464 trojanscan_database_query("INSERT INTO logs (userid, act, description) VALUES ('%d', '%s', '%s')", nickid
, eevent
, edetails
);
467 void trojanscan_generateclone(void *arg
) {
468 int i
= (int)arg
, loops
= 0, modes
= UMODE_XOPER
;
469 char c_nick
[NICKLEN
+1], c_ident
[USERLEN
+1], c_host
[HOSTLEN
+1], c_real
[REALLEN
+1];
471 /* PPA: unlikely to be infinite */
473 if ((loops
++ < 10) && trojanscan_hostmode
) {
474 trojanscan_generatenick(c_nick
, NICKLEN
);
476 trojanscan_gennick(c_nick
, trojanscan_minmaxrand(7, TROJANSCAN_MMIN(13, NICKLEN
)));
478 } while (c_nick
&& (getnickbynick(c_nick
) != NULL
));
480 trojanscan_generateident(c_ident
, USERLEN
);
482 trojanscan_genident(c_ident
, trojanscan_minmaxrand(4, TROJANSCAN_MMIN(8, USERLEN
)));
484 if(trojanscan_hostmode
) {
485 trojanscan_generatehost(c_host
, HOSTLEN
);
487 trojanscan_genhost(c_host
, HOSTLEN
);
489 trojanscan_genhost(c_host
, HOSTLEN
);
492 trojanscan_generaterealname(c_real
, REALLEN
);
494 trojanscan_genreal(c_real
, trojanscan_minmaxrand(15, TROJANSCAN_MMIN(50, REALLEN
)));
496 if(trojanscan_minmaxrand(0, TROJANSCAN_INVISIBLE_ODDS
- 1))
499 trojanscan_swarm
[i
].clone
= registerlocaluser(c_nick
, c_ident
, c_host
, c_real
, NULL
, modes
, &trojanscan_clonehandlemessages
);
500 trojanscan_swarm
[i
].remaining
= trojanscan_minmaxrand(5, 100);
502 trojanscan_swarm
[i
].sitting
= 0;
506 void trojanscan_free_channels(void) {
508 if(trojanscan_chans
) {
509 for(i
=0;i
<trojanscan_activechans
;i
++)
510 freesstring(trojanscan_chans
[i
]);
511 free(trojanscan_chans
);
512 trojanscan_chans
= NULL
;
513 trojanscan_activechans
= 0;
517 void trojanscan_repool(void *arg
) {
518 if (trojanscan_generatepool() < TROJANSCAN_MINPOOLSIZE
) {
519 trojanscan_hostmode
= 0;
522 trojanscan_hostmode
= 1;
523 trojanscan_poolschedule
= scheduleoneshot(time(NULL
) + TROJANSCAN_POOL_REGENERATION
, &trojanscan_repool
, NULL
);
527 void trojanscan_registerclones(void *arg
) {
530 if (trojanscan_generatepool() < TROJANSCAN_MINPOOLSIZE
) {
531 trojanscan_hostmode
= 0;
532 trojanscan_cloneschedule
= scheduleoneshot(time(NULL
) + 10, &trojanscan_registerclones
, NULL
);
535 trojanscan_hostmode
= 1;
536 trojanscan_poolschedule
= scheduleoneshot(time(NULL
) + TROJANSCAN_POOL_REGENERATION
, &trojanscan_repool
, NULL
);
537 trojanscan_cloneschedule
= NULL
;
540 for (i
=0;i
<TROJANSCAN_CLONE_TOTAL
;i
++)
541 trojanscan_generateclone((void *)i
);
542 trojanscan_mainchanmsg("n: swarm (%d clones) created.", TROJANSCAN_CLONE_TOTAL
);
543 trojanscan_swarm_created
= 1;
546 int trojanscan_status(void *sender
, int cargc
, char **cargv
) {
547 nick
*np
= (nick
*)sender
;
548 trojanscan_log(np
, "status", "");
549 trojanscan_reply(np
, "Channels in schedule: %d", trojanscan_activechans
);
550 trojanscan_reply(np
, "Channels in database: %d", trojanscan_database
.total_channels
);
551 trojanscan_reply(np
, "Phrases: %d", trojanscan_database
.total_phrases
);
552 trojanscan_reply(np
, "Worms: %d", trojanscan_database
.total_worms
);
553 trojanscan_reply(np
, "Detections: %d", trojanscan_database
.detections
);
554 trojanscan_reply(np
, "Glines: %d", trojanscan_database
.glines
);
555 trojanscan_reply(np
, "Host/tail pool size: %d", TROJANSCAN_POOLSIZE
);
556 trojanscan_reply(np
, "Cycletime: %d", trojanscan_cycletime
);
557 trojanscan_reply(np
, "Clones: %d", TROJANSCAN_CLONE_TOTAL
);
561 int trojanscan_chanlist(void *sender
, int cargc
, char **cargv
) {
563 nick
*np
= (nick
*)sender
;
564 trojanscan_reply(np
, "Channel list (%d total):", trojanscan_activechans
);
565 for(i
=0;i
<trojanscan_activechans
;i
++)
566 trojanscan_reply(np
, "%s", trojanscan_chans
[i
]->content
);
567 trojanscan_reply(np
, "Done.");
571 int trojanscan_whois(void *sender
, int cargc
, char **cargv
) {
573 nick
*np
= (nick
*)sender
, *np2
;
577 trojanscan_reply(np
, "Not enough parameters.");
581 if (cargv
[0][0] == '#') {
582 tochange
= cargv
[0] + 1;
585 np2
= getnickbynick(cargv
[0]);
587 trojanscan_reply(np
, "That nickname is not on the network.");
590 for(i
=0;i
<TROJANSCAN_CLONE_TOTAL
;i
++) {
591 if(trojanscan_swarm
[i
].clone
->nick
&& !ircd_strcmp(trojanscan_swarm
[i
].clone
->nick
, np2
->nick
)) { /* PPA: ircd_strncmp ? - order of args? */
592 trojanscan_reply(np
, "Nickname : %s", np2
->nick
);
593 trojanscan_reply(np
, "Swarm nick : yes", trojanscan_swarm
[i
].clone
->nick
);
597 if (!IsAccount(np2
)) {
598 trojanscan_reply(np
, "User is not authed.");
601 tochange
= np2
->authname
;
604 templevel
= trojanscan_user_level_by_authname(tochange
);
605 if (templevel
== -1) {
606 trojanscan_reply(np
, "User does not exist.");
608 union trojanscan_userlevel flags
;
609 flags
.number
= templevel
;
610 trojanscan_reply(np
, "Authname : %s", tochange
);
611 trojanscan_reply(np
, "Flags : +" TROJANSCAN_FLAG_MASK
, TrojanscanFlagsInfo(flags
));
617 void trojanscan_privmsg_chan_or_nick(channel
*cp
, nick
*np
, char *message
, ...) {
621 if (!trojanscan_nick
)
624 va_start(va
, message
);
625 vsnprintf(buf
, sizeof(buf
) - 1, message
, va
);
629 sendmessagetochannel(trojanscan_nick
, cp
, buf
);
631 sendmessagetouser(trojanscan_nick
, np
, buf
);
636 int trojanscan_mew(void *sender
, int cargc
, char **cargv
) {
637 nick
*np
= (nick
*)sender
, *np2
= NULL
;
641 trojanscan_reply(np
, "Not enough paramaters.");
645 if(cargv
[0][0] == '#') {
646 if (!(cp
= findchannel(cargv
[0]))) {
647 trojanscan_reply(np
, "Channel not found.");
650 trojanscan_log(np
, "mew", "%s %s", cp
->index
->name
->content
, cargv
[1]);
652 if (!(np2
= getnickbynick(cargv
[0]))) {
653 trojanscan_reply(np
, "Nickname is not present on the network.");
656 trojanscan_log(np
, "mew", "%s %s", np2
->nick
, cargv
[1]);
659 trojanscan_privmsg_chan_or_nick(cp
, np2
, "\001ACTION mews hopefully at %s\001", cargv
[1]);
662 trojanscan_reply(np
, "Mewed at %s in %s.", cargv
[1], cp
->index
->name
->content
);
664 trojanscan_reply(np
, "Mewed at %s at %s.", cargv
[1], np2
->nick
);
669 int trojanscan_cat(void *sender
, int cargc
, char **cargv
) {
670 nick
*np
= (nick
*)sender
, *np2
= NULL
;
676 trojanscan_reply(np
, "Not enough paramaters.");
680 if(cargv
[0][0] == '#') {
681 if (!(cp
= findchannel(cargv
[0]))) {
682 trojanscan_reply(np
, "Channel not found.");
685 trojanscan_log(np
, "cat", cp
->index
->name
->content
);
687 if (!(np2
= getnickbynick(cargv
[0]))) {
688 trojanscan_reply(np
, "Nickname is not present on the network.");
691 trojanscan_log(np
, "cat", np2
->nick
);
694 if ((!(cat
= fopen(TROJANSCAN_CAT
, "r")))) {
695 trojanscan_reply(np
, "Unable to open cat!");
699 /* PPA: some opers/admins may not like this.... stuff them 8] */
700 while (fgets(buf
, sizeof(buf
) - 1, cat
)) {
701 if ((p
= strchr(buf
, '\n'))) {
703 trojanscan_privmsg_chan_or_nick(cp
, np2
, "%s", buf
);
704 } else if (feof(cat
)) {
705 trojanscan_privmsg_chan_or_nick(cp
, np2
, "%s", buf
);
712 trojanscan_reply(np
, "Spammed cat in %s.", cp
->index
->name
->content
);
714 trojanscan_reply(np
, "Spammed cat at %s.", np2
->nick
);
720 int trojanscan_reschedule(void *sender
, int cargc
, char **cargv
) {
721 nick
*np
= (nick
*)sender
;
722 trojanscan_log(np
, "reschedule", "");
723 trojanscan_fill_channels(NULL
);
725 trojanscan_reply(np
, "Rescheduled.");
729 int trojanscan_listusers(void *sender
, int cargc
, char **cargv
) {
730 nick
*np
= (nick
*)sender
;
732 trojanscan_log(np
, "listusers", "");
734 trojanscan_reply(np
, "User list:");
736 if (!(trojanscan_database_query("SELECT authname, authlevel FROM users ORDER BY authlevel DESC, authname"))) {
737 trojanscan_database_res
*res
;
738 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
739 if (trojanscan_database_num_rows(res
)) {
740 trojanscan_database_row sqlrow
;
741 union trojanscan_userlevel flags
;
742 while((sqlrow
= trojanscan_database_fetch_row(res
))) {
743 flags
.number
= atoi(sqlrow
[1]);
744 trojanscan_reply(np
, "%s +" TROJANSCAN_FLAG_MASK
, sqlrow
[0], TrojanscanIsDeveloper(flags
) ? "d" : "", TrojanscanIsTeamLeader(flags
) ? "t" : "", TrojanscanIsStaff(flags
) ? "s" : "", TrojanscanIsWebsite(flags
) ? "w" : "", TrojanscanIsCat(flags
) ? "c" : "");
747 trojanscan_database_free_result(res
);
751 trojanscan_reply(np
, "Done.");
755 int trojanscan_help(void *sender
, int cargc
, char **cargv
) {
756 nick
*np
= (nick
*)sender
;
759 trojanscan_reply(np
, "Not enough parameters.");
763 if (!strcasecmp("help", cargv
[0])) {
764 trojanscan_reply(np
, "Syntax: help <command name>");
765 trojanscan_reply(np
, "Gives help on commands.");
766 } else if (!strcasecmp("status", cargv
[0])) {
767 trojanscan_reply(np
, "Syntax: status");
768 trojanscan_reply(np
, "Gives statistical information about the bot.");
769 } else if (!strcasecmp("join", cargv
[0])) {
770 trojanscan_reply(np
, "Syntax: join <#channel>");
771 trojanscan_reply(np
, "Orders a clone to join supplied channel.");
772 } else if (!strcasecmp("showcommands", cargv
[0])) {
773 trojanscan_reply(np
, "Syntax: showcommands");
774 trojanscan_reply(np
, "Pretty obvious.");
775 } else if (!strcasecmp("hello", cargv
[0])) {
776 trojanscan_reply(np
, "Syntax: hello ?nickname?");
777 trojanscan_reply(np
, "Creates a new user.");
778 } else if (!strcasecmp("rehash", cargv
[0])) {
779 trojanscan_reply(np
, "Syntax: rehash");
780 trojanscan_reply(np
, "Reloads bot database.");
781 } else if (!strcasecmp("changelev", cargv
[0])) {
782 trojanscan_reply(np
, "Syntax: changelev <nickname or #authname> <flags>");
783 trojanscan_reply(np
, "Changes access flags of selected user to supplied input.");
784 trojanscan_reply(np
, "+d -> developer");
785 trojanscan_reply(np
, "+t -> team leader");
786 trojanscan_reply(np
, "+s -> staff");
787 trojanscan_reply(np
, "+w -> web management");
788 trojanscan_reply(np
, "+c -> cat access");
789 } else if (!strcasecmp("deluser", cargv
[0])) {
790 trojanscan_reply(np
, "Syntax: deluser <nickname or #authname>");
791 trojanscan_reply(np
, "Deletes selected user from my database.");
792 } else if (!strcasecmp("mew", cargv
[0])) {
793 trojanscan_reply(np
, "Syntax: mew <#channel or nickname> <nickname>");
794 trojanscan_reply(np
, "Gracefully mews at target in selected channel or query.");
795 } else if (!strcasecmp("cat", cargv
[0])) {
796 trojanscan_reply(np
, "Syntax: cat <#channel or nickname>");
797 trojanscan_reply(np
, "Shows the almightly cat.");
798 } else if (!strcasecmp("reschedule", cargv
[0])) {
799 trojanscan_reply(np
, "Syntax: reschedule");
800 trojanscan_reply(np
, "Recalculates bots schedule.");
801 } else if (!strcasecmp("chanlist", cargv
[0])) {
802 trojanscan_reply(np
, "Syntax: chanlist");
803 trojanscan_reply(np
, "Displays bots current channel list.");
804 } else if (!strcasecmp("whois", cargv
[0])) {
805 trojanscan_reply(np
, "Syntax: whois <nickname or #authname>");
806 trojanscan_reply(np
, "Displays information on given user.");
807 } else if (!strcasecmp("whois", cargv
[0])) {
808 trojanscan_reply(np
, "Syntax: listusers <flags>");
809 trojanscan_reply(np
, "Displays users with listusersing flags.");
811 trojanscan_reply(np
, "Command not found.");
818 int trojanscan_hello(void *sender
, int cargc
, char **cargv
) {
819 nick
*np
= (nick
*)sender
, *toadd
;
820 char eaccount
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
];
824 toadd
= getnickbynick(cargv
[0]);
826 trojanscan_reply(np
, "That nickname is not on the network.");
829 if (!IsAccount(toadd
)) {
830 trojanscan_reply(np
, "That user is not authed with the network.");
834 if (!IsAccount(np
)) {
835 trojanscan_reply(np
, "You are not authed with the network, auth before creating your user.");
841 if (trojanscan_user_level_by_authname(toadd
->authname
)!=-1) {
842 trojanscan_reply(np
, "Authname (%s) is already on file.", toadd
->authname
);
846 trojanscan_log(np
, "hello", toadd
->authname
);
848 if (!(trojanscan_database_query("SELECT id FROM users LIMIT 1"))) {
849 trojanscan_database_res
*res
;
850 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
851 if (trojanscan_database_num_rows(res
) == 0)
852 level
= TROJANSCAN_ACL_DEVELOPER
| TROJANSCAN_ACL_STAFF
| TROJANSCAN_ACL_WEBSITE
| TROJANSCAN_ACL_CAT
;
853 trojanscan_database_free_result(res
);
857 trojanscan_database_escape_string(eaccount
, toadd
->authname
, strlen(toadd
->authname
));
858 trojanscan_database_query("INSERT INTO users (authname, authlevel) VALUES ('%s', %d)", eaccount
, level
);
859 trojanscan_reply(np
, "Account added to database, account %s%s.", toadd
->authname
, level
>0?" (first user so developer access)":"");
864 int trojanscan_user_level_by_authname(char *authname
) {
865 int result
= -1, sl
= strlen(authname
);
866 char eaccount
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
];
868 trojanscan_database_escape_string(eaccount
, authname
, sl
);
869 if (!(trojanscan_database_query("SELECT authlevel, authname FROM users WHERE authname = '%s'", eaccount
))) {
870 trojanscan_database_res
*res
;
871 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
872 if (trojanscan_database_num_rows(res
) > 0) {
873 trojanscan_database_row sqlrow
= trojanscan_database_fetch_row(res
);
874 result
= atoi(sqlrow
[0]);
875 strncpy(authname
, sqlrow
[1], sl
);
877 trojanscan_database_free_result(res
);
883 int trojanscan_user_id_by_authname(char *authname
) {
885 char eaccount
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
];
887 trojanscan_database_escape_string(eaccount
, authname
, strlen(authname
));
888 if (!(trojanscan_database_query("SELECT id FROM users WHERE authname = '%s'", eaccount
))) {
889 trojanscan_database_res
*res
;
890 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
891 if (trojanscan_database_num_rows(res
) > 0) {
892 trojanscan_database_row sqlrow
= trojanscan_database_fetch_row(res
);
893 result
= atoi(sqlrow
[0]);
895 trojanscan_database_free_result(res
);
901 struct trojanscan_clones
*trojanscan_selectclone(char type
) {
902 struct trojanscan_clones
*rc
;
903 int randomclone
, hits
= 0, minlimit
, maxlimit
;
905 if(type
== TROJANSCAN_WATCH_CLONES
) {
906 minlimit
= TROJANSCAN_CLONE_MAX
;
907 maxlimit
= minlimit
+ TROJANSCAN_WATCH_CLONES
- 1;
910 maxlimit
= TROJANSCAN_CLONE_MAX
- 1;
914 randomclone
= trojanscan_minmaxrand(minlimit
, maxlimit
);
917 rc
= &trojanscan_swarm
[randomclone
];
918 if ((type
== TROJANSCAN_NORMAL_CLONES
) && (rc
->sitting
== 0) && (rc
->remaining
== 0))
921 } while (rc
->remaining
== 0);
923 if(type
== TROJANSCAN_NORMAL_CLONES
) {
924 if ((rc
->sitting
== 0) && (rc
->remaining
== 0)) {
925 if ((!rc
->remaining
) && (!rc
->sitting
)) {
927 deregisterlocaluser(rc
->clone
, NULL
);
930 trojanscan_generateclone((void *)rc
->index
);
941 struct trojanscan_realchannels
*trojanscan_allocaterc(char *chan
) {
942 struct trojanscan_realchannels
*rc
;
943 struct trojanscan_clones
*clonep
;
948 trojanscan_errorcode
= 1; /* sorry splidge ;( */
953 trojanscan_errorcode
= 2;
957 if (strlen(chan
) > 1) {
958 if(strrchr(chan
, ',')) {
959 trojanscan_errorcode
= 3;
963 if(strrchr(chan
, ' ')) {
964 trojanscan_errorcode
= 4;
969 cp
= findchannel(chan
);
971 trojanscan_errorcode
= 5;
974 if (!(clonep
= trojanscan_selectclone(TROJANSCAN_NORMAL_CLONES
))) {
975 trojanscan_errorcode
= 6;
978 rc
= (struct trojanscan_realchannels
*)malloc(sizeof(struct trojanscan_realchannels
));
988 void trojanscan_join(struct trojanscan_realchannels
*rc
) {
989 struct trojanscan_realchannels
*rp
= trojanscan_realchanlist
;
991 if (rc
->clone
&& rc
->clone
->clone
) {
992 if (!localjoinchannel(rc
->clone
->clone
, rc
->chan
)) {
993 if (trojanscan_minmaxrand(1, TROJANSCAN_NICKCHANGE_ODDS
)%TROJANSCAN_NICKCHANGE_ODDS
== 0)
994 trojanscan_donickchange((void *)rc
->clone
);
996 rc
->schedule
= scheduleoneshot(time(NULL
)+trojanscan_part_time
, &trojanscan_dopart
, (void *)rc
);
999 for(;rp
->next
;rp
=rp
->next
);
1002 trojanscan_realchanlist
= rc
;
1009 int trojanscan_userjoin(void *sender
, int cargc
, char **cargv
) {
1010 nick
*np
= (nick
*)sender
;
1011 struct trojanscan_realchannels
*rc
;
1014 trojanscan_reply(np
, "Not enough paramaters");
1018 if (!trojanscan_swarm_created
) {
1019 trojanscan_reply(np
, "My swarm is currently empty.");
1023 if((rc
= trojanscan_allocaterc(cargv
[0]))) {
1024 trojanscan_log(np
, "join", cargv
[0]);
1025 trojanscan_join(rc
);
1026 trojanscan_reply(np
, "Clone has joined channel.");
1028 trojanscan_mainchanmsg("n: join: %s (%s/%s)", cargv
[0], np
->nick
, np
->authname
);
1030 if (trojanscan_errorcode
== 5) {
1031 trojanscan_reply(np
, "Not joining empty channel, check you entered the correct channel name.");
1033 trojanscan_reply(np
, "Clone could not join channel (error code %d)!", trojanscan_errorcode
);
1039 int trojanscan_rehash(void *sender
, int cargc
, char **cargv
) {
1040 nick
*np
= (void *)sender
;
1041 trojanscan_read_database(0);
1042 trojanscan_log(np
, "rehash", "");
1043 trojanscan_reply(np
, "Done.");
1047 int trojanscan_changelev(void *sender
, int cargc
, char **cargv
) {
1048 nick
*np
= (nick
*)sender
, *np2
;
1050 char eaccount
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], *tochange
, *p
, mode
= 1, error
= 0, clast
= 0, specialcase
;
1051 union trojanscan_userlevel flags1
, flags2
;
1054 trojanscan_reply(np
, "Not enough parameters.");
1058 templevel
= trojanscan_user_level_by_authname(np
->authname
);
1060 if (templevel
== -1) {
1061 trojanscan_reply(np
, "You do not have an account.");
1065 flags1
.number
= templevel
;
1067 if (cargv
[0][0] == '#') {
1068 tochange
= cargv
[0] + 1;
1070 np2
= getnickbynick(cargv
[0]);
1072 trojanscan_reply(np
, "That nickname is not on the network.");
1075 if (!IsAccount(np2
)) {
1076 trojanscan_reply(np
, "That user is not authed with the network.");
1079 tochange
= np2
->authname
;
1082 templevel
= trojanscan_user_level_by_authname(tochange
);
1084 if (templevel
== -1) {
1085 trojanscan_reply(np
, "User does not exist.");
1089 flags2
.number
= templevel
;
1091 if (!ircd_strcmp(np
->authname
, tochange
)) {
1097 for (p
=cargv
[1];*p
;p
++) {
1104 if (!TrojanscanIsDeveloper(flags1
))
1106 flags2
.values
.developer
= mode
;
1109 if (!TrojanscanIsDeveloper(flags1
))
1111 flags2
.values
.teamleader
= mode
;
1114 if (!TrojanscanIsLeastTeamLeader(flags1
))
1116 flags2
.values
.staff
= mode
;
1119 if (!TrojanscanIsDeveloper(flags1
))
1121 flags2
.values
.website
= mode
;
1124 if (!TrojanscanIsDeveloper(flags1
))
1126 flags2
.values
.cat
= mode
;
1134 if (specialcase
&& !mode
) { /* allow user to remove their own flags */
1145 trojanscan_reply(np
, "Unknown mode: %c%c.", mode
?'+':'-', *p
);
1147 trojanscan_reply(np
, "You have insufficient privilidges to add/remove one or more flags specified.");
1152 trojanscan_log(np
, "changelev", "%s %s", tochange
, cargv
[1]);
1153 trojanscan_database_escape_string(eaccount
, tochange
, strlen(tochange
));
1154 trojanscan_database_query("UPDATE users SET authlevel = %d WHERE authname = '%s'", flags2
.number
, eaccount
);
1156 trojanscan_reply(np
, "Flags changed.");
1161 int trojanscan_deluser(void *sender
, int cargc
, char **cargv
) {
1162 nick
*np
= (nick
*)sender
, *to
;
1164 char eaccount
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], *account
;
1165 union trojanscan_userlevel flags1
, flags2
;
1168 trojanscan_reply(np
, "Not enough parameters.");
1172 if (cargv
[0][0] == '#') {
1173 account
= cargv
[0] + 1;
1175 to
= getnickbynick(cargv
[0]);
1177 trojanscan_reply(np
, "That nickname is not on the network.");
1180 if (!IsAccount(to
)) {
1181 trojanscan_reply(np
, "That user is not authed with the network.");
1184 account
= to
->authname
;
1187 flags1
.number
= trojanscan_user_level_by_authname(np
->authname
);
1188 templevel
= trojanscan_user_level_by_authname(account
);
1190 if (templevel
== -1) {
1191 trojanscan_reply(np
, "Auth %s does not exist.", account
);
1195 flags2
.number
= templevel
;
1197 if (!TrojanscanIsDeveloper(flags1
) && TrojanscanIsLeastTeamLeader(flags2
)) {
1198 trojanscan_reply(np
, "Your cannot delete %s as his/her flags equal or surpass your own.", account
);
1202 trojanscan_log(np
, "deluser", account
);
1203 trojanscan_database_escape_string(eaccount
, account
, strlen(account
));
1204 trojanscan_database_query("DELETE FROM users WHERE authname = '%s'", eaccount
);
1205 trojanscan_reply(np
, "User deleted.");
1210 int trojanscan_add_ll(struct trojanscan_prechannels
**head
, struct trojanscan_prechannels
*newitem
) {
1211 struct trojanscan_prechannels
*position
, *lastitem
= NULL
, *location
= NULL
;
1214 newitem
->next
= NULL
;
1215 if (newitem
->exempt
) {
1221 /* if its exempt, we don't give a monkeys where it is... */
1222 if (newitem
->exempt
) {
1223 newitem
->next
= *head
;
1228 for(position
=*head
;position
;lastitem
=position
,position
=position
->next
) {
1229 if (!ircd_strcmp(position
->name
->content
, newitem
->name
->content
)) {
1233 if (!location
&& (position
->size
< newitem
->size
)) {
1237 location
= lastitem
;
1242 newitem
->next
= NULL
;
1243 lastitem
->next
= newitem
;
1245 newitem
->next
= location
->next
;
1246 location
->next
= newitem
;
1248 if(newitem
->exempt
) {
1255 void trojanscan_watch_clone_update(struct trojanscan_prechannels
*hp
, int count
) {
1256 int i
, j
, *markedlist
, marked
;
1257 struct trojanscan_prechannels
*lp
;
1260 markedlist
= (int *)calloc(count
, sizeof(int));
1265 for(i
=0;i
<trojanscan_activechans
;i
++) {
1267 for(lp
=hp
,j
=0;j
<count
&&lp
;j
++,lp
=lp
->next
) {
1268 if(!markedlist
[j
] && !lp
->exempt
&& !ircd_strcmp(lp
->name
->content
, trojanscan_chans
[i
]->content
)) { /* we're already on the channel */
1275 trojanscan_mainchanmsg("perm clone parting %s", trojanscan_chans
[i
]->content
);
1276 //this channel no longer exists in the list, part
1280 for(j
=0,lp
=hp
;j
<count
&&lp
;j
++,lp
=lp
->next
) {
1281 if(!markedlist
[j
] && !lp
->exempt
) {
1282 trojanscan_mainchanmsg("perm clone joining %s", lp
->name
->content
);
1284 //join channels here, as they're new to the list
1290 void trojanscan_fill_channels(void *arg
) {
1291 struct trojanscan_prechannels
*head
= NULL
, *lp
, *last
= NULL
;
1292 int i
, count
, tempctime
= 0;
1296 for (count
=i
=0;i
<trojanscan_database
.total_channels
;i
++) {
1297 lp
= (trojanscan_prechannels
*)malloc(sizeof(trojanscan_prechannels
));
1298 lp
->name
= trojanscan_database
.channels
[i
].name
;
1300 lp
->exempt
= trojanscan_database
.channels
[i
].exempt
;
1301 if (trojanscan_add_ll(&head
, lp
))
1305 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
1306 for(chn
=chantable
[i
];chn
;chn
=chn
->next
) {
1307 /* TODO, add IsInvite */
1308 if (chn
->channel
&& !IsKey(chn
->channel
) && (chn
->channel
->users
->totalusers
>= trojanscan_minchansize
)) {
1309 lp
= (trojanscan_prechannels
*)malloc(sizeof(trojanscan_prechannels
));
1310 lp
->name
= chn
->name
;
1311 lp
->size
= chn
->channel
->users
->totalusers
;
1313 if (trojanscan_add_ll(&head
, lp
))
1319 count
= TROJANSCAN_MMIN(count
, trojanscan_maxchans
);
1323 trojanscan_watch_clone_update(head, count);
1326 trojanscan_free_channels();
1327 trojanscan_chans
= (sstring
**)malloc(sizeof(sstring
*) * count
);
1328 trojanscan_activechans
= count
;
1332 for(lp
=head
;lp
;last
=lp
,lp
=lp
->next
) {
1333 if (!(lp
->exempt
) && (i
< count
))
1334 trojanscan_chans
[i
++] = getsstring(lp
->name
->content
, lp
->name
->length
);
1342 if (trojanscan_activechans
> 0) {
1343 tempctime
= trojanscan_cycletime
/ trojanscan_activechans
;
1346 trojanscan_mainchanmsg("d: just escaped a divide by zero error (no activechans!), rescheduling in 60 seconds");
1349 if(trojanscan_schedule
)
1350 deleteschedule(trojanscan_schedule
, &trojanscan_dojoin
, NULL
);
1352 trojanscan_channumber
= 0;
1354 trojanscan_schedule
= schedulerecurring(time(NULL
) + tempctime
, trojanscan_activechans
+ 1, tempctime
, trojanscan_dojoin
, NULL
);
1358 void trojanscan_dojoin(void *arg
) {
1359 struct trojanscan_realchannels
*rc
;
1360 if (trojanscan_channumber
>= trojanscan_activechans
) {
1361 trojanscan_schedule
= NULL
;
1362 trojanscan_fill_channels(NULL
);
1364 if ((rc
= trojanscan_allocaterc(trojanscan_chans
[trojanscan_channumber
++]->content
)))
1365 trojanscan_join(rc
);
1370 void trojanscan_dopart(void *arg
) {
1371 struct trojanscan_realchannels
*rc
= (struct trojanscan_realchannels
*)arg
, *rp
, *past
= NULL
;
1373 if (rc
->kickedout
) { /* there's a join scheduled, wait for it (reschedule) */
1374 rc
->schedule
= scheduleoneshot(time(NULL
)+5, &trojanscan_dopart
, (void *)rc
);
1378 if (rc
->clone
&& rc
->clone
->clone
&& (!(rc
->donotpart
))) {
1379 localpartchannel(rc
->clone
->clone
, rc
->chan
);
1382 trojanscan_mainchanmsg("d: clone could not part: %s, most likely due to kill, flag: %d.", rc->chan->index->name->content, rc->donotpart);
1385 rc
->clone
->sitting
--;
1387 for(rp
=trojanscan_realchanlist
;rp
;rp
=rp
->next
) {
1390 trojanscan_realchanlist
= rp
->next
;
1392 past
->next
= rp
->next
;
1402 void trojanscan_donickchange(void *arg
) { /* just incase I choose to make this schedule at some point */
1403 struct trojanscan_clones
*clone
= (trojanscan_clones
*)arg
;
1404 if (clone
&& clone
->clone
) {
1405 char c_nick
[NICKLEN
+1];
1407 /* PPA: unlikely to be infinite */
1409 if ((loops
++ < 10) && trojanscan_hostmode
) {
1410 trojanscan_generatenick(c_nick
, NICKLEN
);
1412 trojanscan_gennick(c_nick
, trojanscan_minmaxrand(7, TROJANSCAN_MMIN(13, NICKLEN
)));
1414 } while (c_nick
&& (getnickbynick(c_nick
) != NULL
));
1416 renamelocaluser(clone
->clone
, c_nick
);
1421 int trojanscan_keysort(const void *v1
, const void *v2
) {
1422 return ((*(trojanscan_prechannels
**)v2
)->size
- (*(trojanscan_prechannels
**)v1
)->size
);
1425 int trojanscan_showcommands(void *sender
, int cargc
, char **cargv
) {
1426 nick
*np
= (nick
*)sender
;
1427 Command
*cmdlist
[100];
1431 n
= getcommandlist(trojanscan_cmds
, cmdlist
, 100);
1433 trojanscan_reply(np
, "The following commands are registered at present:");
1436 if (cmdlist
[i
]->level
& TROJANSCAN_ACL_STAFF
) {
1438 } else if (cmdlist
[i
]->level
& TROJANSCAN_ACL_DEVELOPER
) {
1440 } else if (cmdlist
[i
]->level
& TROJANSCAN_ACL_TEAMLEADER
) {
1442 } else if (cmdlist
[i
]->level
& TROJANSCAN_ACL_CAT
) {
1444 } else if (cmdlist
[i
]->level
& TROJANSCAN_ACL_WEBSITE
) {
1446 } else if (cmdlist
[i
]->level
& TROJANSCAN_ACL_UNAUTHED
) {
1450 trojanscan_reply(np
, "%s (+%c)", cmdlist
[i
]->command
->content
, level
);
1452 trojanscan_reply(np
, "%s", cmdlist
[i
]->command
->content
);
1455 trojanscan_reply(np
, "End of list.");
1459 void trojanscan_handlemessages(nick
*target
, int messagetype
, void **args
) {
1462 int cargc
, templevel
;
1464 union trojanscan_userlevel level
;
1466 switch(messagetype
) {
1469 /* If it's a message, first arg is nick and second is message */
1470 sender
= (nick
*)args
[0];
1472 if(strncmp(TROJANSCAN_VERSION_DETECT
, args
[1], sizeof(TROJANSCAN_VERSION_DETECT
)-1)==0) {
1473 char p
= ((char *)args
[1])[sizeof(TROJANSCAN_VERSION_DETECT
)-1];
1474 if((p
== ' ') || (p
== '\0') || (p
== 1)) {
1475 trojanscan_reply(sender
, "\001VERSION Trojanscan (or Tigger) Newserv module version %s by Chris Porter (slug), Newserv by David Mansell (splidge). Compiled " __DATE__
" " __TIME__
".\001", TROJANSCAN_VERSION
);
1480 /* Split the line into params */
1481 cargc
= splitline((char *)args
[1], cargv
, 50, 0);
1483 cmd
=findcommandintree(trojanscan_cmds
, cargv
[0], 1);
1485 trojanscan_reply(sender
, "Unknown command.");
1489 if ((cmd
->level
& TROJANSCAN_ACL_OPER
) && !IsOper(sender
)) {
1490 trojanscan_reply(sender
, "You need to be opered to use this command.");
1494 /* bit grim code... */
1496 if (!(cmd
->level
& TROJANSCAN_ACL_UNAUTHED
)) {
1497 if (!IsAccount(sender
)) {
1498 trojanscan_reply(sender
, "You must be authed with the network to access this command!");
1501 templevel
= trojanscan_user_level_by_authname(sender
->authname
);
1503 if (templevel
== -1) {
1504 trojanscan_reply(sender
, "You do not have an account.");
1508 level
.number
= templevel
;
1510 if ((cmd
->level
& TROJANSCAN_ACL_DEVELOPER
) && !TrojanscanIsDeveloper(level
)) {
1511 trojanscan_reply(sender
, "Access denied.");
1514 if ((cmd
->level
& TROJANSCAN_ACL_TEAMLEADER
) && !TrojanscanIsLeastTeamLeader(level
)) {
1515 trojanscan_reply(sender
, "Access denied.");
1518 if ((cmd
->level
& TROJANSCAN_ACL_STAFF
) && !TrojanscanIsLeastStaff(level
)) {
1519 trojanscan_reply(sender
, "Access denied.");
1522 if ((cmd
->level
& TROJANSCAN_ACL_CAT
) && !TrojanscanIsCat(level
)) {
1523 trojanscan_reply(sender
, "Access denied.");
1526 if ((cmd
->level
& TROJANSCAN_ACL_WEBSITE
) && !TrojanscanIsLeastWebsite(level
)) {
1527 trojanscan_reply(sender
, "Access denied.");
1532 /* Check the maxargs */
1533 if (cmd
->maxparams
<(cargc
-1)) {
1534 /* We need to do some rejoining */
1535 rejoinline(cargv
[cmd
->maxparams
], cargc
-(cmd
->maxparams
));
1536 cargc
= (cmd
->maxparams
) + 1;
1539 (cmd
->handler
)((void *)sender
, cargc
- 1, &(cargv
[1]));
1543 /* someone killed me? Bastards */
1544 trojanscan_connect_schedule
= scheduleoneshot(time(NULL
) + 1, &trojanscan_connect
, NULL
);
1545 trojanscan_nick
= NULL
;
1553 char trojanscan_getmtfrommessagetype(int input
) {
1555 case LU_PRIVMSG
: return 'm';
1556 case LU_PRIVNOTICE
: return 'n';
1557 case LU_SECUREMSG
: return 's';
1558 case LU_CHANMSG
: return 'M';
1559 case LU_CHANNOTICE
: return 'N';
1560 default: return '?';
1564 void trojanscan_clonehandlemessages(nick
*target
, int messagetype
, void **args
) {
1565 char *pretext
= NULL
, etext
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], enick
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], eident
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], ehost
[TROJANSCAN_QUERY_TEMP_BUF_SIZE
], text
[513], detected
= 0;
1567 struct trojanscan_realchannels
*rp
;
1568 struct trojanscan_rejoinlist
*rj
;
1569 unsigned int i
, len
;
1570 struct trojanscan_worms
*worm
;
1572 char mt
= trojanscan_getmtfrommessagetype(messagetype
);
1574 switch(messagetype
) {
1579 pretext
= (char *)args
[1];
1584 sender
= (nick
*)args
[0];
1585 if (strlen(sender
->nick
) < 2)
1589 pretext
= (char *)args
[2];
1591 if(strncmp(TROJANSCAN_VERSION_DETECT
, pretext
, sizeof(TROJANSCAN_VERSION_DETECT
)-1)==0) {
1592 char p
= pretext
[sizeof(TROJANSCAN_VERSION_DETECT
)-1];
1593 if((p
== ' ') || (p
== '\0') || (p
== 1)) {
1595 if (IsOper(sender
)) {
1598 if (IsAccount(sender
)) {
1599 int templevel
= trojanscan_user_level_by_authname(sender
->authname
);
1600 if (templevel
!= -1) {
1601 union trojanscan_userlevel level
;
1602 level
.number
= templevel
;
1603 if (TrojanscanIsLeastStaff(level
))
1609 sendnoticetouser(target
, sender
, "\001VERSION T clone, check T for confirmation.\001");
1610 sendnoticetouser(trojanscan_nick
, sender
, "\001VERSION %s is part of my swarm.\001", target
->nick
);
1612 sendnoticetouser(target
, sender
, "\001VERSION " TROJANSCAN_CLONE_VERSION_REPLY
"\001");
1619 trojanscan_strip_codes(text
, sizeof(text
) - 1, pretext
);
1623 for(i
=0;i
<trojanscan_database
.total_phrases
;i
++) {
1626 (worm
= trojanscan_database
.phrases
[i
].worm
)
1631 (messagetype
== LU_PRIVMSG
) || (messagetype
== LU_SECUREMSG
) || (messagetype
== LU_PRIVNOTICE
)
1634 (trojanscan_database
.phrases
[i
].worm
->hitpriv
)
1639 (messagetype
== LU_CHANMSG
) || (messagetype
== LU_CHANNOTICE
)
1642 (trojanscan_database
.phrases
[i
].worm
->hitchans
)
1646 (trojanscan_database
.phrases
[i
].phrase
)
1648 int pre
= pcre_exec(trojanscan_database
.phrases
[i
].phrase
, trojanscan_database
.phrases
[i
].hint
, text
, len
, 0, 0, vector
, 30);
1650 char glinemask
[HOSTLEN
+ USERLEN
+ NICKLEN
+ 4];
1653 unsigned int j
, usercount
, frequency
;
1654 char ip
[TROJANSCAN_IPLEN
];
1656 channel
*chp
= (channel
*)args
[1];
1658 nick
*np
= NULL
; /* sigh at warnings */
1662 trojanscan_database
.detections
++;
1664 if (!(hp
=findhost(sender
->host
->name
->content
))) {
1665 trojanscan_mainchanmsg("w: user %s!%s@%s triggered infection monitor, yet no hosts found at stage 1 -- worm: %s", sender
->nick
, sender
->ident
, sender
->host
->name
->content
, worm
->name
->content
);
1669 usercount
= 0; /* stupid warnings */
1670 if (worm
->monitor
) {
1673 } else if (worm
->glinehost
) {
1674 /* snprintf(glinemask, sizeof(glinemask) - 1, "*@%s", sender->host->name->content);*/
1675 snprintf(glinemask
, sizeof(glinemask
) - 1, "*@%s", trojanscan_iptostr(ip
, sizeof(ip
) - 1, sender
->ipaddress
));
1676 usercount
= hp
->clonecount
;
1677 } else if (worm
->glineuser
) {
1678 userbit
= sender
->ident
;
1679 if(userbit
[0] == '~')
1681 /* snprintf(glinemask, sizeof(glinemask) - 1, "*%s@%s", userbit, sender->host->name->content);*/
1682 snprintf(glinemask
, sizeof(glinemask
) - 1, "*%s@%s", userbit
, trojanscan_iptostr(ip
, sizeof(ip
) - 1, sender
->ipaddress
));
1683 for (j
=0;j
<NICKHASHSIZE
;j
++) {
1684 for (np
=nicktable
[j
];np
;np
=np
->next
) {
1685 if ((np
->host
==hp
) && (!ircd_strcmp(np
->ident
,sender
->ident
)))
1692 trojanscan_mainchanmsg("w: user %s!%s@%s triggered infection monitor, yet no hosts found at stage 2 -- worm: %s", sender
->nick
, sender
->ident
, sender
->host
->name
->content
, worm
->name
->content
);
1696 if (glining
&& (usercount
> trojanscan_maxusers
)) {
1697 trojanscan_mainchanmsg("w: not glining %s!%s@%s due to too many users (%d) with mask: *!%s -- worm: %s)", sender
->nick
, sender
->ident
, sender
->host
->name
->content
, usercount
, glinemask
, worm
->name
->content
);
1701 if (glining
&& !worm
->datalen
) {
1702 trojanscan_mainchanmsg("w: not glining %s!%s@%s due to too lack of removal data with mask: *!%s (%d users) -- worm: %s)", sender
->nick
, sender
->ident
, sender
->host
->name
->content
, glinemask
, usercount
, worm
->name
->content
);
1706 trojanscan_database_escape_string(enick
, sender
->nick
, strlen(sender
->nick
));
1707 trojanscan_database_escape_string(eident
, sender
->ident
, strlen(sender
->ident
));
1708 trojanscan_database_escape_string(ehost
, sender
->host
->name
->content
, sender
->host
->name
->length
);
1712 if (!(trojanscan_database_query("SELECT COUNT(*) FROM hits WHERE glined = %d AND host = '%s'", glining
, ehost
))) {
1713 trojanscan_database_res
*res
;
1714 if ((res
= trojanscan_database_store_result(&trojanscan_sql
))) {
1715 trojanscan_database_row sqlrow
;
1716 if ((trojanscan_database_num_rows(res
) > 0) && (sqlrow
= trojanscan_database_fetch_row(res
)))
1717 frequency
= atoi(sqlrow
[0]) + 1;
1718 trojanscan_database_free_result(res
);
1722 trojanscan_database_query("INSERT INTO hits (nickname, ident, host, phrase, messagetype, glined) VALUES ('%s', '%s', '%s', %d, '%c', %d)", enick
, eident
, ehost
, trojanscan_database
.phrases
[i
].id
, mt
, glining
);
1727 matchbuf
[512] = 0; /* hmm */
1730 if (pcre_copy_substring(text
, vector
, pre
, 1, matchbuf
, sizeof(matchbuf
) - 1) <= 0)
1733 trojanscan_mainchanmsg("m: t: %c u: %s!%s@%s%s%s w: %s f: %d%s%s", mt
, sender
->nick
, sender
->ident
, sender
->host
->name
->content
, mt
=='N'||mt
=='M'?" #: ":"", mt
=='N'||mt
=='M'?chp
->index
->name
->content
:"", worm
->name
->content
, frequency
, matchbuf
[0]?" --: ":"", matchbuf
[0]?matchbuf
:"");
1735 trojanscan_database
.glines
++;
1737 irc_send("%s GL * +%s %d :You are infected with a worm (%s), see %s%d for details - banned for %d hours\r\n", mynumeric
->content
, glinemask
, 3600 * TROJANSCAN_FIRST_OFFENSE
* frequency
, worm
->name
->content
, TROJANSCAN_URL_PREFIX
, worm
->id
, TROJANSCAN_FIRST_OFFENSE
* frequency
);
1738 //trojanscan_mainchanmsg("%s GL * +%s %d :You are infected with a worm (%s), see %s%d for details - banned for %d hours\r\n", mynumeric->content, glinemask, 3600 * TROJANSCAN_FIRST_OFFENSE * frequency, worm->name->content, TROJANSCAN_URL_PREFIX, worm->id, TROJANSCAN_FIRST_OFFENSE * frequency);
1740 trojanscan_mainchanmsg("g: *!%s t: %c u: %s!%s@%s%s%s c: %d w: %s f: %d", glinemask
, mt
, sender
->nick
, sender
->ident
, sender
->host
->name
->content
, mt
=='N'||mt
=='M'?" #: ":"", mt
=='N'||mt
=='M'?chp
->index
->name
->content
:"", usercount
, worm
->name
->content
, frequency
, mt
);
1747 if (!detected
&& (mt
!= 'N') && (mt
!= 'M')) {
1748 trojanscan_database_escape_string(etext
, text
, len
);
1749 trojanscan_database_escape_string(enick
, sender
->nick
, strlen(sender
->nick
));
1750 trojanscan_database_escape_string(eident
, sender
->ident
, strlen(sender
->ident
));
1751 trojanscan_database_escape_string(ehost
, sender
->host
->name
->content
, sender
->host
->name
->length
);
1752 trojanscan_database_query("INSERT INTO unknownlog (data, user) VALUES ('%s','%s!%s@%s')", etext
, enick
, eident
, ehost
);
1756 /* someone killed me? Bastards */
1757 /* PPA: we do NOT rejoin channels at this moment in time, it is possible to do this though */
1758 for (i
=0;i
<TROJANSCAN_CLONE_MAX
;i
++) {
1759 if (trojanscan_swarm
[i
].clone
== target
) {
1760 trojanscan_mainchanmsg("d: clone %s killed!", target
->nick
);
1762 scheduleoneshot(time(NULL
)+1, &trojanscan_generateclone
, (void *)i
);
1763 for(rp
=trojanscan_realchanlist
;rp
;rp
=rp
->next
)
1764 if ((rp
->clone
== &(trojanscan_swarm
[i
])))
1766 trojanscan_swarm
[i
].clone
= NULL
;
1767 trojanscan_swarm
[i
].remaining
= 0; /* bah */
1774 rj
= (struct trojanscan_rejoinlist
*)malloc(sizeof(struct trojanscan_rejoinlist
));
1777 trojanscan_mainchanmsg("k: %s on %s by %s", target->nick, ((channel *)args[1])->index->name->content, (((nick *)args[0])->nick)?(((nick *)args[0])->nick):"(server)");
1781 for(rp
=trojanscan_realchanlist
;rp
;rp
=rp
->next
)
1782 if ((rp
->clone
->clone
== target
) && (rp
->chan
== args
[1])) {
1788 trojanscan_mainchanmsg("d: kicked from %s after parting", ((channel
*)args
[1])->index
->name
->content
);
1793 rj
->channel
= getsstring(((channel
*)args
[1])->index
->name
->content
, ((channel
*)args
[1])->index
->name
->length
);
1795 trojanscan_mainchanmsg("d: unable to allocate memory for channel: %s upon rejoin", ((channel
*)args
[1])->index
->name
->content
);
1801 rj
->next
= trojanscan_schedulerejoins
;
1802 trojanscan_schedulerejoins
= rj
;
1804 rj
->schedule
= scheduleoneshot(time(NULL
)+1, &trojanscan_rejoin_channel
, (void *)rj
);
1813 void trojanscan_rejoin_channel(void *arg
) {
1814 struct trojanscan_rejoinlist
*rj2
, *lrj
, *rj
= (struct trojanscan_rejoinlist
*)arg
;
1815 /* TODO: there is a pretty major bug here */
1817 channel
*cp
= findchannel(rj
->channel
->content
);
1818 freesstring(rj
->channel
);
1821 rj
->rp
->kickedout
--;
1823 rj
->rp
->donotpart
= 1; /* we were the last user on the channel, so we need to be VERY careful freeing it */
1825 if(!rj
->rp
->donotpart
&& !rj
->rp
->kickedout
) { /* check we're allowed to join channels (not killed), and we're the last one to join */
1826 if (nickbanned(rj
->clone
, cp
)) {
1827 rj
->rp
->donotpart
= 1;
1829 localjoinchannel(rj
->clone
, cp
);
1835 rj2
= trojanscan_schedulerejoins
;
1839 trojanscan_schedulerejoins
= rj
->next
;
1842 for(rj2
=trojanscan_schedulerejoins
;rj2
;lrj
=rj2
,rj2
=rj2
->next
) {
1844 lrj
->next
= rj2
->next
;
1853 void trojanscan_reply(nick
*target
, char *message
, ... ) {
1857 if (!trojanscan_nick
)
1860 va_start(va
, message
);
1861 vsnprintf(buf
, sizeof(buf
) - 1, message
, va
);
1864 sendnoticetouser(trojanscan_nick
, target
, "%s", buf
);
1868 void trojanscan_mainchanmsg(char *message
, ...) {
1873 if (!trojanscan_nick
)
1875 if (!(cp
= findchannel(TROJANSCAN_CHANNEL
)))
1878 va_start(va
, message
);
1879 vsnprintf(buf
, sizeof(buf
) - 1, message
, va
);
1882 sendmessagetochannel(trojanscan_nick
, cp
, "%s", buf
);
1885 int trojanscan_minmaxrand(float min
, float max
) {
1886 return (int)((max
-min
+1)*rand()/(RAND_MAX
+min
))+min
;
1889 char *trojanscan_iptostr(char *buf
, int buflen
, unsigned int ip
) {
1890 snprintf(buf
, buflen
, "%d.%d.%d.%d", ip
>> 24, (ip
>> 16) & 255, (ip
>> 8) & 255, ip
& 255);
1894 char trojanscan_genchar(int ty
) {
1895 /* hostname and realname characters*/
1897 if (!(trojanscan_minmaxrand(0, 40) % 10)) {
1898 return trojanscan_minmaxrand(48, 57);
1900 return trojanscan_minmaxrand(97, 122);
1902 /* ident characters - without numbers*/
1903 } else if (ty
== 1) {
1904 return trojanscan_minmaxrand(97, 122);
1905 /* ident characters - with numbers*/
1906 } else if (ty
== 2) {
1907 ty
= trojanscan_minmaxrand(97, 125);
1908 if (ty
> 122) return trojanscan_minmaxrand(48, 57);
1910 /* nick characters - with and without numbers*/
1911 } else if (ty
== 3 || ty
== 4) {
1912 if (!(trojanscan_minmaxrand(0, 59) % 16)) {
1913 char weirdos
[6] = { '\\', '|', '[', '{', ']', '}' };
1914 return weirdos
[trojanscan_minmaxrand(0, 5)];
1917 ty
= trojanscan_minmaxrand(65, 93);
1918 if (ty
> 90) return trojanscan_minmaxrand(48, 57);
1920 ty
= trojanscan_minmaxrand(65, 90);
1922 if (!(trojanscan_minmaxrand(0, 40) % 8)) return ty
;
1930 void trojanscan_gennick(char *ptc
, char size
) {
1932 for (i
=0;i
<size
;i
++) {
1934 ptc
[i
] = trojanscan_genchar(3);
1936 ptc
[i
] = trojanscan_genchar(4);
1942 void trojanscan_genident(char *ptc
, char size
) {
1944 for (i
=0;i
<size
;i
++) {
1946 ptc
[i
] = trojanscan_genchar(1);
1948 ptc
[i
] = trojanscan_genchar(2);
1954 void trojanscan_genhost(char *ptc
, char size
) {
1955 int dots
= trojanscan_minmaxrand(2, 5), i
, dotexist
= 0, cur
;
1958 for (i
=0;i
<size
;i
++) {
1959 ptc
[i
] = trojanscan_genchar(0);
1960 if ((i
> 5) && (i
< (size
-4))) {
1961 if ((ptc
[i
-1] != '.') && (ptc
[i
-1] != '-')) {
1962 cur
= trojanscan_minmaxrand(1,size
/ dots
);
1978 void trojanscan_genreal(char *ptc
, char size
) {
1979 int spaces
= trojanscan_minmaxrand(2, 4), i
;
1980 for (i
=0;i
<size
;i
++) {
1981 ptc
[i
] = trojanscan_genchar(0);
1982 if ((i
> 5) && (i
< (size
-4))) {
1983 if (ptc
[i
-1] != ' ') {
1984 if (trojanscan_minmaxrand(1,size
/ spaces
) == 1) ptc
[i
] = ' ';
1991 int trojanscan_is_not_octet(char *begin
, int length
) {
1995 for(i
=0;i
<length
;i
++) {
1996 if (!((*begin
>= '0') && (*begin
<= '9')))
2003 int trojanscan_generatepool(void) {
2004 int i
, k
= 0, j
= 0, loops
= 0;
2008 for (i
=0;i
<NICKHASHSIZE
;i
++)
2009 for (np
=nicktable
[i
];np
;np
=np
->next
)
2012 if(j
< TROJANSCAN_MINIMUM_HOSTS_BEFORE_POOL
)
2017 for (j
=trojanscan_minmaxrand(0, NICKHASHSIZE
-1);j
<NICKHASHSIZE
;j
++) {
2019 for(p
=nicktable
[j
]->host
->name
->content
, pp
=p
;*p
;) {
2021 if (!trojanscan_is_not_octet(pp
, p
-pp
)) {
2022 if (i
< TROJANSCAN_POOLSIZE
) {
2023 if (i
< trojanscan_hostpoolsize
)
2024 freesstring(trojanscan_hostpool
[i
]);
2025 trojanscan_hostpool
[i
] = getsstring(pp
, p
-pp
);
2028 if (k
>= TROJANSCAN_POOLSIZE
)
2035 if (!trojanscan_is_not_octet(pp
, p
-pp
)) {
2036 if (k
< TROJANSCAN_POOLSIZE
) {
2037 if (k
< trojanscan_tailpoolsize
)
2038 freesstring(trojanscan_tailpool
[k
]);
2039 trojanscan_tailpool
[k
] = getsstring(pp
, p
-pp
);
2042 if (i
>= TROJANSCAN_POOLSIZE
)
2049 } while ((loops
< 5) && ((i
< TROJANSCAN_POOLSIZE
) || (k
< TROJANSCAN_POOLSIZE
)));
2051 trojanscan_hostpoolsize
= i
;
2052 trojanscan_tailpoolsize
= k
;
2056 void trojanscan_generatehost(char *buf
, int maxsize
) {
2058 int pieces
= trojanscan_minmaxrand(2, 4), totallen
= 0, a
= 0, i
;
2059 int *choices
= malloc(sizeof(int) * (pieces
+ 1));
2060 int *lengths
= malloc(sizeof(int) * (pieces
+ 1));
2062 choices
[pieces
] = trojanscan_minmaxrand(0, trojanscan_tailpoolsize
-1);
2063 lengths
[pieces
] = strlen(trojanscan_tailpool
[choices
[pieces
]]->content
) + 1;
2064 totallen
+= lengths
[pieces
];
2066 for (i
=0;i
<pieces
;i
++) {
2067 choices
[i
] = trojanscan_minmaxrand(0, trojanscan_hostpoolsize
-1);
2068 lengths
[i
] = strlen(trojanscan_hostpool
[choices
[i
]]->content
) + 1;
2069 if (totallen
+lengths
[i
] > maxsize
) {
2070 choices
[i
] = choices
[pieces
];
2071 lengths
[i
] = lengths
[pieces
];
2075 totallen
+= lengths
[i
];
2078 for (i
=0;i
<pieces
;i
++) {
2079 for (cpos
=trojanscan_hostpool
[choices
[i
]]->content
; *cpos
;)
2084 for (cpos
=trojanscan_tailpool
[choices
[i
]]->content
; *cpos
;) {
2094 void trojanscan_generatenick(char *buf
, int maxsize
) {
2095 int bits
= trojanscan_minmaxrand(2, 4), j
, loops
= 0, d
= 0, wanttocopy
, len
= 0, i
;
2098 for (j
=trojanscan_minmaxrand(0, NICKHASHSIZE
-1);j
<NICKHASHSIZE
;j
++) {
2100 if(nicktable
[j
]->nick
) {
2101 wanttocopy
= trojanscan_minmaxrand(1, (strlen(nicktable
[j
]->nick
) / 2) + 1);
2102 for(i
=0;((i
<wanttocopy
) && (len
<maxsize
));i
++)
2103 buf
[len
++] = nicktable
[j
]->nick
[i
];
2112 } while (loops
< 10);
2116 void trojanscan_generateident(char *buf
, int maxsize
) {
2120 for (j
=trojanscan_minmaxrand(0, NICKHASHSIZE
-1);j
<NICKHASHSIZE
;j
++) {
2122 if(nicktable
[j
]->ident
) {
2123 strncpy(buf
, nicktable
[j
]->ident
, maxsize
);
2129 } while (loops
< 10);
2132 void trojanscan_generaterealname(char *buf
, int maxsize
) {
2136 for (j
=trojanscan_minmaxrand(0, NICKHASHSIZE
-1);j
<NICKHASHSIZE
;j
++) {
2138 if(nicktable
[j
]->realname
->name
->content
) {
2139 strncpy(buf
, nicktable
[j
]->realname
->name
->content
, maxsize
);
2145 } while (loops
< 10);
2148 void trojanscan_database_close(void) {
2149 mysql_close(&trojanscan_sql
);
2152 int trojanscan_database_connect(char *dbhost
, char *dbuser
, char *dbpass
, char *db
, unsigned int port
) {
2153 mysql_init(&trojanscan_sql
);
2154 if (!mysql_real_connect(&trojanscan_sql
, dbhost
, dbuser
, dbpass
, db
, port
, NULL
, 0))
2159 void trojanscan_database_escape_string(char *dest
, char *source
, size_t length
) {
2160 mysql_escape_string(dest
, source
, length
);
2163 int trojanscan_database_query(char *format
, ...) {
2164 char trojanscan_sqlquery
[TROJANSCAN_QUERY_BUF_SIZE
];
2167 va_start(va
, format
);
2168 vsnprintf(trojanscan_sqlquery
, sizeof(trojanscan_sqlquery
) - 1, format
, va
);
2170 return mysql_query(&trojanscan_sql
, trojanscan_sqlquery
);
2173 int trojanscan_database_num_rows(trojanscan_database_res
*res
) {
2174 return mysql_num_rows(res
);
2177 trojanscan_database_res
*trojanscan_database_store_result() {
2178 return mysql_store_result(&trojanscan_sql
);
2181 trojanscan_database_row
trojanscan_database_fetch_row(trojanscan_database_res
*res
) {
2182 return mysql_fetch_row(res
);
2185 void trojanscan_database_free_result(trojanscan_database_res
*res
) {
2186 mysql_free_result(res
);