added dynamic reloading of configuration when file is modified.
This commit is contained in:
parent
4fed9b2ce5
commit
7aa7bce3d9
159
main.c
159
main.c
@ -8,9 +8,12 @@
|
|||||||
#include <utmp.h>
|
#include <utmp.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <libconfig.h>
|
#include <sys/inotify.h>
|
||||||
|
|
||||||
#define HOSTNAME "localhost"
|
#define HOSTNAME "localhost"
|
||||||
|
#define EVENT_SIZE (sizeof(struct inotify_event))
|
||||||
|
|
||||||
|
int debug = 0;
|
||||||
|
|
||||||
struct connexion
|
struct connexion
|
||||||
{
|
{
|
||||||
@ -30,9 +33,17 @@ struct config
|
|||||||
char commande[1024];
|
char commande[1024];
|
||||||
char logfile[4096];
|
char logfile[4096];
|
||||||
char hostname[128];
|
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] )
|
int explode( char * str, char * separator, size_t m, size_t n, char exploded[m][n] )
|
||||||
{
|
{
|
||||||
char * pch;
|
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 );
|
pch = strtok( str, separator );
|
||||||
while( pch != NULL )
|
while( pch != NULL )
|
||||||
{
|
{
|
||||||
//printf("%s\n", pch);
|
if (debug >= 2) printf("%s\n", pch);
|
||||||
strcpy( exploded[x++], pch) ;
|
strcpy( exploded[x++], pch) ;
|
||||||
pch = strtok( NULL , separator );
|
pch = strtok( NULL , separator );
|
||||||
}
|
}
|
||||||
@ -71,11 +82,12 @@ int readconfig( struct config * cfg )
|
|||||||
{
|
{
|
||||||
if ((fh = fopen( path[x], "r")) == NULL)
|
if ((fh = fopen( path[x], "r")) == NULL)
|
||||||
{
|
{
|
||||||
perror(path[x]);
|
if (debug >= 1) perror(path[x]);
|
||||||
if(x==1) retval = -1;
|
if(x==1) retval = -1;
|
||||||
}else
|
}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;
|
x = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,21 +101,22 @@ int readconfig( struct config * cfg )
|
|||||||
if ( fopen(exploded[1],"r") != NULL)
|
if ( fopen(exploded[1],"r") != NULL)
|
||||||
{
|
{
|
||||||
strcpy( cfg->commande, exploded[1] );
|
strcpy( cfg->commande, exploded[1] );
|
||||||
printf("Found command: %s\n", cfg->commande);
|
if (debug >= 1) printf("Found command: %s\n", cfg->commande);
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
perror(exploded[1]);
|
if (debug >= 1) perror(exploded[1]);
|
||||||
}
|
}
|
||||||
}else if( strcmp( exploded[0], "logfile") == 0)
|
}else if( strcmp( exploded[0], "logfile") == 0)
|
||||||
{
|
{
|
||||||
sprintf( logfilepath, "%s%s", homepath, "/.config/sshdetect.log");
|
|
||||||
if ( fopen(exploded[1], "a") != NULL )
|
if ( fopen(exploded[1], "a") != NULL )
|
||||||
{
|
{
|
||||||
strcpy( cfg->logfile, exploded[1] );
|
strcpy( cfg->logfile, exploded[1] );
|
||||||
|
if (debug >= 1) printf("Found logfile: %s\n", cfg->logfile);
|
||||||
}
|
}
|
||||||
}else if( strcmp( exploded[0], "hostname") == 0 )
|
}else if( strcmp( exploded[0], "hostname") == 0 )
|
||||||
{
|
{
|
||||||
strcpy( cfg->hostname, exploded[1] );
|
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 );
|
strcpy( cfg->logfile, logfilepath );
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
perror(logfilepath);
|
if (debug >= 1) perror(logfilepath);
|
||||||
strcpy(cfg->logfile, "/dev/null");
|
strcpy(cfg->logfile, "/dev/null");
|
||||||
retval += 2;
|
retval += 2;
|
||||||
}
|
}
|
||||||
@ -135,16 +148,15 @@ int readconfig( struct config * cfg )
|
|||||||
}
|
}
|
||||||
if (cfg->commande[0] == 0)
|
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;
|
retval += 4;
|
||||||
}
|
}
|
||||||
return retval;
|
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 )
|
int isinarray( int pid, int array[], int n )
|
||||||
{
|
{
|
||||||
//if (n == 0) return 0;
|
|
||||||
int x;
|
int x;
|
||||||
for(x=1;x<=n;x++)
|
for(x=1;x<=n;x++)
|
||||||
{
|
{
|
||||||
@ -152,7 +164,8 @@ int isinarray( int pid, int array[], int n )
|
|||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
} return 0;
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* frtime(const time_t timet)
|
char* frtime(const time_t timet)
|
||||||
@ -165,6 +178,67 @@ char* frtime(const time_t timet)
|
|||||||
return result;
|
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
|
//get utmp datas
|
||||||
void getutmp( struct connexion * conn, time_t * time )
|
void getutmp( struct connexion * conn, time_t * time )
|
||||||
{
|
{
|
||||||
@ -173,6 +247,7 @@ void getutmp( struct connexion * conn, time_t * time )
|
|||||||
int ipv4;
|
int ipv4;
|
||||||
int x;
|
int x;
|
||||||
char str[6];
|
char str[6];
|
||||||
|
|
||||||
conn->host_ip[0]='\0';
|
conn->host_ip[0]='\0';
|
||||||
conn->host_ipv6[0]='\0';
|
conn->host_ipv6[0]='\0';
|
||||||
setutent();
|
setutent();
|
||||||
@ -257,10 +332,10 @@ int getpids(int pid, int exploded[])
|
|||||||
int x = 0;
|
int x = 0;
|
||||||
|
|
||||||
sprintf( path, "/proc/%d/task/%d/children", pid, pid);
|
sprintf( path, "/proc/%d/task/%d/children", pid, pid);
|
||||||
//printf(" %s", proc_path);
|
if (debug >= 1) printf("process path: %s", path);
|
||||||
if ((fh = fopen( path, "r")) == NULL)
|
if ((fh = fopen( path, "r")) == NULL)
|
||||||
{
|
{
|
||||||
perror(path);
|
if (debug >= 1) perror(path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ( fgets( str, 40, fh ) != NULL )
|
if ( fgets( str, 40, fh ) != NULL )
|
||||||
@ -268,12 +343,10 @@ int getpids(int pid, int exploded[])
|
|||||||
pch = strtok( str, separator );
|
pch = strtok( str, separator );
|
||||||
while( pch != NULL )
|
while( pch != NULL )
|
||||||
{
|
{
|
||||||
//printf("%s\n", pch);
|
if (debug >= 2) printf("%s\n", pch);
|
||||||
exploded[x++] = atoi( pch );
|
exploded[x++] = atoi( pch );
|
||||||
pch = strtok( NULL , separator );
|
pch = strtok( NULL , separator );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
return x;
|
return x;
|
||||||
}else
|
}else
|
||||||
@ -327,7 +400,7 @@ int getprocinfo( struct connexion * conn )
|
|||||||
sprintf( child_path, "/proc/%d/cmdline", conn->pid );
|
sprintf( child_path, "/proc/%d/cmdline", conn->pid );
|
||||||
if ( (fh1= fopen( child_path, "r" )) == NULL)
|
if ( (fh1= fopen( child_path, "r" )) == NULL)
|
||||||
{
|
{
|
||||||
perror(child_path);
|
if (debug >= 1) perror(child_path);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
fgets( str, 1024, fh1);
|
fgets( str, 1024, fh1);
|
||||||
@ -338,7 +411,7 @@ int getprocinfo( struct connexion * conn )
|
|||||||
sprintf( child_path, "/proc/%d/comm", conn->pid );
|
sprintf( child_path, "/proc/%d/comm", conn->pid );
|
||||||
if ( (fh1= fopen(child_path, "r" )) == NULL)
|
if ( (fh1= fopen(child_path, "r" )) == NULL)
|
||||||
{
|
{
|
||||||
perror(child_path);
|
if (debug >= 1) perror(child_path);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
fscanf( fh1, "%s", conn->cmd );
|
fscanf( fh1, "%s", conn->cmd );
|
||||||
@ -370,12 +443,14 @@ int main()
|
|||||||
char date[60];
|
char date[60];
|
||||||
time_t now = 0;
|
time_t now = 0;
|
||||||
char * language;
|
char * language;
|
||||||
char * buff;
|
// char * buff;
|
||||||
struct connexion conn;
|
struct connexion conn;
|
||||||
struct connexion connexions[n_ssh];
|
struct connexion connexions[n_ssh];
|
||||||
struct config cfg = {"","",""};
|
struct config cfg = {"","","",""};
|
||||||
|
struct notify_config ncc;
|
||||||
//char * ptr;
|
//char * ptr;
|
||||||
|
|
||||||
|
// Loading configuration
|
||||||
readconfig( &cfg );
|
readconfig( &cfg );
|
||||||
|
|
||||||
//localizing
|
//localizing
|
||||||
@ -392,7 +467,7 @@ int main()
|
|||||||
sprintf( date, "%s", frtime(now));
|
sprintf( date, "%s", frtime(now));
|
||||||
if ( (fh = fopen(cfg.logfile, "a")) == NULL)
|
if ( (fh = fopen(cfg.logfile, "a")) == NULL)
|
||||||
{
|
{
|
||||||
perror(cfg.logfile);
|
if (debug >= 1) perror(cfg.logfile);
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
fprintf(fh, "%s: Démarrage de sshdetect\n", date);
|
fprintf(fh, "%s: Démarrage de sshdetect\n", date);
|
||||||
@ -406,30 +481,30 @@ int main()
|
|||||||
r = system( str );
|
r = system( str );
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
printf("no command defined: no command launched\n");
|
if (debug >= 2) printf("no command defined: no command launched\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(r);
|
exit(r);
|
||||||
}else if( id<0 )
|
}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)
|
while (1)
|
||||||
{
|
{
|
||||||
// get the sshd process ID (PID)
|
// get the sshd process ID (PID)
|
||||||
if ( (fh = fopen("/run/sshd.pid", "r" )) == NULL)
|
if ( (fh = fopen("/run/sshd.pid", "r" )) == NULL)
|
||||||
{
|
{
|
||||||
perror("/run/sshd.pid");
|
if (debug >= 1) perror("/run/sshd.pid");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ( fscanf(fh, "%i", &pid) == 0)
|
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;
|
return 10;
|
||||||
}
|
}
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
//printf("%i", pid);
|
if (debug >= 1) printf("%i", pid);
|
||||||
|
|
||||||
//get the list of children
|
//get the list of children
|
||||||
if ( (n=getpids( pid, pids )) != -1)
|
if ( (n=getpids( pid, pids )) != -1)
|
||||||
@ -457,13 +532,12 @@ int main()
|
|||||||
flag[x] = 1;
|
flag[x] = 1;
|
||||||
connexions[x] = conn;
|
connexions[x] = conn;
|
||||||
// date of connexion
|
// date of connexion
|
||||||
|
|
||||||
if (conn.user[0] == '\0')
|
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
|
}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 )
|
if ( start != 1 )
|
||||||
{
|
{
|
||||||
@ -472,23 +546,23 @@ int main()
|
|||||||
{
|
{
|
||||||
if ( (fh1 = fopen(cfg.logfile, "a")) == NULL)
|
if ( (fh1 = fopen(cfg.logfile, "a")) == NULL)
|
||||||
{
|
{
|
||||||
perror(cfg.logfile);
|
if (debug >= 1) perror(cfg.logfile);
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
fprintf(fh1, "%s: Connexion de %s depuis %s commande: %s %s\n", conn.date, conn.user, ip, conn.cmd, conn.cmdline);
|
fprintf(fh1, "%s: Connexion de %s depuis %s commande: %s %s\n", conn.date, conn.user, ip, conn.cmd, conn.cmdline);
|
||||||
fclose(fh1);
|
fclose(fh1);
|
||||||
}else if (id < 0)
|
}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
|
}else
|
||||||
{
|
{
|
||||||
if (cfg.commande[0] != 0)
|
if (cfg.commande[0] != 0)
|
||||||
{
|
{
|
||||||
printf("%s\n", str);
|
if (debug >= 1) printf("%s\n", str);
|
||||||
r = system( str );
|
r = system( str );
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
printf("no command defined: no command launched\n");
|
if (debug >= 1) printf("no command defined: no command launched\n");
|
||||||
}
|
}
|
||||||
exit(r);
|
exit(r);
|
||||||
}
|
}
|
||||||
@ -496,7 +570,7 @@ int main()
|
|||||||
{
|
{
|
||||||
if ( (fh1 = fopen(cfg.logfile, "a")) == NULL)
|
if ( (fh1 = fopen(cfg.logfile, "a")) == NULL)
|
||||||
{
|
{
|
||||||
perror(cfg.logfile);
|
if (debug >= 1) perror(cfg.logfile);
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
fprintf(fh1, "%s: %s Connecté depuis %s - %s %s\n", conn.date, conn.user, ip, conn.cmd, conn.cmdline);
|
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)
|
}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
|
}else
|
||||||
{
|
{
|
||||||
@ -518,10 +592,10 @@ int main()
|
|||||||
{
|
{
|
||||||
time( &now );
|
time( &now );
|
||||||
sprintf( date, "%s", frtime(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)
|
if ( (fh1 = fopen(cfg.logfile, "a")) == NULL)
|
||||||
{
|
{
|
||||||
perror(cfg.logfile);
|
if (debug >= 1) perror(cfg.logfile);
|
||||||
return 7;
|
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);
|
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;
|
flag[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sleep(2);
|
|
||||||
waitpid(-1, &status ,WNOHANG);
|
|
||||||
}
|
}
|
||||||
|
waitpid(-1, &status ,WNOHANG);
|
||||||
|
// sleep(1);
|
||||||
|
notify_config_change(&ncc, cfg.configfile, &cfg);
|
||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user