From 7aa7bce3d9f8739550fd2207490542872aefa9db Mon Sep 17 00:00:00 2001 From: Daniel Tartavel Date: Sun, 17 May 2020 22:19:03 +0200 Subject: [PATCH] added dynamic reloading of configuration when file is modified. --- main.c | 163 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 119 insertions(+), 44 deletions(-) diff --git a/main.c b/main.c index 6a0b733..91ed5af 100644 --- a/main.c +++ b/main.c @@ -8,9 +8,12 @@ #include #include #include -#include +#include #define HOSTNAME "localhost" +#define EVENT_SIZE (sizeof(struct inotify_event)) + +int debug = 0; struct connexion { @@ -30,9 +33,17 @@ struct config char commande[1024]; char logfile[4096]; char hostname[128]; - + char configfile[4096]; }; +struct notify_config +{ + int fd; + int wd; +}; + + + int explode( char * str, char * separator, size_t m, size_t n, char exploded[m][n] ) { char * pch; @@ -41,7 +52,7 @@ int explode( char * str, char * separator, size_t m, size_t n, char exploded[m][ pch = strtok( str, separator ); while( pch != NULL ) { - //printf("%s\n", pch); + if (debug >= 2) printf("%s\n", pch); strcpy( exploded[x++], pch) ; pch = strtok( NULL , separator ); } @@ -71,11 +82,12 @@ int readconfig( struct config * cfg ) { if ((fh = fopen( path[x], "r")) == NULL) { - perror(path[x]); + if (debug >= 1) perror(path[x]); if(x==1) retval = -1; }else { - printf("Found config file: %s\n", path[x]); + strcpy( cfg->configfile, path[x]); + if (debug >= 1) printf("Found config file: %s\n", path[x]); x = 3; } } @@ -89,21 +101,22 @@ int readconfig( struct config * cfg ) if ( fopen(exploded[1],"r") != NULL) { strcpy( cfg->commande, exploded[1] ); - printf("Found command: %s\n", cfg->commande); + if (debug >= 1) printf("Found command: %s\n", cfg->commande); }else { - perror(exploded[1]); + if (debug >= 1) perror(exploded[1]); } }else if( strcmp( exploded[0], "logfile") == 0) { - sprintf( logfilepath, "%s%s", homepath, "/.config/sshdetect.log"); if ( fopen(exploded[1], "a") != NULL ) { strcpy( cfg->logfile, exploded[1] ); + if (debug >= 1) printf("Found logfile: %s\n", cfg->logfile); } }else if( strcmp( exploded[0], "hostname") == 0 ) { strcpy( cfg->hostname, exploded[1] ); + if (debug >= 1 ) printf("Found hostname: %s\n", cfg->hostname); } } } @@ -117,7 +130,7 @@ int readconfig( struct config * cfg ) strcpy( cfg->logfile, logfilepath ); }else { - perror(logfilepath); + if (debug >= 1) perror(logfilepath); strcpy(cfg->logfile, "/dev/null"); retval += 2; } @@ -135,16 +148,15 @@ int readconfig( struct config * cfg ) } if (cfg->commande[0] == 0) { - printf("command not found: no command will be executed"); + if (debug >=1) printf("command not found in config file: no command will be executed\n"); retval += 4; } return retval; } -//test if pid is in lsit of known sshd processus +//test if pid is in list of known sshd processus int isinarray( int pid, int array[], int n ) { - //if (n == 0) return 0; int x; for(x=1;x<=n;x++) { @@ -152,7 +164,8 @@ int isinarray( int pid, int array[], int n ) { return x; } - } return 0; + } + return 0; } char* frtime(const time_t timet) @@ -165,6 +178,67 @@ char* frtime(const time_t timet) return result; } +int init_config_watch( char config_file[], struct notify_config * ncc ) +{ + ncc->fd = inotify_init(); + if ( ncc->fd < 0 ) + { + perror( "inotify_init" ); + return -1; + } + ncc->wd = inotify_add_watch( ncc->fd, config_file, IN_MODIFY | IN_DELETE ); + if (ncc->wd == -1) + { + perror(config_file); + printf("%s\n", config_file); + return -2; + } + return 0; +} + +int notify_config_change(struct notify_config * ncc, char config_file[], struct config * cfg) +{ + int length=0; + int i=0; + int buff_length = (1024 * (EVENT_SIZE + 16)); + char buff[buff_length]; + fd_set rfds; + struct timeval tv = {1,0}; + int retval; + + FD_ZERO(&rfds); + FD_SET(ncc->fd, &rfds); + retval = select(ncc->fd+1, &rfds, NULL, NULL, &tv); + if (retval == -1) + { + if (debug >= 1) perror("select()"); + } + else if (retval) + { + length = read(ncc->fd, buff, buff_length); + if (length < 0) + { + if (debug >= 1) perror("reading"); + return -1; + } + while (i < length) + { + struct inotify_event *event = (struct inotify_event *) &buff[i]; + if (event->mask & IN_DELETE) + { + if (debug >= 2) printf("The file %s was deleted.\n", event->name); + init_config_watch( config_file, ncc); + } else if (event->mask & IN_MODIFY) + { + if (debug >= 2) printf("The file %s was modified.\n", event->name); + readconfig(cfg); + } + i += EVENT_SIZE + event->len; + } + } + return 0; +} + //get utmp datas void getutmp( struct connexion * conn, time_t * time ) { @@ -173,10 +247,11 @@ void getutmp( struct connexion * conn, time_t * time ) int ipv4; int x; char str[6]; + conn->host_ip[0]='\0'; conn->host_ipv6[0]='\0'; setutent(); - while ( (utmp = getutent()) != NULL ) + while ( (utmp = getutent()) != NULL ) { if ( utmp->ut_pid == conn->pid ) { @@ -256,11 +331,11 @@ int getpids(int pid, int exploded[]) char separator[] = " "; int x = 0; - sprintf( path, "/proc/%d/task/%d/children", pid,pid); - //printf(" %s", proc_path); + sprintf( path, "/proc/%d/task/%d/children", pid, pid); + if (debug >= 1) printf("process path: %s", path); if ((fh = fopen( path, "r")) == NULL) { - perror(path); + if (debug >= 1) perror(path); return -1; } if ( fgets( str, 40, fh ) != NULL ) @@ -268,12 +343,10 @@ int getpids(int pid, int exploded[]) pch = strtok( str, separator ); while( pch != NULL ) { - //printf("%s\n", pch); + if (debug >= 2) printf("%s\n", pch); exploded[x++] = atoi( pch ); pch = strtok( NULL , separator ); - } - fclose(fh); return x; }else @@ -327,7 +400,7 @@ int getprocinfo( struct connexion * conn ) sprintf( child_path, "/proc/%d/cmdline", conn->pid ); if ( (fh1= fopen( child_path, "r" )) == NULL) { - perror(child_path); + if (debug >= 1) perror(child_path); return 2; } fgets( str, 1024, fh1); @@ -338,7 +411,7 @@ int getprocinfo( struct connexion * conn ) sprintf( child_path, "/proc/%d/comm", conn->pid ); if ( (fh1= fopen(child_path, "r" )) == NULL) { - perror(child_path); + if (debug >= 1) perror(child_path); return 3; } fscanf( fh1, "%s", conn->cmd ); @@ -370,12 +443,14 @@ int main() char date[60]; time_t now = 0; char * language; - char * buff; +// char * buff; struct connexion conn; struct connexion connexions[n_ssh]; - struct config cfg = {"","",""}; + struct config cfg = {"","","",""}; + struct notify_config ncc; //char * ptr; + // Loading configuration readconfig( &cfg ); //localizing @@ -392,7 +467,7 @@ int main() sprintf( date, "%s", frtime(now)); if ( (fh = fopen(cfg.logfile, "a")) == NULL) { - perror(cfg.logfile); + if (debug >= 1) perror(cfg.logfile); return 7; } fprintf(fh, "%s: Démarrage de sshdetect\n", date); @@ -406,30 +481,30 @@ int main() r = system( str ); }else { - printf("no command defined: no command launched\n"); + if (debug >= 2) printf("no command defined: no command launched\n"); } exit(r); }else if( id<0 ) { - printf("erreur de création du fork: %s\n", str); + if (debug >= 1) printf("erreur de création du fork: %s\n", str); } - + init_config_watch( cfg.configfile, &ncc); while (1) { // get the sshd process ID (PID) if ( (fh = fopen("/run/sshd.pid", "r" )) == NULL) { - perror("/run/sshd.pid"); + if (debug >= 1) perror("/run/sshd.pid"); return 1; } if ( fscanf(fh, "%i", &pid) == 0) { - printf("erreur fscanf: /run/sshd.pid\n" ); + if (debug >= 1) printf("erreur fscanf: /run/sshd.pid\n" ); return 10; } fclose(fh); - //printf("%i", pid); + if (debug >= 1) printf("%i", pid); //get the list of children if ( (n=getpids( pid, pids )) != -1) @@ -457,13 +532,12 @@ int main() flag[x] = 1; connexions[x] = conn; // date of connexion - if (conn.user[0] == '\0') { - sprintf( str, "%s \"%s: tunnel ouvert le %s depuis %s avec la commande: %s %s\"", cfg.commande, cfg.hostname, conn.date, ip, conn.cmd, conn.cmdline ); + sprintf( str, "%s \"%s: tunnel ouvert le %s depuis %s pid: %d avec la commande: %s %s\"", cfg.commande, cfg.hostname, conn.date, ip, conn.pid, conn.cmd, conn.cmdline ); }else { - sprintf( str, "%s \"%s: %s s'est connecté le %s depuis %s avec la commande: %s %s\"", cfg.commande, cfg.hostname, conn.user, conn.date, ip, conn.cmd, conn.cmdline ); + sprintf( str, "%s \"%s: %s s'est connecté le %s depuis %s pid: %d avec la commande: %s %s\"", cfg.commande, cfg.hostname, conn.user, conn.date,ip, conn.pid, conn.cmd, conn.cmdline ); } if ( start != 1 ) { @@ -472,23 +546,23 @@ int main() { if ( (fh1 = fopen(cfg.logfile, "a")) == NULL) { - perror(cfg.logfile); + if (debug >= 1) perror(cfg.logfile); return 7; } fprintf(fh1, "%s: Connexion de %s depuis %s commande: %s %s\n", conn.date, conn.user, ip, conn.cmd, conn.cmdline); fclose(fh1); }else if (id < 0) { - printf("erreur de création du fork: %s\n", str); + if (debug >= 1) printf("erreur de création du fork: %s\n", str); }else { if (cfg.commande[0] != 0) { - printf("%s\n", str); + if (debug >= 1) printf("%s\n", str); r = system( str ); }else { - printf("no command defined: no command launched\n"); + if (debug >= 1) printf("no command defined: no command launched\n"); } exit(r); } @@ -496,7 +570,7 @@ int main() { if ( (fh1 = fopen(cfg.logfile, "a")) == NULL) { - perror(cfg.logfile); + if (debug >= 1) perror(cfg.logfile); return 7; } fprintf(fh1, "%s: %s Connecté depuis %s - %s %s\n", conn.date, conn.user, ip, conn.cmd, conn.cmdline); @@ -505,7 +579,7 @@ int main() }else if (rinfo == -1) { - printf("%i => 2 pids : en cours de connexion\n", conn.pid); + if (debug >= 2) printf("%i => 2 pids : en cours de connexion\n", conn.pid); } }else { @@ -518,10 +592,10 @@ int main() { time( &now ); sprintf( date, "%s", frtime(now) ); - printf( "Session %d de %s terminée le %s\n", connexions[i].pid, connexions[i].user, date ); + if (debug >= 2) printf( "Session %d de %s terminée le %s\n", connexions[i].pid, connexions[i].user, date ); if ( (fh1 = fopen(cfg.logfile, "a")) == NULL) { - perror(cfg.logfile); + if (debug >= 1) perror(cfg.logfile); return 7; } fprintf(fh1, "%s: pid %d -Connexion de %s terminée le %s\n", cfg.hostname, connexions[i].pid, connexions[i].user, connexions[i].date); @@ -537,9 +611,10 @@ int main() flag[i] = 0; } } - sleep(2); - waitpid(-1, &status ,WNOHANG); } + waitpid(-1, &status ,WNOHANG); +// sleep(1); + notify_config_change(&ncc, cfg.configfile, &cfg); start = 0; } return 0;