diff --git a/bash-gitonly.c b/bash-gitonly.c index 23e4310..68ca91e 100644 --- a/bash-gitonly.c +++ b/bash-gitonly.c @@ -19,72 +19,82 @@ #define AUTHORIZED_COMMANDS "git-receive-pack","git-upload-pack","git-upload-archive" #define AUTHORIZED_COMMANDS_COUNT 3 + #define COMMANDS_PATH "/bin/" #define MAX_FULL_EXECFILENAME_LENGTH 24 #define BDD_PASS_FILE "/pipi-system.pass" #define BDD_CONN_LENGTH 255 +#define ERR(...) \ + fprintf(stderr, ANSI_COLOR_GREEN);\ + fprintf(stderr, ##__VA_ARGS__);\ + fprintf(stderr,ANSI_COLOR_RESET "\n"); + - -char* isCmdAuthorized(char* cmd){ - const char* authorizedCommands[] = {AUTHORIZED_COMMANDS}; - for (int i=0; ierror_code) { + ERR("Impossible de comprendre la commande, erreur nargv %i: %s: at input column %i", gitargv->error_code, gitargv->error_message, gitargv->error_index); + return 1; + } + // Verification que la commande envoyée est bien une commande git - char* sshCommandEnd = isCmdAuthorized(argv[2]); - if(sshCommandEnd == NULL){ - fprintf(stderr, ANSI_COLOR_GREEN "Wow ! ce canal est réservé aux commandes de données git, pour le reste, utilisez un «vrai» accès SSH" ANSI_COLOR_RESET "\n"); + if(strArrMem(gitargv->argv[0],authorizedCommands)==0){ + ERR("Wow ! ce canal est réservé aux commandes de données git, pour le reste, utilisez un «vrai» accès SSH"); + nargv_free(gitargv); return 1; - } - - // Parsing de la commande git - - NARGV* subargv = nargv_parse(argv[2]); - if (subargv->error_code) { - fprintf(stderr,ANSI_COLOR_GREEN "Impossible de comprendre la commande, erreur nargv %i: %s: at input column %i" ANSI_COLOR_RESET "\n", - subargv->error_code, subargv->error_message, subargv->error_index); - return 1; - } - char* subcmdName = subargv->argv[0]; - + } + // Récupération de l'utilisateur - char * userID = getenv("GIT_USERID"); + userID = getenv("GIT_USERID"); if(userID==NULL){ - fprintf(stderr,ANSI_COLOR_GREEN "Impossible de récupérer votre identifiant utilisateur ..." ANSI_COLOR_RESET "\n"); + ERR("Impossible de récupérer votre identifiant utilisateur ..."); + nargv_free(gitargv); return 1; } @@ -92,17 +102,13 @@ int main(int argc, char **argv, char **envp){ // Récupération du repo et du droit d'accès demandés // Normalement, la commande n'a que deux éléments: - char* repoName = subargv->argv[1]; + repoName = gitargv->argv[1]; - char connInfo[BDD_CONN_LENGTH] = "dbname='pipi' user=pipisys password='"; - char lastAp = '\''; - FILE *dbPassFile; - char ch; - int pos = strlen(connInfo); dbPassFile = fopen(BDD_PASS_FILE,"r"); if (dbPassFile == NULL) { - fprintf(stderr,ANSI_COLOR_GREEN "Cannot open file %s, on peut pas se connecter à la base de données en tant que l'uid %d" ANSI_COLOR_RESET "\n",BDD_PASS_FILE,geteuid()); + ERR("Cannot open file %s, on peut pas se connecter à la base de données en tant que l'uid %d", BDD_PASS_FILE, geteuid()); + nargv_free(gitargv); return 1; } while (feof(dbPassFile)) @@ -113,79 +119,77 @@ int main(int argc, char **argv, char **envp){ fclose(dbPassFile); connInfo[pos] = '\''; - PGconn *conn; - conn = PQconnectdb(connInfo); - PGresult *res; - int nFields; + + conn = PQconnectdb(connInfo); + /* Vérifier que la connexion au backend a été faite avec succès */ if (PQstatus(conn) != CONNECTION_OK) { - fprintf(stderr,ANSI_COLOR_GREEN "Connection to database failed: %s" ANSI_COLOR_RESET "\n",PQerrorMessage(conn)); + ERR("Connection to database failed: %s",PQerrorMessage(conn)); + nargv_free(gitargv); return 1; } res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,ANSI_COLOR_GREEN "SET failed: %s" ANSI_COLOR_RESET "\n",PQerrorMessage(conn)); + ERR("SET failed: %s", PQerrorMessage(conn)); PQclear(res); + nargv_free(gitargv); return 1; } PQclear(res); // Récupération de l'autorisation auprès du serveur Pgsql + accessTypeRequestValues[0] = userID; + accessTypeRequestValues[1] = repoName; - const char *paramValues[2]; - paramValues[0] = userID; - paramValues[1] = repoName; - - res = PQexecParams(conn, "SELECT git.\"AccessType\"($1,$2)",2,NULL,paramValues,NULL,NULL,1); + res = PQexecParams(conn, "SELECT git.\"AccessType\"($1,$2)",2,NULL,accessTypeRequestValues,NULL,NULL,1); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,ANSI_COLOR_GREEN "Impossible de lancer la requête SQL pour les autorisations: %s" ANSI_COLOR_RESET "\n",PQerrorMessage(conn)); + ERR("Impossible de lancer la requête SQL pour les autorisations: %s",PQerrorMessage(conn)); PQclear(res); + nargv_free(gitargv); return 1; } nFields = PQntuples(res); // Il y a toujours une seule valeur retournée, renvoie NULL si il n'y a rien - char* niveauAutorisation; niveauAutorisation = PQgetvalue(res, 0, 0); PQclear(res); PQfinish(conn); - fprintf(stderr,ANSI_COLOR_GREEN "Autorisation: sur %s pour l'id %s -> %s" ANSI_COLOR_RESET "\n",repoName,userID,niveauAutorisation); + //ERR("Autorisation: sur %s pour l'id %s -> %s",repoName,userID,niveauAutorisation)); if(niveauAutorisation[0]=='\0'){// If the string is empty i.e. NULL authorisations - fprintf(stderr,ANSI_COLOR_GREEN "Vous n'avez pas le droit d'accéder à ce repo. Il n'existe peut-être même pas ..." ANSI_COLOR_RESET "\n"); + ERR("Vous n'avez pas le droit d'accéder à ce repo. Il n'existe peut-être même pas ..."); + nargv_free(gitargv); return 1; } // Déjà on a la lecture - if(strcmp(subcmdName,"git-receive-pack")==0){ + if(strcmp(gitargv->argv[0],"git-receive-pack")==0){ // Il nous faut aussi le droit d'écriture if(strcmp(niveauAutorisation,"WRITE")!=0){ - fprintf(stderr,ANSI_COLOR_GREEN "Vous n'avez pas le droit d'écrire dans ce repo." ANSI_COLOR_RESET "\n"); + ERR("Vous n'avez pas le droit d'écrire dans ce repo."); + nargv_free(gitargv); return 1; } } // On effectue la commande. - - char execFilename[MAX_FULL_EXECFILENAME_LENGTH] = COMMANDS_PATH; - strcat(execFilename, subcmdName); + // Pour l'instant execFilename = COMMANDS_PATH; + strcat(execFilename, gitargv->argv[0]); - pid_t pid=fork(); - if (pid==0) { /* child process */ - execve(execFilename, subargv->argv, (char *const []){NULL}); // Pas d'environement + gitPid=fork(); + if (gitPid==0) { /* child process */ + execve(execFilename, gitargv->argv, (char *const []){NULL}); // Pas d'environement exit(127); /* only if execv fails */ } else { /* pid!=0; parent process */ - waitpid(pid,0,0); /* wait for child to exit */ + waitpid(gitPid,0,0); /* wait for child to exit */ } - - - nargv_free(subargv); - return 0; + nargv_free(gitargv); + return 1; }