/*
** Ce programme genere les tableaux contenant de maniere
** aleatoire les empreintes md5, les inodes et les mots de passe
** associes. Il est lie au script shell generesrc.sh dont il
** prend le fichier de sortie en argument.
**
**	fichier genesrc.c	Andre Brouty juin - juillet 2001
**
**	Usage: genesrc nb_empreintes cle_aleatoire fichier_temp nb_de_shell
**             fichier_temp contient les chemins, les empreintes et les mots de passe associes
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "donnemdp.h"

u_char auxtab[TALEA];

main(argc,argv)
int argc;
char *argv[];

{
  int i, j, al, ind, nbsh;
  FILE *fp;
  struct stat bufrep;
  void alea();
  char line[MAXLINE], *str, *strchr(), *strtok(), *name;
  if(argc < 5)
    exit(1);
  nbsh = 0;
  al = calalea(argv[2]);
  if((fp=fopen(argv[3],"r")) == (FILE *)0) {
    fprintf(stderr,"Le fichier temporaire des donnees (%s) n'est pas accessible\n",argv[3]);
    exit(1);
  }
  alea(al);
  printf("\n#define NBDATA   %d\n#define NBDT     %d\n\nstruct script tscript[NBDATA];\n\n",atoi(argv[1]),atoi(argv[4]));
  printf("\n#ifdef SHELLNAME\nstruct sh shell[NBDT];\n#endif\n\n");
  for(i=0;i<TALEA;++i) {
    printf("talea[%d] = %d;\n",i,talea[i]);
  }
  printf("\n");
  i = 0;
  ind = 0;
  al = 0;
  while(fgets(line,MAXLINE,fp) != NULL) {
    switch(line[0]) {
    case 'C': /* chemin du script */
      if(al == 3) {
	al = 1;
	++i;
      }
      else
	++al;
      strtok(line,"\040\011");
      if(stat(strtok((char *)0,"\040\011\012\15"), &bufrep) < 0) {
	fprintf(stderr,"Le script (%s) n'est pas accessible\n",line);
      }
      printf("tscript[%d].finode = %ld;\ntscript[%d].device = %ul;\n",i,bufrep.st_ino,i,(int)bufrep.st_dev);
      printf("\n");
      break;
    case 'E': /* empreinte du script */
      if(al == 3) {
	al = 1;
	++i;
      }
      else
	++al;
      strtok(line,"\040\011");
      placealea(1,strtok((char *)0,"\040\011"));
      for(j=0;j<TALEA;++j)
	printf("tscript[%d].md5tab[%d] = '%c';\n",i,j,auxtab[j]);
      printf("\n");
      break;
    case 'P': /* mot de passe associe */
      if(al == 3) {
	al = 1;
	++i;
      }
      else
	++al;
      str = strchr(line,':');
      if(str == (char *)0) {
	fprintf(stderr,"Erreur de syntaxe dans le fichier temporaire des donnees %s\n",argv[3]);
	exit(1);
      };
      ++str;
      while (*str == ' ' || *str == '\t')
	++str;
      placealea(0,str);
      printf("tscript[%d].tpwd = %d;\n\n",i,MIN(strlen(str),TALEA -1));
      for(j=0;j<TALEA;++j)
	printf("tscript[%d].passwd[%d] = '%c';\n",i,j,auxtab[j]);
      printf("\n");
      break;
    case 'T': /* chemin de la commande autorisee a appeler le script */
      strtok(line,"\040\011");
      if(stat(strtok((char *)0,"\040\011\012\15"), &bufrep) < 0) {
	fprintf(stderr,"Fichier %s pas accessible! Modifier le fichier de configuration\n",line);
	continue;
      }
      printf("#ifdef TRACENAME\ntraceaut[%d].finode = %ul;\ntraceaut[%d].device = %ul;\n",ind,(int)bufrep.st_ino,ind,(int)bufrep.st_dev);
      printf("#endif\n\n");
      break;
    case 'V': /* empreinte md5 du script */
      strtok(line,"\040\011");
      placealea(1,strtok((char *)0,"\040\011"));
      printf("#ifdef TRACENAME\n");
      for(j=0;j<TALEA;++j)
	printf("traceaut[%d].md5tab[%d] = '%c';\n",ind,j,auxtab[j]);
      printf("#endif\n\n");
      ++ind;
      break;
    case 'S': /* chemin de l'interprete shell utilise */
      strtok(line,"\040\011");
      if(stat(strtok((char *)0,"\040\011\012\15"), &bufrep) < 0) {
	fprintf(stderr,"L'interprete shell (%s) n'est pas accessible! Modifier le fichier de configuration\n",line);
	exit(1);
      }
      printf("#ifdef SHELLNAME\nshell[%d].finode = %ul;\nshell[%d].device = %ul;\n",nbsh,(int)bufrep.st_ino,nbsh,(int)bufrep.st_dev);
      printf("#endif\n\n");
      break;
    case 'U': /* empreinte associee a l'interprete shell */
      strtok(line,"\040\011");
      placealea(1,strtok((char *)0,"\040\011"));
      printf("#ifdef SHELLNAME\n");
      for(j=0;j<TALEA;++j)
	printf("shell[%d].md5tab[%d] = '%c';\n",nbsh,j,auxtab[j]);
      printf("#endif\n\n");
      ++nbsh;
      break;
    default:
      break;
    }
  }
  exit(0);
}

void alea(al)
     int al;
     
{
  int i, permut();
  srand(rand() + getpid() + al);
  for(i=0;i<TALEA;++i) {
    talea[i] = -1;
  }
  for(i=0;i<TALEA;++i) {
    talea[i] = permut(rand() % TALEA);
  }
}

permut(alea)
     int alea;
     
{
  int i, boucle = 0;
  while(exist(alea)) {
    alea = rand() % TALEA;
    ++boucle;
    if(boucle > 1000) /* il faut prevoir un bouclage eventuel */
      break;
  }
  if(boucle > 1000) {
    i = 0; /* si ca boucle on prend le premier de libre */
    while(exist(i))
      ++i;
    return(i);
  }
  return(alea);
}

exist(n)
     int n;
     
{
  int i;
  for(i=0;i<TALEA;++i) {
    if(talea[i] == n)
      return(1);
  }
  return(0);
}

calalea(ch)
     char *ch;
     
{
  int i = 0;
  while(*ch++)
    i = i + (int)(*ch);
  return(i);
}

placealea(n,ch)
     int n;
     char *ch;
     
{
  int i=0;
  ch[strlen(ch) - 1] = 0; /* elimination du retour chariot mis par echo */
  while(*ch && i < TALEA) {
    auxtab[(int)talea[i]] = *ch;
    ++i;
    ++ch;
  }
  if(n) /* md5 */
    while(i<TALEA) {
      auxtab[(int)talea[i]] = (i%2) ? (u_char) (rand() % 10 + 48) : (u_char) (rand() % 6 + 97);
      ++i;
    }
  else /* mot de passe */
    while(i<TALEA) {
      auxtab[(int)talea[i]] = (i%2) ? (u_char) (rand() % 42 + 48) : (u_char) (rand() % 26 + 97);
      ++i;
    }
}
