/*******************************************************************
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
*******************************************************************/
/*
############################################################
# 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Version "1.04"
#define F_GETPIPE_SZ 1032
#define F_SETPIPE_SZ 1031
static int RUN=1, REQ=0, ENDT=0, REINI=0, REPR=0, JCTL=0, LogC=0, WH=1, p1[2],Trace=0;
static pid_t pid;
static char * NPROG, *IFACE=NULL;
#define DELAYR 20 /* delai avant relance auto */
void interup (int S)
{
switch(S) {
case SIGINT:
write(p1[1],"\n",1);
REQ=1; return;
break;
case SIGCHLD:
if (waitpid(pid,NULL,WNOHANG) == pid) {
ENDT=1;
write(p1[1],"\n",1);
}
break;
case SIGHUP:
case SIGILL:
case SIGSEGV:
ENDT=S+1;
write(p1[1],"\n",1);
break;
default:
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 isIPv6(char *a)
{
struct in6_addr S;
int r;
if ((r = inet_pton(AF_INET6,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 isCidr6(char*r)
{
char buf[52], *sn;
int n;
if (strlen(r)>50) return 0;
strcpy(buf,r);
if ((sn=strstr(buf,"/")) == NULL) return 0;
*sn = '\0';
if (!isIPv6(buf)) return 0;
n = atoi(sn+1);
if (n>128) return 0;
return n;
}
uint64_t NbAddCidrs = 0;
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 0) Tcidr[i] = Tcidr[iC];
return;
}
}
int isAddrInCidr(char * a, int M)
{
int i;
for(i=0;i 0) { /* test si CIDR */
addCidr(w);
NbAddCidrs += (int)(1< 0) { /* test si CIDR6 */
printf("%s : CIDR IPv6 non pris en compte pour l'instant !\n",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) 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; i0) { printf("%d : %s (%d)\n",Tno[i], Turl[i], Trv[i]);
n++;
}
break;
default:
for (i=0; i/dev/null 2>&1",comm);
return comsh(b,EX_SILENT);
}
/* ### 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/o pour OUI, autre touche = NON :\n",q);
if ((n = getline(&rep, &lr, stdin)) != 2) continue;
if (*rep == 'O') return 1;
if (*rep == 'o') return 1;
return 0;
}
}
#define SUNIC "|sort|uniq"
#define JCTLSYS "journalctl --system"
#define JCTLSYSG JCTLSYS"|grep "
#define CHLOG "/var/log/user.log"
#define CHLOGREP "/var/log/user.log|grep "
#define CUT6 "|cut -d' ' -f6"
#define CUTM45 "|cut -d' ' -f1-3,6-"
#define CUT7S "|cut -d' ' -f7-"
#define NOTF "non trouve !!??"
#define ENOVAL "Element non valable !"
#define FHISTO ".octave_history"
#define AWK5 "|awk '{ print $5}'"
#define AWK4 "|awk '{ print $4}'"
#define DREJ "^REJECT "
#define DACC "^ACCEPT "
void * fct_com(void * p)
{
int REQ=1;
char *cmd = NULL, *fauth, pr[30], com[200];
int n2;
pid_t pid;
fauth = (char*)p;
pid = getpid();
read_history(FHISTO);
while (REQ) {
if (kill(pid,SIGUSR1) < 0) { /* verif processus acquisition */
ENDT=1;
write(p1[1],"\n",1);
break;
}
free(cmd);
sprintf(pr,"\e[01;34m%s-> \e[00m",NPROG);
cmd = readline(pr);
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("%s\n",ENOVAL);
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("%s\n",ENOVAL);
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);
if (JCTL) sprintf(com,"%s'%s\\[%d\\]%s'%s%s",JCTLSYSG,NPROG,pid,
".* ok", CUT6,SUNIC);
else sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,
".* ok", CHLOG,CUT6,SUNIC);
comsh(com,0);
break;
case 'i' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
if (JCTL) sprintf(com,"%s'%s\\[%d\\]%s'%s%s",JCTLSYSG,NPROG,pid,
".* DENY", CUT6,SUNIC);
else sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,
".* DENY", CHLOG,CUT6,SUNIC);
comsh(com,0);
break;
case 'e' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
if (JCTL) sprintf(com,"%s'%s\\[%d\\]%s'%s%s",JCTLSYSG,NPROG,pid,
".* ACCEPT", CUT6,SUNIC);
else sprintf(com,"grep '%s\\[%d\\]%s' %s%s%s",NPROG,pid,
".* ACCEPT", CHLOG,CUT6,SUNIC);
comsh(com,0);
break;
case 'E' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
if (JCTL) sprintf(com,"%s'%s\\[%d\\]%s'%s",JCTLSYSG,NPROG,pid,
".*ERR: ", CUTM45);
else sprintf(com,"grep '%s\\[%d\\]%s' %s%s",NPROG,pid,
".*ERR: ", CHLOG,CUTM45);
comsh(com,0);
break;
case 'L' :
if (*(cmd+1) == '\0') {
if (JCTL) sprintf(com,"%s'%s\\[%d\\]'|grep %s%s",JCTLSYSG,NPROG,
pid, "-v 'Re[pq]. '",CUTM45);
else sprintf(com,"grep '%s\\[%d\\]' %s%s%s",NPROG,pid,
CHLOGREP,"-v 'Re[pq]. '",CUTM45);
} else {
if (JCTL) sprintf(com,"%s'%s\\[%d\\]'|grep %s%s|grep '%s'",JCTLSYSG
,NPROG,pid,"-v 'Re[pq]. '",CUTM45,cmd+1);
else sprintf(com,"grep '%s\\[%d\\]' %s%s%s|grep '%s'",NPROG,pid,
CHLOGREP,"-v 'Re[pq]. '",CUTM45,cmd+1);
}
comsh(com,0);
break;
case 'T' :
if (*(cmd+1) != '\0') { /* avec parametre */
if ((*(cmd+1) == '+') && (*(cmd+2) != '\0')) { /* script + param */
sprintf(com,"./t1.sh %d %s >.Trav%d",pid,cmd+2,pid);
comsh(com,0);
sprintf(com,"cat .Trav%d",pid);
} else {
if (JCTL)
sprintf(com,"%s'%s\\[%d\\].*%s'|grep%s%s",JCTLSYSG,NPROG,pid,
cmd+1," 'Re[pq]. '",CUTM45);
else
sprintf(com,"grep '%s\\[%d\\].*%s' %s%s%s",NPROG,pid,cmd+1,
CHLOGREP," 'Re[pq]. '",CUTM45);
}
} else {
if (JCTL)sprintf(com,"%s'%s\\[%d\\]'|grep %s%s",JCTLSYSG,NPROG,pid,
" 'Re[pq]. '",CUTM45);
else sprintf(com,"grep '%s\\[%d\\]' %s%s%s",NPROG,pid,
CHLOGREP," 'Re[pq]. '",CUTM45);
}
comsh(com,0);
prInOut();
break;
case '>' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
if (JCTL) sprintf(com,"%s'%s\\[%d\\].*%s%s%s",JCTLSYSG,NPROG,pid,
" Req. '",CUT7S,SUNIC);
else sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,
CHLOGREP," 'Req. '",CUT7S,SUNIC);
comsh(com,0);
prInOut();
break;
case '<' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
if (JCTL) sprintf(com,"%s'%s\\[%d\\].*%s%s%s",JCTLSYSG,NPROG,pid,
" Rep. '",CUT7S,SUNIC);
else sprintf(com,"grep '%s\\[%d\\]' %s%s%s%s",NPROG,pid,
CHLOGREP," 'Rep. '",CUT7S,SUNIC);
comsh(com,0);
prInOut();
break;
case 'r' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
sprintf(com,"%s -L %s|grep %s%s%s",IPT,OUTP,DREJ,AWK5,SUNIC);
comsh(com,EX_NOERR|EX_DUREE);
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);
comsh(com,EX_NOERR|EX_DUREE);
break;
case 'N' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
if (printQ("Re-initialiser")) {
RUN = 0;
REINI = 1;
write(p1[1],"\n",1);
}
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);
sprintf(com,"%s -L %s|grep %s%s%s",IPT,MYCH,DACC,AWK5,SUNIC);
comsh(com,EX_NOERR|EX_DUREE);
break;
case ' ' :
if (*(cmd+1) != '\0') comsh(cmd+1,0);
break;
case '?' :
if (*(cmd+1) != '\0') printf("ignore %s\n",cmd+1);
printf("Version %s\n",Version);
prInOut();
default :
printf("?\t\t: Version et menu.\n");
printf("+url\t\t: Allow (autoriser une Url)\n");
printf("-url\t\t: Deny (interdire une Url)\n");
printf("a\t\t: Autorisations suivant analyse\n");
printf("i\t\t: Interdictions suivant analyse\n");
printf("e\t\t: Exceptions suivant analyse\n");
printf("E\t\t: Liste des erreurs\n");
printf("l[+|-]\t\t: Liste des elements dynamiques\n");
printf("L[filtre]\t: Logs du systeme avec filtre de type regex\n");
printf("r\t\t: Rejets actifs IPv4 (dure plusieurs sec.)\n");
printf("R\t\t: Rejets actifs IPv6 (dure plusieurs sec.)\n");
printf("v\t\t: Validations actives IPv4 (dure plusieurs sec.)\n");
printf("t+|-\t\t: Niveau de trace : 0 (off) => 3\n");
if (LogC) {
printf("T[+][mot]\t: Traces des demandes/reponses contenant mot.\n\t\t Avec + fait les liaisons entre requetes et reponses.\n");
printf(">\t\t: Traces des demandes triees\n");
printf("<\t\t: Traces des reponses triees\n");
}
printf("N\t\t: Nouvelle initialisation\n");
printf("S\t\t: Stopper\n");
break;
}
}
}
WH=write_history(FHISTO);
free(cmd);
sprintf(com,"rm -f .Trav%d",pid);
comsh(com,0);
/* 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, 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 (comsh(JCTLSYS,EX_SILENT) == 0) JCTL=1;
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,"-tnl","-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);
signal(SIGHUP,interup);
signal(SIGILL,interup);
signal(SIGSEGV,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) {
if (ENDT==1) 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 (strstr(line, " PTR") != NULL) continue; /* ignore PTR */
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 %s\n",np,NOTF);
syslog(LOG_WARNING,"ERR: Elt %d %s\n",np,NOTF);
continue;
}
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;
}
}
}
}
if (REINI==0) {
if (ENDT==1) syslog(LOG_INFO,"Fin de l'analyse !");
else syslog(LOG_WARNING,"Reçu signal %d !",ENDT-1);
}
free(line);
free(cmd);
kill(pid,SIGTERM);
close(p1[0]);
close(p1[1]);
closelog();
if (ENDT|REINI) { /* relance auto */
if (T1) printf("Relance auto %s dans %d sec. ...\n",strPID, DELAYR);
sleep(DELAYR); /* attend N s */
NP = (char**)malloc((sizeof(Pars))*(N+3));
ie=0;
for (i=0;i