Code afférent au projet Kouglof 2 de l'E2L
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1061 lines
27 KiB

  1. /*******************************************************************
  2. Copyright (C) 2011-2024 Patrick H. E. Foubet - S.E.R.I.A.N.E.
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or any
  6. later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>
  13. *******************************************************************/
  14. /*
  15. ############################################################
  16. # Projet Kouglof 2 de l'Ecole du Logiciel Libre d'Ivry : #
  17. ############################################################
  18. octave.c : outil pour scanner l'interface reseau afin d'analyser les sites
  19. auxquels les applications veulent se connecter.
  20. A utiliser avec le fichier auth1.txt pour stopper les connexions non voulues
  21. Tous les details sur le site :
  22. https://e2li.org -> menu : Projet Prosecco.
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <sys/types.h>
  27. #include <unistd.h>
  28. #include <signal.h>
  29. #include <fcntl.h>
  30. #include <readline/readline.h>
  31. #include <readline/history.h>
  32. #include <sys/wait.h>
  33. #include <string.h>
  34. #include <syslog.h>
  35. #include <time.h>
  36. #include <arpa/inet.h>
  37. #include <pthread.h>
  38. #define Version "1.00"
  39. #define F_GETPIPE_SZ 1032
  40. #define F_SETPIPE_SZ 1031
  41. static int RUN=1, REQ=0, ENDT=0, REPR=0, p1[2],Trace=0;
  42. static pid_t pid;
  43. static char * NPROG, *IFACE=NULL;
  44. #define DELAYR 20 /* delai avant relance auto */
  45. void interup (int S)
  46. {
  47. if (S==SIGINT) {
  48. write(p1[1],"\n",1);
  49. REQ=1; return;
  50. }
  51. if (S==SIGCHLD) {
  52. if (waitpid(pid,NULL,WNOHANG) == pid) {
  53. ENDT=1;
  54. write(p1[1],"\n",1);
  55. }
  56. return;
  57. }
  58. fprintf(stderr,"Reçu signal %d !!??\n",S);
  59. }
  60. /* ### les niveaux de trace */
  61. #define TMIN 0
  62. #define TMAX 3
  63. #define T1 Trace > 0
  64. #define T2 Trace > 1
  65. #define T3 Trace > 2
  66. /* #### les fonctions adresses IPv4 */
  67. int isIPv4(char *a)
  68. {
  69. struct in_addr S;
  70. int r;
  71. if ((r = inet_pton(AF_INET,a, (void *)&S)) <= 0) return 0;
  72. return 1;
  73. }
  74. int isCidr(char*r)
  75. {
  76. char buf[20], *sn;
  77. int n;
  78. if (strlen(r)>18) return 0;
  79. strcpy(buf,r);
  80. if ((sn=strstr(buf,"/")) == NULL) return 0;
  81. *sn = '\0';
  82. if (!isIPv4(buf)) return 0;
  83. n = atoi(sn+1);
  84. if (n>32) return 0;
  85. return n;
  86. }
  87. int isSousRes(char*r, char *a)
  88. {
  89. struct in_addr Sa, Sr, Sm;
  90. int n, m1,m2,m3,m4, m;
  91. char buf[20],smasq[16],*sn;
  92. if (!isCidr(r)) return 0;
  93. if (!isIPv4(a)) return 0;
  94. strcpy(buf,r);
  95. if ((sn=strstr(buf,"/")) == NULL) return 0;
  96. *sn = '\0';
  97. n = atoi(sn+1);
  98. /* calcul du masq */
  99. m=n;
  100. if (m>7) { m1=255; m-=8;
  101. } else { m1=0;
  102. while (m>=0) m1 |= 0x80 >> --m;
  103. }
  104. if (m>7) { m2=255; m-=8;
  105. } else { m2=0;
  106. while (m>=0) m2 |= 0x80 >> --m;
  107. }
  108. if (m>7) { m3=255; m-=8;
  109. } else { m3=0;
  110. while (m>=0) m3 |= 0x80 >> --m;
  111. }
  112. if (m>7) { m4=255; m-=8;
  113. } else { m4=0;
  114. while (m>=0) m4 |= 0x80 >> --m;
  115. }
  116. sprintf(smasq,"%d.%d.%d.%d",m1,m2,m3,m4);
  117. inet_pton(AF_INET,smasq, (void *)&Sm);
  118. inet_pton(AF_INET,a, (void *)&Sa);
  119. inet_pton(AF_INET,buf, (void *)&Sr);
  120. if ((Sr.s_addr & Sm.s_addr) == (Sa.s_addr & Sm.s_addr)) return 1;
  121. return 0;
  122. }
  123. /* #### gestion dynamique des CIDR */
  124. #define NBC 100 /* nb de CIDR */
  125. char* Tcidr[NBC];
  126. int iC=0;
  127. int bloqueIP(char*);
  128. int addCidr(char * c)
  129. {
  130. int i=iC;
  131. if (i==NBC) return i;
  132. Tcidr[i] = (char*)malloc(strlen(c)+1);
  133. strcpy(Tcidr[i],c);
  134. iC++;
  135. bloqueIP(c);
  136. return i;
  137. }
  138. void delCidr(char * c)
  139. {
  140. int i;
  141. for (i=0; i<iC; i++)
  142. if (strcmp(c,Tcidr[i]) == 0) {
  143. iC--;
  144. if (iC == i) return;
  145. if (iC > 0) Tcidr[i] = Tcidr[iC];
  146. return;
  147. }
  148. }
  149. int isAddrInCidr(char * a, int M)
  150. {
  151. int i;
  152. for(i=0;i<iC;i++) {
  153. if (isSousRes(Tcidr[i],a)) {
  154. if (M) syslog(LOG_INFO,"CIDR %s contient %s !",Tcidr[i],a);
  155. return 1;
  156. }
  157. }
  158. return 0;
  159. }
  160. void validCidr(void)
  161. {
  162. int i,j;
  163. char a[20],*p, *g, *w;
  164. for(i=0;i<iC;i++)
  165. for (j=i+1;j<iC;j++) {
  166. if (isCidr(Tcidr[i]) < isCidr(Tcidr[j])) {
  167. p=Tcidr[i]; g=Tcidr[j];
  168. } else {
  169. p=Tcidr[j]; g=Tcidr[i];
  170. }
  171. strcpy(a,g);
  172. w = strstr(a,"/");
  173. *w = '\0';
  174. w++;
  175. if (isSousRes(p,a)) {
  176. if (T3) printf("T3: %s contient %s (%s)\n",p,a,w);
  177. delCidr(g);
  178. }
  179. }
  180. }
  181. void listCidr(void)
  182. {
  183. int i;
  184. printf("CIDR : %d\n",iC);
  185. for (i=0; i<iC; i++) printf("\t%s\n", Tcidr[i]);
  186. }
  187. /* ### gestion des listes */
  188. #define NBAll 500
  189. #define NBDen 300
  190. char * Allow[NBAll];
  191. char * Deny[NBDen];
  192. int iAll=0, iDen=0;
  193. int isDeny(char*u)
  194. {
  195. char *su;
  196. int i, tu, t;
  197. for (i=0;i<iDen;i++) {
  198. tu = strlen(u);
  199. t = strlen(Deny[i]);
  200. if (tu < t) continue;
  201. su = u + tu - t;;
  202. if (strcmp(su,Deny[i]) == 0) {
  203. if (su==u) return 1;
  204. if (*(su-1)=='.') return 1;
  205. }
  206. }
  207. for (i=0;i<iAll;i++) {
  208. tu = strlen(u);
  209. t = strlen(Allow[i]);
  210. if (tu < t) continue;
  211. su = u + tu - t;
  212. if (strcmp(su,Allow[i]) == 0) {
  213. if (*(Allow[i]) == '.') return 0;
  214. if (su==u) return 0;
  215. if (*(su-1)=='.') return 0;
  216. }
  217. }
  218. return 1; /* deny par defaut */
  219. }
  220. void listeAllow(void)
  221. {
  222. int i;
  223. printf("Allow : %d\n",iAll);
  224. for (i=0;i<iAll;i++) printf("\t%s\n",Allow[i]);
  225. }
  226. void listeDeny(void)
  227. {
  228. int i;
  229. printf("Deny : %d\n",iDen);
  230. for (i=0;i<iDen;i++) printf("\t%s\n",Deny[i]);
  231. }
  232. void dejaLa(char * e)
  233. {
  234. printf("%s est deja dans la liste !\n",e);
  235. }
  236. int dejaAllow(char *e)
  237. {
  238. int i;
  239. for (i=0;i<iAll;i++) {
  240. if (strlen(e) != strlen(Allow[i])) continue;
  241. if (strcmp(e,Allow[i])==0) {
  242. dejaLa(e); return 1;
  243. }
  244. }
  245. return 0;
  246. }
  247. int dejaDeny(char *e)
  248. {
  249. int i;
  250. for (i=0;i<iDen;i++) {
  251. if (strlen(e) != strlen(Deny[i])) continue;
  252. if (strcmp(e,Deny[i])==0) {
  253. dejaLa(e); return 1;
  254. }
  255. }
  256. return 0;
  257. }
  258. void recaplistes(void)
  259. {
  260. listeDeny();
  261. listeAllow();
  262. }
  263. int litligne(char * line)
  264. {
  265. char *w, **S;
  266. void * M;
  267. int t;
  268. if (*line == '#') return 1;
  269. if ((w=strstr(line, "\n")) != NULL) *w = '\0';
  270. w=line;
  271. if (*w == '-') w++;
  272. t=strlen(w);
  273. if (t==0) return 1;
  274. if (isCidr(w)) { /* test si CIDR */
  275. addCidr(w);
  276. return 1;
  277. }
  278. if (*line == '-') {
  279. if (iDen == NBDen) return 0;
  280. if (dejaDeny(w)) return 0;
  281. S = &Deny[iDen];
  282. iDen++;
  283. } else {
  284. if (iAll == NBAll) return 0;
  285. if (dejaAllow(w)) return 0;
  286. S = &Allow[iAll];
  287. iAll++;
  288. }
  289. if ((M = malloc(t+1)) == NULL) {
  290. perror("malloc"); return 0;
  291. }
  292. *S=(char*)M;
  293. strcpy(*S,w);
  294. return 1;
  295. }
  296. void lectliste(char *f)
  297. {
  298. FILE * fd;
  299. char *line = NULL;
  300. size_t ll = 0;
  301. int n;
  302. if ((fd = fopen(f,"r")) == NULL) {
  303. perror(f); return;
  304. }
  305. while ((n = getline(&line, &ll, fd)) > 0) {
  306. if (!litligne(line)) {
  307. if (T1) printf("T1: Erreur param. = %s\n",line);
  308. }
  309. }
  310. free(line);
  311. fclose(fd);
  312. validCidr();
  313. if (T1) listCidr();
  314. }
  315. /* ### gestion dynamique des elts */
  316. #define NBT 1000 /* nb d'elts */
  317. int Tno[NBT];
  318. int Trv[NBT];
  319. char* Turl[NBT];
  320. int iT=0, NbElt=0, MaxElt=0;
  321. int addElt(int n, char * u)
  322. {
  323. int i=iT;
  324. if (i == NBT) return i;
  325. Tno[i]=n;
  326. Trv[i]=0;
  327. Turl[i] = (char*)malloc(strlen(u)+1);
  328. strcpy(Turl[i],u);
  329. iT++;
  330. NbElt++;
  331. if (NbElt > MaxElt) MaxElt=NbElt;
  332. return i;
  333. }
  334. int isElt(int n)
  335. {
  336. int i;
  337. for (i=0; i<iT; i++) if (n==Tno[i]) return i;
  338. return -1;
  339. }
  340. void delIElt(int i)
  341. {
  342. if (i>=iT) return;
  343. if (T3) printf("T3: Del %d : %s \n",Tno[i],Turl[i]);
  344. iT--;
  345. if (iT == i) return;
  346. if (iT > 0) {
  347. Tno[i] = Tno[iT];
  348. Turl[i] = Turl[iT];
  349. Trv[i] = Trv[iT];
  350. }
  351. return;
  352. }
  353. void delElt(int n)
  354. {
  355. int i;
  356. for (i=0; i<iT; i++)
  357. if (n==Tno[i]) {
  358. delIElt(i);
  359. return;
  360. }
  361. }
  362. int markElt(int i, int v)
  363. {
  364. if (Trv[i] & v) return 0;
  365. Trv[i] |= v;
  366. return 1;
  367. }
  368. void listElt(void)
  369. {
  370. int i;
  371. for (i=0; i<iT; i++)
  372. printf("%d : %s (%d)\n",Tno[i], Turl[i], Trv[i]);
  373. }
  374. int exeCom(char * comm) /* on se reserve le droit de modifier */
  375. {
  376. char b[120];
  377. sprintf(b,"%s >/dev/null 2>&1",comm);
  378. return system(b);
  379. }
  380. /* ### fct de MAJ iptables */
  381. static char * IPT = "iptables";
  382. static char * IP6T = "ip6tables";
  383. static char * MYCH = "valide4";
  384. static char * OUTP = "OUTPUT";
  385. static char * MNO = "REJECT";
  386. static char * MOK = "ACCEPT";
  387. int initIPT(void)
  388. {
  389. int i=0;
  390. char b[90];
  391. if (REPR) return 0;
  392. sprintf(b,"%s -F",IPT);
  393. i += exeCom(b);
  394. sprintf(b,"%s -F",IP6T);
  395. i += exeCom(b);
  396. sprintf(b,"%s -L %s -n",IPT,MYCH);
  397. if (exeCom(b)) {
  398. sprintf(b,"%s -N %s",IPT,MYCH);
  399. i += exeCom(b);
  400. }
  401. sprintf(b,"%s -A %s -j %s",IPT,OUTP,MYCH);
  402. i += exeCom(b);
  403. return i;
  404. }
  405. int isPresentIP(char * comm, char * ip, char * chain)
  406. {
  407. char buf[100];
  408. sprintf(buf,"%s -L %s -n|grep %s",comm,chain,ip);
  409. if (exeCom(buf) == 0) return 1;
  410. return 0;
  411. }
  412. int retireChain(char * comm, char * ip, char * chain, char * jump)
  413. {
  414. char buf[100];
  415. sprintf(buf,"%s -D %s -d %s -j %s",comm,chain, ip, jump);
  416. return exeCom(buf);
  417. }
  418. int ajouteChain(char * comm, char * ip, char * chain, char * jump)
  419. {
  420. char buf[100];
  421. sprintf(buf,"%s -A %s -d %s -j %s",comm,chain, ip, jump);
  422. return exeCom(buf);
  423. }
  424. int bloqueIP(char* ip)
  425. {
  426. if (isAddrInCidr(ip,0)) return 0;
  427. if (isPresentIP(IPT,ip,OUTP)) return 0;
  428. return ajouteChain(IPT,ip,OUTP,MNO);
  429. }
  430. int debloqueIP(char* ip, char * url)
  431. {
  432. if (url != NULL) syslog(LOG_INFO,"%s=%s ACCEPT",url,ip);
  433. return ajouteChain(IPT,ip,MYCH,MOK);
  434. }
  435. int rebloqueIP(char* ip)
  436. {
  437. return retireChain(IPT,ip,MYCH,MOK);
  438. }
  439. void dropIP(char * l)
  440. {
  441. char *s,*d=l;
  442. while ((s=strstr(d, "A ")) != NULL) {
  443. s+=2;
  444. if ((d=strstr(s+2, ",")) == NULL) break;
  445. *d = '\0';
  446. d++;
  447. bloqueIP(s);
  448. }
  449. bloqueIP(s);
  450. }
  451. int verifIPOk(char * l, char * url)
  452. {
  453. char *s,*d=l;
  454. while ((s=strstr(d, "A ")) != NULL) {
  455. s+=2;
  456. if ((d=strstr(s+2, ",")) == NULL) break;
  457. *d = '\0';
  458. d++;
  459. if (isPresentIP(IPT,s,MYCH)) continue;
  460. if (isAddrInCidr(s,1)) debloqueIP(s,url);
  461. }
  462. if (isPresentIP(IPT,s,MYCH)) return 1;
  463. if (isAddrInCidr(s,1)) return(debloqueIP(s,url));
  464. return 1;
  465. }
  466. int dropIP6(char * l)
  467. {
  468. char *s,*d=l;
  469. while ((s=strstr(d, "A ")) != NULL) {
  470. s+=2;
  471. if ((d=strstr(s+2, ",")) == NULL) break;
  472. *d = '\0';
  473. d++;
  474. if (isPresentIP(IP6T,s,OUTP)) continue;
  475. ajouteChain(IP6T,s,OUTP,MNO);
  476. }
  477. if (isPresentIP(IP6T,s,OUTP)) return 1;
  478. ajouteChain(IP6T,s,OUTP,MNO);
  479. return 1;
  480. }
  481. /* tache de commande et periodiques */
  482. #define t0 (time_t)0
  483. time_t tim1=t0;
  484. void tachePer1(void) /* vide les elts toutes les 30 secondes */
  485. {
  486. static time_t tim0=t0, tw;
  487. int i, v;
  488. tw = time(NULL);
  489. if ((tw - tim0) < 30) {
  490. if (T3) printf ("T3: tache1 passe %s",ctime(&tw));
  491. return;
  492. }
  493. if (T3) printf ("T3: tache1 exec %s",ctime(&tw));
  494. tim1 = time(NULL);
  495. v = (tim1 - tim0) / 30;
  496. if (tim0 != t0) {
  497. for (i=iT-1; i>=0; i--) {
  498. if ((Trv[i]&0x6) == 6) delIElt(i); // IPv4 + IPV6
  499. else { Trv[i] += 8*v;
  500. if (Trv[i] > 80) delIElt(i); // On laisse 5 min.
  501. }
  502. }
  503. }
  504. tim0 = time(NULL);
  505. return;
  506. }
  507. void ajoutParam(char * ficp, char * param)
  508. {
  509. FILE * fw;
  510. fw = fopen(ficp,"a");
  511. fwrite(param,strlen(param),1,fw);
  512. fwrite("\n",1,1,fw);
  513. fclose(fw);
  514. }
  515. static int NBin=0, NBout=0;
  516. void prInOut(void)
  517. {
  518. printf("%d echanges DNS : %d requetes, %d reponses.\n",NBout+NBin,NBout,NBin);
  519. }
  520. int printQ(char * q)
  521. {
  522. char *rep=NULL;
  523. size_t lr = 0;
  524. int n;
  525. while (1) {
  526. printf("Voulez-vous %s ?\n Taper O (OUI) ou N (NON) :\n",q);
  527. if ((n = getline(&rep, &lr, stdin)) != 2) continue;
  528. if (*rep == 'O') return 1;
  529. if (*rep == 'N') return 0;
  530. }
  531. }
  532. void pr_encours(void)
  533. {
  534. printf(" ...\r"); fflush(stdout);
  535. }
  536. #define SUNIC "|sort|uniq"
  537. #define CHLOG "/var/log/user.log"
  538. #define CHLOGREP "/var/log/user.log|grep "
  539. #define CUT6 "|cut -d' ' -f6"
  540. #define CUT7S "|cut -d' ' -f7-"
  541. #define FHISTO ".octave_history"
  542. #define AWK5 "|awk '{ print $5}'"
  543. #define AWK4 "|awk '{ print $4}'"
  544. #define DREJ "^REJECT "
  545. void * fct_com(void * p)
  546. {
  547. int REQ=1;
  548. char *cmd = NULL, *fauth, com[100];
  549. int n2;
  550. pid_t pid;
  551. fauth = (char*)p;
  552. pid = getpid();
  553. read_history(FHISTO);
  554. if (REPR) system("reset");
  555. while (REQ) {
  556. if (kill(pid,SIGUSR1) < 0) { /* verif processus acquisition */
  557. ENDT=1;
  558. write(p1[1],"\n",1);
  559. }
  560. free(cmd);
  561. cmd = readline("O-> ");
  562. if ((n2 = strlen(cmd)) > 0) {
  563. write(p1[1],"\n",1);
  564. add_history(cmd);
  565. switch (*cmd) {
  566. case '+' :
  567. if (*(cmd+1) != '\0') {
  568. if (litligne(cmd+1)) { /* ajout au fichier fauth */
  569. if (debloqueIP(cmd+1,NULL)) printf("Element non valable !\n");
  570. else {
  571. if (printQ("ajouter au fichier parametres"))
  572. ajoutParam(fauth,cmd+1);
  573. listeAllow();
  574. }
  575. } else printf("Erreur ajout param. !\n");
  576. } else listeAllow();
  577. break;
  578. case '-' :
  579. if (*(cmd+1) != '\0') {
  580. if (litligne(cmd)) { /* ajout au fichier fauth */
  581. if (rebloqueIP(cmd+1)) printf("Element non valable !\n");
  582. else {
  583. if (printQ("ajouter au fichier parametres"))
  584. ajoutParam(fauth,cmd);
  585. listeDeny();
  586. }
  587. } else printf("Erreur ajout param. !\n");
  588. } else listeDeny();
  589. break;
  590. case 'l' :
  591. listElt();
  592. printf("%sReste %d elts (Max. %d)!\n",ctime(&tim1),iT,MaxElt);
  593. prInOut();
  594. break;
  595. case 't' :
  596. if (*(cmd+1) != '\0') {
  597. if ((cmd[1] == '+') || (cmd[1] == '-')) {
  598. if ((cmd[1] == '+') && (Trace < TMAX)) Trace++;
  599. else {
  600. if ((cmd[1] == '-') && (Trace > TMIN)) Trace--;
  601. else printf("Erreur: niveau dans [%d, %d].\n",TMIN,TMAX);
  602. }
  603. } else printf("Erreur: Utiliser t+ ou t- !\n");
  604. }
  605. printf("Trace niveau %d\n",Trace);
  606. break;
  607. case 'a' :
  608. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  609. sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* ok",CHLOG,CUT6,SUNIC);
  610. system(com);
  611. break;
  612. case 'i' :
  613. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  614. sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* DENY",CHLOG,CUT6,SUNIC);
  615. system(com);
  616. break;
  617. case 'e' :
  618. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  619. sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* ACCEPT",CHLOG,CUT6,SUNIC);
  620. system(com);
  621. break;
  622. case 'E' :
  623. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  624. sprintf(com,"grep '%s\\[%d\\]%s' %s",NPROG,pid,".*ERR: ",CHLOG);
  625. system(com);
  626. break;
  627. case 'L' :
  628. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  629. sprintf(com,"grep '%s\\[%d\\]' %s%s",NPROG,pid,CHLOGREP,"-v 'Re[pq]. '");
  630. system(com);
  631. break;
  632. case 'T' :
  633. if (*(cmd+1) != '\0')
  634. sprintf(com,"grep '%s\\[%d\\].*%s' %s%s",NPROG,pid,cmd+1,CHLOGREP," 'Re[pq]. '");
  635. else
  636. sprintf(com,"grep '%s\\[%d\\]' %s%s",NPROG,pid,CHLOGREP," 'Re[pq]. '");
  637. system(com);
  638. prInOut();
  639. break;
  640. case '>' :
  641. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  642. sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,CHLOGREP," 'Req. '",CUT7S,SUNIC);
  643. system(com);
  644. prInOut();
  645. break;
  646. case '<' :
  647. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  648. sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,CHLOGREP," 'Rep. '",CUT7S,SUNIC);
  649. system(com);
  650. prInOut();
  651. break;
  652. case 'r' :
  653. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  654. sprintf(com,"%s -L|grep %s%s%s",IPT,DREJ,AWK5,SUNIC);
  655. pr_encours();
  656. system(com);
  657. break;
  658. case 'R' :
  659. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  660. sprintf(com,"%s -L|grep %s%s%s",IP6T,DREJ,AWK4,SUNIC);
  661. pr_encours();
  662. system(com);
  663. break;
  664. case 'S' :
  665. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  666. RUN = 0;
  667. REQ = 0;
  668. write(p1[1],"\n",1);
  669. break;
  670. case 'V' :
  671. if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
  672. printf("Version %s\n",Version);
  673. prInOut();
  674. break;
  675. case ' ' :
  676. if (*(cmd+1) != '\0') system(cmd+1);
  677. break;
  678. default :
  679. printf("+url\t: Allow (autoriser une Url)\n");
  680. printf("-url\t: Deny (interdire une Url)\n");
  681. printf("a\t: Autorisations suivant analyse\n");
  682. printf("i\t: Interdictions suivant analyse\n");
  683. printf("e\t: Exceptions suivant analyse\n");
  684. printf("E\t: Liste des erreurs\n");
  685. printf("l\t: Liste des elements dynamiques\n");
  686. printf("L\t: Logs du systeme\n");
  687. printf("r\t: Rejets actifs IPv4 (dure plusieurs sec.)\n");
  688. printf("R\t: Rejets actifs IPv6 (dure plusieurs sec.)\n");
  689. printf("S\t: Stopper\n");
  690. printf("t+|-\t: Niveau de trace : 0 (off) => 3\n");
  691. printf("T[mot]\t: Traces des demandes/reponses contenant mot\n");
  692. printf(">\t: Traces des demandes triees\n");
  693. printf("<\t: Traces des reponses triees\n");
  694. printf("V\t: Version\n");
  695. break;
  696. }
  697. }
  698. }
  699. write_history(FHISTO);
  700. free(cmd);
  701. /* fin dialogue */
  702. pthread_exit(NULL);
  703. }
  704. void getIface(void)
  705. {
  706. FILE * fd;
  707. char *line = NULL, *s, *w;
  708. size_t ll = 0;
  709. int n;
  710. if ((fd = fopen("/proc/net/route","r")) == NULL) {
  711. perror("route"); return;
  712. }
  713. while ((n = getline(&line, &ll, fd)) > 0) {
  714. if ((s=strstr(line,"00000000"))==NULL) continue;
  715. w=line;
  716. while ((*w != ' ') && (*w != '\t')) w++;
  717. *w = '\0';
  718. w++;
  719. while ((*w == ' ') || (*w == '\t')) w++;
  720. if (s==w) { /* ok */
  721. IFACE = (char*)malloc(strlen(line)+1);
  722. strcpy(IFACE,line);
  723. break;
  724. }
  725. }
  726. free(line);
  727. fclose(fd);
  728. }
  729. #define Vie (ie >= 0)
  730. int main(int N, char * P[])
  731. {
  732. pthread_t thid;
  733. FILE * fp;
  734. char *analyse="tcpdump", *line = NULL, *cmd = NULL, *s1, *s2, *refU;
  735. char *fauth = "auth1.txt", *strR = "-R", *Pars, strPID[8], **NP;
  736. size_t ll = 0, lc = 0;
  737. ssize_t n,n2;
  738. int Inter=0, LogC=0, i, ie, np=0, opt;
  739. if ((NPROG = strrchr(P[0],(int)'/')) == NULL) NPROG=P[0];
  740. else NPROG++;
  741. sprintf(strPID,"%d",getpid());
  742. /* verif. options */
  743. while ((opt = getopt(N, P, "ilp:R:t")) != -1) {
  744. switch (opt) {
  745. case 'i':
  746. Inter = 1;
  747. break;
  748. case 'l':
  749. LogC = 1;
  750. break;
  751. case 't':
  752. Trace = TMIN+1;
  753. break;
  754. case 'p':
  755. fauth = optarg;
  756. break;
  757. case 'R':
  758. REPR=1;
  759. np = atoi(optarg);
  760. break;
  761. default: /* '?' */
  762. fprintf(stderr, "Utilisation: %s [options]\nAvec les options :\n", NPROG);
  763. fprintf(stderr, "\t-i : mode interactif,\n");
  764. fprintf(stderr, "\t-l : log des requetes,\n");
  765. fprintf(stderr, "\t-p fichier : nom du fichier parametres (%s par defaut),\n",fauth);
  766. fprintf(stderr, "\t-t : avec trace.\n");
  767. return 1;
  768. }
  769. }
  770. if ((REPR) && (np != getpid())) {
  771. fprintf(stderr,"Erreur reprise %d\n", np);
  772. return 1;
  773. }
  774. if (optind < N) {
  775. fprintf(stderr,"Parametre inconnu : %s\n", P[optind]);
  776. return 1;
  777. }
  778. getIface();
  779. if (REPR) {
  780. while (IFACE==NULL) { sleep(1); getIface(); }
  781. } else {
  782. if (IFACE == NULL) {
  783. fprintf(stderr,"Interface reseau absente !\n");
  784. return 9;
  785. }
  786. }
  787. printf("%s %s sur %s\n", NPROG, Version, IFACE);
  788. /* verif privilege root */
  789. if ((getuid() > 0) && (geteuid() > 0)) {
  790. fprintf(stderr,"A executer sous root !\n");
  791. return 2;
  792. }
  793. if (T1) printf("T1: Fichier parametres = %s\n",fauth);
  794. signal(SIGUSR1,SIG_IGN);
  795. if (pipe(p1) < 0) {
  796. perror("pipe"); return 3;
  797. }
  798. openlog(NULL,LOG_PID,0);
  799. /* on lance le fils : */
  800. if ((pid = fork()) < 0) {
  801. perror("fork"); return 4;
  802. }
  803. if (pid == 0) {
  804. signal(SIGINT,SIG_IGN);
  805. close(0);
  806. close(p1[0]);
  807. dup2(p1[1],1); /* stdout dans p1 */
  808. dup2(p1[1],2); /* idem stderr */
  809. setsid();
  810. execlp(analyse,analyse,"-tn","-i",IFACE,"port","53",NULL);
  811. perror("execl");
  812. return 5;
  813. }
  814. if (Inter) signal(SIGINT,SIG_IGN);
  815. else signal(SIGINT,interup);
  816. if ((np=initIPT())!=0) {
  817. if (T1) printf("Erreur initIPT %d !!??\n",np);
  818. syslog(LOG_WARNING, "ERR: Erreur initIPT %d !!??\n",np);
  819. }
  820. /* lecture des listes */
  821. lectliste(fauth);
  822. if (T1) recaplistes();
  823. sleep(1); /* attend le fils en place */
  824. if (kill(pid,SIGUSR1) < 0) return 6;
  825. signal(SIGCHLD,interup);
  826. /*
  827. fcntl(p1[0], F_SETFL, O_NONBLOCK);
  828. flag0 = fcntl(0, F_GETFL, O_NONBLOCK);
  829. fcntl(0, F_SETFL, O_NONBLOCK);
  830. */
  831. /* on analyse la sortie de p1 */
  832. if ((fp = fdopen(p1[0],"r")) == NULL) {
  833. perror("fdopen"); return 7;
  834. }
  835. fcntl(p1[0], F_SETPIPE_SZ,1048576);
  836. if (T1) printf("Depart %s %s PIDF:%d !\n",NPROG, strPID,pid);
  837. if (T1) printf("Capacite pipe : %ld bytes\n", (long)fcntl(p1[0], F_GETPIPE_SZ));
  838. np=0;
  839. /* lancement du thread */
  840. if (Inter) {
  841. if (pthread_create(&thid,NULL,fct_com,(void*)fauth) != 0) {
  842. fprintf(stderr,"Erreur pthread_create !\n"); return 9;
  843. }
  844. }
  845. while (RUN) {
  846. tachePer1();
  847. if ((n = getline(&line, &ll, fp)) > 0) {
  848. if (ENDT) {
  849. printf("Erreur : plus de tache d'analyse !\n"); break;
  850. }
  851. if (RUN == 0) break;
  852. if ((n==1) && (*line=='\n')) continue;
  853. if (np==0) { np++;
  854. if (REPR) syslog(LOG_INFO,"Reprise de l'analyse !");
  855. else syslog(LOG_INFO,"Debut de l'analyse !");
  856. }
  857. /* analyse */
  858. if ((s1=strstr(line, " > ")) == NULL) continue;
  859. if (strncmp(s1-3,".53",3) == 0) { /* REPONSE */
  860. if ((s2=strstr(s1+3, ":")) == NULL) continue;
  861. NBin++;
  862. *s2 = '\0';
  863. s1 = s2 -1;
  864. while (*s1 != '.') s1--;
  865. np = atoi(s1+1);
  866. if ((ie = isElt(np)) == -1) { /* Elt OK ou ABSENT ! */
  867. ie = isElt(-np);
  868. s1 = s2+1;
  869. if ((s2=strstr(s1, " A ")) != NULL) { /* IPv4 */
  870. s2++;
  871. s1 = strrchr(s2,(int)' ');
  872. *s1 = '\0';
  873. if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
  874. if Vie {
  875. markElt(ie,4); refU = Turl[ie];
  876. } else {
  877. if (T1) printf("Elt %d non trouve !!??\n",np);
  878. syslog(LOG_WARNING,"ERR: Elt %d non trouve !!??\n",np);
  879. refU = NULL;
  880. }
  881. if (!verifIPOk(s2, refU))
  882. if Vie syslog(LOG_INFO,"Deblocage IP4 %s",refU);
  883. } else {
  884. if ((s2=strstr(s1, " AAAA ")) != NULL) { /* IPv6 */
  885. s2++;
  886. s1 = strrchr(s2,(int)' ');
  887. *s1 = '\0';
  888. if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
  889. if Vie markElt(ie,2);
  890. dropIP6(s2);
  891. } else {
  892. if Vie markElt(ie,1);
  893. }
  894. }
  895. continue;
  896. }
  897. s1 = s2+1;
  898. if ((s2=strstr(s1, " A ")) == NULL) {
  899. if ((s2=strstr(s1, " AAAA ")) == NULL) {
  900. markElt(ie,1);
  901. } else { /* traitement IPv6 */
  902. s2++;
  903. if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
  904. s1 = strrchr(s2,(int)' ');
  905. *s1 = '\0';
  906. if (markElt(ie,2)) dropIP6(s2);
  907. }
  908. continue;
  909. }
  910. /* IPv4 REJECT */
  911. s2++;
  912. s1 = strrchr(s2,(int)' ');
  913. *s1 = '\0';
  914. if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
  915. syslog(LOG_INFO,"%s DENY",Turl[ie]);
  916. if (markElt(ie,4)) dropIP(s2);
  917. } else { /* DEMANDE */
  918. NBout++;
  919. *s1 = '\0';
  920. s2 = s1 +1;
  921. while (*s1 != '.') s1--;
  922. np = atoi(s1+1);
  923. if ((s1=strstr(s2, " A? ")) == NULL) continue;
  924. s1 += 4;
  925. s2 = s1 +1;
  926. while (*s2 != ' ') s2++;
  927. *(s2-1) = '\0'; /* on supprime le '.' */
  928. if (LogC) syslog(LOG_INFO,"Req. %d %s",np,s1);
  929. if (strstr(s1, ".") == NULL) { /* il doit en rester 1 */
  930. if (T1) printf("Ignore : %d %s !\n",np,s1);
  931. syslog(LOG_WARNING,"ERR: Ignore %d %s !\n",np,s1);
  932. continue;
  933. }
  934. if (!isDeny(s1)) { // V2 ! On enregistre le OK en NEGATIF
  935. if (isElt(-np) < 0) {
  936. addElt(-np,s1);
  937. syslog(LOG_INFO,"%s ok",s1);
  938. }
  939. continue;
  940. }
  941. if (isElt(np) < 0) {
  942. i=addElt(np,s1);
  943. if (T3) printf("T3: addElt %d %d/%d\n",NbElt,i,NBT);
  944. }
  945. }
  946. }
  947. if (REQ) {
  948. printf("Taper votre commande : H pour help !\n");
  949. if ((n2 = getline(&cmd, &lc, stdin)) > 0) {
  950. switch (*cmd) {
  951. case 'C' :
  952. REQ = 0;
  953. break;
  954. case 'L' :
  955. printf("Reste %d elts !\n",iT);
  956. listElt();
  957. break;
  958. case 'S' :
  959. RUN = 0;
  960. REQ = 0;
  961. break;
  962. default :
  963. printf("C\t: continuer\n");
  964. printf("L\t: liste des elts\n");
  965. printf("S\t: stopper\n");
  966. break;
  967. }
  968. }
  969. }
  970. }
  971. syslog(LOG_INFO,"Fin de l'analyse !");
  972. free(line);
  973. free(cmd);
  974. kill(pid,SIGTERM);
  975. close(p1[0]);
  976. close(p1[1]);
  977. closelog();
  978. if (ENDT) { /* relance auto */
  979. system("reset");
  980. if (T1) printf("Relance auto %s dans %d sec. ...\n",strPID, DELAYR);
  981. sleep(DELAYR); /* attend N s */
  982. NP = (char**)malloc((sizeof(Pars))*(N+3));
  983. for (i=0;i<N;i++) NP[i] = P[i];
  984. NP[i++]=strR;
  985. NP[i++]=strPID;
  986. NP[i]=NULL;
  987. execv(P[0],NP);
  988. perror("execv");
  989. }
  990. printf("Fin du programme!\n");
  991. return 0;
  992. }