added dynamic reloading of configuration when file is modified.
This commit is contained in:
parent
4fed9b2ce5
commit
7aa7bce3d9
163
main.c
163
main.c
@ -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;
|
||||
|
Reference in New Issue
Block a user