1
0

added dynamic reloading of configuration when file is modified.

This commit is contained in:
Daniel Tartavel 2020-05-17 22:19:03 +02:00
parent 4fed9b2ce5
commit 7aa7bce3d9

163
main.c
View File

@ -8,9 +8,12 @@
#include <utmp.h>
#include <locale.h>
#include <libgen.h>
#include <libconfig.h>
#include <sys/inotify.h>
#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;