Ajout de la Webterface, renommage du SQL

This commit is contained in:
Mysaa Java 2021-07-28 22:52:43 +02:00
parent 09af348180
commit 18b2647b12
10 changed files with 224 additions and 41 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
auth-keys-gen auth-keys-gen
cgit-config-gen cgit-config-gen
gen-readable-list
bash-gitonly bash-gitonly
*.so *.so
*.o *.o

View File

@ -1,6 +1,6 @@
.PHONY: all install .PHONY: all install
all: bash-gitonly pam_oath_key.so auth-keys-gen cgit-config-gen all: bash-gitonly pam_oath_key.so auth-keys-gen cgit-config-gen webterface.cgi
argvt.o: nargv/nargv.c argvt.o: nargv/nargv.c
gcc -c nargv/nargv.c -o argvt.o gcc -c nargv/nargv.c -o argvt.o
@ -14,9 +14,11 @@ auth-keys-gen: authKeysPg.c
gcc authKeysPg.c -o auth-keys-gen -L/usr/server/postgresql/lib -I/usr/server/postgresql/include -lpq gcc authKeysPg.c -o auth-keys-gen -L/usr/server/postgresql/lib -I/usr/server/postgresql/include -lpq
cgit-config-gen: cgit-config-gen.c cgit-config-gen: cgit-config-gen.c
gcc cgit-config-gen.c -o cgit-config-gen -L/usr/server/postgresql/lib -I/usr/server/postgresql/include -lpq $(CFLAGS) gcc cgit-config-gen.c -o cgit-config-gen -L/usr/server/postgresql/lib -I/usr/server/postgresql/include -lpq $(CFLAGS)
webterface.cgi: webterface.c
gcc webterface.c -o webterface.cgi -L/usr/server/postgresql/lib -I/usr/server/postgresql/include -lpq $(CFLAGS)
install-sql: sql/AccessType.sql sql/ReadableRepos.sql install-sql: sql/AccessType.sql sql/AccessibleRepos.sql
/usr/server/postgresql/bin/psql -Upostgres -dpipi -f sql/AccessType.sql -f sql/ReadableRepos.sql /usr/server/postgresql/bin/psql -Upostgres -dpipi -f sql/AccessType.sql -f sql/AccessibleRepos.sql
install: all install: all
cp pam_oath_key.so /lib/security cp pam_oath_key.so /lib/security
@ -24,3 +26,5 @@ install: all
cp bash-gitonly /srv/git/bin cp bash-gitonly /srv/git/bin
cp auth-keys-gen /srv/etc/auth-git-keys cp auth-keys-gen /srv/etc/auth-git-keys
cp cgit-config-gen /srv/etc/cgit-config-gen cp cgit-config-gen /srv/etc/cgit-config-gen
cp webterface.cgi /srv/admin/webterface/webterface.cgi
cp clone-all.sh /srv/admin/public/clone-all.sh

View File

@ -59,7 +59,7 @@ int main(int argc, char **argv, char **envp){
PGresult *res; PGresult *res;
int nFields; int nFields;
const char *accessTypeRequestValues[2]; const char *accessTypeRequestValues[3];
char* niveauAutorisation; char* niveauAutorisation;
char execFilename[MAX_FULL_EXECFILENAME_LENGTH] = COMMANDS_PATH; char execFilename[MAX_FULL_EXECFILENAME_LENGTH] = COMMANDS_PATH;
@ -142,8 +142,8 @@ int main(int argc, char **argv, char **envp){
// Récupération de l'autorisation auprès du serveur Pgsql // Récupération de l'autorisation auprès du serveur Pgsql
accessTypeRequestValues[0] = userID; accessTypeRequestValues[0] = userID;
accessTypeRequestValues[1] = repoName; accessTypeRequestValues[1] = repoName;
accessTypeRequestValues[2] = (strcmp(gitargv->argv[0],"git-receive-pack")==0)?"WRITE":"READ";
res = PQexecParams(conn, "SELECT git.\"AccessType\"($1,$2)",2,NULL,accessTypeRequestValues,NULL,NULL,1); res = PQexecParams(conn, "SELECT * FROM git.\"AccessibleRepos\"($1,$3) WHERE path=$2;",3,NULL,accessTypeRequestValues,NULL,NULL,1);
if (PQresultStatus(res) != PGRES_TUPLES_OK) { if (PQresultStatus(res) != PGRES_TUPLES_OK) {
ERR("Impossible de lancer la requête SQL pour les autorisations: %s",PQerrorMessage(conn)); ERR("Impossible de lancer la requête SQL pour les autorisations: %s",PQerrorMessage(conn));
PQclear(res); PQclear(res);
@ -153,28 +153,15 @@ int main(int argc, char **argv, char **envp){
} }
nFields = PQntuples(res); nFields = PQntuples(res);
// Il y a toujours une seule valeur retournée, renvoie NULL si il n'y a rien
niveauAutorisation = PQgetvalue(res, 0, 0);
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
//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 if(nFields<1){
ERR("Vous n'avez pas le droit d'accéder à ce repo. Il n'existe peut-être même pas ..."); ERR("Vous n'avez pas le droit d'accéder à ce repo. Il n'existe peut-être même pas ...");
nargv_free(gitargv); nargv_free(gitargv);
return 1; return 1;
} }
// Déjà on a la lecture
if(strcmp(gitargv->argv[0],"git-receive-pack")==0){
// Il nous faut aussi le droit d'écriture
if(strcmp(niveauAutorisation,"WRITE")!=0){
ERR("Vous n'avez pas le droit d'écrire dans ce repo.");
nargv_free(gitargv);
return 1;
}
}
// On effectue la commande. // On effectue la commande.
// Pour l'instant execFilename = COMMANDS_PATH; // Pour l'instant execFilename = COMMANDS_PATH;
strcat(execFilename, gitargv->argv[0]); strcat(execFilename, gitargv->argv[0]);
@ -192,5 +179,5 @@ int main(int argc, char **argv, char **envp){
nargv_free(gitargv); nargv_free(gitargv);
return 1; return 0;
} }

View File

@ -92,10 +92,10 @@ main(int argc, char **argv)
} }
PQclear(res); PQclear(res);
// Demande les données à la BDD // Demande les données à la BDD
const char const * sqlParamValues[] = {"0"}; const char const * sqlParamValues[] = {"0"};
res = PQexecParams(conn,"SELECT path,owner,description,logoUrl,groupeID,gdr.nom FROM git.\"ReadableRepos\"($1) JOIN git.\"groupesDeRepo\" AS gdr ON gdr.\"ID\"=groupeID ORDER BY groupeID",1,NULL,sqlParamValues,NULL,NULL,0); res = PQexecParams(conn,"SELECT path,owner,description,logoUrl,groupeID,gdr.nom FROM git.\"AccessibleRepos\"($1,'READ') JOIN git.\"groupesDeRepo\" AS gdr ON gdr.\"ID\"=groupeID ORDER BY groupeID",1,NULL,sqlParamValues,NULL,NULL,0);
if (PQresultStatus(res) != PGRES_TUPLES_OK) { if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr,"Impossible de lancer la requête SQL pour la liste des repos: %s",PQerrorMessage(conn)); fprintf(stderr,"Impossible de lancer la requête SQL pour la liste des repos: %s",PQerrorMessage(conn));
PQclear(res); PQclear(res);
@ -106,7 +106,7 @@ main(int argc, char **argv)
// Renvoie le résultat à travers stdout // Renvoie le résultat à travers stdout
for (i = 0; i < PQntuples(res); i++) for (i = 0; i < PQntuples(res); i++)
{ {
if(PQgetisnull(res,i,4)!=1 && (strcmp(PQgetvalue(res, i, 4),lastRgid)!=0)){ if(PQgetisnull(res,i,4)!=1 && (strcmp(PQgetvalue(res, i, 4),lastRgid)!=0)){
lastRgid = PQgetvalue(res, i, 4); lastRgid = PQgetvalue(res, i, 4);
printf("\nsection=%s\n\n",PQgetvalue(res,i,5)); printf("\nsection=%s\n\n",PQgetvalue(res,i,5));

34
clone-all.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
token=FgBxePzpabd+9D1EJWrZ4tEbY6UQ5QLFR+7tdrtfCqFbN210trnyAynByxlsb2voDkz1oR1yoZkPR9mMMwPxjw
liste=`curl https://admin.bernard.com.de/wtf/$token/list-readable-repos`
for path in $liste
do
if [ -f ./$path ]
then
echo "Vérification du repo $path"
if [[ ! -z $(git -C "./$path" status -s) ]]
then
echo "Le repository $path a des fichiers non enregistrés dans un commit... faudrait y corriger"
git -C "./$path" status
exit 1
fi
# Bon. on télécharge
if git -C "./$path" pull
then
/bin/true # Ou bien rien à merge, ou bien ca à marché.
else
# Impossible de merge
echo "Le repository $path a suivi un chemin de commits différent, il faut résoudre ça à la main."
exit 1
fi
# Enfin, on envoie nos changements
git -C "./$path" push --all
else
git clone git@bernard.com.de:$path ./$path
fi
done

View File

@ -166,6 +166,15 @@ pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char ** argv
D("Running the oath authenticator !\n"); D("Running the oath authenticator !\n");
D("Environement récupéré:\n");
char** envp = pam_getenvlist(pamh);
for (char **env = envp; *env != 0; env++)
{
char *thisEnv = *env;
printf("%s\n", thisEnv);
}
/***** Parsing config *****/ /***** Parsing config *****/
parse_cfg(pamh, flags, argc, argv, &cfg); parse_cfg(pamh, flags, argc, argv, &cfg);

View File

@ -8,7 +8,10 @@ AS $code$
DECLARE DECLARE
selectedrepo git.gitrepoaccesstype; selectedrepo git.gitrepoaccesstype;
BEGIN BEGIN
IF gitrepo LIKE '/%'
THEN gitrepo := SUBSTRING(gitrepo,1,LENGTH(gitrepo)-1);
END IF;
/* user.repo */ /* user.repo */
SELECT MAX("accessType") SELECT MAX("accessType")
INTO selectedrepo INTO selectedrepo
@ -16,26 +19,26 @@ BEGIN
JOIN git.repos ON "repoID"=repos."ID" JOIN git.repos ON "repoID"=repos."ID"
WHERE repos.path=gitrepo AND "userID"=gituserid; WHERE repos.path=gitrepo AND "userID"=gituserid;
RETURN selectedrepo;
IF selectedrepo != NULL IF selectedrepo != NULL
THEN RETURN selectedrepo; THEN RETURN selectedrepo;
END IF; END IF;
RAISE WARNING 'Le repo na pas marche 2';
/* groupe.repo */ /* groupe.repo */
SELECT MAX('accessType') SELECT MAX(perms."accessType")
INTO selectedrepo INTO selectedrepo
FROM git.perms FROM git.perms
JOIN git.repos ON repoID=repos."ID" JOIN git.repos ON "repoID"=repos."ID"
JOIN git.appartenances ON appartenances."groupeID"=-perms."userID" JOIN git.appartenances ON appartenances."groupeID"=-perms."userID"
WHERE repos.path=gitrepo AND appartenances."utilisateurID"=gituserid; WHERE repos.path=gitrepo AND appartenances."utilisateurID"=gituserid;
IF selectedrepo != NULL IF selectedrepo != NULL
THEN RETURN selectedrepo; THEN RETURN selectedrepo;
END IF; END IF;
RAISE WARNING 'Le repo na pas marche 3';
/* user.repoGroup */ /* user.repoGroup */
SELECT MAX('accessType') SELECT MAX("accessType")
INTO selectedrepo INTO selectedrepo
FROM git.perms FROM git.perms
JOIN git.repos ON "repoID"=-repos."groupeID" JOIN git.repos ON "repoID"=-repos."groupeID"
@ -44,9 +47,9 @@ BEGIN
IF selectedrepo != NULL IF selectedrepo != NULL
THEN RETURN selectedrepo; THEN RETURN selectedrepo;
END IF; END IF;
RAISE WARNING 'Le repo na pas marche 4';
/* groupe.repoGroupe */ /* groupe.repoGroupe */
SELECT MAX('accessType') SELECT MAX("accessType")
INTO selectedrepo INTO selectedrepo
FROM git.perms FROM git.perms
JOIN git.appartenances ON appartenances."groupeID"=-perms."userID" JOIN git.appartenances ON appartenances."groupeID"=-perms."userID"

View File

@ -1,5 +1,6 @@
CREATE OR REPLACE FUNCTION git."ReadableRepos" ( CREATE OR REPLACE FUNCTION git."AccessibleRepos" (
gituserid integer gituserid integer,
accesst git.gitrepoaccesstype
) )
RETURNS table( RETURNS table(
ID integer, ID integer,
@ -18,26 +19,26 @@ BEGIN
SELECT repos.* SELECT repos.*
FROM git.perms FROM git.perms
JOIN git.repos ON "repoID"=repos."ID" JOIN git.repos ON "repoID"=repos."ID"
WHERE "accessType">='READ' AND "userID"=gituserid WHERE "accessType">=accesst AND "userID"=gituserid
UNION UNION
/* groupe.repo */ /* groupe.repo */
SELECT repos.* SELECT repos.*
FROM git.perms FROM git.perms
JOIN git.repos ON "repoID"=repos."ID" JOIN git.repos ON "repoID"=repos."ID"
JOIN git.appartenances ON appartenances."groupeID"=-perms."userID" JOIN git.appartenances ON appartenances."groupeID"=-perms."userID"
WHERE "accessType">='READ' AND appartenances."utilisateurID"=gituserid WHERE "accessType">=accesst AND appartenances."utilisateurID"=gituserid
UNION UNION
/* user.repoGroup */ /* user.repoGroup */
SELECT repos.* SELECT repos.*
FROM git.perms FROM git.perms
JOIN git.repos ON "repoID"=-repos."groupeID" JOIN git.repos ON "repoID"=-repos."groupeID"
WHERE "accessType">='READ' AND "userID"=gituserid WHERE "accessType">=accesst AND "userID"=gituserid
UNION UNION
/* groupe.repoGroupe */ /* groupe.repoGroupe */
SELECT repos.* SELECT repos.*
FROM git.perms FROM git.perms
JOIN git.appartenances ON appartenances."groupeID"=-perms."userID" JOIN git.appartenances ON appartenances."groupeID"=-perms."userID"
JOIN git.repos ON "repoID"=-repos."groupeID" JOIN git.repos ON "repoID"=-repos."groupeID"
WHERE "accessType">='READ' AND "userID"=gituserid; WHERE "accessType">=accesst AND "userID"=gituserid;
END END
$code$ $code$

144
webterface.c Normal file
View File

@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <dirent.h>
#define BDD_PASS_FILE "/srv/bdd/pipi-system.pass"
#define BDD_CONN_LENGTH 255
int
main(int argc, char **argv, char **envp)
{
// Print cgi headers
printf("Content-Type: text/plain; charset=UTF-8\n\n");
char* pathInfo = getenv("PATH_INFO");
if(pathInfo==NULL){
printf("Je n'ai pas accès au PATH_INFO.\n");
return 2;
}
const char slash[] = {'/'};
char* token = strtok(pathInfo,slash);
if(token == NULL){
printf("Il vous faut un token non nul pour accéder à l'interface\n");
return 2;
}
char* action = strtok(NULL,slash);
if(action == NULL){
printf("Que voulez-vous faire avec votre token %s ?\n",token);
return 2;
}
char* reste = strtok(NULL,slash);
//printf("Données récupérées: %s, puis %s, puis %s",token,action,reste);
int i;
/*
//Dumping args
for(i = 0; i < argc; i++)
printf("argv[%d] -> %s\n",i,argv[i]);
//Dumping env
for (char **env = envp; *env != 0; env++)
{
char *thisEnv = *env;
printf("env: %s\n", thisEnv);
}
printf("-------------------------------------------\n");
*/
char connInfo[BDD_CONN_LENGTH] = "host='/var/run/postgresql' dbname='pipi' user=pipisys password='";
FILE *dbPassFile;
char ch;
int pos = strlen(connInfo);
PGconn *conn;
PGresult *res;
char* userId = "0";
if(argc>1){
userId=*(argv+1);
}
// Récupère le mdp à la BDD
dbPassFile = fopen(BDD_PASS_FILE,"r");
if (dbPassFile == NULL) {
fprintf(stderr,"Cannot open file %s, on peut pas se connecter à la base de données pour lister les clés en tant que %d -> fopen error %d\n", BDD_PASS_FILE,geteuid(),errno);
return 1;
}
while (feof(dbPassFile))
{
connInfo[pos] = fgetc(dbPassFile);
pos++;
}
fclose(dbPassFile);
connInfo[pos] = '\'';
// Connecte à la BDD
conn = PQconnectdb(connInfo);
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
PQfinish(conn);
return 1;
}
res = PQexec(conn,
"SELECT pg_catalog.set_config('search_path', '', false)");
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
return 1;
}
PQclear(res);
// Demande de l'autorisation
char const * sqlParamValues[] = {action,token};
res = PQexecParams(conn,"SELECT userID FROM git.tokens WHERE type=$1 AND token=$2",2,NULL,sqlParamValues,NULL,NULL,0);
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr,"Impossible de lancer la requête SQL pour authentifier le token: %s",PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
return 1;
}
if(PQntuples(res)<1){
printf("Ce token est invalide !!!");
PQclear(res);
PQfinish(conn);
return 0;
}
userId=PQgetvalue(res,0,0);
PQclear(res);
// Demande les données à la BDD
sqlParamValues[0] = userId;
res = PQexecParams(conn,"SELECT path,owner,description,logoUrl,groupeID,gdr.nom FROM git.\"AccessibleRepos\"($1,'WRITE') JOIN git.\"groupesDeRepo\" AS gdr ON gdr.\"ID\"=groupeID ORDER BY groupeID",1,NULL,sqlParamValues,NULL,NULL,0);
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr,"Impossible de lancer la requête SQL pour la liste des repos: %s",PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
return 1;
}
// Renvoie le résultat à travers stdout
for (i = 0; i < PQntuples(res); i++)
{
printf("%s\n",PQgetvalue(res,i,0));
}
PQclear(res);
PQfinish(conn);
return 0;
}

BIN
webterface.cgi Executable file

Binary file not shown.