Guest User

Untitled

a guest
May 8th, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.48 KB | None | 0 0
  1. /* [ ORIGNICK: irc bot -- version X+final+++. ] ******************************
  2. * irc bot for obtaining names stored in a file, looping until one is found. *
  3. * supports general irc functions, channel invite/(re)joining, random *
  4. * nicknames, backgrounding, server list, quit priority, passwd auth, debug *
  5. * and other misc. functions. *
  6. * *
  7. * AUTHOR: *
  8. * v9/vade79@realhalo.org, realhalo.org. (* model) *
  9. * Estella/Estella@Mystagic, mystagic.com (ipv6 port) *
  10. * *
  11. * COMPILE: *
  12. * # cc orignick.c -o orignick -lcrypt *
  13. * method 1(usually), depends on distribution/os. *
  14. * *
  15. * # cc orignick.c -o orignick *
  16. * method 2(secondary), depends distribution/os. *
  17. * *
  18. * note: apply the "-DNOCOLOR" argument to your compiler to disable color. *
  19. * *
  20. * DISTRIBUTION: *
  21. * +autostop(snatch->solid model) : stops scanning once met any objective. *
  22. * +check(snatch->solid model) : extended buffer checking for security. *
  23. * +fix(snatch->solid model) : appended fixes from the snatch model. *
  24. * +cchannel(snatch->solid model) : channel correction support. *
  25. * +noroot(snatch->solid model) : disallowed root to run by default. *
  26. * +version(snatch->solid model) : display the version and id information. *
  27. * +nickfix(snatch->solid model) : major non-functional error fixed. (1.9) *
  28. * +extended(snatch->solid model) : for servers that allow 30 char names. *
  29. * +buffix(snatch->solid model) : fixes off-by-one buffer sizes. (2.3) *
  30. * +buffix2(snatch->solid model) : fixes differences in allocations. (2.4) *
  31. * -permnick(snatch->solid model) : conflicted with new options. *
  32. * +combine(solid->complete model): combined both features of both models. *
  33. * +invite(solid->complete model) : re-included for the combined model. *
  34. * +doquit(complete->iodine model): priority to get nicknames that quit. *
  35. * +passwd(complete->iodine model): kill passwd option used via privmsg. *
  36. * +nodisp(complete->iodine model): disable bot showing status. *
  37. * +envfix(complete->iodine model): fixes possible null sets in env vars. *
  38. * +global(iodine->global model) : support for more linux distributions. *
  39. * +buffree(iodine->global model) : released finished buffers, save memory. *
  40. * +kdelay(iodine->global model) : delay remote kills, prevent regain. *
  41. * +vhost(iodine->global model) : virtual host support. (3.5) *
  42. * +delay(iodine->global model) : delay support, to prevent flood. (3.8) *
  43. * +vhostfix(iodine->global model): fixes reconnection memory wipe. (3.9) *
  44. * +vreply(iodine->global model) : version response option. *
  45. * +delayfix(iodine->global model): change in delay method, less waste. *
  46. * +cvreply(iodine->global model) : won't reply to version until newnick. *
  47. * -buffix2(iodine->global model) : reverted to old buffer method, for new. *
  48. * +bsd(global->glob++ model) : support for bsd distributions/os. *
  49. * +kencrypt(global->glob++ model): kill passwd encryption. *
  50. * +finished(glob++->final model) : orignick project completed. (NUL) *
  51. * +finished(final->final+ model) : minor fix from previous version. (NUL) *
  52. * +done(final+->final++ model) : final changes. (X) *
  53. * +done(final++->final+++ model) : so i thought, fixed fd volume. (X) *
  54. * *
  55. * TUTORIAL: *
  56. * the names file(-f argument) should contain a list similar to this: *
  57. * ------------------------------------------------------------------------- *
  58. * a *
  59. * b *
  60. * c *
  61. * ... *
  62. * ------------------------------------------------------------------------- *
  63. * if you are trying to get one letter nicknames, for example. other uses *
  64. * could be to hold botnet names - to prevent posing. or possibly to hold *
  65. * an array of nicknames you use. many reasons can apply. *
  66. * *
  67. * the server file(-s argument) should contain a list similar to this: *
  68. * ------------------------------------------------------------------------- *
  69. * irc.server1.net *
  70. * irc.server2.net *
  71. * irc.server3.net *
  72. * ... *
  73. * ------------------------------------------------------------------------- *
  74. * the port is changed via the -p argument, if none is given it reverts to *
  75. * the default port. *
  76. * *
  77. * EXAMPLES: *
  78. * note: all examples include the same load file("alphabet") and server *
  79. * file("servers") in the current directory. (-f and -s options, required) *
  80. * *
  81. * # ./orignick -f alphabet -s servers -c '#private' -k keyed -n on[a-z] *
  82. * this example would join #private with the key 'keyed' and use the *
  83. * nickname "on[a-z]" if not in use. *
  84. * *
  85. * # ./orignick -f alphabet -s servers -P 6666 -d *
  86. * this example would change the irc connection port to 6666 and show the *
  87. * output of server data. *
  88. * *
  89. * # ./orignick -f alphabet -s servers -b -P ~/pid.orignick *
  90. * this example would background orignick and write the pid to *
  91. * pid.orignick in the home directory. *
  92. * *
  93. * # ./orignick -f alphabet -s servers -K killme *
  94. * this example would set the kill password to "killme" and could be *
  95. * killed via "/msg <botnick/channel> killme" remotely. by being killed *
  96. * it will simply quit the server and reconnect to the next server on the *
  97. * server list. so, since it can be killed via the channel, don't make it *
  98. * an easy password. also, if you are not comfortable with having your *
  99. * password in the command line you can set the environmental variable *
  100. * "PASSWD"(default) to the password you desire. (use -E or the *
  101. * environmental variable "EPASSWD" for encrypted passwords, if you don't *
  102. * know how to encrypt your password use the -M option of orignick) *
  103. * *
  104. * # ./orignick -f alphabet -s servers -Z -S 1000000 -L 3000000 -H host.com *
  105. * this example would disable version replies, set a server delayed *
  106. * response time for a full second, set a special situation delayed *
  107. * response time for a full three seconds(both delay times are used to *
  108. * prevent excess flooding) and use host.com as a virtual host. *
  109. * *
  110. * # ./orignick -f alphabet -s servers -V "mIRC32 v5.82 K.Mardam-Bey" *
  111. * this example would set the version reply to "mIRC32 v5.82 K.Mardam-Bey" *
  112. * instead of the default orignick reply. (note: will only reply after *
  113. * the desired nickname(s) has been obtained.) *
  114. * *
  115. * final note: if the -e argument is used make sure the server supports 30 *
  116. * character names. otherwise, display and internal errors will occur. if *
  117. * you notice excess flooding quits by the bot, apply the -S and/or -L *
  118. * arguments with a specified time that stops the excess flood quits. *
  119. * (-S 1000000 and/or -L 3000000 perhaps?) *
  120. * *
  121. * COMMENTS: *
  122. * i'm aware that i didn't write this in the most clean manner, but it is *
  123. * effective and compact to me. i'm the only person who really needs to *
  124. * read it anyways. also, there are benefits from having a channel for the *
  125. * bot to join, it will keep the nicknames you already have via the quit *
  126. * method. finally, when orignick is placed in the background it will not *
  127. * exit due to errors that it would during normal foreground processing. *
  128. * *
  129. * orignick.c: program source code for orignick. (969l!2992w!36061b) *
  130. *****************************************************************************/
  131. #include <stdio.h>
  132. #include <stdlib.h>
  133. #include <string.h>
  134. #include <unistd.h>
  135. #include <pwd.h>
  136. #include <signal.h>
  137. #include <netdb.h>
  138. #include <sys/time.h>
  139. #include <sys/types.h>
  140. #include <sys/socket.h>
  141. #include <netinet/in.h>
  142.  
  143. /* GENERAL INFORMATION, POSSIBLE CHANGES. */
  144. #define VERSION "X+final-ipv6+++" /* version information. */
  145. #define ENV_IRCHOST "IRC_HOST" /* optional virtual host variable. */
  146. #define ENV_PASSWORD "PASSWD" /* optional passwd variable. */
  147. #define ENV_EPASSWORD "EPASSWD" /* optional crypted passwd variable. */
  148. #define ENV_USERNAME "USERNAME" /* optional username variable. */
  149. #define ENV_REALNAME "REALNAME" /* optional realname variable. */
  150. #define DEFAULT_INFO "Unknown" /* generic name info if no other. */
  151. #define DEFAULT_PORT 6667 /* generic irc port to connect to. */
  152. #define MAX_NAME_LENGTH 9 /* name argument limit. (regular) */
  153. #define MAX_NAME_LENGTH_EXT 30 /* name argument limit. (extended) */
  154. #define MAX_ARGS 512 /* name and server array limit. */
  155. #define MAX_ERRORS 5 /* invalid nicknames before exit. */
  156. #define KILL_DELAY 5 /* delay after remote kill to rcon. */
  157. #define BASE_BUFFER 1024 /* shouldn't change this. */
  158. #define VERSION_FPROT 5 /* delay for version reply. (secs) */
  159. #define ALLOW_ROOT 0 /* 1=allow root to run, 0=don't. */
  160. /* #define NOCOLOR */ /* un-comment to disable color. */
  161. #define _XOPEN_SOURCE /* for the encrypted passwd option. */
  162. /* PROMPTS OR PRECURSORS TO DISPLAY TEXT. */
  163. #ifdef NOCOLOR
  164. #define PMT "[orignick6]: " /* regular. (no color) */
  165. #define EPMT "[ERROR]: " /* error. (no color) */
  166. #define DPMT "[debug]: " /* debug. (no color) */
  167. #endif
  168. #ifndef NOCOLOR
  169. #define PMT "\033[1;30m[\033[1;37morignick6\033[1;30m]:\033[0m " /* regular. */
  170. #define EPMT "\033[1;30m[\033[1;31mERROR\033[1;30m]:\033[0m " /* error. */
  171. #define DPMT "\033[1;30m[\033[0;36mdebug\033[1;30m]:\033[0m " /* debug. */
  172. #endif
  173. /* PROGRAM BEGIN. */
  174. int port=DEFAULT_PORT;
  175. int name_length=MAX_NAME_LENGTH;
  176. int killd=KILL_DELAY;
  177. int ischannel=0;
  178. int ispasswd=0;
  179. int isnick=0;
  180. int isvhost=0;
  181. int isversion=1;
  182. int isbg=0;
  183. int allowversion=0;
  184. int nodisplay=0;
  185. int noquit=0;
  186. int debug=0;
  187. int delay=0;
  188. int delay2=0;
  189. int tot_n=0;
  190. int tot_s=0;
  191. int bg=0;
  192. char id[]="$Id: orignick.c,v "VERSION" 2001/03/30 23:35:21 EST vade79 Exp $";
  193. char *names[MAX_ARGS];
  194. char *servers[MAX_ARGS];
  195. char *vreply="orignick/v"VERSION": v9@realhalo.org, realhalo.org.";
  196. char *channel_key="none";
  197. char *parm;
  198. char *nickname;
  199. char *basenickname;
  200. char *username;
  201. char *realname;
  202. char *password;
  203. char *channel;
  204. char *vhost;
  205. void abort_show(){
  206. fprintf(stderr,"(ctrl-c aborted)\n");
  207. exit(0);
  208. }
  209. void bug_show(){
  210. printe("orignick failed in memory management, please report this event and ho"
  211. "w it occured",1);
  212. }
  213. void version_fprot(){
  214. allowversion=0;
  215. }
  216. int main(int argc,char **argv){
  217. int i=0;
  218. int j=0;
  219. int isname=0;
  220. int isserver=0;
  221. int isun=0;
  222. int isrn=0;
  223. int ispid=0;
  224. char *pid_file;
  225. char *name_file;
  226. char *server_file;
  227. extern char *optarg;
  228. FILE *pid_f;
  229. setreuid(getuid(),getuid());
  230. setregid(getgid(),getgid());
  231. signal(SIGHUP,SIG_IGN);
  232. signal(SIGPIPE,SIG_IGN);
  233. signal(SIGTSTP,SIG_IGN);
  234. signal(SIGSEGV,bug_show);
  235. signal(SIGINT,abort_show);
  236. fprintf(stderr,"(%u) [*] orignick/v%s, written by: vade79/v9[@realhalo.org]."
  237. "\n\n",getpid(),VERSION);
  238. if((!getuid()||!getgid())&&!ALLOW_ROOT)
  239. printe("running orignick as root is disabled",1);
  240. make_userinfo();
  241. while((i=getopt(argc,argv,"f:s:p:u:r:c:k:n:S:L:P:dbK:E:M:D:H:V:ZzNev"))!=EOF){
  242. switch(i){
  243. case 'f':
  244. if(!isname){
  245. isname=1;
  246. if(!(name_file=(char *)malloc(strlen(optarg)+1)))
  247. printe("main(): allocating memory",1);
  248. strcpy(name_file,optarg);
  249. }
  250. break;
  251. case 's':
  252. if(!isserver){
  253. isserver=1;
  254. if(!(server_file=(char *)malloc(strlen(optarg)+1)))
  255. printe("main(): allocating memory",1);
  256. strcpy(server_file,optarg);
  257. }
  258. break;
  259. case 'p':
  260. if(atoi(optarg)>0)
  261. port=atoi(optarg);
  262. break;
  263. case 'u':
  264. if(!isun){
  265. if(!(username=(char *)malloc(strlen(optarg)+1)))
  266. printe("main(): allocating memory",1);
  267. strcpy(username,optarg);
  268. isun=1;
  269. }
  270. break;
  271. case 'r':
  272. if(!isrn){
  273. if(!(realname=(char *)malloc(strlen(optarg)+1)))
  274. printe("main(): allocating memory",1);
  275. strcpy(realname,optarg);
  276. isrn=1;
  277. }
  278. break;
  279. case 'c':
  280. ischannel=1;
  281. if(!(channel=(char *)malloc(strlen(optarg)+2)))
  282. printe("main(): allocating memory",1);
  283. strcpy(channel,optarg);
  284. if(channel[0]!=0x23&&channel[0]!=0x26)
  285. sprintf(channel,"#%s",optarg);
  286. strtok(channel,",");
  287. break;
  288. case 'k':
  289. if(!(channel_key=(char *)malloc(strlen(optarg)+1)))
  290. printe("main(): allocating memory",1);
  291. strcpy(channel_key,optarg);
  292. break;
  293. case 'n':
  294. isnick=1;
  295. if(!(nickname=(char *)malloc(strlen(optarg)+1)))
  296. printe("main(): allocating memory",1);
  297. strcpy(nickname,optarg);
  298. if(!(basenickname=(char *)malloc(strlen(nickname)+1)))
  299. printe("main(): allocating memory",1);
  300. strcpy(basenickname,nickname);
  301. break;
  302. case 'S':
  303. delay=atoi(optarg);
  304. break;
  305. case 'L':
  306. delay2=atoi(optarg);
  307. break;
  308. case 'P':
  309. ispid=1;
  310. if(!(pid_file=(char *)malloc(strlen(optarg)+1)))
  311. printe("main(): allocating memory",1);
  312. strcpy(pid_file,optarg);
  313. break;
  314. case 'd':
  315. debug=1;
  316. break;
  317. case 'b':
  318. bg=1;
  319. break;
  320. case 'K':
  321. ispasswd=1;
  322. if(!(password=(char *)malloc(strlen(optarg)+1)))
  323. printe("main(): allocating memory",1);
  324. strcpy(password,optarg);
  325. break;
  326. case 'E':
  327. ispasswd=2;
  328. if(!(password=(char *)malloc(strlen(optarg)+1)))
  329. printe("main(): allocating memory",1);
  330. strcpy(password,optarg);
  331. break;
  332. case 'M':
  333. orignick_encrypt(optarg);
  334. fprintf(stderr,"%sEncrypted password: %s\n",PMT,password);
  335. exit(0);
  336. break;
  337. case 'D':
  338. if(atoi(optarg)>-1)
  339. killd=atoi(optarg);
  340. break;
  341. case 'H':
  342. isvhost=1;
  343. if(!(vhost=(char *)malloc(strlen(optarg)+1)))
  344. printe("main(): allocating memory",1);
  345. strcpy(vhost,optarg);
  346. break;
  347. case 'V':
  348. isversion=1;
  349. if(!(vreply=(char *)malloc(strlen(optarg)+1)))
  350. printe("main(): allocating memory",1);
  351. strcpy(vreply,optarg);
  352. break;
  353. case 'Z':
  354. isversion=0;
  355. break;
  356. case 'z':
  357. noquit=1;
  358. break;
  359. case 'N':
  360. nodisplay=1;
  361. break;
  362. case 'e':
  363. name_length=MAX_NAME_LENGTH_EXT;
  364. break;
  365. case 'v':
  366. fprintf(stderr,"Version information: orignick/v%s.\n"
  367. "Id inormation: %s\n",VERSION,id);
  368. exit(0);
  369. break;
  370. default:
  371. usage(argv[0]);
  372. break;
  373. }
  374. }
  375. if(!isvhost)
  376. if(getenv(ENV_IRCHOST)&&strlen((char *)getenv(ENV_IRCHOST))>0){
  377. isvhost=1;
  378. if(!(vhost=(char *)malloc(strlen((char *)getenv(ENV_IRCHOST))+1)))
  379. printe("main(): allocating memory",1);
  380. strcpy(vhost,(char *)getenv(ENV_IRCHOST));
  381. }
  382. if(!ispasswd){
  383. if(getenv(ENV_PASSWORD)&&strlen((char *)getenv(ENV_PASSWORD))>0){
  384. ispasswd=1;
  385. if(!(password=(char *)malloc(strlen((char *)getenv(ENV_PASSWORD))+1)))
  386. printe("main(): allocating memory",1);
  387. strcpy(password,(char *)getenv(ENV_PASSWORD));
  388. }
  389. if(getenv(ENV_EPASSWORD)&&strlen((char *)getenv(ENV_EPASSWORD))>0){
  390. ispasswd=2;
  391. if(!(password=(char *)malloc(strlen((char *)getenv(ENV_EPASSWORD))+1)))
  392. printe("main(): allocating memory",1);
  393. strcpy(password,(char *)getenv(ENV_EPASSWORD));
  394. }
  395. }
  396. if(!isun)
  397. if(getenv(ENV_USERNAME)&&strlen((char *)getenv(ENV_USERNAME))>0){
  398. isun=1;
  399. if(!(username=(char *)malloc(strlen((char *)getenv(ENV_USERNAME))+1)))
  400. printe("main(): allocating memory",1);
  401. strcpy(username,(char *)getenv(ENV_USERNAME));
  402. }
  403. if(!isrn)
  404. if(getenv(ENV_REALNAME)&&strlen((char *)getenv(ENV_REALNAME))>0){
  405. isrn=1;
  406. if(!(realname=(char *)malloc(strlen((char *)getenv(ENV_REALNAME))+1)))
  407. printe("main(): allocating memory",1);
  408. strcpy(realname,(char *)getenv(ENV_REALNAME));
  409. }
  410. if(!isserver||!isname)
  411. usage(argv[0]);
  412. else{
  413. fprintf(stderr,"%sHostname is set: %s.\n",PMT,isvhost?vhost:"default");
  414. fprintf(stderr,"%sServer response delays are set: 1(%dms), 2(%dms).\n",PMT,
  415. delay,delay2);
  416. fprintf(stderr,"%sMaximum nickname length is set: %d. (%s)\n",PMT,
  417. name_length,name_length==MAX_NAME_LENGTH?"default":"extended");
  418. fprintf(stderr,"%sChannel join is set: %s.\n",PMT,ischannel?channel:"none");
  419. fprintf(stderr,"%sVersion reply is set: %s.\n",PMT,isversion?"on":"off");
  420. fprintf(stderr,"%sOn quit grab is set: %s.\n",PMT,noquit?"off":"on");
  421. fprintf(stderr,"%sKill password is set: %s.\n",PMT,ispasswd?"on":"off");
  422. if(ispasswd)
  423. fprintf(stderr,"%sKill delay time is set: %ds. (%s)\n",PMT,killd,
  424. killd==KILL_DELAY?"default":"extended");
  425. fprintf(stderr,"%sUsing server file: %s.\n",PMT,server_file);
  426. make_server_list(server_file);
  427. if(!tot_s){
  428. fprintf(stderr,"%sNot enough servers gathered to create an array.\n",PMT);
  429. exit(1);
  430. }
  431. fprintf(stderr,"%sArray server list created: %d server(s).\n",PMT,tot_s--);
  432. fprintf(stderr,"%sUsing name file: %s.\n",PMT,name_file);
  433. make_names_list(name_file);
  434. if(!tot_n){
  435. fprintf(stderr,"%sNot enough names gathered to create an array.\n",PMT);
  436. exit(1);
  437. }
  438. fprintf(stderr,"%sArray name list created: %d name(s).\n",PMT,tot_n--);
  439. if(!isnick)
  440. rand_nickname(name_length);
  441. if(bg){
  442. fprintf(stderr,"%sForking into the background.\n",PMT);
  443. switch(isbg=fork()){
  444. case -1:
  445. printe("forking into the background",1);
  446. break;
  447. case 0:
  448. if(ispid){
  449. pid_f=fopen(pid_file,"w");
  450. fprintf(pid_f,"%u\n",getpid());
  451. fclose(pid_f);
  452. }
  453. setsid();
  454. while(1){
  455. irc_parse(servers[j++],port);
  456. usleep(250000);
  457. if(tot_s<j)
  458. j=0;
  459. }
  460. break;
  461. default:
  462. fprintf(stderr,"%sBackgrounded to pid: %u.\n",PMT,isbg);
  463. exit(0);
  464. break;
  465. }
  466. }
  467. else
  468. while(1){
  469. irc_parse(servers[j++],port);
  470. usleep(250000);
  471. if(tot_s<j)
  472. j=0;
  473. }
  474. }
  475. exit(0);
  476. }
  477. int valid_name(char *word){
  478. int i=0;
  479. for(i=0;i<strlen(word);i++)
  480. if(word[i]<0x30||word[i]>0x7D)
  481. return(1);
  482. return(0);
  483. }
  484. int make_names_list(char *path){
  485. int i=0;
  486. int j=0;
  487. char read[(BASE_BUFFER+name_length)];
  488. FILE *fd;
  489. if(!(fd=fopen(path,"r")))
  490. printe("name file doesn't appear to exist or isn't readable",1);
  491. tot_n=0;
  492. while(fgets(read,sizeof(read),fd)){
  493. if(j>=MAX_ARGS)
  494. printe("too many names to store in memory",1);
  495. if(read[0]!=0x23){
  496. for(i=0;i<strlen(read);i++)
  497. if(read[i]==0x0A)
  498. read[i]=0x0;
  499. if(read[0]!=0x0A&&read[0]!=0x0){
  500. if(j-tot_n>MAX_ERRORS)
  501. printe("maximum invalid name(s) exceeded",1);
  502. if(strlen(read)>name_length)
  503. printe("ignored name in name file due to length restrictions",0);
  504. else if(valid_name(read))
  505. printe("ignored name in name file due to invalid character(s)",0);
  506. else{
  507. if(!(names[tot_n]=(char *)malloc(name_length)+1))
  508. printe("make_names_list(): allocating memory",1);
  509. strcpy(names[tot_n++],read);
  510. }
  511. }
  512. bzero(read,sizeof(read));
  513. }
  514. j++;
  515. }
  516. fclose(fd);
  517. return(0);
  518. }
  519. int make_server_list(char *path){
  520. int i=0;
  521. int j=0;
  522. char read[(256+2)];
  523. FILE *fd;
  524. if(!(fd=fopen(path,"r")))
  525. printe("server file doesn't appear to exist or isn't readable",1);
  526. while(fgets(read,sizeof(read),fd)){
  527. if(j>=MAX_ARGS)
  528. printe("too many servers to store in memory",1);
  529. if(read[0]!=0x23){
  530. for(i=0;i<strlen(read);i++)
  531. if(read[i]==0x0A)
  532. read[i]=0x0;
  533. if(read[0]!=0x0A&&read[0]!=0x0)
  534. if(strlen(read)>256)
  535. printe("ignored server due to length restrictions",0);
  536. else{
  537. if(!(servers[tot_s]=(char *)malloc(256+1)))
  538. printe("make_server_list(): allocating memory",1);
  539. strcpy(servers[tot_s++],read);
  540. }
  541. bzero(read,sizeof(read));
  542. }
  543. j++;
  544. }
  545. fclose(fd);
  546. return(0);
  547. }
  548. int make_userinfo(){
  549. struct passwd *userinfo;
  550. if(!(userinfo=getpwuid(getuid())))
  551. printe("passwd entry doesn't appear to exist",1);
  552. else{
  553. if(strlen(userinfo->pw_name)){
  554. if(!(username=(char *)malloc(strlen((char *)userinfo->pw_name)+1)))
  555. printe("make_userinfo(): allocating memory",1);
  556. strcpy(username,(char *)userinfo->pw_name);
  557. }
  558. else{
  559. if(!(username=(char *)malloc(strlen(DEFAULT_INFO)+1)))
  560. printe("make_userinfo(): allocating memory",1);
  561. strcpy(username,DEFAULT_INFO);
  562. }
  563. if(strlen(userinfo->pw_gecos)){
  564. if(!(realname=(char *)malloc(strlen((char *)userinfo->pw_gecos)+1)))
  565. printe("make_userinfo(): allocating memory",1);
  566. strcpy(realname,(char *)userinfo->pw_gecos);
  567. }
  568. else{
  569. if(!(realname=(char *)malloc(strlen(DEFAULT_INFO)+1)))
  570. printe("make_userinfo(): allocating memory",1);
  571. strcpy(realname,DEFAULT_INFO);
  572. }
  573. }
  574. return(0);
  575. }
  576. int parameter(char *array,int i){
  577. int j=0;
  578. int k=0;
  579. char buf[(strlen(array)+1)];
  580. bzero(buf,sizeof(buf));
  581. if(i<0)
  582. strcpy(buf,"*");
  583. else
  584. for(j=0;j<strlen(array);j++){
  585. if(array[j]==0x20)
  586. i--;
  587. else if(!i)
  588. buf[k++]=array[j];
  589. if(array[j]==0x0A||array[j]==0x0)
  590. j=(strlen(array)+1);
  591. }
  592. if(i>0)
  593. strcpy(buf,"*");
  594. free(parm);
  595. if(!(parm=(char *)malloc(strlen(buf)+1)))
  596. printe("parameter(): allocating memory",1);
  597. strcpy(parm,buf);
  598. return(0);
  599. }
  600. int orignick_encrypt(char *pwd){
  601. char chr[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
  602. char salt[3];
  603. struct timeval tv;
  604. srandom(time(0));
  605. sprintf(salt,"%c%c%c",chr[random()%64],chr[random()%64],0x0);
  606. if(!(password=(char *)malloc(strlen((char *)crypt(pwd,salt))+1)))
  607. printe("orignick_encrypt(): allocating memory",1);
  608. strcpy(password,(char *)crypt(pwd,salt));
  609. return(0);
  610. }
  611. int rand_nickname(int size){
  612. int i=0;
  613. int r=0;
  614. char string[(MAX_NAME_LENGTH_EXT+1)];
  615. struct timeval tv;
  616. while(i<=sizeof(string)){
  617. gettimeofday(&tv,(struct timezone*)0);
  618. srand(tv.tv_usec);
  619. if((2.0*rand()/(RAND_MAX+1.0))>1)
  620. r=(0x41+(int)(26.0*rand()/(RAND_MAX+1.0)));
  621. else
  622. r=(0x61+(int)(26.0*rand()/(RAND_MAX+1.0)));
  623. string[i++]=r;
  624. }
  625. if(!(nickname=(char *)malloc(strlen(string)+1)))
  626. printe("rand_nickname(): allocating memory",1);
  627. strncpy(nickname,string,size);
  628. return(0);
  629. }
  630. int irc_parse(char *host,int port){
  631. int err;
  632. int i=0;
  633. int j=0;
  634. int k=0;
  635. int l=0;
  636. int m=0;
  637. int sock=0;
  638. int serr=0;
  639. int first_ison=0;
  640. int start=0;
  641. int stop=0;
  642. char *tmpchannel;
  643. char *tmppassword;
  644. char active_nickname[BASE_BUFFER];
  645. char swrite[BASE_BUFFER];
  646. char sread[BASE_BUFFER];
  647. char sread_line[BASE_BUFFER];
  648. struct hostent *he;
  649. struct sockaddr_in6 irc;
  650. alarm(0);
  651. allowversion=0;
  652. if(!bg)
  653. fprintf(stderr,"%sAttempting to connect to: %s:%d.\n",PMT,host,port);
  654. sock=socket(PF_INET6,SOCK_STREAM,0);
  655. if(sock<0){
  656. if(!bg)
  657. printe("socket error",0);
  658. serr=1;
  659. }
  660. bzero(&irc,sizeof(struct sockaddr_in6));
  661. irc.sin6_family=AF_INET6;
  662. if(isvhost){
  663. if (inet_pton(AF_INET6, vhost, &(irc.sin6_addr)) <= 0) {
  664. if ((he = getipnodebyname(vhost, AF_INET6, AI_DEFAULT, &err)) == NULL) {
  665. if(!bg&&!serr)
  666. printe("couldn't resolve the provided host, trying any.",0);
  667. irc.sin6_addr=in6addr_any;
  668. }
  669. else
  670. memcpy((char *)&irc.sin6_addr,(char *)he->h_addr,he->h_length);
  671. }
  672. if(bind(sock,(struct sockaddr*)&irc,sizeof(struct sockaddr_in6))){
  673. if(!bg&&!serr)
  674. printe("binding name to socket, trying any.",0);
  675. bzero(&irc,sizeof(struct sockaddr_in6));
  676. irc.sin6_len=sizeof(irc);
  677. irc.sin6_family=AF_INET6;
  678. irc.sin6_addr=in6addr_any;
  679. if(bind(sock,(struct sockaddr*)&irc,sizeof(struct sockaddr_in6))){
  680. if(!bg&&!serr)
  681. printe("binding any name to socket.",0);
  682. serr=1;
  683. }
  684. }
  685. }
  686. bzero(&irc,sizeof(struct sockaddr_in6));
  687. irc.sin6_len=sizeof(irc);
  688. irc.sin6_family=AF_INET6;
  689. irc.sin6_port=htons(port);
  690. if (inet_pton(AF_INET6, host, &(irc.sin6_addr)) <= 0) {
  691. if ((he = getipnodebyname(host, AF_INET6, AI_DEFAULT, &err)) == NULL) {
  692. if(!bg&&!serr)
  693. printe("couldn't resolve the provided host",0);
  694. serr=1;
  695. }
  696. else
  697. memcpy((char *)&irc.sin6_addr,(char *)he->h_addr,he->h_length);
  698. }
  699. if(connect(sock,(struct sockaddr *)&irc,sizeof(irc))){
  700. if(!bg&&!serr)
  701. printe("couldn't connect to the provided host",0);
  702. serr=1;
  703. }
  704. if(!serr){
  705. if(isnick){
  706. if(!(nickname=(char *)malloc(strlen(basenickname)+1)))
  707. printe("main(): allocating memory",1);
  708. strcpy(nickname,basenickname);
  709. }
  710. else
  711. rand_nickname(name_length);
  712. strtok(username," ");
  713. sprintf(swrite,"\nUSER %.128s %.128s %.128s :%.128s\nNICK %.128s\n",username,
  714. username,username,realname,nickname);
  715. write(sock,swrite,sizeof(swrite));
  716. while(1){
  717. bzero(sread,sizeof(sread));
  718. bzero(swrite,sizeof(swrite));
  719. if(!read(sock,sread,sizeof(sread))){
  720. if(!bg){
  721. if(first_ison&&!nodisplay)
  722. fprintf(stderr,"\n");
  723. fprintf(stderr,"%sSession closed from: %s:%d.\n",PMT,host,port);
  724. }
  725. break;
  726. }
  727. for(i=0;i<strlen(sread);i++){
  728. if(sread[i]==0x0A){
  729. sread_line[j]=0x0;
  730. parameter(sread_line,0);
  731. if(!strcmp(parm,"PING")){
  732. parameter(sread_line,1);
  733. snprintf(swrite,sizeof(swrite),"\nPONG %s\n",parm);
  734. write(sock,swrite,sizeof(swrite));
  735. }
  736. bzero(active_nickname,sizeof(active_nickname));
  737. strncpy(active_nickname,sread_line,sizeof(active_nickname));
  738. strtok(active_nickname,"!");
  739. for(l=1;l<strlen(active_nickname);l++)
  740. active_nickname[(l-1)]=active_nickname[l];
  741. active_nickname[l-1]=0x0;
  742. parameter(sread_line,1);
  743. if(!stop){
  744. if(!strcmp(parm,"303")){
  745. if(!first_ison){
  746. first_ison=1;
  747. if(!bg&&!debug)
  748. if(nodisplay)
  749. fprintf(stderr,"%sAttempting to obtain supplied names...\n",PMT);
  750. else
  751. fprintf(stderr,"(. = in use, ! = free, % = failed, * = success%s): ",
  752. ispasswd?", @ = killed":"");
  753. }
  754. parameter(sread_line,3);
  755. if(strlen(parm)==1){
  756. ondelay(1);
  757. snprintf(swrite,sizeof(swrite),"\nNICK %s\n",names[(k-1)]);
  758. write(sock,swrite,sizeof(swrite));
  759. if(!bg&&!debug&&first_ison&&!nodisplay)
  760. fprintf(stderr,"!(%s is free)",names[(k-1)]);
  761. }
  762. else{
  763. if(k>tot_n)
  764. k=0;
  765. snprintf(swrite,sizeof(swrite),"\nISON %s\n",names[k++]);
  766. write(sock,swrite,sizeof(swrite));
  767. if(!bg&&!debug&&first_ison&&!nodisplay)
  768. fprintf(stderr,".");
  769. ondelay(0);
  770. }
  771. }
  772. if(!strcmp(parm,"431")||!strcmp(parm,"432")||!strcmp(parm,"433")){
  773. if(!first_ison){
  774. rand_nickname(name_length);
  775. if(!bg)
  776. fprintf(stderr,"%sFailed setting nickname, trying random. (%s)\n",
  777. PMT,nickname);
  778. snprintf(swrite,sizeof(swrite),"\nNICK %s\n",nickname);
  779. write(sock,swrite,sizeof(swrite));
  780. }
  781. if(start){
  782. if(!bg&&!debug&&first_ison&&!nodisplay)
  783. fprintf(stderr,"%(set failed)");
  784. if(k>tot_n)
  785. k=0;
  786. snprintf(swrite,sizeof(swrite),"\nISON %s\n",names[k++]);
  787. write(sock,swrite,sizeof(swrite));
  788. ondelay(0);
  789. }
  790. }
  791. if(!strcmp(parm,"NICK")){
  792. if(!strcmp(active_nickname,nickname)){
  793. parameter(sread_line,2);
  794. if(!(nickname=(char *)malloc(strlen(parm)+1)))
  795. printe("irc_parse(): allocating memory",1);
  796. strcpy(nickname,parm);
  797. for(m=1;m<strlen(nickname);m++)
  798. nickname[(m-1)]=nickname[m];
  799. nickname[(m-1)]=0x0;
  800. if(!bg&&!debug&&first_ison)
  801. if(!nodisplay)
  802. fprintf(stderr,"*(%s set, now idle)",nickname);
  803. else
  804. fprintf(stderr,"%sObtained nickname: %s.\n",PMT,nickname);
  805. stop=1;
  806. }
  807. }
  808. if(!strcmp(parm,"QUIT")&&ischannel&&!noquit){
  809. for(m=0;m<=tot_n;m++)
  810. if(!(strcmp(active_nickname,names[m]))){
  811. ondelay(1);
  812. snprintf(swrite,sizeof(swrite),"\nNICK %s\n",names[m]);
  813. write(sock,swrite,sizeof(swrite));
  814. if(!bg&&!debug&&first_ison&&!nodisplay)
  815. fprintf(stderr,"!(%s is free, quit in %s)",names[m],channel);
  816. }
  817. }
  818. }
  819. if(!strcmp(parm,"001")){
  820. if(!bg)
  821. fprintf(stderr,"%sConnected successfully to: %s:%d.\n",PMT,host,port);
  822. parameter(sread_line,2);
  823. if(!(nickname=(char *)malloc(strlen(parm)+1)))
  824. printe("irc_parse(): allocating memory",1);
  825. strcpy(nickname,parm);
  826. if(!bg)
  827. fprintf(stderr,"%sConnected with nickname: %s.\n",PMT,nickname);
  828. if(ischannel){
  829. snprintf(swrite,sizeof(swrite),"\nJOIN %s :%s\n",channel,channel_key);
  830. write(sock,swrite,sizeof(swrite));
  831. }
  832. if(k>tot_n)
  833. k=0;
  834. snprintf(swrite,sizeof(swrite),"\nISON %s\n",names[k++]);
  835. write(sock,swrite,sizeof(swrite));
  836. start=1;
  837. ondelay(0);
  838. }
  839. if(!strcmp(parm,"366")){
  840. parameter(sread_line,3);
  841. if(!bg&&!first_ison)
  842. fprintf(stderr,"%sJoined channel: %s.\n",PMT,parm);
  843. }
  844. if((!strcmp(parm,"403")||!strcmp(parm,"471")||!strcmp(parm,"472")
  845. ||!strcmp(parm,"473")||!strcmp(parm,"474")||!strcmp(parm,"475"))&&!bg
  846. &&!first_ison){
  847. parameter(sread_line,3);
  848. fprintf(stderr,"%sFailed joining channel: %s.\n",PMT,parm);
  849. }
  850. if(!strcmp(parm,"461")){
  851. make_userinfo();
  852. sprintf(swrite,"\nUSER %.128s %.128s %.128s :%.128s\nNICK %.128s\n",
  853. username,username,username,realname,nickname);
  854. write(sock,swrite,sizeof(swrite));
  855. }
  856. if(!strcmp(parm,"PRIVMSG")){
  857. parameter(sread_line,3);
  858. if(isversion&&!allowversion&&stop&&!strcasecmp(":\x01VERSION\x01",parm)){
  859. snprintf(swrite,sizeof(swrite),"\nNOTICE %s :%cVERSION %s%c\n",
  860. active_nickname,0x01,vreply,0x01);
  861. write(sock,swrite,sizeof(swrite));
  862. allowversion=1;
  863. signal(SIGALRM,version_fprot);
  864. alarm(VERSION_FPROT);
  865. }
  866. else if(ispasswd){
  867. if(!(tmppassword=(char *)malloc(strlen(parm)+1)))
  868. printe("irc_parse(): allocating memory",1);
  869. strcpy(tmppassword,parm);
  870. for(m=1;m<strlen(tmppassword);m++)
  871. tmppassword[(m-1)]=tmppassword[m];
  872. tmppassword[(m-1)]=0x0;
  873. if((ispasswd==2&&!strcmp((char *)crypt(tmppassword,password),password))
  874. ||(ispasswd==1&&!strcmp(tmppassword,password))){
  875. if(!bg&&!debug&&first_ison&&!nodisplay)
  876. fprintf(stderr,"@(%s sent kill passwd, killing with %ds delay)",
  877. active_nickname,killd);
  878. shutdown(sock,2);
  879. stop=1;
  880. sleep(killd);
  881. }
  882. free(tmppassword);
  883. }
  884. }
  885. if(!strcmp(parm,"KICK")&&ischannel){
  886. parameter(sread_line,2);
  887. if(!strcmp(parm,channel)){
  888. parameter(sread_line,3);
  889. if(!strcmp(parm,nickname)){
  890. snprintf(swrite,sizeof(swrite),"\nJOIN %s :%s\n",channel,channel_key);
  891. write(sock,swrite,sizeof(swrite));
  892. }
  893. }
  894. }
  895. if(!strcmp(parm,"INVITE")&&ischannel){
  896. parameter(sread_line,3);
  897. if(!(tmpchannel=(char *)malloc(strlen(parm)+1)))
  898. printe("irc_parse(): allocating memory",1);
  899. strcpy(tmpchannel,parm);
  900. for(m=1;m<strlen(tmpchannel);m++)
  901. tmpchannel[(m-1)]=tmpchannel[m];
  902. tmpchannel[(m-1)]=0x0;
  903. if(!strcmp(tmpchannel,channel)){
  904. snprintf(swrite,sizeof(swrite),"\nJOIN %s :%s\n",channel,channel_key);
  905. write(sock,swrite,sizeof(swrite));
  906. }
  907. free(tmpchannel);
  908. }
  909. bzero(swrite,sizeof(swrite));
  910. parameter(sread_line,1);
  911. if(!bg&&debug&&strcmp(parm,"421"))
  912. fprintf(stderr,"%s%s\n",DPMT,sread_line);
  913. bzero(sread_line,sizeof(sread_line));
  914. j=0;
  915. }
  916. else if(sread[i]!=0x0D)
  917. sread_line[j++]=sread[i];
  918. }
  919. }
  920. }
  921. else if(!bg){
  922. if(first_ison&&!nodisplay)
  923. fprintf(stderr,"\n");
  924. fprintf(stderr,"\n%sSession closed from: %s:%d.\n",PMT,host,port);
  925. }
  926. if(sock)
  927. close(sock);
  928. return(0);
  929. }
  930. int printe(char *err,int quit){
  931. if(isbg<1)
  932. fprintf(stderr,"%s%s.\n",EPMT,err);
  933. if(quit)
  934. exit(1);
  935. }
  936. int ondelay(int ext){
  937. if(ext)
  938. if(delay2)
  939. usleep(delay2);
  940. else
  941. if(delay)
  942. usleep(delay);
  943. return(0);
  944. }
  945. int usage(char *prog){
  946. fprintf(stderr,"Usage: %s <-s file> <-f file> [options...]\n\n"
  947. " -s <file>%cserver file list. [standard per line format] (required)\n"
  948. " -f <file>%cname file list. [standard per line format] (required)\n"
  949. " -p <numeric>%cwill use an alternate ircd port to connect to.\n"
  950. " -u <argument>%cwill use an alternate user name. [non-passwd entry]\n"
  951. " -r <argument>%cwill use an alternate real name. [non-passwd entry]\n"
  952. " -c <argument>%cwill join the provided channel.\n"
  953. " -k <argument>%cwill apply a key to join the channel. [for the -c option]\n"
  954. " -n <argument>%cwill use a non-random nickname to start with.\n"
  955. " -d%c%cwill use debug mode. [show server data]\n"
  956. " -b%c%cwill place orignick into the background. [with errors ignored]\n"
  957. " -S <numeric>%cwill delay responding with provided time. [1000000=1s]\n"
  958. " -L <numeric>%cis like -S, but used for special situations. [3000000=3s]\n"
  959. " -P <file>%cfile to place the pid of the bg process. [for the -b option]\n"
  960. " -K <argument>%cwill use a kill passwd to reset the bot via irc.\n"
  961. " -E <argument>%cis like -K, but uses an encrypted password instead.\n"
  962. " -M <argument>%cwill encrypt the argument as a password and exit.\n"
  963. " -D <numeric>%cwill use an alternate remote kill delay time.\n"
  964. " -H <argument>%cwill use the provided argument as a virtual host.\n"
  965. " -V <argument>%cwill use the provided argument as a version reply.\n"
  966. " -Z%c%cwill ignore remote version requests.\n"
  967. " -z%c%cwill disable on quit nickname grabs. [if in channel]\n"
  968. " -N%c%cwill disable local status showing on the bot.\n"
  969. " -e%c%cwill use extended nickname length. [servers with >9 nick limit]\n"
  970. " -v%c%cwill display version information and exit.\n"
  971. "\nAuthor: vade79@realhalo.org, realhalo.org. [ihadnihn]\n",prog,0x9,0x9,0x9,
  972. 0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,
  973. 0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9);
  974. exit(0);
  975. }
Add Comment
Please, Sign In to add comment