|
- /*******************************************************************
- Copyright (C) 2011-2024 Patrick H. E. Foubet - S.E.R.I.A.N.E.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>
- *******************************************************************/
-
- /*
- ############################################################
- # Projet Kouglof 2 de l'Ecole du Logiciel Libre d'Ivry : #
- ############################################################
-
- octave.c : outil pour scanner l'interface reseau afin d'analyser les sites
- auxquels les applications veulent se connecter.
- A utiliser avec le fichier auth1.txt pour stopper les connexions non voulues
-
- Tous les details sur le site :
- https://e2li.org -> menu : Projet Prosecco.
-
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <signal.h>
- #include <fcntl.h>
- #include <readline/readline.h>
- #include <readline/history.h>
- #include <sys/wait.h>
- #include <string.h>
- #include <syslog.h>
- #include <time.h>
- #include <arpa/inet.h>
- #include <pthread.h>
-
- #define Version "1.00"
-
- #define F_GETPIPE_SZ 1032
- #define F_SETPIPE_SZ 1031
-
- static int RUN=1, REQ=0, ENDT=0, REPR=0, p1[2],Trace=0;
- static pid_t pid;
- static char * NPROG, *IFACE=NULL;
- #define DELAYR 20 /* delai avant relance auto */
-
- void interup (int S)
- {
- if (S==SIGINT) {
- write(p1[1],"\n",1);
- REQ=1; return;
- }
- if (S==SIGCHLD) {
- if (waitpid(pid,NULL,WNOHANG) == pid) {
- ENDT=1;
- write(p1[1],"\n",1);
- }
- return;
- }
- fprintf(stderr,"Reçu signal %d !!??\n",S);
- }
-
- /* ### les niveaux de trace */
- #define TMIN 0
- #define TMAX 3
- #define T1 Trace > 0
- #define T2 Trace > 1
- #define T3 Trace > 2
-
- /* #### les fonctions adresses IPv4 */
-
- int isIPv4(char *a)
- {
- struct in_addr S;
- int r;
- if ((r = inet_pton(AF_INET,a, (void *)&S)) <= 0) return 0;
- return 1;
- }
-
- int isCidr(char*r)
- {
- char buf[20], *sn;
- int n;
- if (strlen(r)>18) return 0;
- strcpy(buf,r);
- if ((sn=strstr(buf,"/")) == NULL) return 0;
- *sn = '\0';
- if (!isIPv4(buf)) return 0;
- n = atoi(sn+1);
- if (n>32) return 0;
- return n;
- }
-
- int isSousRes(char*r, char *a)
- {
- struct in_addr Sa, Sr, Sm;
- int n, m1,m2,m3,m4, m;
- char buf[20],smasq[16],*sn;
- if (!isCidr(r)) return 0;
- if (!isIPv4(a)) return 0;
- strcpy(buf,r);
- if ((sn=strstr(buf,"/")) == NULL) return 0;
- *sn = '\0';
- n = atoi(sn+1);
- /* calcul du masq */
- m=n;
- if (m>7) { m1=255; m-=8;
- } else { m1=0;
- while (m>=0) m1 |= 0x80 >> --m;
- }
- if (m>7) { m2=255; m-=8;
- } else { m2=0;
- while (m>=0) m2 |= 0x80 >> --m;
- }
- if (m>7) { m3=255; m-=8;
- } else { m3=0;
- while (m>=0) m3 |= 0x80 >> --m;
- }
- if (m>7) { m4=255; m-=8;
- } else { m4=0;
- while (m>=0) m4 |= 0x80 >> --m;
- }
- sprintf(smasq,"%d.%d.%d.%d",m1,m2,m3,m4);
- inet_pton(AF_INET,smasq, (void *)&Sm);
- inet_pton(AF_INET,a, (void *)&Sa);
- inet_pton(AF_INET,buf, (void *)&Sr);
- if ((Sr.s_addr & Sm.s_addr) == (Sa.s_addr & Sm.s_addr)) return 1;
- return 0;
- }
-
- /* #### gestion dynamique des CIDR */
-
- #define NBC 100 /* nb de CIDR */
- char* Tcidr[NBC];
- int iC=0;
-
- int bloqueIP(char*);
-
- int addCidr(char * c)
- {
- int i=iC;
- if (i==NBC) return i;
- Tcidr[i] = (char*)malloc(strlen(c)+1);
- strcpy(Tcidr[i],c);
- iC++;
- bloqueIP(c);
- return i;
- }
-
- void delCidr(char * c)
- {
- int i;
- for (i=0; i<iC; i++)
- if (strcmp(c,Tcidr[i]) == 0) {
- iC--;
- if (iC == i) return;
- if (iC > 0) Tcidr[i] = Tcidr[iC];
- return;
- }
- }
-
- int isAddrInCidr(char * a, int M)
- {
- int i;
- for(i=0;i<iC;i++) {
- if (isSousRes(Tcidr[i],a)) {
- if (M) syslog(LOG_INFO,"CIDR %s contient %s !",Tcidr[i],a);
- return 1;
- }
- }
- return 0;
- }
-
- void validCidr(void)
- {
- int i,j;
- char a[20],*p, *g, *w;
- for(i=0;i<iC;i++)
- for (j=i+1;j<iC;j++) {
- if (isCidr(Tcidr[i]) < isCidr(Tcidr[j])) {
- p=Tcidr[i]; g=Tcidr[j];
- } else {
- p=Tcidr[j]; g=Tcidr[i];
- }
- strcpy(a,g);
- w = strstr(a,"/");
- *w = '\0';
- w++;
- if (isSousRes(p,a)) {
- if (T3) printf("T3: %s contient %s (%s)\n",p,a,w);
- delCidr(g);
- }
- }
- }
-
- void listCidr(void)
- {
- int i;
- printf("CIDR : %d\n",iC);
- for (i=0; i<iC; i++) printf("\t%s\n", Tcidr[i]);
- }
-
- /* ### gestion des listes */
-
- #define NBAll 500
- #define NBDen 300
- char * Allow[NBAll];
- char * Deny[NBDen];
- int iAll=0, iDen=0;
-
- int isDeny(char*u)
- {
- char *su;
- int i, tu, t;
- for (i=0;i<iDen;i++) {
- tu = strlen(u);
- t = strlen(Deny[i]);
- if (tu < t) continue;
- su = u + tu - t;;
- if (strcmp(su,Deny[i]) == 0) {
- if (su==u) return 1;
- if (*(su-1)=='.') return 1;
- }
- }
- for (i=0;i<iAll;i++) {
- tu = strlen(u);
- t = strlen(Allow[i]);
- if (tu < t) continue;
- su = u + tu - t;
- if (strcmp(su,Allow[i]) == 0) {
- if (*(Allow[i]) == '.') return 0;
- if (su==u) return 0;
- if (*(su-1)=='.') return 0;
- }
- }
- return 1; /* deny par defaut */
- }
-
- void listeAllow(void)
- {
- int i;
- printf("Allow : %d\n",iAll);
- for (i=0;i<iAll;i++) printf("\t%s\n",Allow[i]);
- }
- void listeDeny(void)
- {
- int i;
- printf("Deny : %d\n",iDen);
- for (i=0;i<iDen;i++) printf("\t%s\n",Deny[i]);
- }
- void dejaLa(char * e)
- {
- printf("%s est deja dans la liste !\n",e);
- }
- int dejaAllow(char *e)
- {
- int i;
- for (i=0;i<iAll;i++) {
- if (strlen(e) != strlen(Allow[i])) continue;
- if (strcmp(e,Allow[i])==0) {
- dejaLa(e); return 1;
- }
- }
- return 0;
- }
- int dejaDeny(char *e)
- {
- int i;
- for (i=0;i<iDen;i++) {
- if (strlen(e) != strlen(Deny[i])) continue;
- if (strcmp(e,Deny[i])==0) {
- dejaLa(e); return 1;
- }
- }
- return 0;
- }
-
- void recaplistes(void)
- {
- listeDeny();
- listeAllow();
- }
-
- int litligne(char * line)
- {
- char *w, **S;
- void * M;
- int t;
- if (*line == '#') return 1;
- if ((w=strstr(line, "\n")) != NULL) *w = '\0';
- w=line;
- if (*w == '-') w++;
- t=strlen(w);
- if (t==0) return 1;
- if (isCidr(w)) { /* test si CIDR */
- addCidr(w);
- return 1;
- }
- if (*line == '-') {
- if (iDen == NBDen) return 0;
- if (dejaDeny(w)) return 0;
- S = &Deny[iDen];
- iDen++;
- } else {
- if (iAll == NBAll) return 0;
- if (dejaAllow(w)) return 0;
- S = &Allow[iAll];
- iAll++;
- }
- if ((M = malloc(t+1)) == NULL) {
- perror("malloc"); return 0;
- }
- *S=(char*)M;
- strcpy(*S,w);
- return 1;
- }
-
- void lectliste(char *f)
- {
- FILE * fd;
- char *line = NULL;
- size_t ll = 0;
- int n;
- if ((fd = fopen(f,"r")) == NULL) {
- perror(f); return;
- }
- while ((n = getline(&line, &ll, fd)) > 0) {
- if (!litligne(line)) {
- if (T1) printf("T1: Erreur param. = %s\n",line);
- }
- }
- free(line);
- fclose(fd);
- validCidr();
- if (T1) listCidr();
- }
-
- /* ### gestion dynamique des elts */
-
- #define NBT 1000 /* nb d'elts */
- int Tno[NBT];
- int Trv[NBT];
- char* Turl[NBT];
- int iT=0, NbElt=0, MaxElt=0;
-
- int addElt(int n, char * u)
- {
- int i=iT;
- if (i == NBT) return i;
- Tno[i]=n;
- Trv[i]=0;
- Turl[i] = (char*)malloc(strlen(u)+1);
- strcpy(Turl[i],u);
- iT++;
- NbElt++;
- if (NbElt > MaxElt) MaxElt=NbElt;
- return i;
- }
-
- int isElt(int n)
- {
- int i;
- for (i=0; i<iT; i++) if (n==Tno[i]) return i;
- return -1;
- }
-
- void delIElt(int i)
- {
- if (i>=iT) return;
- if (T3) printf("T3: Del %d : %s \n",Tno[i],Turl[i]);
- iT--;
- if (iT == i) return;
- if (iT > 0) {
- Tno[i] = Tno[iT];
- Turl[i] = Turl[iT];
- Trv[i] = Trv[iT];
- }
- return;
- }
- void delElt(int n)
- {
- int i;
- for (i=0; i<iT; i++)
- if (n==Tno[i]) {
- delIElt(i);
- return;
- }
- }
-
-
- int markElt(int i, int v)
- {
- if (Trv[i] & v) return 0;
- Trv[i] |= v;
- return 1;
- }
-
- void listElt(char c)
- {
- int i,n=0;
- switch (c) {
- case '-':
- for (i=0; i<iT; i++)
- if (Tno[i]<0) { printf("%d : %s (%d)\n",Tno[i], Turl[i], Trv[i]);
- n++;
- }
- break;
- case '+':
- for (i=0; i<iT; i++)
- if (Tno[i]>0) { printf("%d : %s (%d)\n",Tno[i], Turl[i], Trv[i]);
- n++;
- }
- break;
- default:
- for (i=0; i<iT; i++) {
- printf("%d : %s (%d)\n",Tno[i], Turl[i], Trv[i]);
- n++;
- }
- break;
- }
- printf(" %d elements trouves.\n",n);
- }
-
-
-
- int comsh(char *com)
- {
- pid_t pid;
- int ret;
- if ((pid = fork()) < 0) {
- perror("fork2"); return 99;
- }
- if (pid == 0) {
- signal(SIGINT,SIG_IGN);
- execl("/bin/sh", "sh", "-c", com, (char *) 0);
- perror("execl2"); return 98;
- }
- waitpid(pid,&ret,0);
- return WEXITSTATUS(ret);
- }
-
- int exeCom(char * comm) /* on se reserve le droit de modifier */
- {
- char b[120];
- sprintf(b,"%s >/dev/null 2>&1",comm);
- return comsh(b);
- }
-
- /* ### fct de MAJ iptables */
- static char * IPT = "iptables";
- static char * IP6T = "ip6tables";
- static char * MYCH = "valide4";
- static char * OUTP = "OUTPUT";
- static char * MNO = "REJECT";
- static char * MOK = "ACCEPT";
-
- int initIPT(void)
- {
- int i=0;
- char b[90];
- if (REPR) return 0;
- sprintf(b,"%s -F",IPT);
- i += exeCom(b);
- sprintf(b,"%s -F",IP6T);
- i += exeCom(b);
- sprintf(b,"%s -L %s -n",IPT,MYCH);
- if (exeCom(b)) {
- sprintf(b,"%s -N %s",IPT,MYCH);
- i += exeCom(b);
- }
- sprintf(b,"%s -A %s -j %s",IPT,OUTP,MYCH);
- i += exeCom(b);
- return i;
- }
-
- int isPresentIP(char * comm, char * ip, char * chain)
- {
- char buf[100];
- sprintf(buf,"%s -L %s -n|grep %s",comm,chain,ip);
- if (exeCom(buf) == 0) return 1;
- return 0;
- }
-
-
- int retireChain(char * comm, char * ip, char * chain, char * jump)
- {
- char buf[100];
- sprintf(buf,"%s -D %s -d %s -j %s",comm,chain, ip, jump);
- return exeCom(buf);
- }
-
- int ajouteChain(char * comm, char * ip, char * chain, char * jump)
- {
- char buf[100];
- sprintf(buf,"%s -A %s -d %s -j %s",comm,chain, ip, jump);
- return exeCom(buf);
- }
-
- int bloqueIP(char* ip)
- {
- if (isAddrInCidr(ip,0)) return 0;
- if (isPresentIP(IPT,ip,OUTP)) return 0;
- return ajouteChain(IPT,ip,OUTP,MNO);
- }
-
- int debloqueIP(char* ip, char * url)
- {
- if (url != NULL) syslog(LOG_INFO,"%s=%s ACCEPT",url,ip);
- return ajouteChain(IPT,ip,MYCH,MOK);
- }
-
- int rebloqueIP(char* ip)
- {
- return retireChain(IPT,ip,MYCH,MOK);
- }
-
- void dropIP(char * l)
- {
- char *s,*d=l;
- while ((s=strstr(d, "A ")) != NULL) {
- s+=2;
- if ((d=strstr(s+2, ",")) == NULL) break;
- *d = '\0';
- d++;
- bloqueIP(s);
- }
- bloqueIP(s);
- }
-
- int verifIPOk(char * l, char * url)
- {
- char *s,*d=l;
- while ((s=strstr(d, "A ")) != NULL) {
- s+=2;
- if ((d=strstr(s+2, ",")) == NULL) break;
- *d = '\0';
- d++;
- if (isPresentIP(IPT,s,MYCH)) continue;
- if (isAddrInCidr(s,1)) debloqueIP(s,url);
- }
- if (isPresentIP(IPT,s,MYCH)) return 1;
- if (isAddrInCidr(s,1)) return(debloqueIP(s,url));
- return 1;
- }
-
- int dropIP6(char * l)
- {
- char *s,*d=l;
- while ((s=strstr(d, "A ")) != NULL) {
- s+=2;
- if ((d=strstr(s+2, ",")) == NULL) break;
- *d = '\0';
- d++;
- if (isPresentIP(IP6T,s,OUTP)) continue;
- ajouteChain(IP6T,s,OUTP,MNO);
- }
- if (isPresentIP(IP6T,s,OUTP)) return 1;
- ajouteChain(IP6T,s,OUTP,MNO);
- return 1;
- }
-
-
- /* tache de commande et periodiques */
- #define t0 (time_t)0
- time_t tim1=t0;
- void tachePer1(void) /* vide les elts toutes les 30 secondes */
- {
- static time_t tim0=t0, tw;
- int i, v;
- tw = time(NULL);
- if ((tw - tim0) < 30) {
- if (T3) printf ("T3: tache1 passe %s",ctime(&tw));
- return;
- }
- if (T3) printf ("T3: tache1 exec %s",ctime(&tw));
- tim1 = time(NULL);
- v = (tim1 - tim0) / 30;
- if (tim0 != t0) {
- for (i=iT-1; i>=0; i--) {
- if ((Trv[i]&0x6) == 6) delIElt(i); // IPv4 + IPV6
- else { Trv[i] += 8*v;
- if (Trv[i] > 80) delIElt(i); // On laisse 5 min.
- }
- }
- }
- tim0 = time(NULL);
- return;
- }
-
- void ajoutParam(char * ficp, char * param)
- {
- FILE * fw;
- fw = fopen(ficp,"a");
- fwrite(param,strlen(param),1,fw);
- fwrite("\n",1,1,fw);
- fclose(fw);
- }
-
- static int NBin=0, NBout=0;
- void prInOut(void)
- {
- printf(" %d messages DNS: %d requetes, %d reponses.\n",NBout+NBin,NBout,NBin);
- }
-
- int printQ(char * q)
- {
- char *rep=NULL;
- size_t lr = 0;
- int n;
- while (1) {
- printf("Voulez-vous %s ?\n Taper O (OUI) ou N (NON) :\n",q);
- if ((n = getline(&rep, &lr, stdin)) != 2) continue;
- if (*rep == 'O') return 1;
- if (*rep == 'N') return 0;
- }
- }
-
- void pr_encours(void)
- {
- printf(" ...\r"); fflush(stdout);
- }
-
- #define SUNIC "|sort|uniq"
- #define CHLOG "/var/log/user.log"
- #define CHLOGREP "/var/log/user.log|grep "
- #define CUT6 "|cut -d' ' -f6"
- #define CUT7S "|cut -d' ' -f7-"
-
- #define FHISTO ".octave_history"
- #define AWK5 "|awk '{ print $5}'"
- #define AWK4 "|awk '{ print $4}'"
- #define DREJ "^REJECT "
- void * fct_com(void * p)
- {
- int REQ=1;
- char *cmd = NULL, *fauth, com[100];
- int n2;
- pid_t pid;
- fauth = (char*)p;
- pid = getpid();
- read_history(FHISTO);
- if (REPR) comsh("reset");
- while (REQ) {
- if (kill(pid,SIGUSR1) < 0) { /* verif processus acquisition */
- ENDT=1;
- write(p1[1],"\n",1);
- }
- free(cmd);
- cmd = readline("O-> ");
- if ((n2 = strlen(cmd)) > 0) {
- write(p1[1],"\n",1);
- add_history(cmd);
- switch (*cmd) {
- case '+' :
- if (*(cmd+1) != '\0') {
- if (litligne(cmd+1)) { /* ajout au fichier fauth */
- if (debloqueIP(cmd+1,NULL)) printf("Element non valable !\n");
- else {
- if (printQ("ajouter au fichier parametres"))
- ajoutParam(fauth,cmd+1);
- listeAllow();
- }
- } else printf("Erreur ajout param. !\n");
- } else listeAllow();
- break;
- case '-' :
- if (*(cmd+1) != '\0') {
- if (litligne(cmd)) { /* ajout au fichier fauth */
- if (rebloqueIP(cmd+1)) printf("Element non valable !\n");
- else {
- if (printQ("ajouter au fichier parametres"))
- ajoutParam(fauth,cmd);
- listeDeny();
- }
- } else printf("Erreur ajout param. !\n");
- } else listeDeny();
- break;
- case 'l' :
- listElt(cmd[1]);
- printf(" %s Utilise %d elts/%d : %.2f%% (Max. %d)!\n",ctime(&tim1),iT,
- NBT, (float)(iT*100)/(float)NBT, MaxElt);
- prInOut();
- break;
- case 't' :
- if (*(cmd+1) != '\0') {
- if ((cmd[1] == '+') || (cmd[1] == '-')) {
- if ((cmd[1] == '+') && (Trace < TMAX)) Trace++;
- else {
- if ((cmd[1] == '-') && (Trace > TMIN)) Trace--;
- else printf("Erreur: niveau dans [%d, %d].\n",TMIN,TMAX);
- }
- } else printf("Erreur: Utiliser t+ ou t- !\n");
- }
- printf(" Trace niveau %d\n",Trace);
- break;
- case 'a' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* ok",
- CHLOG,CUT6,SUNIC);
- comsh(com);
- break;
- case 'i' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* DENY",
- CHLOG,CUT6,SUNIC);
- comsh(com);
- break;
- case 'e' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,".* ACCEPT",
- CHLOG,CUT6,SUNIC);
- comsh(com);
- break;
- case 'E' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"grep '%s\\[%d\\]%s' %s",NPROG,pid,".*ERR: ",CHLOG);
- comsh(com);
- break;
- case 'L' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"grep '%s\\[%d\\]' %s%s",NPROG,pid,
- CHLOGREP,"-v 'Re[pq]. '");
- comsh(com);
- break;
- case 'T' :
- if (*(cmd+1) != '\0')
- sprintf(com,"grep '%s\\[%d\\].*%s' %s%s",NPROG,pid,cmd+1,
- CHLOGREP," 'Re[pq]. '");
- else
- sprintf(com,"grep '%s\\[%d\\]' %s%s",NPROG,pid,
- CHLOGREP," 'Re[pq]. '");
- comsh(com);
- prInOut();
- break;
- case '>' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,
- CHLOGREP," 'Req. '",CUT7S,SUNIC);
- comsh(com);
- prInOut();
- break;
- case '<' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,
- CHLOGREP," 'Rep. '",CUT7S,SUNIC);
- comsh(com);
- prInOut();
- break;
- case 'r' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"%s -L|grep %s%s%s",IPT,DREJ,AWK5,SUNIC);
- pr_encours();
- comsh(com);
- break;
- case 'R' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- sprintf(com,"%s -L|grep %s%s%s",IP6T,DREJ,AWK4,SUNIC);
- pr_encours();
- comsh(com);
- break;
- case 'S' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- RUN = 0;
- REQ = 0;
- write(p1[1],"\n",1);
- break;
- case 'V' :
- if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
- printf("Version %s\n",Version);
- prInOut();
- break;
- case ' ' :
- if (*(cmd+1) != '\0') comsh(cmd+1);
- break;
- default :
- printf("+url\t: Allow (autoriser une Url)\n");
- printf("-url\t: Deny (interdire une Url)\n");
- printf("a\t: Autorisations suivant analyse\n");
- printf("i\t: Interdictions suivant analyse\n");
- printf("e\t: Exceptions suivant analyse\n");
- printf("E\t: Liste des erreurs\n");
- printf("l[+|-]\t: Liste des elements dynamiques\n");
- printf("L\t: Logs du systeme\n");
- printf("r\t: Rejets actifs IPv4 (dure plusieurs sec.)\n");
- printf("R\t: Rejets actifs IPv6 (dure plusieurs sec.)\n");
- printf("S\t: Stopper\n");
- printf("t+|-\t: Niveau de trace : 0 (off) => 3\n");
- printf("T[mot]\t: Traces des demandes/reponses contenant mot\n");
- printf(">\t: Traces des demandes triees\n");
- printf("<\t: Traces des reponses triees\n");
- printf("V\t: Version\n");
- break;
- }
- }
- }
- write_history(FHISTO);
- free(cmd);
- /* fin dialogue */
- pthread_exit(NULL);
- }
-
- void getIface(void)
- {
- FILE * fd;
- char *line = NULL, *s, *w;
- size_t ll = 0;
- int n;
- if ((fd = fopen("/proc/net/route","r")) == NULL) {
- perror("route"); return;
- }
- while ((n = getline(&line, &ll, fd)) > 0) {
- if ((s=strstr(line,"00000000"))==NULL) continue;
- w=line;
- while ((*w != ' ') && (*w != '\t')) w++;
- *w = '\0';
- w++;
- while ((*w == ' ') || (*w == '\t')) w++;
- if (s==w) { /* ok */
- IFACE = (char*)malloc(strlen(line)+1);
- strcpy(IFACE,line);
- break;
- }
- }
- free(line);
- fclose(fd);
- }
-
- #define Vie (ie >= 0)
- int main(int N, char * P[])
- {
- pthread_t thid;
- FILE * fp;
- char *analyse="tcpdump", *line = NULL, *cmd = NULL, *s1, *s2, *refU;
- char *fauth = "auth1.txt", *strR = "-R", *Pars, strPID[8], **NP;
- size_t ll = 0, lc = 0;
- ssize_t n,n2;
- int Inter=0, LogC=0, i, ie, np=0, opt;
- if ((NPROG = strrchr(P[0],(int)'/')) == NULL) NPROG=P[0];
- else NPROG++;
- sprintf(strPID,"%d",getpid());
- /* verif. options */
- while ((opt = getopt(N, P, "ilp:R:t")) != -1) {
- switch (opt) {
- case 'i':
- Inter = 1;
- break;
- case 'l':
- LogC = 1;
- break;
- case 't':
- Trace = TMIN+1;
- break;
- case 'p':
- fauth = optarg;
- break;
- case 'R':
- REPR=1;
- np = atoi(optarg);
- break;
- default: /* '?' */
- fprintf(stderr, "Utilisation: %s [options]\nAvec les options :\n", NPROG);
- fprintf(stderr, "\t-i : mode interactif,\n");
- fprintf(stderr, "\t-l : log des requetes,\n");
- fprintf(stderr, "\t-p fichier : nom du fichier parametres (%s par defaut),\n",fauth);
- fprintf(stderr, "\t-t : avec trace.\n");
- return 1;
- }
- }
- if ((REPR) && (np != getpid())) {
- fprintf(stderr,"Erreur reprise %d\n", np);
- return 1;
- }
- if (optind < N) {
- fprintf(stderr,"Parametre inconnu : %s\n", P[optind]);
- return 1;
- }
- getIface();
- if (REPR) {
- while (IFACE==NULL) { sleep(1); getIface(); }
- } else {
- if (IFACE == NULL) {
- fprintf(stderr,"Interface reseau absente !\n");
- return 9;
- }
- }
- printf("%s %s sur %s\n", NPROG, Version, IFACE);
- /* verif privilege root */
- if ((getuid() > 0) && (geteuid() > 0)) {
- fprintf(stderr,"A executer sous root !\n");
- return 2;
- }
- if (T1) printf("T1: Fichier parametres = %s\n",fauth);
- signal(SIGUSR1,SIG_IGN);
- if (pipe(p1) < 0) {
- perror("pipe"); return 3;
- }
- openlog(NULL,LOG_PID,0);
- /* on lance le fils : */
- if ((pid = fork()) < 0) {
- perror("fork"); return 4;
- }
- if (pid == 0) {
- signal(SIGINT,SIG_IGN);
- close(0);
- close(p1[0]);
- dup2(p1[1],1); /* stdout dans p1 */
- dup2(p1[1],2); /* idem stderr */
- setsid();
- execlp(analyse,analyse,"-tn","-i",IFACE,"port","53",NULL);
- perror("execl");
- return 5;
- }
- if (Inter) signal(SIGINT,SIG_IGN);
- else signal(SIGINT,interup);
- if ((np=initIPT())!=0) {
- if (T1) printf("Erreur initIPT %d !!??\n",np);
- syslog(LOG_WARNING, "ERR: Erreur initIPT %d !!??\n",np);
- }
- /* lecture des listes */
- lectliste(fauth);
- if (T1) recaplistes();
- sleep(1); /* attend le fils en place */
- if (kill(pid,SIGUSR1) < 0) return 6;
- signal(SIGCHLD,interup);
- /*
- fcntl(p1[0], F_SETFL, O_NONBLOCK);
- flag0 = fcntl(0, F_GETFL, O_NONBLOCK);
- fcntl(0, F_SETFL, O_NONBLOCK);
- */
- /* on analyse la sortie de p1 */
- if ((fp = fdopen(p1[0],"r")) == NULL) {
- perror("fdopen"); return 7;
- }
- fcntl(p1[0], F_SETPIPE_SZ,1048576);
- if (T1) printf("Depart %s %s PIDF:%d !\n",NPROG, strPID,pid);
- if (T1) printf("Capacite pipe : %ld bytes\n", (long)fcntl(p1[0], F_GETPIPE_SZ));
- np=0;
- /* lancement du thread */
- if (Inter) {
- if (pthread_create(&thid,NULL,fct_com,(void*)fauth) != 0) {
- fprintf(stderr,"Erreur pthread_create !\n"); return 9;
- }
- }
- while (RUN) {
- tachePer1();
- if ((n = getline(&line, &ll, fp)) > 0) {
- if (ENDT) {
- printf("Erreur : plus de tache d'analyse !\n"); break;
- }
- if (RUN == 0) break;
- if ((n==1) && (*line=='\n')) continue;
- if (np==0) { np++;
- if (REPR) syslog(LOG_INFO,"Reprise de l'analyse !");
- else syslog(LOG_INFO,"Debut de l'analyse !");
- }
- /* analyse */
- if ((s1=strstr(line, " > ")) == NULL) continue;
- if (strncmp(s1-3,".53",3) == 0) { /* REPONSE */
- if ((s2=strstr(s1+3, ":")) == NULL) continue;
- NBin++;
- *s2 = '\0';
- s1 = s2 -1;
- while (*s1 != '.') s1--;
- np = atoi(s1+1);
- if ((ie = isElt(np)) == -1) { /* Elt OK ou ABSENT ! */
- ie = isElt(-np);
- s1 = s2+1;
- if ((s2=strstr(s1, " A ")) != NULL) { /* IPv4 */
- s2++;
- s1 = strrchr(s2,(int)' ');
- *s1 = '\0';
- if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
- if Vie {
- markElt(ie,4); refU = Turl[ie];
- } else {
- if (T1) printf("Elt %d non trouve !!??\n",np);
- syslog(LOG_WARNING,"ERR: Elt %d non trouve !!??\n",np);
- refU = NULL;
- }
- if (!verifIPOk(s2, refU))
- if Vie syslog(LOG_INFO,"Deblocage IP4 %s",refU);
- } else {
- if ((s2=strstr(s1, " AAAA ")) != NULL) { /* IPv6 */
- s2++;
- s1 = strrchr(s2,(int)' ');
- *s1 = '\0';
- if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
- if Vie markElt(ie,2);
- dropIP6(s2);
- } else {
- if Vie markElt(ie,1);
- }
- }
- continue;
- }
- s1 = s2+1;
- if ((s2=strstr(s1, " A ")) == NULL) {
- if ((s2=strstr(s1, " AAAA ")) == NULL) {
- markElt(ie,1);
- } else { /* traitement IPv6 */
- s2++;
- if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
- s1 = strrchr(s2,(int)' ');
- *s1 = '\0';
- if (markElt(ie,2)) dropIP6(s2);
- }
- continue;
- }
- /* IPv4 REJECT */
- s2++;
- s1 = strrchr(s2,(int)' ');
- *s1 = '\0';
- if (LogC) syslog(LOG_INFO,"Rep. %d %s",np,s2);
- syslog(LOG_INFO,"%s DENY",Turl[ie]);
- if (markElt(ie,4)) dropIP(s2);
- } else { /* DEMANDE */
- NBout++;
- *s1 = '\0';
- s2 = s1 +1;
- while (*s1 != '.') s1--;
- np = atoi(s1+1);
- if ((s1=strstr(s2, " A? ")) == NULL) continue;
- s1 += 4;
- s2 = s1 +1;
- while (*s2 != ' ') s2++;
- *(s2-1) = '\0'; /* on supprime le '.' */
- if (LogC) syslog(LOG_INFO,"Req. %d %s",np,s1);
- if (strstr(s1, ".") == NULL) { /* il doit en rester 1 */
- if (T1) printf("Ignore : %d %s !\n",np,s1);
- syslog(LOG_WARNING,"ERR: Ignore %d %s !\n",np,s1);
- continue;
- }
- if (!isDeny(s1)) { // V2 ! On enregistre le OK en NEGATIF
- if (isElt(-np) < 0) {
- addElt(-np,s1);
- syslog(LOG_INFO,"%s ok",s1);
- }
- continue;
- }
- if (isElt(np) < 0) {
- i=addElt(np,s1);
- if (T3) printf("T3: addElt %d %d/%d\n",NbElt,i,NBT);
- }
- }
- }
- if (REQ) {
- printf("Taper votre commande : H pour help !\n");
- if ((n2 = getline(&cmd, &lc, stdin)) > 0) {
- switch (*cmd) {
- case 'C' :
- REQ = 0;
- break;
- case 'L' :
- listElt(cmd[1]);
- printf(" %s Utilise %d elts/%d : %.2f%% (Max. %d)!\n",
- ctime(&tim1),iT,NBT,(float)(iT*100)/(float)NBT,MaxElt);
- break;
- case 'S' :
- RUN = 0;
- REQ = 0;
- break;
- default :
- printf("C\t: continuer\n");
- printf("L\t: liste des elts\n");
- printf("S\t: stopper\n");
- break;
- }
- }
- }
- }
- syslog(LOG_INFO,"Fin de l'analyse !");
- free(line);
- free(cmd);
- kill(pid,SIGTERM);
- close(p1[0]);
- close(p1[1]);
- closelog();
- if (ENDT) { /* relance auto */
- comsh("reset");
- if (T1) printf("Relance auto %s dans %d sec. ...\n",strPID, DELAYR);
- sleep(DELAYR); /* attend N s */
- NP = (char**)malloc((sizeof(Pars))*(N+3));
- for (i=0;i<N;i++) NP[i] = P[i];
- NP[i++]=strR;
- NP[i++]=strPID;
- NP[i]=NULL;
- execv(P[0],NP);
- perror("execv");
- }
- printf("Fin du programme!\n");
- return 0;
- }
-
|