197 lines
4.5 KiB
C
197 lines
4.5 KiB
C
// basic JASON API to BPQ Node
|
|
|
|
// Authentication is via Telnet USER records.
|
|
|
|
|
|
#define _CRT_SECURE_NO_DEPRECATE
|
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
|
|
|
//#include <windows.h>
|
|
#include "CHeaders.h"
|
|
#include <stdlib.h>
|
|
#include "bpqmail.h"
|
|
|
|
|
|
// Constants
|
|
#define TOKEN_SIZE 32 // Length of the authentication token
|
|
#define TOKEN_EXPIRATION 7200 // Token expiration time in seconds (2 hours)
|
|
|
|
// Token data structure
|
|
typedef struct MailToken {
|
|
char token[TOKEN_SIZE + 1];
|
|
time_t expiration_time;
|
|
struct UserInfo * User;
|
|
char Call[10];
|
|
struct MailToken* next;
|
|
} MailToken;
|
|
|
|
static MailToken * token_list = NULL;
|
|
|
|
static int verify_token(const char* token);
|
|
static void remove_expired_tokens();
|
|
static int request_token(char * response);
|
|
static void add_token_to_list(MailToken* token);
|
|
static MailToken * find_token(const char* token);
|
|
|
|
static MailToken * generate_token()
|
|
{
|
|
// Generate a random authentication token
|
|
int i;
|
|
|
|
MailToken * token = malloc(sizeof(MailToken));
|
|
|
|
srand(time(NULL));
|
|
|
|
for (i = 0; i < TOKEN_SIZE; i++)
|
|
{
|
|
token->token[i] = 'A' + rand() % 26; // Random uppercase alphabet character
|
|
}
|
|
token->token[TOKEN_SIZE] = '\0'; // Null-terminate the token
|
|
token->expiration_time = time(NULL) + TOKEN_EXPIRATION; // Set token expiration time
|
|
add_token_to_list(token);
|
|
return token;
|
|
}
|
|
|
|
// Function to add the token to the token_list
|
|
static void add_token_to_list(MailToken * token)
|
|
{
|
|
if (token_list == NULL)
|
|
{
|
|
token_list = token;
|
|
token->next = NULL;
|
|
}
|
|
else
|
|
{
|
|
MailToken * current = token_list;
|
|
|
|
while (current->next != NULL)
|
|
current = current->next;
|
|
|
|
current->next = token;
|
|
token->next = NULL;
|
|
}
|
|
}
|
|
|
|
static int verify_token(const char* token)
|
|
{
|
|
// Find the token in the token list
|
|
MailToken * existing_token = find_token(token);
|
|
|
|
if (existing_token != NULL)
|
|
{
|
|
// Check if the token has expired
|
|
time_t current_time = time(NULL);
|
|
if (current_time > existing_token->expiration_time)
|
|
{
|
|
// Token has expired, remove it from the token list
|
|
remove_expired_tokens();
|
|
return 0;
|
|
}
|
|
// Token is valid
|
|
return 1;
|
|
}
|
|
|
|
// Token doesn't exist in the token list
|
|
return 0;
|
|
}
|
|
|
|
static void remove_expired_tokens()
|
|
{
|
|
time_t current_time = time(NULL);
|
|
MailToken* current_token = token_list;
|
|
MailToken* prev_token = NULL;
|
|
MailToken* next_token;
|
|
|
|
while (current_token != NULL)
|
|
{
|
|
if (current_time > current_token->expiration_time)
|
|
{
|
|
// Token has expired, remove it from the token list
|
|
if (prev_token == NULL)
|
|
{
|
|
token_list = current_token->next;
|
|
} else {
|
|
prev_token->next = current_token->next;
|
|
}
|
|
next_token = current_token->next;
|
|
free(current_token);
|
|
current_token = next_token;
|
|
} else {
|
|
prev_token = current_token;
|
|
current_token = current_token->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
static MailToken * find_token(const char* token)
|
|
{
|
|
MailToken * current_token = token_list;
|
|
while (current_token != NULL)
|
|
{
|
|
if (strcmp(current_token->token, token) == 0)
|
|
{
|
|
return current_token;
|
|
}
|
|
current_token = current_token->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static int send_http_response(char * response, const char* msg)
|
|
{
|
|
return sprintf(response, "HTTP/1.1 %s\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", msg);
|
|
}
|
|
|
|
|
|
int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, char *Params)
|
|
{
|
|
char * pass = strlop(Params, '&');
|
|
int Flags = 0;
|
|
MailToken * Token;
|
|
|
|
|
|
// Check if the request is for token generation
|
|
|
|
if (strcmp(Method, "GET") != 0)
|
|
return send_http_response(response, "403 (Bad Method)");
|
|
|
|
if (_stricmp(URL, "/mail/api/login") == 0)
|
|
{
|
|
// user is in Params and Password in pass
|
|
|
|
struct UserInfo * User;
|
|
char Msg[256];
|
|
int n;
|
|
|
|
User = LookupCall(Params);
|
|
|
|
if (User)
|
|
{
|
|
// Check Password
|
|
|
|
if (pass[0] == 0 || strcmp(User->pass, pass) != 0 || User->flags & F_Excluded)
|
|
return send_http_response(response, "403 (Login Failed)");
|
|
|
|
n=sprintf_s(Msg, sizeof(Msg), "API Connect from %s", _strupr(Params));
|
|
WriteLogLine(NULL, '|',Msg, n, LOG_BBS);
|
|
|
|
Token = generate_token();
|
|
add_token_to_list(Token);
|
|
|
|
Token->User = User;
|
|
|
|
strcpy(Token->Call, Params);
|
|
|
|
// Return Token
|
|
|
|
sprintf(response, "{\"access_token\":\"%s\", \"expires_in\":%d, \"scope\":\"create\"}\r\n",
|
|
Token->token, TOKEN_EXPIRATION);
|
|
|
|
return strlen(response);
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|