Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbe362c65d | ||
|
|
b702f8a548 | ||
|
|
352a4b3df0 | ||
|
|
0dc02cb3e6 | ||
|
|
a7d4cadd1b |
@@ -1,4 +1,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -12,6 +15,8 @@
|
||||
|
||||
/* compilation : gcc -o api api.c -Wall -lssl -lcrypto */
|
||||
|
||||
char * flog = NULL;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
@@ -39,6 +44,36 @@ int mSignal; // indique si fin demandee par un signal (kill ou dmd arret depuis
|
||||
long mNbFils; // > 0 si serveur
|
||||
long mPid; // pid du process
|
||||
|
||||
// -----------------------------------------------------------
|
||||
void trace(const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
if(flog)
|
||||
{
|
||||
if(*flog == '0') return; // si fichier log = "0" : ne rien afficher ni logguer
|
||||
//
|
||||
FILE * f = fopen(flog, "a+");
|
||||
if(f)
|
||||
{
|
||||
fprintf(f, "%s%d%s", mServeur ? "Serveur " : "Cnx ", getpid(), ": ");
|
||||
vfprintf(f, fmt, args);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s%d%s", mServeur ? "Serveur " : "Cnx ", getpid(), ": ");
|
||||
vprintf(fmt, args);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s%d%s", mServeur ? "Serveur " : "Cnx ", getpid(), ": ");
|
||||
vprintf(fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
void libereSecu()
|
||||
{
|
||||
@@ -77,14 +112,14 @@ int secuSocket()
|
||||
int cr;
|
||||
if((mClientSsl = SSL_new(mSslCtx)) == NULL)
|
||||
{
|
||||
printf("Erreur SSL_new\n");
|
||||
trace("Erreur SSL_new\n");
|
||||
/* erreur gestion etat SSL */
|
||||
libereSecu();
|
||||
return FALSE;
|
||||
}
|
||||
if(!SSL_set_fd(mClientSsl, mSocket))
|
||||
{
|
||||
printf("Erreur SSL_set_fd\n");
|
||||
trace("Erreur SSL_set_fd\n");
|
||||
/* erreur assoc socket */
|
||||
libereSecu();
|
||||
return FALSE;
|
||||
@@ -103,7 +138,7 @@ int secuSocket()
|
||||
}
|
||||
if(cr != 1)
|
||||
{
|
||||
printf("Erreur SSL_accept, code %d error %d\n", sslcr, errno);
|
||||
trace("Erreur SSL_accept, code %d error %d\n", sslcr, errno);
|
||||
libereSecu();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -119,7 +154,7 @@ int securise(char * certificat, char * privateKey, int socket)
|
||||
{
|
||||
if((mSslCtx = SSL_CTX_new(TLS_server_method())) == NULL)
|
||||
{
|
||||
printf("Erreur SSL_CTX_new\n");
|
||||
trace("Erreur SSL_CTX_new\n");
|
||||
libereSecu();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -133,19 +168,19 @@ int securise(char * certificat, char * privateKey, int socket)
|
||||
/* */
|
||||
if (SSL_CTX_use_certificate_file(mSslCtx, certificat, SSL_FILETYPE_PEM) <= 0)
|
||||
{
|
||||
printf("Erreur SSL_CTX_use_certificate_file\n");
|
||||
trace("Erreur SSL_CTX_use_certificate_file\n");
|
||||
libereSecu();
|
||||
return FALSE;
|
||||
}
|
||||
if (SSL_CTX_use_PrivateKey_file(mSslCtx, privateKey, SSL_FILETYPE_PEM) <= 0)
|
||||
{
|
||||
printf("Erreur SSL_CTX_use_PrivateKey_file\n");
|
||||
trace("Erreur SSL_CTX_use_PrivateKey_file\n");
|
||||
libereSecu();
|
||||
return FALSE;
|
||||
}
|
||||
if (!SSL_CTX_check_private_key(mSslCtx))
|
||||
{
|
||||
printf("Erreur SSL_CTX_check_private_key\n");
|
||||
trace("Erreur SSL_CTX_check_private_key\n");
|
||||
libereSecu();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -201,27 +236,27 @@ int creerServeur(long port)
|
||||
/* mise en place de la socket serveur d'ecoute */
|
||||
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
printf("Erreur creation socket\n");
|
||||
trace("Erreur creation socket\n");
|
||||
return FALSE; // erreur
|
||||
}
|
||||
ioctl(sock, FIONBIO, &arg); /* socket non bloquant (sys/ioctl.h) */
|
||||
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int))) /* pour eliminer une erreur : permet de rouvrir des socket suite a fermeture avec des clients encore connectes */
|
||||
{
|
||||
printf("Erreur setsockopt SO_REUSEADDR\n");
|
||||
trace("Erreur setsockopt SO_REUSEADDR\n");
|
||||
/* erreur */
|
||||
close(sock);
|
||||
return FALSE;
|
||||
}
|
||||
if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void*)&buf, sizeof(buf)))
|
||||
{
|
||||
printf("Erreur setsockopt SO_RCVBUF\n");
|
||||
trace("Erreur setsockopt SO_RCVBUF\n");
|
||||
/* erreur */
|
||||
close(sock);
|
||||
return FALSE;
|
||||
}
|
||||
if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void*)&buf, sizeof(buf)))
|
||||
{
|
||||
printf("Erreur setsockopt SO_SNDBUF\n");
|
||||
trace("Erreur setsockopt SO_SNDBUF\n");
|
||||
/* erreur */
|
||||
close(sock);
|
||||
return FALSE;
|
||||
@@ -231,21 +266,21 @@ int creerServeur(long port)
|
||||
l_s.l_linger = 0; // les 2 valeurs provoquent un close avec retour immediat, sans traiter les donnees eventuelles en attente d'envoi et envoi RST au client s'il est connecte en TCP
|
||||
if(setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&l_s, sizeof (l_s)))
|
||||
{
|
||||
printf("Erreur setsockopt SO_LINGER\n");
|
||||
trace("Erreur setsockopt SO_LINGER\n");
|
||||
/* erreur */
|
||||
close(sock);
|
||||
return FALSE;
|
||||
}
|
||||
if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||
{
|
||||
printf("Erreur bind, errno %d\n", errno);
|
||||
trace("Erreur bind, errno %d\n", errno);
|
||||
close(sock);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
if(listen(sock, 10) < 0)
|
||||
{
|
||||
printf("Erreur listen\n");
|
||||
trace("Erreur listen\n");
|
||||
close(sock);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -312,7 +347,7 @@ int lireConnexion(char * data)
|
||||
int err = SSL_get_error(mClientSsl, nblu);
|
||||
if(err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL)
|
||||
{
|
||||
printf("Fermeture de la connexion par le client\n");
|
||||
trace("Fermeture de la connexion par le client\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -417,13 +452,13 @@ void trt_sig(int sig)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
char data[64000]; // buffer de lecture/ecriture sur la socket securisee
|
||||
char data[64000], rep[64000]; // buffer de lecture/ecriture sur la socket securisee
|
||||
void trt_connexion()
|
||||
{
|
||||
FILE * fp;
|
||||
//Dynamic req, methode, uri, rep, tmp, fld;
|
||||
//long meth, cr, nb;
|
||||
int keepAlive;
|
||||
printf("trt demande\n");
|
||||
//
|
||||
*data = 0;
|
||||
keepAlive = TRUE;
|
||||
@@ -431,36 +466,59 @@ void trt_connexion()
|
||||
{
|
||||
//tmp.let("GET;HEAD;POST");
|
||||
//// lire les donnees entrantes sur la socket // pbm ici bloquant : sans doute pbm de longueur attendue !? a tester
|
||||
//printf("debut boucle\n");
|
||||
//trace("debut boucle\n");
|
||||
if ( ! lireConnexion(data))
|
||||
break; // fin du client
|
||||
printf("lu:\n%s\n", data);
|
||||
//if(strstr(data,"keep-alive") == NULL)
|
||||
// keepAlive = FALSE;
|
||||
trace("lu:\n%s\n", data);
|
||||
if(strstr(data,"keep-alive") == NULL)
|
||||
keepAlive = FALSE;
|
||||
//
|
||||
strcpy(data, "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Type:text/html\r\nContent-Length:35\r\n\r\n<html><h2>Hello World !</h2></html>");
|
||||
printf("Reponse:\n%s\n", data);
|
||||
//strcpy(data, "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Type:text/html\r\nContent-Length:35\r\n\r\n<html><h2>Hello World !</h2></html>");
|
||||
if((fp = popen("/root/create_ttyd_session.sh", "r")) == NULL)
|
||||
strcpy(data, "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Type:text/html\r\nContent-Length:97\r\n\r\n<html><h2>Erreur, console de test non disponible, veuillez contacter l'administrateur</h2></html>");
|
||||
else
|
||||
{
|
||||
*data = 0;
|
||||
*rep = 0;
|
||||
char ligne[10] = {0};
|
||||
while (fgets(ligne, sizeof(ligne) - 1, fp)) {
|
||||
strcat(rep, ligne);
|
||||
}
|
||||
pclose(fp);
|
||||
sprintf(data, "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Type:text/html\r\nContent-Length:%ld", strlen(rep));
|
||||
strcat(data, "\r\n\r\n");
|
||||
strcat(data, rep);
|
||||
}
|
||||
//
|
||||
trace("Reponse:\n%s\n", data);
|
||||
ecrireConnexion(data);
|
||||
*data = 0;
|
||||
//// faire une attente passive ici (sinon consomme trop de CPU)
|
||||
//printf("Attente fin boucle\n");
|
||||
//while(attente(10) <= 0 && ! mFin) ;
|
||||
//trace("Attente fin boucle\n");
|
||||
while(attente(10) <= 0 && ! mFin) ;
|
||||
//if ( ! lireConnexion(data))
|
||||
// break;
|
||||
//if(mFin)
|
||||
break; // sortie sur signal
|
||||
if(mFin)
|
||||
break; // sortie sur signal
|
||||
}
|
||||
printf("fin cnx client\n");
|
||||
trace("fin cnx client\n");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc != 4)
|
||||
if(argc != 4 && argc != 5)
|
||||
{
|
||||
printf("Usage : %s <port> <certificat> <cleprivee>\n", argv[0]);
|
||||
trace("Usage : %s <port> <certificat> <cleprivee> [<fichierlog>]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
int demon = (argv[0][strlen(argv[0]) - 1] == 'd');
|
||||
if(argc == 5)
|
||||
{
|
||||
flog = argv[4];
|
||||
if(*flog != '0')
|
||||
remove(flog);
|
||||
}
|
||||
/* */
|
||||
int port = atoi(argv[1]);
|
||||
certificat = argv[2];
|
||||
@@ -487,28 +545,28 @@ int main(int argc, char *argv[])
|
||||
mSslCtx = NULL;
|
||||
mClientSsl = NULL;
|
||||
//
|
||||
if(1)
|
||||
if(demon)
|
||||
{
|
||||
if((mPid = fork()) != 0)
|
||||
{
|
||||
printf("Lancement en tache de fond du process pid %ld\n", mPid);
|
||||
trace("Lancement en tache de fond du process pid %ld\n", mPid);
|
||||
exit(0); /* sortie du pere */
|
||||
}
|
||||
mPid = getpid();
|
||||
chdir("/"); // permet de ne pas bloquer un filesystem avec ce process
|
||||
//chdir("/"); // permet de ne pas bloquer un filesystem avec ce process
|
||||
setsid();
|
||||
for(int i=0;i < FOPEN_MAX; i++) /* OPEN_MAX sous AIX */
|
||||
close(i);
|
||||
//for(int i=0;i < FOPEN_MAX; i++) /* OPEN_MAX sous AIX */
|
||||
// close(i);
|
||||
}
|
||||
//
|
||||
printf("Demarrage serveur, port %d pid %d mode %d bits\n", port, getpid(), sizeof(long)==4?32:64);
|
||||
trace("Demarrage serveur, port %d pid %d mode %d bits\n", port, getpid(), sizeof(long)==4?32:64);
|
||||
/* initialisations internes openssl */
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_ssl_algorithms();
|
||||
// verification du contexte securise avant de continuer
|
||||
if( ! securise(certificat, cleprivee, FALSE))
|
||||
{
|
||||
printf("Erreur lors de la mise en place du contexte securise SSL/TLS\n");
|
||||
trace("Erreur lors de la mise en place du contexte securise SSL/TLS\n");
|
||||
exit(4);
|
||||
}
|
||||
else
|
||||
@@ -533,7 +591,7 @@ int main(int argc, char *argv[])
|
||||
// dans le pere
|
||||
mNbFils++;
|
||||
signal(SIGCHLD, trt_sig); /* SIGCHLD : prevenu quand un process fils se termine */
|
||||
printf("Connexion depuis ip %d.%d.%d.%d : creation process pid %ld\n", (ipClient >> 24) & 0xFF, (ipClient >> 16) & 0xFF, (ipClient >> 8) & 0xFF, (ipClient & 0xFF), pid_fils);
|
||||
trace("Connexion depuis ip %d.%d.%d.%d : creation process pid %ld\n", (ipClient >> 24) & 0xFF, (ipClient >> 16) & 0xFF, (ipClient >> 8) & 0xFF, (ipClient & 0xFF), pid_fils);
|
||||
arret(sock_fils, TRUE);
|
||||
}
|
||||
else if(pid_fils == 0)
|
||||
@@ -542,7 +600,7 @@ int main(int argc, char *argv[])
|
||||
mServeur = FALSE;
|
||||
mNbFils = 0;
|
||||
mPid = getpid();
|
||||
printf("Connexion entrante pid %ld socket %d\n", mPid, sock_fils);
|
||||
trace("Connexion entrante pid %ld socket %d\n", mPid, sock_fils);
|
||||
close(mSocket); // le fils n'a pas besoin de la socket serveur mere
|
||||
mSocket = sock_fils;
|
||||
mSockServeur = 0;
|
||||
@@ -552,7 +610,7 @@ int main(int argc, char *argv[])
|
||||
if( ! securise(certificat, cleprivee, TRUE))
|
||||
{
|
||||
// erreur : handshake securise SSL/TLS ko avec le client
|
||||
printf("Erreur de handshake securise SSL/TLS\n");
|
||||
trace("Erreur de handshake securise SSL/TLS\n");
|
||||
break;
|
||||
}
|
||||
//
|
||||
@@ -561,26 +619,26 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
else
|
||||
printf("Erreur de fork() creation fils - demande non traitee\n");
|
||||
trace("Erreur de fork() creation fils - demande non traitee\n");
|
||||
}
|
||||
verifierFinFils();
|
||||
}
|
||||
else
|
||||
printf("Attente... %d\n", mSocket);
|
||||
trace("Attente... %d\n", mSocket);
|
||||
}
|
||||
// arret socket en cours
|
||||
arret(mSocket, TRUE);
|
||||
if(mServeur)
|
||||
{
|
||||
demandeArretFilsEtAttente();
|
||||
printf("Arret du serveur\n");
|
||||
trace("Arret du serveur\n");
|
||||
}
|
||||
else
|
||||
printf("Arret du client\n");
|
||||
trace("Arret du client\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Erreur d'initialisation du socket serveur - ARRET\n");
|
||||
trace("Erreur d'initialisation du socket serveur - ARRET\n");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
Reference in new issue
Block a user