Cgi common gateway interface en c

Description

Cette source permet a l'aide de formulaire html et d'un serveur supportant le Cgi de pouvoir créer des comptes dans un fichier data.log et de s'authentifier avec le compte que l'on a créé.

Le programme en C décompose correctement la requête POST afin de bien récupérer les variables de login et mot de passe et les écrit dans le fichier data.log si l'on est passé par le formulaire de création de compte ou teste les variables en lisant dans le fichier data.log si l'on est passé par le formulaire d'authentification.

NB: Compilé sous gcc, est fonctionnel grâce au serveur python "serveur.py". Il est préferable de faire fonctionner cette source sous linux car ca ne marche pas sous windows jusqu'à preuve du contraire ;D.

Source / Exemple :


/* C'est la source pour s'authentifier, regarder dans le zip pour tout avoir (-; be happy!!! */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Ces trois premieres fonctions permettent d'afficher du code correct en HTML, la fonction erreur permet d'afficher un message d'erreur en html si il ya un problème lors de la reception de la chaine en POST*/
void erreur (message)
{
  printf("\n<br><font color=\"red\">ERREUR : %s</font>", message);
  exit(0);
}
void reponsehttp (void)
{
  printf("Content-type: text/html\n\n");
}
void debutpage (char *titre)
{
  printf("\n<html>\n\t<head><title>%s\n</title>\n</head>", titre);
  printf("<body bgcolor=\"white\">\n");
}
void finpage (void)
{
  printf("</body></html>");
}
/* Voici la fonction decoupe qui va permettre de récupérer correctement les données reçues en POST,elle fonctionne avec le paremètre *entre qui correspond a la chaine de base, ensuite on trouve *sortie1 et *sortie2 qui sont deux variables qui contiendront la chaine de base découpée de par et d'autre par "carac", c'est à dire le caractère qu'on a choisi pour délimiter la chaîne */

void coupe (char *entree, char *sortie1, char* sortie2, char carac)
{
	char *position;
	
	position=strchr(entree, carac);
	
	strncpy(sortie2, position+1, strlen(position));
	strncpy(sortie1, entree, strlen(entree)-strlen(position));
  	
	sortie1[strlen(entree)-strlen(position)]='\0';
}
/* C'est grace a cette fonction que l'on va lire toutes les données du post */
char *LitDonneesPost()
{
  char *donnees; //donnees du formulaire
  char *chtaille;
  int taille; //taille des donnees
  chtaille = getenv("CONTENT_LENGTH");
  taille = atoi(chtaille);
  fflush(stdout);
  donnees = (char *) malloc(taille);
  if (donnees == NULL) erreur("pb allocation memoire");
  if (fread(donnees, 1, taille, stdin) != taille)
    erreur("Pb lecture entree standard");
  return donnees; 
}
/* dans cette fonction on va pouvoir traiter les données que l'on a recu dans le POST */
void recupdonnees(void)
{
FILE *fichier;
struct user { //ici on déclare la structure pour pouvoir lire dans le fichier data.log
char login[100];// c'est la variable qui contiendra le login du fichier
char passwd[100];// ici pour le mot de passe dans le fichier
};
struct user utilisateur;
int ok,ok2,i;//Declaration des deux booléens et initialisation à 0
ok=0;
ok2=0;
char login[20],maitre[20],yoda[20],name[20],input1[20],input2[20],pass[20],dechet1[30],dechet2[30];
//ici on declare toutes les variable char dont on a besoin, eh oui il yen a beaucoup !!!
long taille;
char *methode;
char *data;
	methode = getenv("REQUEST_METHOD");

	fflush(stdout);
	if (strcmp(methode,"POST")==0)
	data = LitDonneesPost();
	
	else exit(0);
	taille=strlen(data);

	for (i=0; i<taille; i++) if (data[i] == '&') data[i] = ' ' ;//ici on applique une boucle for afin de remplace l'esperluette par un espace et que cela soit par la suite plus aisé pour le decoupage

	//printf("<br>%s",data);
	coupe(data, input1, input2, ' ');//ici on coupe de par et d'autre la chaine recu a partir d'un espace et on met ce que l'on a obtenu dans deux variables input1 et input2

	coupe(input1,name,maitre,'=');// ici on va decouper le input1 de par et d'autre du "=" afin de récupérer maitre qui contient le login posté.La variable name contiendra simplement le nom qu'on a donné au input dans le formulaire HTML

	strcpy(login,maitre);// pour des raisons de bon fonctionnement il faut copier la chaine maitre dans login. Car a la fin de quelques utilisations de la fonction coupe, la variable "maitre" ne contenait plus le login.
	//printf("%s",login);

	coupe(input2,dechet1,yoda,'=');//le formulaire transmettait quelques données en plus avec x=un_nbre&y=un_nbre, il suffit juste d'utiliser cette fois-ci la fonction coupe deux fois pour récupérer le mot de passe posté

	coupe(yoda, pass, dechet2,' ');// le mot de passe posté se trouvera donc dans la variable passe
	//printf("%s",pass);

	/* une fois les variable de login et mot de passe correctement récupérées on peut enfin les comparées avec celle se trouvant dans le fichier data.log */
		fichier=fopen("data.log","rb");
			if (fichier != NULL){
			while (!feof(fichier)){
			fread(&utilisateur,sizeof(struct user),1,fichier);
			
			if(strcmp(utilisateur.login,login)==0){
			ok=1;
			if(strcmp(utilisateur.passwd,pass)==0){
			ok2=1;
			}
			}
			}
			}
			
		fclose(fichier);
		
		if(ok==1 && ok2==1) {
		printf("<p align=\"center\" <font color=\"green\">Vous etes bien enregistrer</font><p>");
		}
		else{
		printf("<p align=\"center\" <font color=\"red\">Mauvais login/password,Veuillez resaisir</font><p>");
		}
	
}
int main (int argc, char *argv[])
{
  reponsehttp();
  debutpage("Identification en Cgi");
  recupdonnees();
  finpage();
  return 0;
}

Conclusion :


On peut améliorer la source en écrivant des empreintes MD5 dans le fichier data.log au lieu d'écrire les mots de passe en brut (-; ! Je n'ai pas encore réussi, si quelqu'un veut bien essayer alors je ferais la mise à jour nécessaire !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.