init(cgi): add Common Gateway Interface with authentication only
This commit is contained in:
parent
091b1757c6
commit
5019c54380
@ -28,3 +28,7 @@ add_library(tanabata SHARED ${TANABATA_SRC})
|
||||
|
||||
# Tanabata CLI app
|
||||
add_executable(tfm ${TANABATA_SRC} ${CLI_SRC})
|
||||
|
||||
# Authentication CGI app
|
||||
add_executable(tfm-cgi ${TANABATA_SRC} cgi/cgi.c)
|
||||
target_link_libraries(tfm-cgi fcgi ssl crypto pthread)
|
||||
|
||||
114
cgi/cgi.c
Normal file
114
cgi/cgi.c
Normal file
@ -0,0 +1,114 @@
|
||||
#include <fcgi_stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define TOKEN_RENTALTIME 604800
|
||||
#define TOKEN_SIZE 64
|
||||
|
||||
static time_t SID;
|
||||
static char TOKEN[TOKEN_SIZE];
|
||||
static int socket_auth;
|
||||
static int socket_cgi;
|
||||
|
||||
int validate(FCGX_Request *request) {
|
||||
if (time(NULL) - SID > TOKEN_RENTALTIME) {
|
||||
return 1;
|
||||
}
|
||||
char token[TOKEN_SIZE];
|
||||
FCGX_GetStr(token, TOKEN_SIZE, request->in);
|
||||
if (memcmp(token, TOKEN, TOKEN_SIZE) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *auth() {
|
||||
FCGX_Request request;
|
||||
if (FCGX_InitRequest(&request, socket_auth, FCGI_FAIL_ACCEPT_ON_INTR) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
unsigned char password[SHA256_DIGEST_LENGTH];
|
||||
FILE *passfile = fopen("/etc/tfm/password", "rb");
|
||||
if (passfile == NULL ||
|
||||
fread(password, 1, SHA256_DIGEST_LENGTH, passfile) < SHA256_DIGEST_LENGTH) {
|
||||
exit(1);
|
||||
}
|
||||
fclose(passfile);
|
||||
int rc;
|
||||
char buffer[33];
|
||||
for (;;) {
|
||||
static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_lock(&accept_mutex);
|
||||
rc = FCGX_Accept_r(&request);
|
||||
pthread_mutex_unlock(&accept_mutex);
|
||||
if (rc < 0) {
|
||||
break;
|
||||
}
|
||||
memset(buffer, 0, 33);
|
||||
FCGX_GetStr(buffer, 32, request.in);
|
||||
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||||
SHA256((const unsigned char *) buffer, strlen(buffer), hash);
|
||||
if (memcmp(hash, password, SHA256_DIGEST_LENGTH) == 0) {
|
||||
time(&SID);
|
||||
uint64_t subtoken = SID;
|
||||
SHA256((const unsigned char *) &subtoken, 8, hash);
|
||||
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
|
||||
sprintf(TOKEN + (i * 2), "%02x", hash[i]);
|
||||
}
|
||||
FCGX_PutS("Content-type: application/json\r\n\r\n"
|
||||
"{\"status\":true,\"token\":\"", request.out);
|
||||
FCGX_PutS(TOKEN, request.out);
|
||||
FCGX_PutS("\"}\n", request.out);
|
||||
FCGX_Finish_r(&request);
|
||||
continue;
|
||||
}
|
||||
FCGX_PutS("Content-type: application/json\r\n\r\n"
|
||||
"{\"status\":false}\n", request.out);
|
||||
FCGX_Finish_r(&request);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *tfmcgi() {
|
||||
FCGX_Request request;
|
||||
if (FCGX_InitRequest(&request, socket_cgi, FCGI_FAIL_ACCEPT_ON_INTR) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
int rc;
|
||||
for (;;) {
|
||||
static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_lock(&accept_mutex);
|
||||
rc = FCGX_Accept_r(&request);
|
||||
pthread_mutex_unlock(&accept_mutex);
|
||||
if (rc < 0) {
|
||||
break;
|
||||
}
|
||||
if (validate(&request) != 0) {
|
||||
FCGX_PutS("Content-type: application/json\r\n\r\n"
|
||||
"{\"status\":false}\n", request.out);
|
||||
FCGX_Finish_r(&request);
|
||||
continue;
|
||||
}
|
||||
FCGX_PutS("Content-type: application/json\r\n\r\n"
|
||||
"{\"status\":true}\n", request.out);
|
||||
FCGX_Finish_r(&request);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t thread_auth, thread_cgi;
|
||||
FCGX_Init();
|
||||
if ((socket_auth = FCGX_OpenSocket("/tmp/tfm-auth.sock", 0)) == -1 ||
|
||||
(socket_cgi = FCGX_OpenSocket("/tmp/tfm-cgi.sock", 0)) == -1) {
|
||||
return 1;
|
||||
}
|
||||
pthread_create(&thread_auth, NULL, auth, NULL);
|
||||
pthread_create(&thread_cgi, NULL, tfmcgi, NULL);
|
||||
pthread_join(thread_auth, NULL);
|
||||
pthread_join(thread_cgi, NULL);
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user