diff --git a/BBSHTMLConfig.c b/BBSHTMLConfig.c
index d328419..d1a62ce 100644
--- a/BBSHTMLConfig.c
+++ b/BBSHTMLConfig.c
@@ -116,7 +116,7 @@ int SendWebMailHeader(char * Reply, char * Key, struct HTTPConnectionInfo * Sess
struct UserInfo * FindBBS(char * Name);
void ReleaseWebMailStruct(WebMailInfo * WebMail);
VOID TidyWelcomeMsg(char ** pPrompt);
-int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param);
+int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param, char * Token);
char UNC[] = "";
char CHKD[] = "checked=checked ";
@@ -447,7 +447,7 @@ void ConvertTitletoUTF8(WebMailInfo * WebMail, char * Title, char * UTF8Title, i
BOOL GotFirstMessage = 0;
-void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen)
+void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen, char * Token)
{
char * Context = 0, * NodeURL;
int ReplyLen;
@@ -480,7 +480,7 @@ void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method,
if (_memicmp(URL, "/Mail/API/v1/", 13) == 0)
{
- *RLen = MailAPIProcessHTTPMessage(Session, Reply, Method, URL, input, LOCAL, Context);
+ *RLen = MailAPIProcessHTTPMessage(Session, Reply, Method, URL, input, LOCAL, Context, Token);
return;
}
@@ -2997,6 +2997,8 @@ int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer);
static char PipeFileName[] = "\\\\.\\pipe\\BPQMailWebPipe";
+// Constants
+
static DWORD WINAPI InstanceThread(LPVOID lpvParam)
// This routine is a thread processing function to read from and reply to a client
@@ -3017,6 +3019,7 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam)
char URL[100001];
char * Context, * Method;
int n;
+ char token[16]= "";
char * ptr;
@@ -3052,18 +3055,43 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam)
}
else
{
- strcpy(URL, MsgPtr);
+ // look for auth header
+
+ const char * auth_header = "Authorization: Bearer ";
+ char * token_begin = strstr(MsgPtr, auth_header);
+ int Flags = 0, n;
- ptr = strstr(URL, " HTTP");
+ // Node Flags isn't currently used
- if (ptr)
- *ptr = 0;
+ char * Tok;
+ char * param;
- Method = strtok_s(URL, " ", &Context);
+ if (token_begin)
+ {
+ // Using Auth Header
+
+ // Extract the token from the request (assuming it's present in the request headers)
- ProcessMailHTTPMessage(&Session, Method, Context, MsgPtr, OutBuffer, &OutputLen, InputLen);
+ token_begin += strlen(auth_header); // Move to the beginning of the token
+ strncpy(token, token_begin, 13);
+ token[13] = '\0'; // Null-terminate the token
+ }
}
+ strcpy(URL, MsgPtr);
+
+
+
+ ptr = strstr(URL, " HTTP");
+
+ if (ptr)
+ *ptr = 0;
+
+ Method = strtok_s(URL, " ", &Context);
+
+ ProcessMailHTTPMessage(&Session, Method, Context, MsgPtr, OutBuffer, &OutputLen, InputLen, token);
+
+
WriteFile(hPipe, &Session, sizeof (struct HTTPConnectionInfo), &n, NULL);
WriteFile(hPipe, OutBuffer, OutputLen, &cbWritten, NULL);
diff --git a/BBSUtilities.c b/BBSUtilities.c
index 1db4bed..06feafc 100644
--- a/BBSUtilities.c
+++ b/BBSUtilities.c
@@ -8136,6 +8136,15 @@ BOOL ProcessBBSConnectScript(CIRCUIT * conn, char * Buffer, int len)
Line = Scripts[n];
}
+ if (Line == NULL)
+ {
+ // No more lines - Disconnect
+
+ conn->BBSFlags &= ~RunningConnectScript; // so it doesn't get reentered
+ Disconnect(conn->BPQStream);
+ return FALSE;
+ }
+
if (_memicmp(Line, "TIMES", 5) == 0)
{
NextBand:
diff --git a/HTTPcode.c b/HTTPcode.c
index 14ed523..284170e 100644
--- a/HTTPcode.c
+++ b/HTTPcode.c
@@ -106,7 +106,7 @@ char * strlop(char * buf, char delim);
VOID sendandcheck(SOCKET sock, const char * Buffer, int Len);
int CompareNode(const void *a, const void *b);
int CompareAlias(const void *a, const void *b);
-void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen);
+void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen, char * Token);
void ProcessChatHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen);
struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
int SetupNodeMenu(char * Buff, int SYSOP);
@@ -2123,11 +2123,7 @@ Returnit:
Compressed = Reply;
if (NodeURL && _memicmp(NodeURL, "/mail/api/", 10) == 0)
- HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\n"
- "Content-Length: %d\r\n"
- "Content-Type: application/json\r\n"
- "Connection: close\r\n"
- "%s\r\n", ReplyLen, Encoding);
+ HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json\r\nConnection: close\r\n%s\r\n", ReplyLen, Encoding);
else
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n%s\r\n", ReplyLen, Encoding);
@@ -2150,6 +2146,27 @@ doHeader:
char _REPLYBUFFER[250000];
struct HTTPConnectionInfo Dummy = {0};
int Sent, Loops = 0;
+ char token[16] = "";
+
+ // look for auth header
+
+ const char * auth_header = "Authorization: Bearer ";
+ char * token_begin = strstr(MsgPtr, auth_header);
+ int Flags = 0, n;
+
+ char * Tok;
+ char * param;
+
+ if (token_begin)
+ {
+ // Using Auth Header
+
+ // Extract the token from the request (assuming it's present in the request headers)
+
+ token_begin += strlen(auth_header); // Move to the beginning of the token
+ strncpy(token, token_begin, 13);
+ token[13] = '\0'; // Null-terminate the token
+ }
ReplyLen = 0;
@@ -2161,7 +2178,7 @@ doHeader:
else
Session->TNC = (void *)0;
- ProcessMailHTTPMessage(Session, Method, Context, MsgPtr, _REPLYBUFFER, &ReplyLen, MsgLen);
+ ProcessMailHTTPMessage(Session, Method, Context, MsgPtr, _REPLYBUFFER, &ReplyLen, MsgLen, token);
if (Context && _memicmp(Context, "/mail/api/", 10) == 0)
{
@@ -2171,9 +2188,9 @@ doHeader:
if (allowDeflate)
Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen);
else
- Compressed = Reply;
+ Compressed = _REPLYBUFFER;
- HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n%s\r\n", ReplyLen, Encoding);
+ HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json\r\nConnection: close\r\n%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, Compressed, ReplyLen);
@@ -2306,6 +2323,8 @@ doHeader:
// Pass to MailChat if active
+ NodeURL = Context;
+
if ((_memicmp(Context, "/MAIL/", 6) == 0) || (_memicmp(Context, "/WebMail", 8) == 0))
{
// If for Mail, Pass to Mail Server via Named Pipe
@@ -4248,42 +4267,53 @@ int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char
int i;
struct UserRec * USER;
- user = strlop(MsgPtr, '?');
- password = strlop(user, '&');
- strlop(password, ' ');
-
-
- for (i = 0; i < TCP->NumberofUsers; i++)
+ if (strchr(MsgPtr, '?'))
{
- USER = TCP->UserRecPtr[i];
+ // Check Password
+
+ user = strlop(MsgPtr, '?');
+ password = strlop(user, '&');
+ strlop(password, ' ');
- if (user && _stricmp(user, USER->UserName) == 0)
+ for (i = 0; i < TCP->NumberofUsers; i++)
{
- if ((strcmp(password, USER->Password) == 0) && (USER->Secure || WebMail))
+ USER = TCP->UserRecPtr[i];
+
+ if (user && _stricmp(user, USER->UserName) == 0)
{
- // ok
+ if ((strcmp(password, USER->Password) == 0) && (USER->Secure || WebMail))
+ {
+ // ok
- NewSession = AllocateSession(Appl[0], 'M');
+ NewSession = AllocateSession(Appl[0], 'M');
- *Session = NewSession;
+ *Session = NewSession;
+
+ if (NewSession)
+ {
+ ReplyLen = 0;
+ strcpy(NewSession->Callsign, USER->Callsign);
+ }
+ else
+ {
+ ReplyLen = SetupNodeMenu(Reply, LOCAL);
+ ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError);
+ }
+ return ReplyLen;
- if (NewSession)
- {
- ReplyLen = 0;
- strcpy(NewSession->Callsign, USER->Callsign);
- }
- else
- {
- ReplyLen = SetupNodeMenu(Reply, LOCAL);
- ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError);
}
- return ReplyLen;
-
}
}
- }
- // Pass failed attempt to BBS code so it can try a bbs user login
+ // Pass failed attempt to BBS code so it can try a bbs user login
+
+ // Need to put url back together
+
+ if (user && user[0] && password && password[0])
+ {
+ sprintf(MsgPtr, "%s?%s&%s", MsgPtr, user, password);
+ }
+ }
NewSession = AllocateSession(Appl[0], 'M');
diff --git a/mailapi.c b/mailapi.c
index 44de32c..f447e7b 100644
--- a/mailapi.c
+++ b/mailapi.c
@@ -1,6 +1,6 @@
// basic JASON API to BPQ Node
-// Authentication is via Telnet USER records.
+// Authentication is via Telnet USER records or bbs records
#define _CRT_SECURE_NO_DEPRECATE
@@ -62,9 +62,9 @@ int sendFwdConfig(struct HTTPConnectionInfo * Session, char * response, char * R
static struct MailAPI APIList[] =
{
- "/mail/api/v1/msgs", 17, sendMsgList, AuthBBSUser | AuthSysop,
- "/mail/api/v1/FwdQLen", 20, sendFwdQueueLen, AuthBBSUser | AuthSysop,
- "/mail/api/v1/FwdConfig", 22, sendFwdConfig, AuthBBSUser | AuthSysop,
+ "/mail/api/v1/msgs", 17, sendMsgList, 0,
+ "/mail/api/v1/FwdQLen", 20, sendFwdQueueLen, AuthSysop,
+ "/mail/api/v1/FwdConfig", 22, sendFwdConfig, AuthSysop,
};
static int APICount = sizeof(APIList) / sizeof(struct MailAPI);
@@ -152,29 +152,6 @@ static void add_token_to_list(MailToken * token)
}
}
-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);
@@ -206,6 +183,7 @@ static void remove_expired_tokens()
static MailToken * find_token(const char* token)
{
MailToken * current_token = token_list;
+
while (current_token != NULL)
{
if (strcmp(current_token->token, token) == 0)
@@ -223,7 +201,7 @@ static int send_http_response(char * response, const char* msg)
}
-int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char *Params)
+int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char *Params, char * TokenString)
{
char * pass = strlop(Params, '&');
int Flags = 0, n;
@@ -261,6 +239,11 @@ int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * respon
strcpy(Session->Callsign, User->Call);
Auth = AuthBBSUser;
+ if (User->flags & F_SYSOP)
+ Auth |= AuthSysop;
+
+
+
}
}
else
@@ -295,6 +278,29 @@ int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * respon
return strlen(response);
}
+ // Find Token
+
+ if (TokenString[0]) // Token form Auth Header
+ Token = find_token(TokenString);
+ else
+ Token = find_token(Params); // Token form URL
+
+ if (Token != NULL)
+ {
+ // Check if the token has expired
+
+ time_t current_time = time(NULL);
+ if (current_time > Token->expiration_time)
+ {
+ // Token has expired, remove it from the token list
+ remove_expired_tokens();
+ Token = NULL;
+ }
+ }
+
+ if (Token)
+ Auth |= Token->Auth;
+
// Determine the requested API endpoint
for (n = 0; n < APICount; n++)
@@ -329,6 +335,9 @@ int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * respon
if (APIEntry->Auth)
{
// Check Level
+
+ if ((Auth & APIEntry->Auth) == 0)
+ return send_http_response(response, "403 (Not Authorized)");
}
if (rest[0] == ' ' || rest[0] == '/' || rest[0] == '?')