From f05b00d6a83cffeb536f717c170ac7abfe2dd987 Mon Sep 17 00:00:00 2001 From: saut Date: Tue, 23 May 2000 22:51:15 +0200 Subject: [PATCH] Je veux rentrer dans l'histoire aussi. Version initiale. darcs-hash:20000523205115-b92a9-d4947e0175aedff70c10ecbadbea29fa5a1ca316.gz --- beastie.c | 189 +++++++++++++++++++++++++++++++++++ mailCRANS.c | 281 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 470 insertions(+) create mode 100644 beastie.c create mode 100644 mailCRANS.c diff --git a/beastie.c b/beastie.c new file mode 100644 index 00000000..62665d07 --- /dev/null +++ b/beastie.c @@ -0,0 +1,189 @@ +/* + * Un faux daemon. + * + * Copyright (c) 1999 Association CRANS. + * + * Auteur: Olivier Saut + * + * gvim c'est vraiment le pied :-) + * + * A faire : detecter le premier paquet SYN. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef LINUX +#include +#endif + + +#define kZamok_Tourne 1 +#define kPORT 514 /* Port de rshd */ +#define kMaxDaemonChildren 10 + +int nbrFils; + + +int daemon_init(void) { + pid_t pid; + + if((pid = fork())<0) + return (-1); + else if (pid !=0) { + (void)fprintf(stdout,"beastie launched : %d\n",pid); + exit(0); + } + setsid(); + chdir("/"); + umask(0); + return(0); +} + +/* Attention subtil (waitpid plutot que wait) :-) */ +void zombie(int signo) { + pid_t pid; + int stat; + + while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) + nbrFils--; + + return; +} + +void sigterm(int signo) { + syslog(LOG_NOTICE,"beastie killed by SIGTERM."); + closelog(); + exit(EXIT_SUCCESS); +} + + +int main(int argc, char *argv[]){ +int serv_sock, client_sock, cli_len; +struct sockaddr_in serv_addr, cli_addr; +struct hostent *cli_ent; +char *clientname,*message; +int PORT; +pid_t pid; +sig_t previous_handler; +char buffer[1024]; + + if(argc>1) + PORT=atoi(argv[1]); + else + PORT=kPORT; + + if(setuid(getuid())) { + perror("Setuid."); + exit(EXIT_FAILURE); + } + + /* On se daemonize */ + if(daemon_init()) { + perror("Initialize as daemon."); + exit(EXIT_FAILURE); + } + + /* Pour éviter les zombies (vade retro...) */ + previous_handler = signal(SIGCHLD,(sig_t)zombie); + if(previous_handler==SIG_ERR) { + perror("Installing SIGCHLD handler"); + exit(EXIT_FAILURE); + } + + /* Pour détecter le SIGTERM */ + previous_handler = signal(SIGTERM,(sig_t)sigterm); + if(previous_handler==SIG_ERR) { + perror("Installing SIGTERM handler"); + exit(EXIT_FAILURE); + } + + nbrFils=0; + +#ifndef LINUX + setproctitle("ecoute le port %d",PORT); +#endif + + openlog("beastie", LOG_PID|LOG_CONS,LOG_LOCAL2); + + serv_sock = socket(AF_INET, SOCK_STREAM, 0); + if (serv_sock < 0) + { + perror("Creating server socket."); + exit(EXIT_FAILURE); + } + + /* On remplit la structure */ + bzero((char *) &serv_addr, sizeof (serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(PORT); + + /* Et on lie la socket au port */ + if (bind(serv_sock, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) + { + perror("Binding server socket."); + exit(EXIT_FAILURE); + } + + listen(serv_sock,5); + + while(kZamok_Tourne) { + + cli_len = sizeof (cli_addr); + bzero((char *) &cli_addr, sizeof (cli_addr)); + + client_sock = accept(serv_sock, (struct sockaddr *) &cli_addr, &cli_len); + if (client_sock < 0) + { + perror("Accepting connection on server socket."); + break; + } + + /* On forke, on traite la requete dans le fils */ + /* Evaluation paresseuse */ + if((nbrFils++ < kMaxDaemonChildren) && ((pid=fork())==0) ) { + close(serv_sock); + clientname=inet_ntoa(cli_addr.sin_addr); /* On recupere le nom */ + /* Hehe t'es loggue mon pote */ + if(strcmp(clientname, "127.0.0.1")) { + if (!((cli_ent= gethostbyaddr((char *)&cli_addr.sin_addr.s_addr, + sizeof (u_long), AF_INET)) == (struct hostent *)0)) { + snprintf(buffer,1023, "Tentative de connexion de %s au port %d.",cli_ent->h_name,PORT); + syslog(LOG_NOTICE,buffer ); + } + else { + snprintf(buffer,1023, "Tentative de connexion de %s au port %d.",clientname,PORT); + syslog(LOG_NOTICE,buffer); + } + } + close(client_sock); + exit(0); + } + /* Fin du fork */ + + close(client_sock); + + } + + closelog(); + close(serv_sock); + exit( 0); +} diff --git a/mailCRANS.c b/mailCRANS.c new file mode 100644 index 00000000..8e10f1e2 --- /dev/null +++ b/mailCRANS.c @@ -0,0 +1,281 @@ +/* + * Mail a tous les adherents de CRANS. + * + * Copyright (c) 1999 Association CRANS. + * + * Auteur: Olivier Saut + * + * A faire : sécuriser les strcat, faire la gestion des bats avec la libregex... + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define kPCGuestUID 502 +#define kCorbeauUID 536 +#define kNobodyUID 65534 +#define kRealUsers 500 + +/* Prototypes */ +int mk_tmpfile(); +void edit(); +int sendmail(char *name); +void help(); +int isValidUID(uid_t uid); +void mySig_handler(int iInt); + +/* Variables globales */ +char *gTempname; +uid_t gCurrent_UID; +uid_t gUid_start; +uid_t gUid_stop; +int gVerbose; +int gSimulate; + +/* Programme principal */ +int main(int argc, char *argv[]) +{ + + struct passwd *passwd_ent; + struct passwd *user; + char buf[1024]; + extern char *optarg; + extern int optind; + int ch ; + struct stat begin, end; + sig_t previous_handler; + char tildefn[MAXPATHLEN]; + int fd=-1; + + + gUid_start=kRealUsers; + gUid_stop=kNobodyUID; + gVerbose=0; + gSimulate=0; + while ((ch = getopt(argc, argv, "svhf:d:a:")) != -1) + switch (ch) { + case 'h': + help(); + break; + case 'v': + gVerbose=1; + break; + case 's': + gVerbose=1; + gSimulate=1; + break; + case 'f': + gTempname=optarg; + if ((fd = open(optarg, O_RDONLY, 0)) < 0) { + (void)fprintf(stderr, + "myname: %s: %s\n", optarg, strerror(errno)); + exit(1); + } + break; + case 'd': + gUid_start=atoi(optarg); + break; + case 'a': + gUid_stop=atoi(optarg); + break; + + } + argc -= optind; + argv += optind; + + previous_handler = signal(SIGTERM & SIGINT,(sig_t) mySig_handler); + if(previous_handler==SIG_ERR) { + (void)fprintf(stderr,"Erreur lors de l'installation du sighandler."); + exit(EXIT_FAILURE); + } + + + if(gVerbose) + fprintf(stdout,"mailCRANS by OS. Version 0.1\n"); + + if(fd==-1) { + fd=mk_tmpfile(); + user=getpwuid(getuid()); + sprintf(buf,"From: %s\nSubject: \nReply-To: \nContent-Type: text/plain; charset=iso-8859-1", user->pw_name); + + if (write (fd,(void *)buf,strlen(buf)) < 0) { + close(fd); + fprintf(stderr, "Erreur en écriture."); + exit(EXIT_FAILURE); + } + + (void) fsync(fd); + if(fstat(fd,&begin)) { + perror("Erreur stat(1)"); + close(fd); + exit(EXIT_FAILURE); + } + + + (void) edit(); + + if(stat(gTempname,&end)) { + perror("Erreur stat(2)"); + close(fd); + exit(EXIT_FAILURE); + } + + if (begin.st_mtime == end.st_mtime) { + warnx("No changes made : exiting"); + close(fd); + (void)unlink(gTempname); + exit(EXIT_FAILURE); + } + } + + + + setpwent(); + + while((int)(passwd_ent=(struct passwd *)getpwent())) { + gCurrent_UID=passwd_ent->pw_uid; + + if(isValidUID(gCurrent_UID)) + if(sendmail(passwd_ent->pw_name )) { + exit(EXIT_FAILURE); + } + else + usleep(250000); + } + + endpwent(); + + (void)unlink(gTempname); + /* Bon on efface le fichier parasite */ + (void)strcpy((char *)tildefn,gTempname); + (void)strcat((char *)tildefn,"~"); + + if(!access(tildefn,F_OK)) + (void)unlink(tildefn); + + return 0; +} + +int isValidUID(uid_t uid) { + if(uidgUid_stop) + return 0; + + if((uid==kPCGuestUID)|| (uid==kCorbeauUID) || (uid==kNobodyUID)) + return 0; + + return 1; +} + +void mySig_handler(int iInt) { + (void) fprintf(stdout,"\n Signal %d intercepté.\n",iInt); + (void) fprintf(stderr,"Le programme s'est arreté sur l'uid : %d\n",gCurrent_UID); + exit(EXIT_SUCCESS); +} + +int mk_tmpfile() +{ + int fd; + char p[MAXPATHLEN]; + p[MAXPATHLEN-1]='\0'; + + strcpy(p, "/tmp/EAll.XXXXXX"); + if ((fd = mkstemp(p)) == -1) + err(1, "%s", p); + gTempname = malloc(strlen(p)); + (void)strncpy(gTempname,p,strlen(p)); + if(gVerbose) + fprintf(stdout,"Tempfile name : %s\n",gTempname); + return (fd); +} + +void edit() +{ + int pstat; + int editpid; + char *p, *editor; + + if (!(editor = getenv("EDITOR"))) + editor = _PATH_VI; + if ((p = strrchr(editor, '/'))) + ++p; + else + p = editor; + + if (!(editpid = fork())) { + errno = 0; + execlp(editor, p, gTempname, NULL); + _exit(errno); + } + for (;;) { + editpid = waitpid(editpid, (int *)&pstat, WUNTRACED); + errno = WEXITSTATUS(pstat); + (void) fprintf(stderr,"\n *** %d ***\n",WEXITSTATUS(pstat)); + if (editpid == -1) + exit(EXIT_FAILURE); + else if (WIFSTOPPED(pstat)) + raise(WSTOPSIG(pstat)); + else if (WIFEXITED(pstat) && errno == 0) + break; + else + exit(EXIT_FAILURE); + } + editpid = -1; +} + + + +int sendmail(char *pw_name) { + int res=0; + char *buff; + int length; + buff=malloc(1024); + + buff[1023]='\0'; + buff[0]='\0'; + + (void)strcat((char *)buff,(const char *)"cat "); + (void)strcat(buff,(const char *) gTempname); + (void)strcat(buff, " | sendmail "); + (void)strcat(buff, pw_name); + if(gVerbose) + fprintf(stdout,"\n ** %s ** \n", buff); + if(!gSimulate) + res=system(buff); + return res; +} + +void help() { + fprintf(stdout,"usage: mailCRANS [-v] [-s] [-f filename] [-{d,a} uid]\n"); + fprintf(stdout," -v : mode bavard\n"); + fprintf(stdout," -f filename : envoie le fichier en argument\n"); + fprintf(stdout," (rajouter une ligne Subject: en première ligne du fichier pour avoir un sujet\n"); + fprintf(stdout," -d uid : envoie à partir de l'UID argument\n"); + fprintf(stdout," -a uid : arrete après l'UID argument\n"); + fprintf(stdout," -s : mode simulation."); + exit(EXIT_SUCCESS); + +} + +