diff --git a/BPQChat.ncb b/BPQChat.ncb deleted file mode 100644 index 0e4d2b5..0000000 Binary files a/BPQChat.ncb and /dev/null differ diff --git a/BPQChat.suo b/BPQChat.suo deleted file mode 100644 index 7b21326..0000000 Binary files a/BPQChat.suo and /dev/null differ diff --git a/HTTPcode.c.bak b/HTTPcode.c.bak deleted file mode 100644 index 0107b30..0000000 --- a/HTTPcode.c.bak +++ /dev/null @@ -1,6290 +0,0 @@ -/* -Copyright 2001-2022 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - - -//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -#define _CRT_SECURE_NO_DEPRECATE - -#define DllImport - -#include "cheaders.h" -#include - -#include "tncinfo.h" -#include "time.h" -#include "bpq32.h" -#include "telnetserver.h" - -// This is needed to link with a lib built from source - -#ifdef WIN32 -#define ZEXPORT __stdcall -#endif - -#include - -#define CKernel -#include "httpconnectioninfo.h" - -extern int MAXBUFFS, QCOUNT, MINBUFFCOUNT, NOBUFFCOUNT, BUFFERWAITS, L3FRAMES; -extern int NUMBEROFNODES, MAXDESTS, L4CONNECTSOUT, L4CONNECTSIN, L4FRAMESTX, L4FRAMESRX, L4FRAMESRETRIED, OLDFRAMES; -extern int STATSTIME; -extern TRANSPORTENTRY * L4TABLE; -extern BPQVECSTRUC BPQHOSTVECTOR[]; -extern BOOL APRSApplConnected; -extern char VersionString[]; -VOID FormatTime3(char * Time, time_t cTime); -DllExport int APIENTRY Get_APPLMASK(int Stream); -VOID SaveUIConfig(); -int ProcessNodeSignon(SOCKET sock, struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, int LOCAL); -VOID SetupUI(int Port); -VOID SendUIBeacon(int Port); -VOID GetParam(char * input, char * key, char * value); -VOID ARDOPAbort(struct TNCINFO * TNC); -VOID WriteMiniDump(); -BOOL KillTNC(struct TNCINFO * TNC); -BOOL RestartTNC(struct TNCINFO * TNC); -int GetAISPageInfo(char * Buffer, int ais, int adsb); -int GetAPRSPageInfo(char * Buffer, double N, double S, double W, double E, int aprs, int ais, int adsb); -unsigned char * Compressit(unsigned char * In, int Len, int * OutLen); -char * stristr (char *ch1, char *ch2); -int GetAPRSIcon(unsigned char * _REPLYBUFFER, char * NodeURL); -char * GetStandardPage(char * FN, int * Len); -BOOL SHA1PasswordHash(char * String, char * Hash); -char * byte_base64_encode(char *str, int len); -int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE); -int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE); -unsigned char * Compressit(unsigned char * In, int Len, int * OutLen); -int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen); -void SendDeviceWebPage(int Port); -int SendMsgNoSem(int stream, char * msg, int len); -int SessionStateNoSem(int stream, int * state, int * change); -int DoWebSockTerm(struct HTTPConnectionInfo * Session, struct ConnectionInfo * conn, char * _REPLYBUFFER, int LOCAL, int COOKIE, char * Context, SOCKET sock); - -extern struct ROUTE * NEIGHBOURS; -extern int ROUTE_LEN; -extern int MAXNEIGHBOURS; - -extern struct DEST_LIST * DESTS; // NODE LIST -extern int DEST_LIST_LEN; -extern int MAXDESTS; // MAX NODES IN SYSTEM - -extern struct _LINKTABLE * LINKS; -extern int LINK_TABLE_LEN; -extern int MAXLINKS; -extern char * RigWebPage; -extern COLORREF Colours[256]; - -extern BOOL IncludesMail; -extern BOOL IncludesChat; - -extern BOOL APRSWeb; -extern BOOL RigActive; - -extern HKEY REGTREE; - -extern BOOL APRSActive; - -extern UCHAR LogDirectory[]; - -extern struct RIGPORTINFO * PORTInfo[34]; -extern int NumberofPorts; - -extern UCHAR ConfigDirectory[260]; - -extern struct AXIPPORTINFO * Portlist[]; - -int sendandcheck(SOCKET sock, const char * Buffer, int Len); -int CompareNode(const void *a, const void *b); -int CompareAlias(const void *a, const void *b); -int CompareRoutes(const void * a, const void * b); - -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); -int StatusProc(char * Buff); -int ProcessMailSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL); -int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL); -int ProcessChatSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, int LOCAL); -VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE); -int FindFreeStreamNoSem(); - -static struct HTTPConnectionInfo * SessionList; // active term mode sessions - -char Mycall[10]; - -char MAILPipeFileName[] = "\\\\.\\pipe\\BPQMAILWebPipe"; -char CHATPipeFileName[] = "\\\\.\\pipe\\BPQCHATWebPipe"; - -char Index[] = "%s's BPQ32 Web Server

" -"" -"" -"
Node PagesAPRS Pages
"; - -char IndexNoAPRS[] = "" -""; - -//char APRSBit[] = "APRS Pages"; - -//char MailBit[] = "Mail Mgmt" -// "WebMail"; -//char ChatBit[] = "Chat Mgmt"; - -char Tail[] = ""; - -char RouteHddr[] = "

Routes

" -"" -""; - -char RouteLine[] = "" -""; - -char RouteLineINP3[] = "" -""; - -char xNodeHddr[] = "
" -"
PortCallQualityNode CountFrame CountRetriesPercentMaxframeFrackLast HeardQueuedRem QualSRTTRem SRTT
%s%d%s%s%d%d%d%d%d%%d%d%02d:%02d%d%d
%s%d%s%s%d%d%d%d%d%%d%d%02d:%02d%d%d%4.2fs%4.2fs
" -"
" -"" -"
" -"

Nodes %s

"; - -char NodeHddr[] = "
" -"" -"" -"
" -"

Nodes %s

"; - -char NodeLine[] = ""; - - -char StatsHddr[] = "

Node Stats

%s:%s
" -""; - -char PortStatsHddr[] = "

Stats for Port %d

"; - -char PortStatsLine[] = ""; - - -char Beacons[] = "

Beacon Configuration for Port %d

You need to be signed in to save changes

%s %d
" -"" -"
" -"" -"" -"" -"" -"" -"
Send Interval (Minutes)
To
Path
Send From File
Text
" -"" - -"

" -""; - - -char LinkHddr[] = "

Links

" -""; - -char LinkLine[] = ""; - -char UserHddr[] = "

Sessions

Far CallOur CallPortax.25 stateLink Typeax.25 Version
%s%s%d%s%s%d
"; - -char UserLine[] = ""; - -char TermSignon[] = "BPQ32 Node %s Terminal Access" -"

BPQ32 Node %s Terminal Access

" -"

Please enter username and password to access the node

" -"" -"
%s%s%s
" -"" -"
User
Password
" -"

" -""; - - -char PassError[] = "

Sorry, User or Password is invalid - please try again

"; - -char BusyError[] = "

Sorry, No sessions available - please try later

"; - -char LostSession[] = "Sorry, Session had been lost - refresh page to sign in again"; -char NoSessions[] = "Sorry, No Sessions available - refresh page to try again"; - -char TermPage[] = "" -"BPQ32 Node %s" -"" -"" -"

BPQ32 Node %s

" -"
" -"

" -"" -"" -""; - -char TermOutput[] = "" -"" -"" -"" -"" -"" -"" -"
\""; - - -// font-family:monospace;background-color:black;color:lawngreen;font-size:12px - -char TermOutputTail[] = "
"; - -/* -char InputLine[] = "" -"
" -"" -"
"; -*/ -char InputLine[] = "" -"
" -"\" id=inp type=text text width=100%% name=input />" -"
"; - -static char NodeSignon[] = "BPQ32 Node SYSOP Access" -"

BPQ32 Node %s SYSOP Access

" -"

This page sets Cookies. Don't continue if you object to this

" -"

Please enter Callsign and Password to access the Node

" -"
" -"" -"" -"
User
Password
" -"

"; - - -static char MailSignon[] = "BPQ32 Mail Server Access" -"

BPQ32 Mail Server %s Access

" -"

Please enter Callsign and Password to access the BBS

" -"
" -"" -"" -"
User
Password
" -"

"; - -static char ChatSignon[] = "BPQ32 Chat Server Access" -"

BPQ32 Chat Server %s Access

" -"

Please enter Callsign and Password to access the Chat Server

" -"
" -"" -"" -"
User
Password
" -"

"; - - -static char MailLostSession[] = "" -"
" -"Sorry, Session had been lost

    " -"
"; - - -static char ConfigEditPage[] = "" -"Edit Config" -"
" -"

" -"
"; - -static char EXCEPTMSG[80] = ""; - -void UndoTransparency(char * input) -{ - char * ptr1, * ptr2; - char c; - int hex; - - if (input == NULL) - return; - - ptr1 = ptr2 = input; - - // Convert any %xx constructs - - while (1) - { - c = *(ptr1++); - - if (c == 0) - break; - - if (c == '%') - { - c = *(ptr1++); - if(isdigit(c)) - hex = (c - '0') << 4; - else - hex = (tolower(c) - 'a' + 10) << 4; - - c = *(ptr1++); - if(isdigit(c)) - hex += (c - '0'); - else - hex += (tolower(c) - 'a' + 10); - - *(ptr2++) = hex; - } - else if (c == '+') - *(ptr2++) = 32; - else - *(ptr2++) = c; - } - *ptr2 = 0; -} - - - - -VOID PollSession(struct HTTPConnectionInfo * Session) -{ - int state, change; - int count, len; - char Msg[400] = ""; - char Formatted[8192]; - char * ptr1, * ptr2; - char c; - int Line; - - // Poll Node - - SessionState(Session->Stream, &state, &change); - - if (change == 1) - { - int Line = Session->LastLine++; - free(Session->ScreenLines[Line]); - - if (state == 1)// Connected - Session->ScreenLines[Line] = _strdup("*** Connected
\r\n"); - else - Session->ScreenLines[Line] = _strdup("*** Disconnected
\r\n"); - - if (Line == 99) - Session->LastLine = 0; - - Session->Changed = TRUE; - } - - if (RXCount(Session->Stream) > 0) - { - int realLen = 0; - - do - { - GetMsg(Session->Stream, &Msg[0], &len, &count); - - // replace cr with
and space with   - - - ptr1 = Msg; - ptr2 = &Formatted[0]; - - if (Session->PartLine) - { - // Last line was incomplete - append to it - - realLen = Session->PartLine; - - Line = Session->LastLine - 1; - - if (Line < 0) - Line = 99; - - strcpy(Formatted, Session->ScreenLines[Line]); - ptr2 += strlen(Formatted); - - Session->LastLine = Line; - Session->PartLine = FALSE; - } - - while (len--) - { - c = *(ptr1++); - realLen++; - - if (c == 13) - { - int LineLen; - - strcpy(ptr2, "
\r\n"); - - // Write to screen - - Line = Session->LastLine++; - free(Session->ScreenLines[Line]); - - LineLen = (int)strlen(Formatted); - - // if line starts with a colour code, process it - - if (Formatted[0] == 0x1b && LineLen > 1) - { - int ColourCode = Formatted[1] - 10; - COLORREF Colour = Colours[ColourCode]; - char ColString[30]; - - memmove(&Formatted[20], &Formatted[2], LineLen); - sprintf(ColString, "", GetRValue(Colour), GetGValue(Colour), GetBValue(Colour)); - memcpy(Formatted, ColString, 20); - strcat(Formatted, ""); - LineLen =+ 28; - } - - Session->ScreenLineLen[Line] = LineLen; - Session->ScreenLines[Line] = _strdup(Formatted); - - if (Line == 99) - Session->LastLine = 0; - - ptr2 = &Formatted[0]; - realLen = 0; - continue; - - } - - if (c != 9 && c < 32) c = '.'; - - if (c == 32) - { - memcpy(ptr2, " ", 6); - ptr2 += 6; - } - else if (c == '>') - { - memcpy(ptr2, ">", 4); - ptr2 += 4; - } - else if (c == '<') - { - memcpy(ptr2, "<", 4); - ptr2 += 4; - } - else - *(ptr2++) = c; - - // Make sure line isn't too long - // but beware of spaces expanded to   - count chars in line - - if ((realLen) > 250) - { - strcpy(ptr2, "
\r\n"); - - Line = Session->LastLine++; - free(Session->ScreenLines[Line]); - - Session->ScreenLines[Line] = _strdup(Formatted); - - if (Line == 99) - Session->LastLine = 0; - - ptr2 = &Formatted[0]; - realLen = 0; - } - - } - - *ptr2 = 0; - - if (ptr2 != &Formatted[0]) - { - // Incomplete line - - // Save to screen - - Line = Session->LastLine++; - free(Session->ScreenLines[Line]); - - Session->ScreenLines[Line] = _strdup(Formatted); - - if (Line == 99) - Session->LastLine = 0; - - Session->PartLine = realLen; - } - - // strcat(Session->ScreenBuffer, Formatted); - Session->Changed = TRUE; - - } while (count > 0); - } -} - - - - - -VOID PollWebSockSession(struct HTTPConnectionInfo * Session, char * Formatted) -{ - int state, change; - int count, len; - char Line[8192]; - char Msg[400]; - char * ptr1, * ptr2; - byte c; - int totalLen = 0; - int needSpan = 0; - int realLen = 0; - int LineLen; - - Formatted[0] = 0; - - // Poll Node - - SessionState(Session->Stream, &state, &change); - - if (change == 1) - { - if (state == 1) // Connected - strcpy(Formatted, "*** Connected\r\n"); - else - strcpy(Formatted, "*** Disconnected\r\n"); - - Session->Changed = TRUE; - } - - if (RXCount(Session->Stream) > 0) - { - - char * lasteol = 0; - - do - { - GetMsg(Session->Stream, &Msg[0], &len, &count); - - // replace cr with
and space with   - - ptr1 = Msg; - ptr2 = Line; - *(ptr2) = 0; - - Msg[len] = 0; - -/* if (Session->PartLine) - { - // Last line was incomplete - append to it - - realLen = Session->PartLine; - - strcpy(Line, Session->ScreenLines[0]); - ptr2 += strlen(Line); - - Session->PartLine = FALSE; - } -*/ - while (len--) - { - c = *(ptr1++); - realLen++; - - if (c == 13 || c == 10) - { - - - // Write to screen - - lasteol = ptr2; - - *ptr2 = 0; - LineLen = (int)strlen(Line); - totalLen += LineLen; - - strcat(Formatted, Line); - - strcat(Formatted, "\r\n"); - - if (*ptr1 == 10) - ptr1++; - - ptr2 = Line; - realLen = 0; - - continue; - - } - - if (c == 0x1b && len > 2) - { - // colour code, process it - - // Now we are using textContent text isn't formatted so just ignore colour escapes - -/* - int ColourCode = Line[1] - 10; - COLORREF Colour = Colours[ColourCode]; - - // Send in a so we can apply formatting - - ptr2 += sprintf(ptr2, "", GetRValue(Colour), GetGValue(Colour), GetBValue(Colour)); - needSpan = 1; -*/ - len --; - ptr1++; - - continue; - } - - if (c != 9 && c < 32) - c = '.'; - - /* if (c == 255) - { - memcpy(ptr2, " ", 6); - ptr2 += 6; - } - else if (c == '>') - { - memcpy(ptr2, ">", 4); - ptr2 += 4; - } - else if (c == '<') - { - memcpy(ptr2, "<", 4); - ptr2 += 4; - } - */ else - *(ptr2++) = c; - - // Make sure line isn't too long - // but beware of spaces expanded to   - count chars in line - // Ideally we should look for multichar sequences - - if ((realLen) > 120) - { - strcpy(ptr2, "\r\n"); - - strcat(Formatted, Line); - - ptr2 = Line; - realLen = 0; - } - - } - - *(ptr2) = 0; - - if (realLen) - { - // Incomplete line Add to output - - // Save to screen - -//// if (Session->ScreenLines[0]) -// free(Session->ScreenLines[0]); - -// Session->ScreenLines[0] = _strdup(Line); -// Session->PartLine = realLen; - - LineLen = (int)strlen(Line); - totalLen += LineLen; - strcat(Formatted, Line); - } - - Session->Changed = TRUE; - - if (totalLen > 2000) - return; - - } while (count > 0); - } -} - - - -VOID HTTPTimer() -{ - // Run every tick. Check for status change and data available - - struct HTTPConnectionInfo * Session = SessionList; // active term mode sessions - struct HTTPConnectionInfo * PreviousSession = NULL; - - while (Session) - { - Session->KillTimer++; - - if (Session->Key[0] != 'T') - { - PreviousSession = Session; - Session = Session->Next; - continue; - } - - if (Session->KillTimer > 864000 || Session->KillTimer < 0) // Day or corrupt - { - if (Session->Stream == 0) - { - if (PreviousSession) - PreviousSession->Next = Session->Next; // Remove from chain - else - SessionList = Session->Next; - - free(Session); - } - continue; - } - - if (Session->KillTimer > 9000) // Around 15 mins - { - int i; - int Stream = Session->Stream; - - - if (!Session->WebsockTerm) - { - for (i = 0; i < 100; i++) - { - free(Session->ScreenLines[i]); - } - } - - SessionControl(Stream, 2, 0); - SessionState(Stream, &i, &i); - DeallocateStream(Stream); - Session->Stream = 0; - - - if (Session->WebsockTerm && Session->sockptr) - { - char Msg[256]; - char Text[] = "Session Timeout"; - - Msg[0] = 0x88; // Fin, Close - Msg[1] = strlen(Text); - strcpy(&Msg[2], Text); - - if (send(Session->sockptr->socket, Msg, Msg[1] + 2, 0) == -1) - { - // Send has failed - ? socket error - - if (PreviousSession) - PreviousSession->Next = Session->Next; // Remove from chain - else - SessionList = Session->Next; - - free(Session); - } - - - } - - else - { - if (PreviousSession) - PreviousSession->Next = Session->Next; // Remove from chain - else - SessionList = Session->Next; - - free(Session); - } - break; - } - - if (Session->WebsockTerm) - { - char Formatted[8192]; - - if (Session->sockptr == 0) // Websock not connected - wait - { - PreviousSession = Session; - Session = Session->Next; - continue; - } - - PollWebSockSession(Session, Formatted); - - if (Session->Changed) - { - struct ConnectionInfo * sock = Session->sockptr; - - int Last = Session->LastLine; - - // Make sure still websocks - - if (sock->HTTPMode && sock->WebSocks && strcmp(sock->WebURL, "WEBTERM") == 0) - { - char Msg[65536]; - int MsgLen = strlen(Formatted); - char * ptr; - char * OutBuffer; - int TxLen; - - // Websocks must be UTF8 - - if (IsUTF8(Formatted, MsgLen) == FALSE) - { - unsigned char UTF[16384]; - int code; - - // Try to guess encoding - - code = TrytoGuessCode(Formatted, MsgLen); - - if (code == 437) - MsgLen = Convert437toUTF8(Formatted, MsgLen, UTF); - else if (code == 1251) - MsgLen = Convert1251toUTF8(Formatted, MsgLen, UTF); - else - MsgLen = Convert1252toUTF8(Formatted, MsgLen, UTF); - - UTF[MsgLen] = 0; - - strcpy(Formatted, UTF); - } - - strcpy(&Msg[4], Formatted); - - // WebSock Encode. Buffer has 4 bytes on front for header but header len depends on Msg len - - if (MsgLen < 126) - { - // Two Byte Header - - Msg[2] = 0x81; // Fin, Data - Msg[3] = MsgLen; - - TxLen = MsgLen + 2; - OutBuffer = &Msg[2]; - } - else // We don't allow more than65535 if (Len < 65536) - { - Msg[0] = 0x81; // Fin, Data - Msg[1] = 126; // Unmasked, Extended Len - Msg[2] = MsgLen >> 8; - Msg[3] = MsgLen & 0xff; - TxLen = MsgLen + 4; - OutBuffer = &Msg[0]; - } - - // If secure session enable an hidden controls - - if (sock->WebSecure) - { - while (ptr = strstr(&Msg[4], "hidden")) - memcpy(ptr, " ", 6); - } - - sendandcheck(sock->socket, OutBuffer, TxLen); - Session->ResponseTimer = Session->Changed = 0; - Session->KillTimer = 0; - - } - else - { - // Session messaed up?? - } - } - PreviousSession = Session; - Session = Session->Next; - } - else - { - PollSession(Session); - - // if (Session->ResponseTimer == 0 && Session->Changed) - // Debugprintf("Data to send but no outstanding GET"); - - if (Session->ResponseTimer) - { - Session->ResponseTimer--; - - if (Session->ResponseTimer == 0 || Session->Changed) - { - SOCKET sock = Session->sock; - char _REPLYBUFFER[100000]; - int ReplyLen; - char Header[256]; - int HeaderLen; - int Last = Session->LastLine; - int n; - struct TNCINFO * TNC = Session->TNC; - struct TCPINFO * TCP = 0; - - if (TNC) - TCP = TNC->TCPInfo; - - if (TCP && TCP->WebTermCSS) - sprintf(_REPLYBUFFER, TermOutput, TCP->WebTermCSS); - else - sprintf(_REPLYBUFFER, TermOutput, ""); - - for (n = Last;;) - { - if ((strlen(Session->ScreenLines[n]) + strlen(_REPLYBUFFER)) < 99999) - strcat(_REPLYBUFFER, Session->ScreenLines[n]); - - if (n == 99) - n = -1; - - if (++n == Last) - break; - } - - ReplyLen = (int)strlen(_REPLYBUFFER); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", TermOutputTail); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, _REPLYBUFFER, ReplyLen); - - Session->ResponseTimer = Session->Changed = 0; - } - } - PreviousSession = Session; - Session = Session->Next; - } - } -} - - -struct HTTPConnectionInfo * AllocateSession(SOCKET sock, char Mode) -{ - time_t KeyVal; - struct HTTPConnectionInfo * Session = zalloc(sizeof(struct HTTPConnectionInfo)); - int i; - - if (Session == NULL) - return NULL; - - if (Mode == 'T') - { - // Terminal - - for (i = 0; i < 20; i++) - Session->ScreenLines[i] = _strdup("Scroll to end
"); - - for (i = 20; i < 100; i++) - Session->ScreenLines[i] = _strdup("
\r\n"); - - Session->Stream = FindFreeStreamNoSem(); - - if (Session->Stream == 0) - return NULL; - - SessionControl(Session->Stream, 1, 0); - } - - KeyVal = (int)sock * NOW; - - sprintf(Session->Key, "%c%012X", Mode, (int)KeyVal); - - if (SessionList) - Session->Next = SessionList; - - SessionList = Session; - - return Session; -} - -struct HTTPConnectionInfo * FindSession(char * Key) -{ - struct HTTPConnectionInfo * Session = SessionList; - - while (Session) - { - if (strcmp(Session->Key, Key) == 0) - return Session; - - Session = Session->Next; - } - - return NULL; -} - -void ProcessTermInput(SOCKET sock, char * MsgPtr, int MsgLen, char * Key) -{ - char _REPLYBUFFER[2048]; - int ReplyLen; - char Header[256]; - int HeaderLen; - int State; - struct HTTPConnectionInfo * Session = FindSession(Key); - int Stream; - int maxlen = 2000; - - - if (Session == NULL) - { - ReplyLen = sprintf(_REPLYBUFFER, "%s", LostSession); - } - else - { - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - char * end = &MsgPtr[MsgLen]; - int Line = Session->LastLine++; - char * ptr1, * ptr2; - char c; - UCHAR hex; - - int msglen = end - input; - - struct TNCINFO * TNC = Session->TNC; - struct TCPINFO * TCP = 0; - - if (TNC) - TCP = TNC->TCPInfo; - - if (TCP && TCP->WebTermCSS) - maxlen -= strlen(TCP->WebTermCSS); - - if (MsgLen > maxlen) - { - Session->KillTimer = 99999; // close session - return; - } - - - if (TCP && TCP->WebTermCSS) - ReplyLen = sprintf(_REPLYBUFFER, InputLine, Key, TCP->WebTermCSS); - else - ReplyLen = sprintf(_REPLYBUFFER, InputLine, Key, ""); - - - Stream = Session->Stream; - - input += 10; - ptr1 = ptr2 = input; - - // Convert any %xx constructs - - while (ptr1 != end) - { - c = *(ptr1++); - if (c == '%') - { - c = *(ptr1++); - if(isdigit(c)) - hex = (c - '0') << 4; - else - hex = (tolower(c) - 'a' + 10) << 4; - - c = *(ptr1++); - if(isdigit(c)) - hex += (c - '0'); - else - hex += (tolower(c) - 'a' + 10); - - *(ptr2++) = hex; - } - else if (c == '+') - *(ptr2++) = 32; - else - *(ptr2++) = c; - } - - end = ptr2; - - *ptr2 = 0; - - strcat(input, "
\r\n"); - - - if (!Session->WebsockTerm) - { - free(Session->ScreenLines[Line]); - Session->ScreenLines[Line] = _strdup(input); - - if (Line == 99) - Session->LastLine = 0; - } - - *end++ = 13; - *end = 0; - - SessionStateNoAck(Stream, &State); - - if (State == 0) - { - char AXCall[10]; - SessionControl(Stream, 1, 0); - if (BPQHOSTVECTOR[Session->Stream -1].HOSTSESSION == NULL) - { - //No L4 sessions free - - ReplyLen = sprintf(_REPLYBUFFER, "%s", NoSessions); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - return; - } - - ConvToAX25(Session->HTTPCall, AXCall); - ChangeSessionCallsign(Stream, AXCall); - if (Session->USER) - BPQHOSTVECTOR[Session->Stream -1].HOSTSESSION->Secure_Session = Session->USER->Secure; - else - Debugprintf("HTTP Term Session->USER is NULL"); - } - - SendMsg(Stream, input, (int)(end - input)); - Session->Changed = TRUE; - Session->KillTimer = 0; - } - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); -} - - -void ProcessTermClose(SOCKET sock, char * MsgPtr, int MsgLen, char * Key, int LOCAL) -{ - char _REPLYBUFFER[8192]; - int ReplyLen = sprintf(_REPLYBUFFER, InputLine, Key, ""); - char Header[256]; - int HeaderLen; - struct HTTPConnectionInfo * Session = FindSession(Key); - - if (Session) - { - Session->KillTimer = 99999; - } - - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n" - "\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); -} - -struct HTTPConnectionInfo * ProcessTermSignon(struct TNCINFO * TNC, SOCKET sock, char * MsgPtr, int MsgLen, int LOCAL) -{ - char _REPLYBUFFER[8192]; - int ReplyLen = 0; - char Header[256]; - int HeaderLen; - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - char * user, * password, * Context, * Appl; - char NoApp[] = ""; - char Flag[16] = ""; - int Websocks = 0; - - struct TCPINFO * TCP = TNC->TCPInfo; - - if (input) - { - int i; - struct UserRec * USER; - - UndoTransparency(input); - - if (strstr(input, "Cancel=Cancel")) - { - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - goto Sendit; - } - - if (strstr(input, "Flag=Websocks")) - { - Websocks = 1; - strcpy(Flag, "Websocks"); - } - user = strtok_s(&input[9], "&", &Context); - password = strtok_s(NULL, "=", &Context); - password = strtok_s(NULL, "&", &Context); - - Appl = strtok_s(NULL, "=", &Context); - Appl = strtok_s(NULL, "&", &Context); - - if (Appl == 0) - Appl = NoApp; - - if (password == NULL) - { - ReplyLen = sprintf(_REPLYBUFFER, TermSignon, Mycall, Mycall, Appl, Flag); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", PassError); - goto Sendit; - } - - for (i = 0; i < TCP->NumberofUsers; i++) - { - USER = TCP->UserRecPtr[i]; - - if ((strcmp(password, USER->Password) == 0) && - ((_stricmp(user, USER->UserName) == 0 ) || (_stricmp(USER->UserName, "ANON") == 0))) - { - // ok - - struct HTTPConnectionInfo * Session = AllocateSession(sock, 'T'); - - if (Session) - { - char AXCall[10]; - if (_stricmp(USER->UserName, "ANON") == 0) - strcpy(Session->HTTPCall, _strupr(user)); - else - strcpy(Session->HTTPCall, USER->Callsign); - ConvToAX25(Session->HTTPCall, AXCall); - ChangeSessionCallsign(Session->Stream, AXCall); - BPQHOSTVECTOR[Session->Stream -1].HOSTSESSION->Secure_Session = USER->Secure; - Session->USER = USER; - - if (USER->Appl[0]) - SendMsg(Session->Stream, USER->Appl, (int)strlen(USER->Appl)); - - if (Websocks) - return Session; - - // Old Style Terminal - - ReplyLen = sprintf(_REPLYBUFFER, TermPage, Mycall, Mycall, Session->Key, Session->Key, Session->Key); - - } - else - { - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", BusyError); - } - break; - } - } - - if (i == TCP->NumberofUsers) - { - // Not found - - ReplyLen = sprintf(_REPLYBUFFER, TermSignon, Mycall, Mycall, Appl, Flag); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", PassError); - } - } - -Sendit: - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 0; -} - -char * LookupKey(char * Key) -{ - if (strcmp(Key, "##MY_CALLSIGN##") == 0) - { - char Mycall[10]; - memcpy(Mycall, &MYNODECALL, 10); - strlop(Mycall, ' '); - - return _strdup(Mycall); - } - return NULL; -} - - -int ProcessSpecialPage(char * Buffer, int FileSize) -{ - // replaces ##xxx### constructs with the requested data - - char * NewMessage = malloc(100000); - char * ptr1 = Buffer, * ptr2, * ptr3, * ptr4, * NewPtr = NewMessage; - int PrevLen; - int BytesLeft = FileSize; - int NewFileSize = FileSize; - char * StripPtr = ptr1; - - // strip comments blocks - - while (ptr4 = strstr(ptr1, ""); - if (ptr2) - { - PrevLen = (int)(ptr4 - ptr1); - memcpy(StripPtr, ptr1, PrevLen); - StripPtr += PrevLen; - ptr1 = ptr2 + 3; - BytesLeft = (int)(FileSize - (ptr1 - Buffer)); - } - } - - memcpy(StripPtr, ptr1, BytesLeft); - StripPtr += BytesLeft; - - BytesLeft = (int)(StripPtr - Buffer); - - FileSize = BytesLeft; - NewFileSize = FileSize; - ptr1 = Buffer; - ptr1[FileSize] = 0; - -loop: - ptr2 = strstr(ptr1, "##"); - - if (ptr2) - { - PrevLen = (int)(ptr2 - ptr1); // Bytes before special text - - ptr3 = strstr(ptr2+2, "##"); - - if (ptr3) - { - char Key[80] = ""; - int KeyLen; - char * NewText; - int NewTextLen; - - ptr3 += 2; - KeyLen = (int)(ptr3 - ptr2); - - if (KeyLen < 80) - memcpy(Key, ptr2, KeyLen); - - NewText = LookupKey(Key); - - if (NewText) - { - NewTextLen = (int)strlen(NewText); - NewFileSize = NewFileSize + NewTextLen - KeyLen; - // NewMessage = realloc(NewMessage, NewFileSize); - - memcpy(NewPtr, ptr1, PrevLen); - NewPtr += PrevLen; - memcpy(NewPtr, NewText, NewTextLen); - NewPtr += NewTextLen; - - free(NewText); - NewText = NULL; - } - else - { - // Key not found, so just leave - - memcpy(NewPtr, ptr1, PrevLen + KeyLen); - NewPtr += (PrevLen + KeyLen); - } - - ptr1 = ptr3; // Continue scan from here - BytesLeft = (int)(Buffer + FileSize - ptr3); - } - else // Unmatched ## - { - memcpy(NewPtr, ptr1, PrevLen + 2); - NewPtr += (PrevLen + 2); - ptr1 = ptr2 + 2; - } - goto loop; - } - - // Copy Rest - - memcpy(NewPtr, ptr1, BytesLeft); - NewMessage[NewFileSize] = 0; - - strcpy(Buffer, NewMessage); - free(NewMessage); - - return NewFileSize; -} - -int SendMessageFile(SOCKET sock, char * FN, BOOL OnlyifExists, int allowDeflate) -{ - int FileSize = 0, Sent, Loops = 0; - char * MsgBytes; - char MsgFile[512]; - FILE * hFile; - int ReadLen; - BOOL Special = FALSE; - int Len; - int HeaderLen; - char Header[256]; - char TimeString[64]; - char FileTimeString[64]; - struct stat STAT; - char * ptr; - char * Compressed = 0; - char Encoding[] = "Content-Encoding: deflate\r\n"; - char Type[64] = "Content-Type: text/html\r\n"; - -#ifdef WIN32 - - struct _EXCEPTION_POINTERS exinfo; - strcpy(EXCEPTMSG, "SendMessageFile"); - - __try { -#endif - - UndoTransparency(FN); - - if (strstr(FN, "..")) - { - FN[0] = '/'; - FN[1] = 0; - } - - if (strlen(FN) > 256) - { - FN[256] = 0; - Debugprintf("HTTP File Name too long %s", FN); - } - - if (strcmp(FN, "/") == 0) - if (APRSActive) - sprintf(MsgFile, "%s/HTML/index.html", BPQDirectory); - else - sprintf(MsgFile, "%s/HTML/indexnoaprs.html", BPQDirectory); - else - sprintf(MsgFile, "%s/HTML%s", BPQDirectory, FN); - - - // First see if file exists so we can override standard ones in code - - if (stat(MsgFile, &STAT) == 0 && (hFile = fopen(MsgFile, "rb"))) - { - FileSize = STAT.st_size; - - MsgBytes = zalloc(FileSize + 1); - - ReadLen = (int)fread(MsgBytes, 1, FileSize, hFile); - - fclose(hFile); - - // ft.QuadPart -= 116444736000000000; - // ft.QuadPart /= 10000000; - - // ctime = ft.LowPart; - - FormatTime3(FileTimeString, STAT.st_ctime); - } - else - { - // See if it is a hard coded file - - MsgBytes = GetStandardPage(&FN[1], &FileSize); - - if (MsgBytes) - { - if (FileSize == 0) - FileSize = strlen(MsgBytes); - - FormatTime3(FileTimeString, 0); - } - else - { - if (OnlyifExists) // Set if we dont want an error response if missing - return -1; - - Len = sprintf(Header, "HTTP/1.1 404 Not Found\r\nContent-Length: 16\r\n\r\nPage not found\r\n"); - send(sock, Header, Len, 0); - return 0; - } - } - - // if HTML file, look for ##...## substitutions - - if ((strcmp(FN, "/") == 0 || strstr(FN, "htm" ) || strstr(FN, "HTM")) && strstr(MsgBytes, "##" )) - { - FileSize = ProcessSpecialPage(MsgBytes, FileSize); - FormatTime3(FileTimeString, NOW); - - } - - FormatTime3(TimeString, NOW); - - ptr = FN; - - while (strchr(ptr, '.')) - { - ptr = strchr(ptr, '.'); - ++ptr; - } - - if (_stricmp(ptr, "js") == 0) - strcpy(Type, "Content-Type: text/javascript\r\n"); - - if (_stricmp(ptr, "css") == 0) - strcpy(Type, "Content-Type: text/css\r\n"); - - if (_stricmp(ptr, "pdf") == 0) - strcpy(Type, "Content-Type: application/pdf\r\n"); - - if (allowDeflate) - { - Compressed = Compressit(MsgBytes, FileSize, &FileSize); - } - else - { - Encoding[0] = 0; - Compressed = MsgBytes; - } - - if (_stricmp(ptr, "jpg") == 0 || _stricmp(ptr, "jpeg") == 0 || _stricmp(ptr, "png") == 0 || - _stricmp(ptr, "gif") == 0 || _stricmp(ptr, "bmp") == 0 || _stricmp(ptr, "ico") == 0) - strcpy(Type, "Content-Type: image\r\n"); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n" - "Date: %s\r\n" - "Last-Modified: %s\r\n" - "%s%s" - "\r\n", FileSize, TimeString, FileTimeString, Type, Encoding); - - send(sock, Header, HeaderLen, 0); - - Sent = send(sock, Compressed, FileSize, 0); - - while (Sent != FileSize && Loops++ < 3000) // 100 secs max - { - if (Sent > 0) // something sent - { -// Debugprintf("%d out of %d sent", Sent, FileSize); - FileSize -= Sent; - memmove(Compressed, &Compressed[Sent], FileSize); - } - - Sleep(30); - Sent = send(sock, Compressed, FileSize, 0); - } - -// Debugprintf("%d out of %d sent %d loops", Sent, FileSize, Loops); - - - free (MsgBytes); - if (allowDeflate) - free (Compressed); - -#ifdef WIN32 - } -#include "StdExcept.c" - Debugprintf("Sending FIle %s", FN); -} -#endif - -return 0; -} - -int sendandcheck(SOCKET sock, const char * Buffer, int Len) -{ - int Loops = 0; - int Sent = send(sock, Buffer, Len, 0); - char * Copy = NULL; - - if (Sent == -1) - return 0; - - while (Sent != Len && Loops++ < 300) // 10 secs max - { - // Debugprintf("%d out of %d sent %d Loops", Sent, Len, Loops); - - if (Copy == NULL) - { - Copy = malloc(Len); - memcpy(Copy, Buffer, Len); - } - - if (Sent > 0) // something sent - { - Len -= Sent; - memmove(Copy, &Copy[Sent], Len); - } - - Sleep(30); - Sent = send(sock, Copy, Len, 0); - } - - if (Copy) - free(Copy); - - return 1; -} - -int RefreshTermWindow(struct TCPINFO * TCP, struct HTTPConnectionInfo * Session, char * _REPLYBUFFER) -{ - char Msg[400] = ""; - int HeaderLen, ReplyLen; - char Header[256]; - - PollSession(Session); // See if anything received - - if (Session->Changed) - { - int Last = Session->LastLine; - int n; - - if (TCP && TCP->WebTermCSS) - sprintf(_REPLYBUFFER, TermOutput, TCP->WebTermCSS); - else - sprintf(_REPLYBUFFER, TermOutput, ""); - - for (n = Last;;) - { - strcat(_REPLYBUFFER, Session->ScreenLines[n]); - - if (n == 99) - n = -1; - - if (++n == Last) - break; - } - - Session->Changed = 0; - - ReplyLen = (int)strlen(_REPLYBUFFER); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", TermOutputTail); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen); - sendandcheck(Session->sock, Header, HeaderLen); - sendandcheck(Session->sock, _REPLYBUFFER, ReplyLen); - - return 1; - } - else - return 0; -} - -int SetupNodeMenu(char * Buff, int LOCAL) -{ - int Len = 0, i; - struct TNCINFO * TNC; - int top = 0, left = 0; - - char NodeMenuHeader[] = "%s's BPQ32 Web Server" - "" - - "" - "

BPQ32 Node %s

" - "

" - "" - "" - "" - "" - "" - "" - "%s%s%s%s%s%s"; - - char DriverBit[] = "" - ""; - - char APRSBit[] = ""; - - char MailBit[] = "" - ""; - - char ChatBit[] = ""; - char SigninBit[] = ""; - - char NodeTail[] = - "\ -
RoutesNodesPortsLinksUsersStatsTerminalDriver WindowsStream StatusAPRS PagesMail MgmtWebMailChat MgmtSYSOP SigninEdit Config\ -
"; - - - Len = sprintf(Buff, NodeMenuHeader, Mycall); - - for (i=1; i <= MAXBPQPORTS; i++) - { - TNC = TNCInfo[i]; - if (TNC == NULL) - continue; - - if (TNC->WebWindowProc) - { - Len += sprintf(&Buff[Len], NodeMenuLine, i, TNC->WebWinX, TNC->WebWinY, top, left); - top += 22; - left += 22; - } - } - - Len += sprintf(&Buff[Len], NodeMenuRest, Mycall, - DriverBit, - (APRSWeb)?APRSBit:"", - (IncludesMail)?MailBit:"", (IncludesChat)?ChatBit:"", (LOCAL)?"":SigninBit, NodeTail); - - return Len; -} - -VOID SaveConfigFile(SOCKET sock , char * MsgPtr, char * Rest, int LOCAL) -{ - int ReplyLen = 0; - char * ptr, * ptr1, * ptr2, *input; - char c; - int MsgLen, WriteLen = 0; - char inputname[250]="bpq32.cfg"; - FILE *fp1; - char Header[256]; - int HeaderLen; - char Reply[4096]; - char Mess[256]; - char Backup1[MAX_PATH]; - char Backup2[MAX_PATH]; - struct stat STAT; - - input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - - if (input) - { - if (strstr(input, "Cancel=Cancel")) - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - // ReplyLen = sprintf(Reply, "%s", ""); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, Reply, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - return; - } - - ptr = strstr(input, "&Save="); - - if (ptr) - { - *ptr = 0; - - // Undo any % transparency - - ptr1 = ptr2 = input + 8; - - c = *(ptr1++); - - while (c) - { - if (c == '%') - { - int n; - int m = *(ptr1++) - '0'; - if (m > 9) m = m - 7; - n = *(ptr1++) - '0'; - if (n > 9) n = n - 7; - - c = m * 16 + n; - } - else if (c == '+') - c = ' '; - -#ifndef WIN32 - if (c != 13) // Strip CR if Linux -#endif - *(ptr2++) = c; - - c = *(ptr1++); - - } - - *(ptr2++) = 0; - - MsgLen = (int)strlen(input + 8); - - if (ConfigDirectory[0] == 0) - { - strcpy(inputname, "bpq32.cfg"); - } - else - { - strcpy(inputname,ConfigDirectory); - strcat(inputname,"/"); - strcat(inputname, "bpq32.cfg"); - } - - // Make a backup of the config - - // Keep 4 Generations - - strcpy(Backup2, inputname); - strcat(Backup2, ".bak.3"); - - strcpy(Backup1, inputname); - strcat(Backup1, ".bak.2"); - - DeleteFile(Backup2); // Remove old .bak.3 - MoveFile(Backup1, Backup2); // Move .bak.2 to .bak.3 - - strcpy(Backup2, inputname); - strcat(Backup2, ".bak.1"); - - MoveFile(Backup2, Backup1); // Move .bak.1 to .bak.2 - - strcpy(Backup1, inputname); - strcat(Backup1, ".bak"); - - MoveFile(Backup1, Backup2); // Move .bak to .bak.1 - - CopyFile(inputname, Backup1, FALSE); // Copy to .bak - - // Get length to compare with new length - - stat(inputname, &STAT); - - fp1 = fopen(inputname, "wb"); - - if (fp1) - { - WriteLen = (int)fwrite(input + 8, 1, MsgLen, fp1); - fclose(fp1); - } - - if (WriteLen != MsgLen) - sprintf_s(Mess, sizeof(Mess), "Failed to write Config File"); - else - sprintf_s(Mess, sizeof(Mess), "Configuration Saved, Orig Length %d New Length %d", - STAT.st_size, MsgLen); - } - - ReplyLen = sprintf(Reply, "", Mess); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen); - send(sock, Header, HeaderLen, 0); - send(sock, Reply, ReplyLen, 0); - } - return; -} - -// Compress using deflate. Caller must free output buffer after use - -unsigned char * Compressit(unsigned char * In, int Len, int * OutLen) -{ - z_stream defstream; - int maxSize; - unsigned char * Out; - - defstream.zalloc = Z_NULL; - defstream.zfree = Z_NULL; - defstream.opaque = Z_NULL; - - defstream.avail_in = Len; // size of input - defstream.next_in = (Bytef *)In; // input char array - - deflateInit(&defstream, Z_BEST_COMPRESSION); - maxSize = deflateBound(&defstream, Len); - - Out = malloc(maxSize); - - defstream.avail_out = maxSize; // size of output - defstream.next_out = (Bytef *)Out; // output char array - - deflate(&defstream, Z_FINISH); - deflateEnd(&defstream); - - *OutLen = defstream.total_out; - - return Out; -} - - -int InnerProcessHTTPMessage(struct ConnectionInfo * conn) -{ - struct TCPINFO * TCP = conn->TNC->TCPInfo; - SOCKET sock = conn->socket; - char * MsgPtr = conn->InputBuffer; - int MsgLen = conn->InputLen; - int InputLen = 0; - int OutputLen = 0; - int Bufferlen; - struct HTTPConnectionInfo CI; - struct HTTPConnectionInfo * sockptr = &CI; - struct HTTPConnectionInfo * Session = NULL; - - char URL[100000]; - char * ptr; - char * encPtr = 0; - int allowDeflate = 0; - char * Compressed = 0; - - char * Context, * Method, * NodeURL = 0, * Key; - char _REPLYBUFFER[250000]; - char Reply[250000]; - - int ReplyLen = 0; - char Header[256]; - int HeaderLen; - char TimeString[64]; - BOOL LOCAL = conn->LOCALAuth; - BOOL COOKIE = FALSE; - int Len; - char * WebSock = 0; - - char PortsHddr[] = "

Ports

" - ""; - -// char PortLine[] = ""; - - char PortLineWithBeacon[] = "" - "\r\n"; - - char SessionPortLine[] = "" - "\r\n"; - - char PortLineWithDriver[] = "" - "\r\n"; - - - char PortLineWithBeaconAndDriver[] = "" - "" - "\r\n"; - - char RigControlLine[] = "" - "\r\n"; - - - char Encoding[] = "Content-Encoding: deflate\r\n"; - -#ifdef WIN32xx - - struct _EXCEPTION_POINTERS exinfo; - strcpy(EXCEPTMSG, "ProcessHTTPMessage"); - - __try { -#endif - - Len = (int)strlen(MsgPtr); - if (Len > 100000) - return 0; - - strcpy(URL, MsgPtr); - - WebSock = strstr(MsgPtr, "Upgrade: websocket"); - - encPtr = stristr(MsgPtr, "Accept-Encoding:"); - - if (encPtr && stristr(encPtr, "deflate")) - allowDeflate = 1; - else - Encoding[0] = 0; - - ptr = strstr(MsgPtr, "BPQSessionCookie=N"); - - if (ptr) - { - COOKIE = TRUE; - Key = ptr + 17; - ptr = strchr(Key, ','); - if (ptr) - { - *ptr = 0; - Session = FindSession(Key); - *ptr = ','; - } - else - { - ptr = strchr(Key, 13); - if (ptr) - { - *ptr = 0; - Session = FindSession(Key); - *ptr = 13; - } - } - } - - if (WebSock) - { - // Websock connection request - Reply and remember state. - - char KeyMsg[128]; - char Webx[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // Fixed UID - char Hash[64] = ""; - char * Hash64; // base 64 version - char * ptr; - - //Sec-WebSocket-Key: l622yZS3n+zI+hR6SVWkPw== - - char ReplyMsg[] = - "HTTP/1.1 101 Switching Protocols\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Accept: %s\r\n" -// "Sec-WebSocket-Protocol: chat\r\n" - "\r\n"; - - ptr = strstr(MsgPtr, "Sec-WebSocket-Key:"); - - if (ptr) - { - ptr += 18; - while (*ptr == ' ') - ptr++; - - memcpy(KeyMsg, ptr, 40); - strlop(KeyMsg, 13); - strlop(KeyMsg, ' '); - strcat(KeyMsg, Webx); - - SHA1PasswordHash(KeyMsg, Hash); - Hash64 = byte_base64_encode(Hash, 20); - - conn->WebSocks = 1; - strlop(&URL[4], ' '); - strcpy(conn->WebURL, &URL[4]); - - ReplyLen = sprintf(Reply, ReplyMsg, Hash64); - - free(Hash64); - goto Returnit; - - } - } - - - ptr = strstr(URL, " HTTP"); - - if (ptr) - *ptr = 0; - - Method = strtok_s(URL, " ", &Context); - - memcpy(Mycall, &MYNODECALL, 10); - strlop(Mycall, ' '); - - - // Look for API messages - - if (_memicmp(Context, "/api/", 5) == 0 || _stricmp(Context, "/api") == 0) - { - char * Compressed; - - // if for mail api process signon here and rearrange url from - // api/v1/mail to mail/api/v1 so it goes to mail handler later - - if (_memicmp(Context, "/api/v1/mail/", 13) == 0) - { - memcpy(MsgPtr, "GET /mail/api/v1/", 17); - - if (memcmp(&Context[13], "login", 5) == 0) - { - ReplyLen = ProcessMailAPISignon(TCP, MsgPtr, "M", Reply, &Session, FALSE, LOCAL); - memcpy(MsgPtr, "GET /mail/api/v1/", 17); - - if (ReplyLen) // Error message - goto Returnit; - } - - memcpy(Context, "/mail/api/v1/", 13); - goto doHeader; - } - else - { - ReplyLen = APIProcessHTTPMessage(_REPLYBUFFER, Method, Context, MsgPtr, LOCAL, COOKIE); - - if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0) - { - // Full Message - just send it - - sendandcheck(sock, _REPLYBUFFER, ReplyLen); - - return 0; - } - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - Compressed = _REPLYBUFFER; - - 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" - "Access-Control-Allow-Origin: *\r\n" - "Cache-Control: no-cache\r\n" - "%s\r\n", ReplyLen, Encoding); - - - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - } - } - - if (_memicmp(Context, "/rhp/", 5) == 0 || _stricmp(Context, "/rhp") == 0) - { - { - ReplyLen = RHPProcessHTTPMessage(conn, _REPLYBUFFER, Method, Context, MsgPtr, LOCAL, COOKIE); - - if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0) - { - // Full Message - just send it - - sendandcheck(sock, _REPLYBUFFER, ReplyLen); - - return 0; - } - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - Compressed = _REPLYBUFFER; - - 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" - "Access-Control-Allow-Origin: *\r\n" - "%s\r\n", ReplyLen, Encoding); - - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - } - } - - // APRS process internally - - if (_memicmp(Context, "/APRS/", 6) == 0 || _stricmp(Context, "/APRS") == 0) - { - if (APRSActive) - { - APRSProcessHTTPMessage(sock, MsgPtr, LOCAL, COOKIE); - return 0; - } - Len = sprintf(Header, "HTTP/1.1 404 Not Found\r\nContent-Length: 16\r\n\r\nPage not found\r\n"); - send(sock, Header, Len, 0); - return 0; - } - - - - if (_stricmp(Context, "/Node/Signon?Node") == 0) - { - char * IContext; - - NodeURL = strtok_s(Context, "?", &IContext); - Key = strtok_s(NULL, "?", &IContext); - - ProcessNodeSignon(sock, TCP, MsgPtr, Key, Reply, &Session, LOCAL); - return 0; - - } - - // If for Mail or Chat, check for a session, and send login screen if necessary - - // Moved here to simplify operation with both internal and external clients - - if (_memicmp(Context, "/Mail/", 6) == 0) - { - int RLen = 0; - char Appl; - char * input; - char * IContext; - - NodeURL = strtok_s(Context, "?", &IContext); - Key = strtok_s(NULL, "?", &IContext); - - if (_stricmp(NodeURL, "/Mail/Signon") == 0) - { - ReplyLen = ProcessMailSignon(TCP, MsgPtr, Key, Reply, &Session, FALSE, LOCAL); - - if (ReplyLen) - { - goto Returnit; - } - -#ifdef LINBPQ - strcpy(Context, "/Mail/Header"); -#else - strcpy(MsgPtr, "POST /Mail/Header"); -#endif - goto doHeader; - } - - if (_stricmp(NodeURL, "/Mail/Lost") == 0) - { - input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - - if (input && strstr(input, "Cancel=Exit")) - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - RLen = ReplyLen; - goto Returnit; - } - if (Key) - Appl = Key[0]; - - Key = 0; - } - - if (Key == 0 || Key[0] == 0) - { - // No Session - - // if not local send a signon screen, else create a user session - - if (LOCAL || COOKIE) - { - Session = AllocateSession(sock, 'M'); - - if (Session) - { - strcpy(Context, "/Mail/Header"); - goto doHeader; - } - else - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError); - } - RLen = ReplyLen; - - goto Returnit; - - } - - ReplyLen = sprintf(Reply, MailSignon, Mycall, Mycall); - - RLen = ReplyLen; - goto Returnit; - } - - Session = FindSession(Key); - - - if (Session == NULL && _memicmp(Context, "/Mail/API/", 10) != 0) - { - ReplyLen = sprintf(Reply, MailLostSession, Key); - RLen = ReplyLen; - goto Returnit; - } - } - - if (_memicmp(Context, "/Chat/", 6) == 0) - { - int RLen = 0; - char Appl; - char * input; - char * IContext; - - // LOCAL is already set - - NodeURL = strtok_s(Context, "?", &IContext); - Key = strtok_s(NULL, "?", &IContext); - - if (_stricmp(NodeURL, "/Chat/Signon") == 0) - { - ReplyLen = ProcessChatSignon(TCP, MsgPtr, Key, Reply, &Session, LOCAL); - - if (ReplyLen) - { - goto Returnit; - } - -#ifdef LINBPQ - strcpy(Context, "/Chat/Header"); -#else - strcpy(MsgPtr, "POST /Chat/Header"); -#endif - goto doHeader; - } - - if (_stricmp(NodeURL, "/Chat/Lost") == 0) - { - input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - - if (input && strstr(input, "Cancel=Exit")) - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - RLen = ReplyLen; - goto Returnit; - } - if (Key) - Appl = Key[0]; - - Key = 0; - } - - if (Key == 0 || Key[0] == 0) - { - // No Session - - // if not local send a signon screen, else create a user session - - if (LOCAL || COOKIE) - { - Session = AllocateSession(sock, 'C'); - - if (Session) - { - strcpy(Context, "/Chat/Header"); - goto doHeader; - } - else - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError); - } - RLen = ReplyLen; - - goto Returnit; - - } - - ReplyLen = sprintf(Reply, ChatSignon, Mycall, Mycall); - - RLen = ReplyLen; - goto Returnit; - } - - Session = FindSession(Key); - - if (Session == NULL) - { - int Sent, Loops = 0; - ReplyLen = sprintf(Reply, MailLostSession, Key); - RLen = ReplyLen; -Returnit: - if (memcmp(Reply, "HTTP", 4) == 0) - { - // Full Header provided by appl - just send it - - // Send may block - - Sent = send(sock, Reply, ReplyLen, 0); - - while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max - { - // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); - - if (Sent > 0) // something sent - { - InputLen -= Sent; - memmove(Reply, &Reply[Sent], ReplyLen); - } - - Sleep(30); - Sent = send(sock, Reply, ReplyLen, 0); - } - - return 0; - } - - if (NodeURL && _memicmp(NodeURL, "/mail/api/", 10) != 0) - { - // Add tail - - strcpy(&Reply[ReplyLen], Tail); - ReplyLen += strlen(Tail); - } - - // compress if allowed - - if (allowDeflate) - Compressed = Compressit(Reply, ReplyLen, &ReplyLen); - else - Compressed = Reply; - - if (NodeURL && _memicmp(NodeURL, "/mail/api/", 10) == 0) - 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); - - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - } - } - -doHeader: - -#ifdef LINBPQ - - if ((_memicmp(Context, "/MAIL/", 6) == 0) || (_memicmp(Context, "/WebMail", 8) == 0)) - { - 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; - - if (Session == 0) - Session = &Dummy; - - if (LOCAL) - Session->TNC = (void *)1; // TNC only used for Web Terminal Sessions - else - Session->TNC = (void *)0; - - ProcessMailHTTPMessage(Session, Method, Context, MsgPtr, _REPLYBUFFER, &ReplyLen, MsgLen, token); - - if (Context && _memicmp(Context, "/mail/api/", 10) == 0) - { - if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0) - { - // Full Header provided by appl - just send it - - // Send may block - - Sent = send(sock, _REPLYBUFFER, ReplyLen, 0); - - while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max - { - // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); - - if (Sent > 0) // something sent - { - InputLen -= Sent; - memmove(_REPLYBUFFER, &_REPLYBUFFER[Sent], ReplyLen); - } - - Sleep(30); - Sent = send(sock, _REPLYBUFFER, ReplyLen, 0); - } - return 0; - } - - // compress if allowed - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - Compressed = _REPLYBUFFER; - - 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); - - if (allowDeflate) - free (Compressed); - - return 0; - } - - if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0) - { - // Full Header provided by appl - just send it - - // Send may block - - Sent = send(sock, _REPLYBUFFER, ReplyLen, 0); - - while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max - { - // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); - - if (Sent > 0) // something sent - { - InputLen -= Sent; - memmove(_REPLYBUFFER, &_REPLYBUFFER[Sent], ReplyLen); - } - - Sleep(30); - Sent = send(sock, _REPLYBUFFER, ReplyLen, 0); - } - return 0; - } - - if (Context && _memicmp(Context, "/mail/api/", 10) != 0) - { - - // Add tail - - strcpy(&_REPLYBUFFER[ReplyLen], Tail); - ReplyLen += strlen(Tail); - - } - - // compress if allowed - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - 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); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - - -/* - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - - // Send may block - - Sent = send(sock, _REPLYBUFFER, ReplyLen, 0); - - if (Sent == -1) - return 0; - - while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max - { - // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); - - if (Sent > 0) // something sent - { - InputLen -= Sent; - memmove(_REPLYBUFFER, &_REPLYBUFFER[Sent], ReplyLen); - } - - Sleep(30); - Sent = send(sock, _REPLYBUFFER, ReplyLen, 0); - } - - send(sock, Tail, (int)strlen(Tail), 0); - return 0; -*/ - } - - if (_memicmp(Context, "/CHAT/", 6) == 0) - { - char _REPLYBUFFER[100000]; - - ReplyLen = 0; - - ProcessChatHTTPMessage(Session, Method, Context, MsgPtr, _REPLYBUFFER, &ReplyLen); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 0; - - } - - - /* - Sent = send(sock, _REPLYBUFFER, InputLen, 0); - - while (Sent != InputLen && Loops++ < 3000) // 100 secs max - { - // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); - - if (Sent > 0) // something sent - { - InputLen -= Sent; - memmove(_REPLYBUFFER, &_REPLYBUFFER[Sent], InputLen); - } - - Sleep(30); - Sent = send(sock, _REPLYBUFFER, InputLen, 0); - } - return 0; - } - */ -#else - - // 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 - - HANDLE hPipe; - - hPipe = CreateFile(MAILPipeFileName, GENERIC_READ | GENERIC_WRITE, - 0, // exclusive access - NULL, // no security attrs - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL ); - - if (hPipe == (HANDLE)-1) - { - InputLen = sprintf(Reply, "HTTP/1.1 404 Not Found\r\nContent-Length: 28\r\n\r\nMail Data is not available\r\n"); - send(sock, Reply, InputLen, 0); - } - else - { - // int Sent; - int Loops = 0; - struct HTTPConnectionInfo Dummy = {0}; - - if (Session == 0) - Session = &Dummy; - - if (LOCAL) - Session->TNC = (struct TNCINFO *)(uintptr_t)1; // TNC is only used on Web Terminal Sessions so can reuse as LOCAL flag - else - Session->TNC = 0; - - WriteFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); - WriteFile(hPipe, MsgPtr, MsgLen, &InputLen, NULL); - - - ReadFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); - ReadFile(hPipe, Reply, 250000, &ReplyLen, NULL); - if (ReplyLen <= 0) - { - InputLen = GetLastError(); - } - - CloseHandle(hPipe); - goto Returnit; - } - return 0; - } - - if (_memicmp(Context, "/CHAT/", 6) == 0) - { - HANDLE hPipe; - - hPipe = CreateFile(CHATPipeFileName, GENERIC_READ | GENERIC_WRITE, - 0, // exclusive access - NULL, // no security attrs - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL ); - - if (hPipe == (HANDLE)-1) - { - InputLen = sprintf(Reply, "HTTP/1.1 404 Not Found\r\nContent-Length: 28\r\n\r\nChat Data is not available\r\n"); - send(sock, Reply, InputLen, 0); - } - else - { - // int Sent; - int Loops = 0; - - WriteFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); - WriteFile(hPipe, MsgPtr, MsgLen, &InputLen, NULL); - - - ReadFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); - ReadFile(hPipe, Reply, 100000, &ReplyLen, NULL); - if (ReplyLen <= 0) - { - InputLen = GetLastError(); - } - - CloseHandle(hPipe); - goto Returnit; - } - return 0; - } - -#endif - - NodeURL = strtok_s(NULL, "?", &Context); - - if (NodeURL == NULL) - return 0; - - if (strcmp(Method, "POST") == 0) - { - if (_stricmp(NodeURL, "/Node/freqOffset") == 0) - { - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - int port = atoi(Context); - - if (input == 0) - return 1; - - if (LOCAL == FALSE && COOKIE == FALSE) - return 1; - - input += 4; - - if (port > 0 && port <= MaxBPQPortNo) - { - struct TNCINFO * TNC = TNCInfo[port]; - char value[6]; - - if (TNC == 0) - return 1; - - TNC->TXOffset = atoi(input); -#ifdef WIN32 - sprintf(value, "%d", TNC->TXOffset); - MySetWindowText(TNC, TNC->xIDC_TXTUNEVAL, value); - SendMessage(TNC->xIDC_TXTUNE, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) TNC->TXOffset); // min. & max. positions - -#endif - } - return 1; - } - - if (_stricmp(NodeURL, "/Node/PortAction") == 0) - { - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - int port = atoi(Context); - - if (input == 0) - return 1; - - input += 4; - - if (port > 0 && port <= MaxBPQPortNo) - { - struct TNCINFO * TNC = TNCInfo[port]; - - if (TNC == 0) - return 1; - - if (LOCAL == FALSE && COOKIE == FALSE) - return 1; - - if (strcmp(input, "Abort") == 0) - { - if (TNC->ForcedCloseProc) - TNC->ForcedCloseProc(TNC, 0); - } - else if (strcmp(input, "Kill") == 0) - { - TNC->DontRestart = TRUE; - KillTNC(TNC); - } - else if (strcmp(input, "KillRestart") == 0) - { - TNC->DontRestart = FALSE; - KillTNC(TNC); - RestartTNC(TNC); - - } - } - return 1; - } - - if (_stricmp(NodeURL, "/TermInput") == 0) - { - ProcessTermInput(sock, MsgPtr, MsgLen, Context); - return 0; - } - - - else if (_stricmp(NodeURL, "/Node/TermAction") == 0) - { - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - - if (input == 0) - return 1; - - input += 4; - - Session = FindSession(Context); - - if (strcmp(input, "Disconnect") == 0) - { - if (Session && Session->Stream) - { - SessionControl(Session->Stream, 2, 0); - } - } - return 1; - } - - if (_stricmp(NodeURL, "/Node/TermSignon") == 0) - { - Session = ProcessTermSignon(conn->TNC, sock, MsgPtr, MsgLen, LOCAL); - - if (Session) - { - char Header[256]; - int HeaderLen; - int ReplyLen; - - ReplyLen = DoWebSockTerm(Session, conn, _REPLYBUFFER, LOCAL, COOKIE, Context, sock); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n" - "\r\n", (int)(ReplyLen + strlen(Tail))); - - send(sock, Header, HeaderLen, 0); - sendandcheck(sock, _REPLYBUFFER, ReplyLen); - send(sock, Tail, (int)strlen(Tail), 0); - - - return 0; - } - } - - if (_stricmp(NodeURL, "/Node/Signon") == 0) - { - ProcessNodeSignon(sock, TCP, MsgPtr, Key, Reply, &Session, LOCAL); - return 0; - } - - if (_stricmp(NodeURL, "/Node/TermClose") == 0) - { - ProcessTermClose(sock, MsgPtr, MsgLen, Context, LOCAL); - return 0; - } - - if (_stricmp(NodeURL, "/Node/BeaconAction") == 0) - { - char Header[256]; - int HeaderLen; - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - int Port; - char Param[100]; -#ifndef LINBPQ - int retCode, disp; - char Key[80]; - HKEY hKey; -#endif - struct PORTCONTROL * PORT; - int Slot = 0; - - - if (LOCAL == FALSE && COOKIE == FALSE) - { - // Send Not Authorized - - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
Not authorized - please sign in"); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 1; - } - - if (strstr(input, "Cancel=Cancel")) - { - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 1; - } - - GetParam(input, "Port=", &Param[0]); - Port = atoi(&Param[0]); - PORT = GetPortTableEntryFromPortNum(Port); // Need slot not number - if (PORT) - Slot = PORT->PortSlot; - - GetParam(input, "Every=", &Param[0]); - Interval[Slot] = atoi(&Param[0]); - - GetParam(input, "Dest=", &Param[0]); - _strupr(Param); - strcpy(UIUIDEST[Slot], &Param[0]); - - GetParam(input, "Path=", &Param[0]); - _strupr(Param); - if (UIUIDigi[Slot]) - free(UIUIDigi[Slot]); - UIUIDigi[Slot] = _strdup(&Param[0]); - - GetParam(input, "File=", &Param[0]); - strcpy(FN[Slot], &Param[0]); - GetParam(input, "Text=", &Param[0]); - strcpy(Message[Slot], &Param[0]); - - MinCounter[Slot] = Interval[Slot]; - - SendFromFile[Slot] = 0; - - if (FN[Slot][0]) - SendFromFile[Slot] = 1; - - SetupUI(Slot); - -#ifdef LINBPQ - SaveUIConfig(); -#else - SaveUIConfig(); - - wsprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\UIUtil\\UIPort%d", Port); - - retCode = RegCreateKeyEx(REGTREE, - Key, 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, &disp); - - if (retCode == ERROR_SUCCESS) - { - retCode = RegSetValueEx(hKey, "UIDEST", 0, REG_SZ,(BYTE *)&UIUIDEST[Port][0], strlen(&UIUIDEST[Port][0])); - retCode = RegSetValueEx(hKey, "FileName", 0, REG_SZ,(BYTE *)&FN[Port][0], strlen(&FN[Port][0])); - retCode = RegSetValueEx(hKey, "Message", 0, REG_SZ,(BYTE *)&Message[Port][0], strlen(&Message[Port][0])); - retCode = RegSetValueEx(hKey, "Interval", 0, REG_DWORD,(BYTE *)&Interval[Port], 4); - retCode = RegSetValueEx(hKey, "SendFromFile", 0, REG_DWORD,(BYTE *)&SendFromFile[Port], 4); - retCode = RegSetValueEx(hKey, "Digis",0, REG_SZ, UIUIDigi[Port], strlen(UIUIDigi[Port])); - - RegCloseKey(hKey); - } -#endif - if (strstr(input, "Test=Test")) - SendUIBeacon(Slot); - - - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], Beacons, Port, - Interval[Slot], &UIUIDEST[Slot][0], &UIUIDigi[Slot][0], &FN[Slot][0], &Message[Slot][0], Port); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 1; - } - - if (_stricmp(NodeURL, "/Node/CfgSave") == 0) - { - // Save Config File - - if (conn->LOCALAuth || COOKIE) - SaveConfigFile(sock, MsgPtr, Key, LOCAL); - else - { - char _REPLYBUFFER[4096]; - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
Not authorizedxx - please sign in"); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - return 1; - } - - return 0; - } - - if (_stricmp(NodeURL, "/Node/LogAction") == 0) - { - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 1; - } - - - if (_stricmp(NodeURL, "/Node/ARDOPAbort") == 0) - { - int port = atoi(Context); - - if (port > 0 && port <= MaxBPQPortNo) - { - struct TNCINFO * TNC = TNCInfo[port]; - - if (TNC && TNC->ForcedCloseProc) - TNC->ForcedCloseProc(TNC, 0); - - - if (TNC && TNC->WebWindowProc) - ReplyLen = TNC->WebWindowProc(TNC, _REPLYBUFFER, LOCAL); - - - ReplyLen = sprintf(Reply, "", "Ok"); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, Reply, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - // goto SendResp; - - // HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + strlen(Tail)); - // send(sock, Header, HeaderLen, 0); - // send(sock, _REPLYBUFFER, ReplyLen, 0); - // send(sock, Tail, strlen(Tail), 0); - - return 1; - } - - } - - send(sock, _REPLYBUFFER, InputLen, 0); - return 0; - } - - if (_stricmp(NodeURL, "/") == 0 || _stricmp(NodeURL, "/Index.html") == 0) - { - // Send if present, else use default - - Bufferlen = SendMessageFile(sock, NodeURL, TRUE, allowDeflate); // return -1 if not found - - if (Bufferlen != -1) - return 0; // We've sent it - else - { - if (APRSApplConnected) - ReplyLen = sprintf(_REPLYBUFFER, Index, Mycall, Mycall); - else - ReplyLen = sprintf(_REPLYBUFFER, IndexNoAPRS, Mycall, Mycall); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 0; - } - } - - else if (_stricmp(NodeURL, "/NodeMenu.html") == 0 || _stricmp(NodeURL, "/Node/NodeMenu.html") == 0) - { - // Send if present, else use default - - char Menu[] = "/NodeMenu.html"; - - Bufferlen = SendMessageFile(sock, Menu, TRUE, allowDeflate); // return -1 if not found - - if (Bufferlen != -1) - return 0; // We've sent it - } - - else if (_memicmp(NodeURL, "/aisdata.txt", 12) == 0) - { - char * Compressed; - ReplyLen = GetAISPageInfo(_REPLYBUFFER, 1, 1); - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - Compressed = _REPLYBUFFER; - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: Text\r\n%s\r\n", ReplyLen, Encoding); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - } - - else if (_memicmp(NodeURL, "/aprsdata.txt", 13) == 0) - { - char * Compressed; - char * ptr; - double N, S, W, E; - int aprs = 1, ais = 1, adsb = 1; - - ptr = &NodeURL[14]; - - N = atof(ptr); - ptr = strlop(ptr, '|'); - S = atof(ptr); - ptr = strlop(ptr, '|'); - W = atof(ptr); - ptr = strlop(ptr, '|'); - E = atof(ptr); - ptr = strlop(ptr, '|'); - if (ptr) - { - aprs = atoi(ptr); - ptr = strlop(ptr, '|'); - ais = atoi(ptr); - ptr = strlop(ptr, '|'); - adsb = atoi(ptr); - } - ReplyLen = GetAPRSPageInfo(_REPLYBUFFER, N, S, W, E, aprs, ais, adsb); - - if (ReplyLen < 240000) - ReplyLen += GetAISPageInfo(&_REPLYBUFFER[ReplyLen], ais, adsb); - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - Compressed = _REPLYBUFFER; - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %d\r\nContent-Type: Text\r\n%s\r\n", ReplyLen, Encoding); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - } - - else if (_memicmp(NodeURL, "/portstats.txt", 15) == 0) - { - char * Compressed; - char * ptr; - int port; - struct PORTCONTROL * PORT; - - ptr = &NodeURL[15]; - - port = atoi(ptr); - - PORT = GetPortTableEntryFromPortNum(port); - - ReplyLen = 0; - - if (PORT && PORT->TX) - { - // We send the last 24 hours worth of data. Buffer is cyclic so oldest byte is at StatsPointer - - int first = PORT->StatsPointer; - int firstlen = 1440 - first; - - memcpy(&_REPLYBUFFER[0], &PORT->TX[first], firstlen); - memcpy(&_REPLYBUFFER[firstlen], PORT->TX, first); - - memcpy(&_REPLYBUFFER[1440], &PORT->BUSY[first], firstlen); - memcpy(&_REPLYBUFFER[1440 + firstlen], PORT->BUSY, first); - - ReplyLen = 2880; - } - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - Compressed = _REPLYBUFFER; - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %d\r\nContent-Type: Text\r\n%s\r\n", ReplyLen, Encoding); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - } - - - else if (_memicmp(NodeURL, "/Icon", 5) == 0 && _memicmp(&NodeURL[10], ".png", 4) == 0) - { - // APRS internal Icon - - char * Compressed; - - ReplyLen = GetAPRSIcon(_REPLYBUFFER, NodeURL); - - if (allowDeflate) - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - else - Compressed = _REPLYBUFFER; - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: Text\r\n%s\r\n", ReplyLen, Encoding); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - - return 0; - - } - - else if (_memicmp(NodeURL, "/NODE/", 6)) - { - // Not Node, See if a local file - - Bufferlen = SendMessageFile(sock, NodeURL, FALSE, allowDeflate); // Send error if not found - return 0; - } - - // Node URL - - { - - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - - if (_stricmp(NodeURL, "/Node/webproc.css") == 0) - { - char WebprocCSS[] = - ".dropbtn {position: relative; border: 1px solid black;padding:1px;}\r\n" - ".dropdown {position: relative; display: inline-block;}\r\n" - ".dropdown-content {display: none; position: absolute;background-color: #ccc; " - "min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,00.2); z-index: 1;}\r\n" - ".dropdown-content a {color: black; padding: 1px 1px;text-decoration:none;display:block;}" - ".dropdown-content a:hover {background-color: #dddfff;}\r\n" - ".dropdown:hover .dropdown-content {display: block;}\r\n" - ".dropdown:hover .dropbtn {background-color: #ddd;}\r\n" - "input.btn:active {background:black;color:white;}\r\n" - "submit.btn:active {background:black;color:white;}\r\n"; - ReplyLen = sprintf(_REPLYBUFFER, "%s", WebprocCSS); - } - - else if (_stricmp(NodeURL, "/Node/Killandrestart") == 0) - { - int port = atoi(Context); - - if (port > 0 && port <= MaxBPQPortNo) - { - struct TNCINFO * TNC = TNCInfo[port]; - - if (TNC == 0) - return 1; - - if (LOCAL == FALSE && COOKIE == FALSE) - return 1; - - KillTNC(TNC); - TNC->DontRestart = FALSE; - RestartTNC(TNC); - - if (TNC && TNC->WebWindowProc) - ReplyLen = TNC->WebWindowProc(TNC, _REPLYBUFFER, LOCAL); - - } - } - - else if (_stricmp(NodeURL, "/Node/Port") == 0 || _stricmp(NodeURL, "/Node/ARDOPAbort") == 0) - { - int port = atoi(Context); - - if (port > 0 && port <= MaxBPQPortNo) - { - struct TNCINFO * TNC = TNCInfo[port]; - - if (TNC && TNC->WebWindowProc) - ReplyLen = TNC->WebWindowProc(TNC, _REPLYBUFFER, LOCAL); - } - - } - - else if (_stricmp(NodeURL, "/Node/Streams") == 0) - { - ReplyLen = StatusProc(_REPLYBUFFER); - } - - else if (_stricmp(NodeURL, "/Node/Stats.html") == 0) - { - struct tm * TM; - char UPTime[50]; - time_t szClock = STATSTIME * 60; - - TM = gmtime(&szClock); - - sprintf(UPTime, "%.2d:%.2d:%.2d", TM->tm_yday, TM->tm_hour, TM->tm_min); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", StatsHddr); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "Version", VersionString); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "Uptime (Days Hours Mins)", UPTime); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "Semaphore: Get-Rel/Clashes", Semaphore.Gets - Semaphore.Rels, Semaphore.Clashes); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "Buffers: Max/Cur/Min/Out/Wait", MAXBUFFS, QCOUNT, MINBUFFCOUNT, NOBUFFCOUNT, BUFFERWAITS); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "Known Nodes/Max Nodes", NUMBEROFNODES, MAXDESTS); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "L4 Connects Sent/Rxed ", L4CONNECTSOUT, L4CONNECTSIN); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "L4 Frames TX/RX/Resent/Reseq", L4FRAMESTX, L4FRAMESRX, L4FRAMESRETRIED, OLDFRAMES); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - "L3 Frames Relayed", L3FRAMES); - - } - - else if (_stricmp(NodeURL, "/Node/RigControl.html") == 0) - { - char Test[] = - "\r\n" - "Rigcontrol\r\n" - "\r\n" - "\r\n" - "\r\n" - "
Waiting for data...
\r\n" - "\r\n"; - - - char NoRigCtl[] = - "\r\n" - "Rigcontrol\r\n" - "\r\n" - "\r\n" - "
RigControl Not Configured...
\r\n" - "\r\n"; - - if (RigWebPage) - ReplyLen = sprintf(_REPLYBUFFER, "%s", Test); - else - ReplyLen = sprintf(_REPLYBUFFER, "%s", NoRigCtl); - } - - else if (_stricmp(NodeURL, "/Node/DevicePage") == 0) - { - char Part1[] = - "\r\n" - "Device\r\n" - "\r\n" - "\r\n" - "\r\n" - "
Waiting for data...
\r\n" - "\r\n"; - - int Port = atoi(Context); - int xxx; - - ReplyLen = sprintf(_REPLYBUFFER, Part1, Port, Port, Port); - xxx = ReplyLen; - } - - else if (_stricmp(NodeURL, "/Node/ShowLog.html") == 0) - { - char ShowLogPage[] = - "" - "" - "Log Display" - "" - "
" - "
" -// "" - "" - "" - "
"; - - char * _REPLYBUFFER; - int ReplyLen; - char Header[256]; - int HeaderLen; - char * CfgBytes; - int CfgLen; - char inputname[250]; - FILE *fp1; - struct stat STAT; - char DummyKey[] = "DummyKey"; - time_t T; - struct tm * tm; - char Name[64] = ""; - - T = NOW; - tm = gmtime(&T); - - if (LOCAL == FALSE && COOKIE == FALSE) - { - // Send Not Authorized - - char _REPLYBUFFER[4096]; - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
Not authorized - please sign in"); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - return 1; - } - - if (COOKIE == FALSE) - Key = DummyKey; - - if (memcmp(Context, "date=", 5) == 0) - { - memset(tm, 0, sizeof(struct tm)); - tm->tm_year = atoi(&Context[5]) - 1900; - tm->tm_mon = atoi(&Context[10]) - 1; - tm->tm_mday = atoi(&Context[13]); - } - - - - if (strcmp(Context, "input=Back") == 0) - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, Reply, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - return 1; - } - - if (LogDirectory[0] == 0) - { - strcpy(inputname, "logs/"); - } - else - { - strcpy(inputname,LogDirectory); - strcat(inputname,"/"); - strcat(inputname, "/logs/"); - } - - if (strstr(Context, "CMS")) - { - sprintf(Name, "CMSAccess_%04d%02d%02d.log", - tm->tm_year +1900, tm->tm_mon+1, tm->tm_mday); - } - else if (strstr(Context, "Debug")) - { - sprintf(Name, "log_%02d%02d%02d_DEBUG.txt", - tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); - } - else if (strstr(Context, "BBS")) - { - sprintf(Name, "log_%02d%02d%02d_BBS.txt", - tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); - } - else if (strstr(Context, "Chat")) - { - sprintf(Name, "log_%02d%02d%02d_CHAT.txt", - tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); - } - else if (strstr(Context, "Telnet")) - { - sprintf(Name, "Telnet_%02d%02d%02d.log", - tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); - } - - strcat(inputname, Name); - - if (stat(inputname, &STAT) == -1) - { - CfgBytes = malloc(256); - sprintf(CfgBytes, "Log %s not found", inputname); - CfgLen = strlen(CfgBytes); - } - else - { - fp1 = fopen(inputname, "rb"); - - if (fp1 == 0) - { - CfgBytes = malloc(256); - sprintf(CfgBytes, "Log %s not found", inputname); - CfgLen = strlen(CfgBytes); - } - else - { - CfgLen = STAT.st_size; - - CfgBytes = malloc(CfgLen + 1); - - CfgLen = (int)fread(CfgBytes, 1, CfgLen, fp1); - CfgBytes[CfgLen] = 0; - } - } - - _REPLYBUFFER = malloc(CfgLen + 1000); - - ReplyLen = sprintf(_REPLYBUFFER, ShowLogPage, CfgBytes); - free (CfgBytes); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, _REPLYBUFFER, ReplyLen); - sendandcheck(sock, Tail, (int)strlen(Tail)); - free (_REPLYBUFFER); - - return 1; - } - - else if (_stricmp(NodeURL, "/Node/EditCfg.html") == 0) - { - char * _REPLYBUFFER; - int ReplyLen; - char Header[256]; - int HeaderLen; - char * CfgBytes; - int CfgLen; - char inputname[250]="bpq32.cfg"; - FILE *fp1; - struct stat STAT; - char DummyKey[] = "DummyKey"; - - if (LOCAL == FALSE && COOKIE == FALSE) - { - // Send Not Authorized - - char _REPLYBUFFER[4096]; - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
Not authorized - please sign in"); - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - send(sock, Header, HeaderLen, 0); - send(sock, _REPLYBUFFER, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - return 1; - } - - if (COOKIE ==FALSE) - Key = DummyKey; - - if (ConfigDirectory[0] == 0) - { - strcpy(inputname, "bpq32.cfg"); - } - else - { - strcpy(inputname,ConfigDirectory); - strcat(inputname,"/"); - strcat(inputname, "bpq32.cfg"); - } - - - if (stat(inputname, &STAT) == -1) - { - CfgBytes = _strdup("Config File not found"); - } - else - { - fp1 = fopen(inputname, "rb"); - - if (fp1 == 0) - { - CfgBytes = _strdup("Config File not found"); - } - else - { - CfgLen = STAT.st_size; - - CfgBytes = malloc(CfgLen + 1); - - CfgLen = (int)fread(CfgBytes, 1, CfgLen, fp1); - CfgBytes[CfgLen] = 0; - } - } - - _REPLYBUFFER = malloc(CfgLen + 1000); - - ReplyLen = sprintf(_REPLYBUFFER, ConfigEditPage, Key, CfgBytes); - free (CfgBytes); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, _REPLYBUFFER, ReplyLen); - sendandcheck(sock, Tail, (int)strlen(Tail)); - free (_REPLYBUFFER); - - return 1; - } - - - - if (_stricmp(NodeURL, "/Node/PortBeacons") == 0) - { - char * PortChar = strtok_s(NULL, "&", &Context); - int PortNo = atoi(PortChar); - struct PORTCONTROL * PORT; - int PortSlot = 0; - - PORT = GetPortTableEntryFromPortNum(PortNo); // Need slot not number - if (PORT) - PortSlot = PORT->PortSlot; - - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], Beacons, PortNo, - Interval[PortSlot], &UIUIDEST[PortSlot][0], &UIUIDigi[PortSlot][0], &FN[PortSlot][0], &Message[PortSlot][0], PortNo); - } - - - - if (_stricmp(NodeURL, "/Node/PortStats") == 0) - { - struct _EXTPORTDATA * Port; - - char * PortChar = strtok_s(NULL, "&", &Context); - int PortNo = atoi(PortChar); - int Protocol; - int PortType; - - // char PORTTYPE; // H/W TYPE - // 0 = ASYNC, 2 = PC120, 4 = DRSI - // 6 = TOSH, 8 = QUAD, 10 = RLC100 - // 12 = RLC400 14 = INTERNAL 16 = EXTERNAL - -#define KISS 0 -#define NETROM 2 -#define HDLC 6 -#define L2 8 -#define WINMOR 10 - - - // char PROTOCOL; // PORT PROTOCOL - // 0 = KISS, 2 = NETROM, 4 = BPQKISS - //; 6 = HDLC, 8 = L2 - - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsHddr, PortNo); - - Port = (struct _EXTPORTDATA *)GetPortTableEntryFromPortNum(PortNo); - - if (Port == NULL) - { - ReplyLen = sprintf(_REPLYBUFFER, "Invalid Port"); - goto SendResp; - } - - Protocol = Port->PORTCONTROL.PROTOCOL; - PortType = Port->PORTCONTROL.PROTOCOL; - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "L2 Frames Digied", Port->PORTCONTROL.L2DIGIED); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "L2 Frames Heard", Port->PORTCONTROL.L2FRAMES); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "L2 Frames Received", Port->PORTCONTROL.L2FRAMESFORUS); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "L2 Frames Sent", Port->PORTCONTROL.L2FRAMESSENT); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "L2 Timeouts", Port->PORTCONTROL.L2TIMEOUTS); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "REJ Frames Received", Port->PORTCONTROL.L2REJCOUNT); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "RX out of Seq", Port->PORTCONTROL.L2OUTOFSEQ); - // ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "L2 Resequenced", Port->PORTCONTROL.L2RESEQ); - if (Protocol == HDLC) - { - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "Underrun", Port->PORTCONTROL.L2URUNC); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "RX Overruns", Port->PORTCONTROL.L2ORUNC); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "RX CRC Errors", Port->PORTCONTROL.RXERRORS); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "Frames abandoned", Port->PORTCONTROL.L1DISCARD); - } - else if ((Protocol == KISS && Port->PORTCONTROL.KISSFLAGS) || Protocol == NETROM) - { - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "Poll Timeout", Port->PORTCONTROL.L2URUNC); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "RX CRC Errors", Port->PORTCONTROL.RXERRORS); - } - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "FRMRs Sent", Port->PORTCONTROL.L2FRMRTX); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortStatsLine, "FRMRs Received", Port->PORTCONTROL.L2FRMRRX); - - // DB 'Link Active % ' - // DD AVSENDING - - } - - if (_stricmp(NodeURL, "/Node/Ports.html") == 0) - { - struct _EXTPORTDATA * ExtPort; - struct PORTCONTROL * Port; - - int count; - char DLL[20]; - char StatsURL[64]; - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", PortsHddr); - - for (count = 1; count <= NUMBEROFPORTS; count++) - { - Port = GetPortTableEntryFromSlot(count); - ExtPort = (struct _EXTPORTDATA *)Port; - - // see if has a stats page - - if (Port->AVACTIVE) - sprintf(StatsURL, " Stats Graph", Port->PORTNUMBER); - else - StatsURL[0] = 0; - - if (Port->PORTTYPE == 0x10) - { - strcpy(DLL, ExtPort->PORT_DLL_NAME); - strlop(DLL, '.'); - } - else if (Port->PORTTYPE == 0) - strcpy(DLL, "ASYNC"); - - else if (Port->PORTTYPE == 22) - strcpy(DLL, "I2C"); - - else if (Port->PORTTYPE == 14) - strcpy(DLL, "INTERNAL"); - - else if (Port->PORTTYPE > 0 && Port->PORTTYPE < 14) - strcpy(DLL, "HDLC"); - - - if (Port->TNC && Port->TNC->WebWindowProc) // Has a Window - { - if (Port->UICAPABLE) - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithBeaconAndDriver, Port->PORTNUMBER, DLL, - Port->PORTDESCRIPTION, Port->PORTNUMBER, Port->PORTNUMBER, Port->TNC->WebWinX, Port->TNC->WebWinY, 200, 200, StatsURL); - else - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithDriver, Port->PORTNUMBER, DLL, - Port->PORTDESCRIPTION, Port->PORTNUMBER, Port->TNC->WebWinX, Port->TNC->WebWinY, 200, 200, StatsURL); - - continue; - } - - if (Port->PORTTYPE == 16 && Port->PROTOCOL == 10 && Port->UICAPABLE == 0) // EXTERNAL, Pactor/WINMO - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], SessionPortLine, Port->PORTNUMBER, DLL, - Port->PORTDESCRIPTION, Port->PORTNUMBER, StatsURL); - else - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithBeacon, Port->PORTNUMBER, Port->PORTNUMBER, - DLL, DLL, Port->PORTDESCRIPTION, Port->PORTNUMBER, StatsURL); - } - - if (RigActive) - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RigControlLine, 64, "Rig Control", "Rig Control", 600, 350, 200, 200); - - } - - if (_stricmp(NodeURL, "/Node/Nodes.html") == 0) - { - struct DEST_LIST * Dests = DESTS; - int count, i; - char Normcall[10]; - char Alias[10]; - int Width = 5; - int x = 0, n = 0; - struct DEST_LIST * List[1000]; - char Param = 0; - - if (Context) - { - _strupr(Context); - Param = Context[0]; - } - - for (count = 0; count < MAXDESTS; count++) - { - if (Dests->DEST_CALL[0] != 0) - { - if (Param != 'T' || Dests->DEST_COUNT) - List[n++] = Dests; - - if (n > 999) - break; - } - - Dests++; - } - - if (n > 1) - { - if (Param == 'C') - qsort(List, n, sizeof(void *), CompareNode); - else - qsort(List, n, sizeof(void *), CompareAlias); - } - - Alias[6] = 0; - - if (Param == 'T') - { - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], NodeHddr, "with traffic"); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], ""); - } - else if (Param == 'C') - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], NodeHddr, "sorted by Call"); - else - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], NodeHddr, "sorted by Alias"); - - for (i = 0; i < n; i++) - { - int len = ConvFromAX25(List[i]->DEST_CALL, Normcall); - Normcall[len]=0; - - memcpy(Alias, List[i]->DEST_ALIAS, 6); - strlop(Alias, ' '); - - if (Param == 'T') - { - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - Normcall, Alias, List[i]->DEST_COUNT, List[i]->DEST_RTT /16, - (List[i]->DEST_STATE & 0x40)? 'B':' ', (List[i]->DEST_STATE & 63)); - - } - else - { - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], NodeLine, Normcall, Alias, Normcall); - - if (++x == Width) - { - x = 0; - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], ""); - } - } - } - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], ""); - } - - if (_stricmp(NodeURL, "/Node/NodeDetail") == 0) - { - UCHAR AXCall[8]; - struct DEST_LIST * Dest = DESTS; - struct NR_DEST_ROUTE_ENTRY * NRRoute; - struct ROUTE * Neighbour; - char Normcall[10]; - int i, len, count, Active; - char Alias[7]; - - Alias[6] = 0; - - _strupr(Context); - - ConvToAX25(Context, AXCall); - - for (count = 0; count < MAXDESTS; count++) - { - if (CompareCalls(Dest->DEST_CALL, AXCall)) - { - break; - } - Dest++; - } - - if (count == MAXDESTS) - { - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "

Call %s not found

", Context); - goto SendResp; - } - - memcpy(Alias, Dest->DEST_ALIAS, 6); - strlop(Alias, ' '); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], - "

Info for Node %s:%s

", Alias, Context); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "

PortDriverIDBeaconsDriver WindowStats Graph
%d %s%s
%d %s%s Beacons %s
%d%s%s %s
%d%s%s Driver Window%s
%d%s%s BeaconsDriver Window%s
%d%s%s Rig Control
%s%s
%s%s
%s%d%d
%s%d%d%d%d%d
%s%d%d
%s%d%d
%s%d%d%d%d
%s%d
CallFramesRTTBPQ?Hops
%s:%s%d%d%c%.0d
"); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
FramesRTTBPQ?Hops
%d%d%c%.0d
", - Dest->DEST_COUNT, Dest->DEST_RTT /16, - (Dest->DEST_STATE & 0x40)? 'B':' ', (Dest->DEST_STATE & 63)); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "

Neighbours

"); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], - "" - ""); - - NRRoute = &Dest->NRROUTE[0]; - - Active = Dest->DEST_ROUTE; - - for (i = 1; i < 4; i++) - { - Neighbour = NRRoute->ROUT_NEIGHBOUR; - - if (Neighbour) - { - len = ConvFromAX25(Neighbour->NEIGHBOUR_CALL, Normcall); - Normcall[len] = 0; - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "", - (Active == i)?'>':' ',NRRoute->ROUT_QUALITY, NRRoute->ROUT_OBSCOUNT, Neighbour->NEIGHBOUR_PORT, Normcall); - } - NRRoute++; - } - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
Qual Obs Port Call
%c %d%d%d%s
"); - - goto SendResp; - - } - /* - - MOV ESI,OFFSET32 NODEROUTEHDDR - MOV ECX,11 - REP MOVSB - - LEA ESI,DEST_CALL[EBX] - CALL DECODENODENAME ; CONVERT TO ALIAS:CALL - REP MOVSB - - CMP DEST_RTT[EBX],0 - JE SHORT @f ; TIMER NOT SET - DEST PROBABLY NOT USED - - MOVSB ; ADD SPACE - CALL DORTT - - @@: - MOV AL,CR - STOSB - - MOV ECX,3 - MOV DH,DEST_ROUTE[EBX] ; CURRENT ACTIVE ROUTE - MOV DL,1 - - push ebx - - PUBLIC CMDN110 - CMDN110: - - MOV ESI,ROUT1_NEIGHBOUR[EBX] - CMP ESI,0 - JE CMDN199 - - - MOV AX,' ' - CMP DH,DL - JNE SHORT CMDN112 ; NOT CURRENT DEST - MOV AX,' >' - - CMDN112: - - STOSW - - PUSH ECX - - MOV AL,ROUT1_QUALITY[EBX] - CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS - - mov AL,' ' - stosb - - MOV AL,ROUT1_OBSCOUNT[EBX] - CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS - - mov AL,' ' - stosb - - MOV AL,NEIGHBOUR_PORT[ESI] ; GET PORT - CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS - - mov AL,' ' - stosb - - - PUSH EDI - CALL CONVFROMAX25 ; CONVERT TO CALL - POP EDI - - MOV ESI,OFFSET32 NORMCALL - REP MOVSB - - MOV AL,CR - STOSB - - ADD EBX,ROUTEVECLEN - INC DL ; ROUTE NUMBER - - POP ECX - DEC ECX - JNZ CMDN110 - - PUBLIC CMDN199 - CMDN199: - - POP EBX - - ; DISPLAY INP3 ROUTES - - MOV ECX,3 - MOV DL,4 - - PUBLIC CMDNINP3 - CMDNINP3: - - MOV ESI,INPROUT1_NEIGHBOUR[EBX] - CMP ESI,0 - JE CMDNINPEND - - MOV AX,' ' - CMP DH,DL - JNE SHORT @F ; NOT CURRENT DEST - MOV AX,' >' - - @@: - - STOSW - - PUSH ECX - - MOV AL, Hops1[EBX] - CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS - - mov AL,' ' - stosb - - MOVZX EAX, SRTT1[EBX] - - MOV EDX,0 - MOV ECX, 100 - DIV ECX - CALL CONV_5DIGITS - MOV AL,'.' - STOSB - MOV EAX, EDX - CALL PRINTNUM - MOV AL,'s' - STOSB - MOV AL,' ' - STOSB - - MOV AL,NEIGHBOUR_PORT[ESI] ; GET PORT - CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS - - mov AL,' ' - stosb - - PUSH EDI - CALL CONVFROMAX25 ; CONVERT TO CALL - POP EDI - - MOV ESI,OFFSET32 NORMCALL - REP MOVSB - - - MOV AL,CR - STOSB - - ADD EBX,INPROUTEVECLEN - INC DL ; ROUTE NUMBER - - POP ECX - LOOP CMDNINP3 - - CMDNINPEND: - - ret - - */ - - // AXIP Partners - - if (_stricmp(NodeURL, "/Node/AXIP.html") == 0) - { - int i; - char Normcall[10]; - int Width = 5; - int x = 0, n = 0, nd = 0; - struct arp_table_entry * List[1000]; - struct arp_table_entry * ListD[1000]; - char AXIPList[10000] = ""; - int ListLen = 0; - - struct AXIPPORTINFO * AXPORT = Portlist[0]; - struct PORTCONTROL * PORT = PORTTABLE; - struct arp_table_entry * arp; - - char AXIPHeader[] = - "" - "
AXIP UpAXIP Down
%s"; - - - while (PORT) - { - AXPORT = Portlist[PORT->PORTNUMBER]; - - if (AXPORT) - { - // Get ARP entries - - for (i = 0; i < AXPORT->arp_table_len; i++) - { - arp = &AXPORT->arp_table[i]; - - if (arp->LastHeard == 0 || (NOW - arp->LastHeard) > 3600) // Considered down - ListD[nd++] = arp; - else - List[n++] = arp; - } - } - PORT = PORT->PORTPOINTER; - } - - if (n > 1) - qsort(List, n, sizeof(void *), CompareNode); - if (nd > 1) - qsort(ListD, nd, sizeof(void *), CompareNode); - - for (i = 0; i < n; i++) - { - int len = ConvFromAX25(List[i]->callsign, Normcall); - Normcall[len]=0; - - ListLen += sprintf(&AXIPList[ListLen], "%02d - %s %d
", i + 1, Normcall, (List[i]->LastHeard)?(NOW - List[i]->LastHeard):0); - } - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], AXIPHeader, AXIPList); - - ListLen = 0; - - for (i = 0; i < nd; i++) - { - int len = ConvFromAX25(ListD[i]->callsign, Normcall); - Normcall[len]=0; - ListLen += sprintf(&AXIPList[ListLen], "%02d - %s %d
", i + 1, Normcall, (ListD[i]->LastHeard)?(NOW - ListD[i]->LastHeard):0); - } - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
%s", AXIPList); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "
"); - } - - if (_stricmp(NodeURL, "/Node/Routes.html") == 0) - { - struct ROUTE * Routes = NEIGHBOURS; - int MaxRoutes = MAXNEIGHBOURS; - int count, i; - char Normcall[10]; - char locked[4] = " "; - int NodeCount; - int Percent = 0; - int Iframes, Retries; - char Active[10]; - int Queued; - - int x = 0, n = 0; - struct ROUTE * List[1000]; - - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", RouteHddr); - - // Build and sort list of routes - - for (count = 0; count < MaxRoutes; count++) - { - if (Routes->NEIGHBOUR_CALL[0] != 0) - { - List[n++] = Routes; - - if (n > 999) - break; - } - - Routes++; - } - - if (n > 1) - qsort(List, n, sizeof(void *), CompareRoutes); - - for (i = 0; i < n; i++) - { - Routes = List[i]; - { - int len = ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall); - Normcall[len]=0; - - if (Routes->NEIGHBOUR_FLAG == LOCKEDBYCONFIG) - strcpy(locked, "!"); - else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP) - strcpy(locked, "!!"); - else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP + LOCKEDBYCONFIG) - strcpy(locked, "!!!"); - else - strcpy(locked, " "); - - NodeCount = COUNTNODES(Routes); - - if (Routes->NEIGHBOUR_LINK) - Queued = COUNT_AT_L2(Routes->NEIGHBOUR_LINK); - else - Queued = 0; - - Iframes = Routes->NBOUR_IFRAMES; - Retries = Routes->NBOUR_RETRIES; - - if (Routes->NEIGHBOUR_LINK && Routes->NEIGHBOUR_LINK->L2STATE >= 5) - strcpy(Active, ">"); - else - strcpy(Active, " "); - - if (Iframes) - Percent = (Retries * 100) / Iframes; - else - Percent = 0; - - if (Routes->INP3Node) // INP3 Enabled? - { - double srtt = Routes->SRTT/100.0; - double nsrtt = Routes->NeighbourSRTT/100.0; - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLineINP3, Active, Routes->NEIGHBOUR_PORT, Normcall, locked, - Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK, - Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual, srtt, nsrtt); - } - else - { - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RouteLine, Active, Routes->NEIGHBOUR_PORT, Normcall, locked, - Routes->NEIGHBOUR_QUAL, NodeCount, Iframes, Retries, Percent, Routes->NBOUR_MAXFRAME, Routes->NBOUR_FRACK, - Routes->NEIGHBOUR_TIME >> 8, Routes->NEIGHBOUR_TIME & 0xff, Queued, Routes->OtherendsRouteQual); - } - } - Routes+=1; - } - } - - if (_stricmp(NodeURL, "/Node/Links.html") == 0) - { - struct _LINKTABLE * Links = LINKS; - int MaxLinks = MAXLINKS; - int count; - char Normcall1[10]; - char Normcall2[10]; - char State[12] = "", Type[12] = "Uplink"; - int axState; - int cctType; - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", LinkHddr); - - for (count=0; countLINKCALL[0] != 0) - { - int len = ConvFromAX25(Links->LINKCALL, Normcall1); - Normcall1[len] = 0; - - len = ConvFromAX25(Links->OURCALL, Normcall2); - Normcall2[len] = 0; - - axState = Links->L2STATE; - - if (axState == 2) - strcpy(State, "Connecting"); - else if (axState == 3) - strcpy(State, "FRMR"); - else if (axState == 4) - strcpy(State, "Closing"); - else if (axState == 5) - strcpy(State, "Active"); - else if (axState == 6) - strcpy(State, "REJ Sent"); - - cctType = Links->LINKTYPE; - - if (cctType == 1) - strcpy(Type, "Uplink"); - else if (cctType == 2) - strcpy(Type, "Downlink"); - else if (cctType == 3) - strcpy(Type, "Node-Node"); - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], LinkLine, Normcall1, Normcall2, Links->LINKPORT->PORTNUMBER, - State, Type, 2 - Links->VER1FLAG ); - - Links+=1; - } - } - } - - if (_stricmp(NodeURL, "/Node/Users.html") == 0) - { - TRANSPORTENTRY * L4 = L4TABLE; - TRANSPORTENTRY * Partner; - int MaxLinks = MAXLINKS; - int count; - char State[12] = "", Type[12] = "Uplink"; - char LHS[50] = "", MID[10] = "", RHS[50] = ""; - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", UserHddr); - - for (count=0; count < MAXCIRCUITS; count++) - { - if (L4->L4USER[0]) - { - RHS[0] = MID[0] = 0; - - if ((L4->L4CIRCUITTYPE & UPLINK) == 0) //SHORT CMDS10A ; YES - { - // IF DOWNLINK, ONLY DISPLAY IF NO CROSSLINK - - if (L4->L4CROSSLINK == 0) //jne CMDS60 ; WILL PROCESS FROM OTHER END - { - // ITS A DOWNLINK WITH NO PARTNER - MUST BE A CLOSING SESSION - // DISPLAY TO THE RIGHT FOR NOW - - strcpy(LHS, "(Closing) "); - DISPLAYCIRCUIT(L4, RHS); - goto CMDS50; - } - else - goto CMDS60; // WILL PROCESS FROM OTHER END - } - - if (L4->L4CROSSLINK == 0) - { - // Single Entry - - DISPLAYCIRCUIT(L4, LHS); - } - else - { - DISPLAYCIRCUIT(L4, LHS); - - Partner = L4->L4CROSSLINK; - - if (Partner->L4STATE == 5) - strcpy(MID, "<-->"); - else - strcpy(MID, "<~~>"); - - DISPLAYCIRCUIT(Partner, RHS); - } -CMDS50: - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], UserLine, LHS, MID, RHS); - } -CMDS60: - L4++; - } - } - /* - PUBLIC CMDUXX_1 - CMDUXX_1: - push EBX - push ESI - PUSH ECX - push EDI - - call _FINDDESTINATION - pop EDI - - jz SHORT NODE_FOUND - - push EDI ; NET/ROM not found - call CONVFROMAX25 ; CONVERT TO CALL - pop EDI - mov ESI,OFFSET32 NORMCALL - rep movsb - - jmp SHORT END_CMDUXX - - PUBLIC NODE_FOUND - NODE_FOUND: - - lea ESI,DEST_CALL[EBX] - call DECODENODENAME - - REP MOVSB - - PUBLIC END_CMDUXX - END_CMDUXX: - - POP ECX - pop ESI - pop EBX - ret - - }}} - */ - - else if (_stricmp(NodeURL, "/Node/Terminal.html") == 0) - { - if (COOKIE && Session) - { - // Already signed in as sysop - - struct UserRec * USER = Session->USER; - - struct HTTPConnectionInfo * NewSession = AllocateSession(sock, 'T'); - - if (NewSession) - { - char AXCall[10]; - ReplyLen = sprintf(_REPLYBUFFER, TermPage, Mycall, Mycall, NewSession->Key, NewSession->Key, NewSession->Key); - strcpy(NewSession->HTTPCall, USER->Callsign); - ConvToAX25(NewSession->HTTPCall, AXCall); - ChangeSessionCallsign(NewSession->Stream, AXCall); - BPQHOSTVECTOR[NewSession->Stream -1].HOSTSESSION->Secure_Session = USER->Secure; - Session->USER = USER; - NewSession->TNC = conn->TNC; - - - // if (Appl[0]) - // { - // strcat(Appl, "\r"); - // SendMsg(Session->Stream, Appl, strlen(Appl)); - // } - - } - else - { - ReplyLen = SetupNodeMenu(_REPLYBUFFER, LOCAL); - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", BusyError); - } - } - else if (LOCAL) - { - // connected to 127.0.0.1 so sign in using node call - - struct HTTPConnectionInfo * NewSession = AllocateSession(sock, 'T'); - - if (NewSession) - { - ReplyLen = sprintf(_REPLYBUFFER, TermPage, Mycall, Mycall, NewSession->Key, NewSession->Key, NewSession->Key); - strcpy(NewSession->HTTPCall, MYNODECALL); - ChangeSessionCallsign(NewSession->Stream, MYCALL); - BPQHOSTVECTOR[NewSession->Stream -1].HOSTSESSION->Secure_Session = TRUE; - NewSession->TNC = conn->TNC; - } - } - else - ReplyLen = sprintf(_REPLYBUFFER, TermSignon, Mycall, Mycall, Context, ""); - } - - else if (_stricmp(NodeURL, "/Node/WebSockTerm.html") == 0) - { - ReplyLen = DoWebSockTerm(Session, conn, _REPLYBUFFER, LOCAL, COOKIE, Context, sock); - } - - else if (_stricmp(NodeURL, "/Node/Signon.html") == 0) - { - ReplyLen = sprintf(_REPLYBUFFER, NodeSignon, Mycall, Mycall, Context); - } - - else if (_stricmp(NodeURL, "/Node/Drivers") == 0) - { - int Bufferlen = SendMessageFile(sock, "/Drivers.htm", TRUE, allowDeflate); // return -1 if not found - - if (Bufferlen != -1) - return 0; // We've sent it - } - - else if (_stricmp(NodeURL, "/Node/OutputScreen.html") == 0) - { - struct HTTPConnectionInfo * Session = FindSession(Context); - - if (Session == NULL) - { - ReplyLen = sprintf(_REPLYBUFFER, "%s", LostSession); - } - else - { - Session->sock = sock; // socket to reply on - ReplyLen = RefreshTermWindow(TCP, Session, _REPLYBUFFER); - - if (ReplyLen == 0) // Nothing new - { - // Debugprintf("GET with no data avail - response held"); - Session->ResponseTimer = 1200; // Delay response for up to a minute - } - else - { - // Debugprintf("GET - outpur sent, timer was %d, set to zero", Session->ResponseTimer); - Session->ResponseTimer = 0; - } - - Session->KillTimer = 0; - return 0; // Refresh has sent any available output - } - } - - else if (_stricmp(NodeURL, "/Node/InputLine.html") == 0) - { - struct TNCINFO * TNC = conn->TNC; - struct TCPINFO * TCP = 0; - - if (TNC) - TCP = TNC->TCPInfo; - - if (TCP && TCP->WebTermCSS) - ReplyLen = sprintf(_REPLYBUFFER, InputLine, Context, TCP->WebTermCSS); - else - ReplyLen = sprintf(_REPLYBUFFER, InputLine, Context, ""); - - } - - else if (_stricmp(NodeURL, "/Node/PTT") == 0) - { - struct TNCINFO * TNC = conn->TNC; - int x = atoi(Context); - } - - -SendResp: - - FormatTime3(TimeString, NOW); - - strcpy(&_REPLYBUFFER[ReplyLen], Tail); - ReplyLen += (int)strlen(Tail); - - - if (allowDeflate) - { - Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); - } - else - { - Encoding[0] = 0; - Compressed = _REPLYBUFFER; - } - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n" - "Date: %s\r\n%s\r\n", ReplyLen, TimeString, Encoding); - sendandcheck(sock, Header, HeaderLen); - sendandcheck(sock, Compressed, ReplyLen); - - if (allowDeflate) - free (Compressed); - } - return 0; - -#ifdef WIN32xx - } -#include "StdExcept.c" -} -return 0; -#endif -} - -void ProcessHTTPMessage(void * conn) -{ - // conn is a malloc'ed copy to handle reused connections, so need to free it - - InnerProcessHTTPMessage((struct ConnectionInfo *)conn); - free(conn); - return; -} - -static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; -static char *dat[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - - -VOID FormatTime3(char * Time, time_t cTime) -{ - struct tm * TM; - TM = gmtime(&cTime); - - sprintf(Time, "%s, %02d %s %3d %02d:%02d:%02d GMT", dat[TM->tm_wday], TM->tm_mday, month[TM->tm_mon], - TM->tm_year + 1900, TM->tm_hour, TM->tm_min, TM->tm_sec); - -} - -// Sun, 06 Nov 1994 08:49:37 GMT - -int StatusProc(char * Buff) -{ - int i; - char callsign[12] = ""; - char flag[3]; - UINT Mask, MaskCopy; - int Flags; - int AppNumber; - int OneBits; - int Len = sprintf(Buff, "" - "Stream Status"); - - Len += sprintf(&Buff[Len], ""); - Len += sprintf(&Buff[Len], ""); - Len += sprintf(&Buff[Len], ""); - Len += sprintf(&Buff[Len], ""); - Len += sprintf(&Buff[Len], ""); - Len += sprintf(&Buff[Len], ""); - Len += sprintf(&Buff[Len], ""); - - for (i=1; i <=BPQHOSTSTREAMS; i++) - { - callsign[0]=0; - - if (GetAllocationState(i)) - - strcpy(flag,"*"); - else - strcpy(flag," "); - - GetCallsign(i,callsign); - - Mask = MaskCopy = Get_APPLMASK(i); - - // if only one bit set, convert to number - - AppNumber = 0; - OneBits = 0; - - while (MaskCopy) - { - if (MaskCopy & 1) - OneBits++; - - AppNumber++; - MaskCopy = MaskCopy >> 1; - } - - Flags=GetApplFlags(i); - - if (OneBits > 1) - Len += sprintf(&Buff[Len], "" - "", - i, flag, RXCount(i), TXCount(i), MONCount(i), Mask, Flags, callsign, BPQHOSTVECTOR[i-1].PgmName); - - else - Len += sprintf(&Buff[Len], "" - "", - i, flag, RXCount(i), TXCount(i), MONCount(i), AppNumber, Flags, callsign, BPQHOSTVECTOR[i-1].PgmName); - - if ((i & 1) == 0) - Len += sprintf(&Buff[Len], ""); - - } - - Len += sprintf(&Buff[Len], "
    RX   TX   MON  App  Flg Callsign  Program    RX   TX   MON  App  Flg Callsign  Program
%d%s%d%d%d%x%x%s%s%d%s%d%d%d%d%x%s%s
"); - return Len; -} - -int ProcessNodeSignon(SOCKET sock, struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, int LOCAL) -{ - int ReplyLen = 0; - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - char * user, * password, * Key; - char Header[256]; - int HeaderLen; - struct HTTPConnectionInfo *Sess; - - - if (input) - { - int i; - struct UserRec * USER; - - UndoTransparency(input); - - if (strstr(input, "Cancel=Cancel")) - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n" - "\r\n", (int)(ReplyLen + strlen(Tail))); - send(sock, Header, HeaderLen, 0); - send(sock, Reply, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - } - user = strtok_s(&input[9], "&", &Key); - password = strtok_s(NULL, "=", &Key); - password = Key; - - for (i = 0; i < TCP->NumberofUsers; i++) - { - USER = TCP->UserRecPtr[i]; - - if (user && _stricmp(user, USER->UserName) == 0) - { - if (strcmp(password, USER->Password) == 0 && USER->Secure) - { - // ok - - Sess = *Session = AllocateSession(sock, 'N'); - Sess->USER = USER; - - ReplyLen = SetupNodeMenu(Reply, LOCAL); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n" - "Set-Cookie: BPQSessionCookie=%s; Path = /\r\n\r\n", (int)(ReplyLen + strlen(Tail)), Sess->Key); - send(sock, Header, HeaderLen, 0); - send(sock, Reply, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return ReplyLen; - } - } - } - } - - ReplyLen = sprintf(Reply, NodeSignon, Mycall, Mycall); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", PassError); - - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", (int)(ReplyLen + strlen(Tail))); - send(sock, Header, HeaderLen, 0); - send(sock, Reply, ReplyLen, 0); - send(sock, Tail, (int)strlen(Tail), 0); - - return 0; - - - return ReplyLen; -} - -int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL) -{ - int ReplyLen = 0; - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - char * user, * password; - struct HTTPConnectionInfo * NewSession; - int i; - struct UserRec * USER; - - if (strchr(MsgPtr, '?')) - { - // Check Password - - user = strlop(MsgPtr, '?'); - password = strlop(user, '&'); - strlop(password, ' '); - - for (i = 0; i < TCP->NumberofUsers; i++) - { - USER = TCP->UserRecPtr[i]; - - if (user && _stricmp(user, USER->UserName) == 0) - { - if ((strcmp(password, USER->Password) == 0) && (USER->Secure || WebMail)) - { - // ok - - NewSession = AllocateSession(Appl[0], 'M'); - - *Session = NewSession; - - 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 - - // Need to put url back together - - if (user && user[0] && password && password[0]) - { - sprintf(&MsgPtr[strlen(MsgPtr)], "?%s&%s", user, password); - } - } - - NewSession = AllocateSession(Appl[0], 'M'); - - *Session = NewSession; - - if (NewSession) - ReplyLen = 0; - else - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError); - } - - return ReplyLen; -} - - - - -int ProcessMailSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL) -{ - int ReplyLen = 0; - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - char * user, * password, * Key; - struct HTTPConnectionInfo * NewSession; - - if (input) - { - int i; - struct UserRec * USER; - - UndoTransparency(input); - - if (strstr(input, "Cancel=Cancel")) - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - return ReplyLen; - } - user = strtok_s(&input[9], "&", &Key); - password = strtok_s(NULL, "=", &Key); - password = Key; - - for (i = 0; i < TCP->NumberofUsers; i++) - { - USER = TCP->UserRecPtr[i]; - - if (user && _stricmp(user, USER->UserName) == 0) - { - if (strcmp(password, USER->Password) == 0 && (USER->Secure || WebMail)) - { - // ok - - NewSession = AllocateSession(Appl[0], 'M'); - - *Session = NewSession; - - if (NewSession) - { - - ReplyLen = 0; - strcpy(NewSession->Callsign, USER->Callsign); - } - else - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError); - } - return ReplyLen; - } - } - } - } - - ReplyLen = sprintf(Reply, MailSignon, Mycall, Mycall); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", PassError); - - return ReplyLen; -} - - -int ProcessChatSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, int LOCAL) -{ - int ReplyLen = 0; - char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers - char * user, * password, * Key; - - if (input) - { - int i; - struct UserRec * USER; - - UndoTransparency(input); - - if (strstr(input, "Cancel=Cancel")) - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - return ReplyLen; - } - - user = strtok_s(&input[9], "&", &Key); - password = strtok_s(NULL, "=", &Key); - password = Key; - - - for (i = 0; i < TCP->NumberofUsers; i++) - { - USER = TCP->UserRecPtr[i]; - - if (user && _stricmp(user, USER->UserName) == 0) - { - if (strcmp(password, USER->Password) == 0 && USER->Secure) - { - // ok - - *Session = AllocateSession(Appl[0], 'C'); - - if (Session) - { - ReplyLen = 0; - } - else - { - ReplyLen = SetupNodeMenu(Reply, LOCAL); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError); - } - return ReplyLen; - } - } - } - } - - ReplyLen = sprintf(Reply, ChatSignon, Mycall, Mycall); - ReplyLen += sprintf(&Reply[ReplyLen], "%s", PassError); - - return ReplyLen; - -} - -#define SHA1_HASH_LEN 20 - -/* - -Copyright (C) 1998, 2009 -Paul E. Jones - -Freeware Public License (FPL) - -This software is licensed as "freeware." Permission to distribute -this software in source and binary forms, including incorporation -into other products, is hereby granted without a fee. THIS SOFTWARE -IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD -LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER -DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA -OR DATA BEING RENDERED INACCURATE. -*/ - -/* sha1.h - * - * Copyright (C) 1998, 2009 - * Paul E. Jones - * All Rights Reserved - * - ***************************************************************************** - * $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $ - ***************************************************************************** - * - * Description: - * This class implements the Secure Hashing Standard as defined - * in FIPS PUB 180-1 published April 17, 1995. - * - * Many of the variable names in the SHA1Context, especially the - * single character names, were used because those were the names - * used in the publication. - * - * Please read the file sha1.c for more information. - * - */ - -#ifndef _SHA1_H_ -#define _SHA1_H_ - -/* - * This structure will hold context information for the hashing - * operation - */ -typedef struct SHA1Context -{ - unsigned Message_Digest[5]; /* Message Digest (output) */ - - unsigned Length_Low; /* Message length in bits */ - unsigned Length_High; /* Message length in bits */ - - unsigned char Message_Block[64]; /* 512-bit message blocks */ - int Message_Block_Index; /* Index into message block array */ - - int Computed; /* Is the digest computed? */ - int Corrupted; /* Is the message digest corruped? */ -} SHA1Context; - -/* - * Function Prototypes - */ -void SHA1Reset(SHA1Context *); -int SHA1Result(SHA1Context *); -void SHA1Input( SHA1Context *, const unsigned char *, unsigned); - -#endif - -BOOL SHA1PasswordHash(char * lpszPassword, char * Hash) -{ - SHA1Context sha; - int i; - - SHA1Reset(&sha); - SHA1Input(&sha, lpszPassword, strlen(lpszPassword)); - SHA1Result(&sha); - - // swap byte order if little endian - - for (i = 0; i < 5; i++) - sha.Message_Digest[i] = htonl(sha.Message_Digest[i]); - - memcpy(Hash, &sha.Message_Digest[0], 20); - - return TRUE; -} - -int BuildRigCtlPage(char * _REPLYBUFFER) -{ - int ReplyLen; - - struct RIGPORTINFO * PORT; - struct RIGINFO * RIG; - int p, i; - - char Page[] = - "\r\n" - // "\r\n" - "Rigcontrol\r\n" - "" - "

Rigcontrol

\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - ""; - char RigLine[] = - "\r\n" - " \r\n" - " \r\n" - " \r\n" - " \r\n" - " \r\n" - " \r\n" - " \r\n"; - char Tail[] = - "
RadioFreqModeSTPorts
%s%s%s/1%c%c%s
\r\n" - "\r\n"; - - ReplyLen = sprintf(_REPLYBUFFER, "%s", Page); - - for (p = 0; p < NumberofPorts; p++) - { - PORT = PORTInfo[p]; - - for (i=0; i< PORT->ConfiguredRigs; i++) - { - RIG = &PORT->Rigs[i]; - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], RigLine, RIG->WEB_Label, RIG->WEB_FREQ, RIG->WEB_MODE, RIG->WEB_SCAN, RIG->WEB_PTT, RIG->WEB_PORTS, RIG->Interlock); - } - } - - ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", Tail); - return ReplyLen; -} - - -void BuildDevicePage(struct TNCINFO * TNC) -{ - int Len; - char Page[65536]; - - Len = TNC->WebWindowProc(TNC, Page, 1); - - if (TNC->WebPage) - { - if (strcmp(TNC->WebPage, Page) == 0) - return; // No change - else - free(TNC->WebPage); - } - - TNC->WebPage = _strdup(Page); - - SendDeviceWebPage(TNC->Port); - -} - -void SendRigWebPage() -{ - int i, n; - struct ConnectionInfo * sockptr; - struct TNCINFO * TNC; - struct TCPINFO * TCP; - - for (i = 0; i < 33; i++) - { - TNC = TNCInfo[i]; - - if (TNC && TNC->Hardware == H_TELNET) - { - TCP = TNC->TCPInfo; - - if (TCP) - { - for (n = 0; n <= TCP->MaxSessions; n++) - { - sockptr = TNC->Streams[n].ConnectionInfo; - - if (sockptr->SocketActive) - { - if (sockptr->HTTPMode && sockptr->WebSocks && strcmp(sockptr->WebURL, "RIGCTL") == 0) - { - char RigMsg[8192]; - int RigMsgLen = strlen(RigWebPage); - char* ptr; - - RigMsg[0] = 0x81; // Fin, Data - RigMsg[1] = 126; // Unmasked, Extended Len - RigMsg[2] = RigMsgLen >> 8; - RigMsg[3] = RigMsgLen & 0xff; - strcpy(&RigMsg[4], RigWebPage); - - // If secure session enable PTT button - - if (sockptr->WebSecure) - { - while (ptr = strstr(RigMsg, "hidden")) - memcpy(ptr, " ", 6); - } - - send(sockptr->socket, RigMsg, RigMsgLen + 4, 0); - } - } - } - } - } - } -} - -void SendDeviceWebPage(int Port) -{ - int i, n; - struct ConnectionInfo * sockptr; - struct TNCINFO * TNC = TNCInfo[Port]; - struct TCPINFO * TCP; - char DevString[16]; - - char Msg[65536]; - int MsgLen; - - if (TNC->WebPage == 0) - return; - - strcpy(&Msg[4], TNC->WebPage); - MsgLen = strlen(&TNC->WebPage[4]); - - sprintf(DevString, "DEVICE%d", Port); - - for (i = 0; i < 33; i++) - { - TNC = TNCInfo[i]; - - if (TNC && TNC->Hardware == H_TELNET) - { - TCP = TNC->TCPInfo; - - if (TCP) - { - for (n = 0; n <= TCP->MaxSessions; n++) - { - sockptr = TNC->Streams[n].ConnectionInfo; - - if (sockptr->SocketActive) - { - if (sockptr->HTTPMode && sockptr->WebSocks && strcmp(sockptr->WebURL, DevString) == 0) - { - char* ptr; - - Msg[0] = 0x81; // Fin, Data - Msg[1] = 126; // Unmasked, Extended Len - Msg[2] = MsgLen >> 8; - Msg[3] = MsgLen & 0xff; - - // If secure session enable PTT button - - if (sockptr->WebSecure) - { - while (ptr = strstr(&Msg[4], "hidden")) - memcpy(ptr, " ", 6); - } - - send(sockptr->socket, Msg, MsgLen + 4, 0); - } - } - } - } - } - } -} - - -// Webmail web socket code - -int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer); - -void ProcessWebmailWebSockThread(void * conn) -{ - // conn is a malloc'ed copy to handle reused connections, so need to free it - - struct ConnectionInfo * sockptr = (struct ConnectionInfo *)conn; - char * URL = sockptr->WebURL; - int Loops = 0; - int Sent; - struct HTTPConnectionInfo Dummy = {0}; - int ReplyLen = 0; - int InputLen = 0; - -#ifdef LINBPQ - - char _REPLYBUFFER[250000]; - - ReplyLen = ProcessWebmailWebSock(URL, _REPLYBUFFER); - - // Send may block - - Sent = send(sockptr->socket, _REPLYBUFFER, ReplyLen, 0); - - if (Sent == -1) // Connecton lost - { - closesocket(sockptr->socket); - free(conn); - return; - } - - while (Sent != ReplyLen && Loops++ < 3000) // 90 secs max - { - if (Sent > 0) // something sent - { - ReplyLen -= Sent; - memmove(_REPLYBUFFER, &_REPLYBUFFER[Sent], ReplyLen); - } - - Sleep(30); - Sent = send(sockptr->socket, _REPLYBUFFER, ReplyLen, 0); - } - -#else - // Send URL to BPQMail via Pipe. Just need a dummy session, as URL contains session key - - HANDLE hPipe; - char Reply[250000]; - - - - hPipe = CreateFile(MAILPipeFileName, GENERIC_READ | GENERIC_WRITE, - 0, // exclusive access - NULL, // no security attrs - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL ); - - if (hPipe == (HANDLE)-1) - { - free(conn); - return; - } - - WriteFile(hPipe, &Dummy, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); - WriteFile(hPipe, URL, strlen(URL), &InputLen, NULL); - - ReadFile(hPipe, &Dummy, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); - ReadFile(hPipe, Reply, 250000, &ReplyLen, NULL); - - if (ReplyLen <= 0) - { - InputLen = GetLastError(); - } - - CloseHandle(hPipe); - - Sent = send(sockptr->socket, Reply, ReplyLen, 0); - - if (Sent == -1) // Connecton lost - { - free(conn); - closesocket(sockptr->socket); - return; - } - - while (Sent != ReplyLen && Loops++ < 3000) // 90 secs max - { - // Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops); - - if (Sent > 0) // something sent - { - InputLen -= Sent; - memmove(Reply, &Reply[Sent], ReplyLen); - } - - Sleep(30); - Sent = send(sockptr->socket, Reply, ReplyLen, 0); - } -#endif - free(conn); - return; -} - -/* - * sha1.c - * - * Copyright (C) 1998, 2009 - * Paul E. Jones - * All Rights Reserved - * - ***************************************************************************** - * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $ - ***************************************************************************** - * - * Description: - * This file implements the Secure Hashing Standard as defined - * in FIPS PUB 180-1 published April 17, 1995. - * - * The Secure Hashing Standard, which uses the Secure Hashing - * Algorithm (SHA), produces a 160-bit message digest for a - * given data stream. In theory, it is highly improbable that - * two messages will produce the same message digest. Therefore, - * this algorithm can serve as a means of providing a "fingerprint" - * for a message. - * - * Portability Issues: - * SHA-1 is defined in terms of 32-bit "words". This code was - * written with the expectation that the processor has at least - * a 32-bit machine word size. If the machine word size is larger, - * the code should still function properly. One caveat to that - * is that the input functions taking characters and character - * arrays assume that only 8 bits of information are stored in each - * character. - * - * Caveats: - * SHA-1 is designed to work with messages less than 2^64 bits - * long. Although SHA-1 allows a message digest to be generated for - * messages of any number of bits less than 2^64, this - * implementation only works with messages with a length that is a - * multiple of the size of an 8-bit character. - * - */ - -/* - * Define the circular shift macro - */ -#define SHA1CircularShift(bits,word) \ - ((((word) << (bits)) & 0xFFFFFFFF) | \ - ((word) >> (32-(bits)))) - -/* Function prototypes */ -void SHA1ProcessMessageBlock(SHA1Context *); -void SHA1PadMessage(SHA1Context *); - -/* - * SHA1Reset - * - * Description: - * This function will initialize the SHA1Context in preparation - * for computing a new message digest. - * - * Parameters: - * context: [in/out] - * The context to reset. - * - * Returns: - * Nothing. - * - * Comments: - * - */ -void SHA1Reset(SHA1Context *context) -{ - context->Length_Low = 0; - context->Length_High = 0; - context->Message_Block_Index = 0; - - context->Message_Digest[0] = 0x67452301; - context->Message_Digest[1] = 0xEFCDAB89; - context->Message_Digest[2] = 0x98BADCFE; - context->Message_Digest[3] = 0x10325476; - context->Message_Digest[4] = 0xC3D2E1F0; - - context->Computed = 0; - context->Corrupted = 0; -} - -/* - * SHA1Result - * - * Description: - * This function will return the 160-bit message digest into the - * Message_Digest array within the SHA1Context provided - * - * Parameters: - * context: [in/out] - * The context to use to calculate the SHA-1 hash. - * - * Returns: - * 1 if successful, 0 if it failed. - * - * Comments: - * - */ -int SHA1Result(SHA1Context *context) -{ - - if (context->Corrupted) - { - return 0; - } - - if (!context->Computed) - { - SHA1PadMessage(context); - context->Computed = 1; - } - - return 1; -} - -/* - * SHA1Input - * - * Description: - * This function accepts an array of octets as the next portion of - * the message. - * - * Parameters: - * context: [in/out] - * The SHA-1 context to update - * message_array: [in] - * An array of characters representing the next portion of the - * message. - * length: [in] - * The length of the message in message_array - * - * Returns: - * Nothing. - * - * Comments: - * - */ -void SHA1Input( SHA1Context *context, - const unsigned char *message_array, - unsigned length) -{ - if (!length) - { - return; - } - - if (context->Computed || context->Corrupted) - { - context->Corrupted = 1; - return; - } - - while(length-- && !context->Corrupted) - { - context->Message_Block[context->Message_Block_Index++] = - (*message_array & 0xFF); - - context->Length_Low += 8; - /* Force it to 32 bits */ - context->Length_Low &= 0xFFFFFFFF; - if (context->Length_Low == 0) - { - context->Length_High++; - /* Force it to 32 bits */ - context->Length_High &= 0xFFFFFFFF; - if (context->Length_High == 0) - { - /* Message is too long */ - context->Corrupted = 1; - } - } - - if (context->Message_Block_Index == 64) - { - SHA1ProcessMessageBlock(context); - } - - message_array++; - } -} - -/* - * SHA1ProcessMessageBlock - * - * Description: - * This function will process the next 512 bits of the message - * stored in the Message_Block array. - * - * Parameters: - * None. - * - * Returns: - * Nothing. - * - * Comments: - * Many of the variable names in the SHAContext, especially the - * single character names, were used because those were the names - * used in the publication. - * - * - */ -void SHA1ProcessMessageBlock(SHA1Context *context) -{ - const unsigned K[] = /* Constants defined in SHA-1 */ - { - 0x5A827999, - 0x6ED9EBA1, - 0x8F1BBCDC, - 0xCA62C1D6 - }; - int t; /* Loop counter */ - unsigned temp; /* Temporary word value */ - unsigned W[80]; /* Word sequence */ - unsigned A, B, C, D, E; /* Word buffers */ - - /* - * Initialize the first 16 words in the array W - */ - for(t = 0; t < 16; t++) - { - W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; - W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; - W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; - W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); - } - - for(t = 16; t < 80; t++) - { - W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); - } - - A = context->Message_Digest[0]; - B = context->Message_Digest[1]; - C = context->Message_Digest[2]; - D = context->Message_Digest[3]; - E = context->Message_Digest[4]; - - for(t = 0; t < 20; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | ((~B) & D)) + E + W[t] + K[0]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 20; t < 40; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 40; t < 60; t++) - { - temp = SHA1CircularShift(5,A) + - ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 60; t < 80; t++) - { - temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - } - - context->Message_Digest[0] = - (context->Message_Digest[0] + A) & 0xFFFFFFFF; - context->Message_Digest[1] = - (context->Message_Digest[1] + B) & 0xFFFFFFFF; - context->Message_Digest[2] = - (context->Message_Digest[2] + C) & 0xFFFFFFFF; - context->Message_Digest[3] = - (context->Message_Digest[3] + D) & 0xFFFFFFFF; - context->Message_Digest[4] = - (context->Message_Digest[4] + E) & 0xFFFFFFFF; - - context->Message_Block_Index = 0; -} - -/* - * SHA1PadMessage - * - * Description: - * According to the standard, the message must be padded to an even - * 512 bits. The first padding bit must be a '1'. The last 64 - * bits represent the length of the original message. All bits in - * between should be 0. This function will pad the message - * according to those rules by filling the Message_Block array - * accordingly. It will also call SHA1ProcessMessageBlock() - * appropriately. When it returns, it can be assumed that the - * message digest has been computed. - * - * Parameters: - * context: [in/out] - * The context to pad - * - * Returns: - * Nothing. - * - * Comments: - * - */ -void SHA1PadMessage(SHA1Context *context) -{ - /* - * Check to see if the current message block is too small to hold - * the initial padding bits and length. If so, we will pad the - * block, process it, and then continue padding into a second - * block. - */ - if (context->Message_Block_Index > 55) - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 64) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - - SHA1ProcessMessageBlock(context); - - while(context->Message_Block_Index < 56) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - else - { - context->Message_Block[context->Message_Block_Index++] = 0x80; - while(context->Message_Block_Index < 56) - { - context->Message_Block[context->Message_Block_Index++] = 0; - } - } - - /* - * Store the message length as the last 8 octets - */ - context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; - context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; - context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; - context->Message_Block[59] = (context->Length_High) & 0xFF; - context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; - context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; - context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; - context->Message_Block[63] = (context->Length_Low) & 0xFF; - - SHA1ProcessMessageBlock(context); -} - -struct UserRec SYSOPUSER = {"", "", "", "", 1}; // Set Secure Flag - -int ProcessNewTermWebSock(struct ConnectionInfo * sockptr, char * Key) -{ - char * User = strlop(Key, '&'); - char * Pass = strlop(User, '&'); - char * Secure = strlop(Pass, '&'); - struct UserRec * USER = 0; - int i; - - char Msg[256]; - char AXCall[10]; - - struct HTTPConnectionInfo * Session = SessionList; - - USER = sockptr->USER; - - while (Session) - { - if (strcmp(Session->Key, Key) == 0) - { - USER = sockptr->USER = Session->USER; - break; - } - - Session = Session->Next; - } - - if (USER == 0) - { - // Look for record in TelnetServere - - for (i = 0; i < sockptr->TNC->TCPInfo->NumberofUsers; i++) - { - USER = sockptr->TNC->TCPInfo->UserRecPtr[i]; - if ((_stricmp(User, USER->Callsign) == 0 ) && (strcmp(Pass, USER->Password) == 0)) - break; - } - - if (i == sockptr->TNC->TCPInfo->NumberofUsers) - { - // Not Found - - if (sockptr->LOCALAuth) - { - // Sign in as sysop - - USER = &SYSOPUSER; - USER->Callsign = MYNODECALL; - } - } - - if (USER == 0) - return 0; - - sockptr->USER = USER; - } - - if (Session == 0) - Session = AllocateSession(sockptr->socket, 'T'); - - if (Session == 0) - { - Msg[0] = 0x81; // Fin, Data - strcpy(&Msg[2], "No Session. Reload Page to reconnect
"); - Msg[1] = strlen(&Msg[2]); - send(sockptr->socket, Msg, Msg[1] + 2, 0); - - Msg[0] = 0x88; // Fin, Close - send(sockptr->socket, Msg, Msg[1] + 2, 0); - return 1; - } - - Session->USER = USER; - strcpy(Session->HTTPCall, USER->Callsign); - - ConvToAX25(Session->HTTPCall, AXCall); - ChangeSessionCallsign(Session->Stream, AXCall); - - BPQHOSTVECTOR[Session->Stream -1].HOSTSESSION->Secure_Session = USER->Secure; - - Session->TNC = sockptr->TNC; - Session->sockptr = sockptr; - Session->WebsockTerm = 1; - return 0; -} - -void ProcessWebTermInput(struct ConnectionInfo * sockptr, char * Payload) -{ - struct HTTPConnectionInfo * Session = SessionList; - char Msg[256]; - char AXCall[10]; - - // Echo CRLF - - Msg[0] = 0x81; // Fin, Data - strcpy(&Msg[2], "\r\n"); - Msg[1] = 2; - send(sockptr->socket, Msg, 4, 0); - - while (Session) - { - if (Session->sockptr == sockptr) - { - int Stream = Session->Stream; - char InputMsg[512]; - char c, hex; - char * ptr1, * ptr2; - int State; - - if (Stream == 0) - { - Session->Stream = FindFreeStreamNoSem(); - - if (Stream == 0) - continue; - } - - - // if (MsgLen > maxlen) - // { - // Session->KillTimer = 99999; // close session - // return; - // } - - - ptr1 = Payload; - ptr2 = InputMsg; - - // Convert any %xx constructs - - while (1) - { - c = *(ptr1++); - - if (c == 0) - break; - - if (c == '%') - { - c = *(ptr1++); - if(isdigit(c)) - hex = (c - '0') << 4; - else - hex = (tolower(c) - 'a' + 10) << 4; - - c = *(ptr1++); - if(isdigit(c)) - hex += (c - '0'); - else - hex += (tolower(c) - 'a' + 10); - - *(ptr2++) = hex; - } - else if (c == '+') - *(ptr2++) = 32; - else - *(ptr2++) = c; - } - - *ptr2 = 0; - - SessionStateNoAck(Stream, &State); - - if (State == 0) - { - char AXCall[10]; - int SaveAuthProg = AuthorisedProgram; - - AuthorisedProgram = 0; - SessionControl(Stream, 1, 0); - AuthorisedProgram = SaveAuthProg; - - if (BPQHOSTVECTOR[Session->Stream -1].HOSTSESSION == NULL) - { - //No L4 sessions free - - char Msg[256]; - - Msg[0] = 0x81; // Fin, Data - strcpy(&Msg[2], "No Free Host Sessions\r\n"); - Msg[1] = strlen(&Msg[2]); - - send(sockptr->socket, Msg, Msg[2] + 2, 0); - return; - } - - ConvToAX25(Session->HTTPCall, AXCall); - ChangeSessionCallsign(Stream, AXCall); - if (Session->USER) - BPQHOSTVECTOR[Session->Stream -1].HOSTSESSION->Secure_Session = Session->USER->Secure; - else - Debugprintf("HTTP Term Session->USER is NULL"); - - } - - SendMsgNoSem(Stream, InputMsg, strlen(InputMsg)); - Session->Changed = TRUE; - Session->KillTimer = 0; - - return; - } - - Session = Session->Next; - } - - // Input with no session create another - - Session = AllocateSession(sockptr->socket, 'T'); - - if (Session == 0) - { - Msg[0] = 0x81; // Fin, Data - strcpy(&Msg[2], "No Session. Reload Page to reconnect\r\n"); - Msg[1] = strlen(&Msg[2]); - send(sockptr->socket, Msg, Msg[1] + 2, 0); - - Msg[0] = 0x88; // Fin, Close - send(sockptr->socket, Msg, Msg[1] + 2, 0); - return; - } - - if (sockptr->USER) - { - Session->USER = sockptr->USER; - strcpy(Session->HTTPCall, sockptr->USER->Callsign); - - ConvToAX25(Session->HTTPCall, AXCall); - ChangeSessionCallsign(Session->Stream, AXCall); - - BPQHOSTVECTOR[Session->Stream -1].HOSTSESSION->Secure_Session = Session->USER->Secure; - } - - Session->TNC = sockptr->TNC; - Session->sockptr = sockptr; - Session->WebsockTerm = 1; - - ProcessWebTermInput(sockptr, Payload); // Reenter -} - -void ProcessWebTermClosed(struct ConnectionInfo * sockptr) -{ - struct HTTPConnectionInfo * Session = SessionList; - struct HTTPConnectionInfo * PreviousSession = NULL; - int i; - - while (Session) - { - if (Session->sockptr == sockptr) - { - int Stream = Session->Stream; - - SessionControl(Stream, 2, 0); - SessionStateNoSem(Stream, &i, &i); - DeallocateStream(Stream); - Session->Stream = 0; - -/* - if (PreviousSession) - PreviousSession->Next = Session->Next; // Remove from chain - else - SessionList = Session->Next; - - free(Session); -*/ - return; - - } - Session = Session->Next; - } -} - - -int DoWebSockTerm(struct HTTPConnectionInfo * Session, struct ConnectionInfo * conn, char * _REPLYBUFFER, int LOCAL, int COOKIE, char * Context, SOCKET sock) -{ - char TermPage[] = - "\r\n" - "Web Terminal\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "

BPQ32 Node %s

" - "

" - " " - - "" - "\r\n" - "" -// "Disconnect from Node" - "Disconnect from Node" -// "Kill and Restart TNC" - "" - - "

Waiting for connection...
\r\n" - "
\r\n" - - "
" - "
\r\n" - "
\r\n"; - - struct TNCINFO * TNC = conn->TNC; - struct TCPINFO * TCP = 0; - struct HTTPConnectionInfo * NewSession; - int ReplyLen; - char Key = 0; - struct UserRec * USER; - - if (Session) - Key = Session->Key[0]; - - if (TNC) - TCP = TNC->TCPInfo; - - // See if we need to send login page - - if (LOCAL == 0 && Key != 'T' && Key != 'N') - { - // Not signed in as Term or Node and not local connection - send login page - - return sprintf(_REPLYBUFFER, TermSignon, Mycall, Mycall, Context, "Websocks"); - } - - if (Key != 'T') - { - // Either logged into node or Local Session - Create Sessiob - - char AXCall[10]; - - NewSession = AllocateSession(sock, 'T'); - - if (NewSession == 0) // No Memory - Give up! - return 0; - - if (Key == 'N' && Session->USER) - { - // signed into node - use call from signin - - strcpy(NewSession->HTTPCall, Session->USER->Callsign); - NewSession->USER = Session->USER; - } - else - { - strcpy(NewSession->HTTPCall, MYNODECALL); - USER = NewSession->USER = &SYSOPUSER; - USER->Callsign = MYNODECALL; - } - - ConvToAX25(NewSession->HTTPCall, AXCall); - ChangeSessionCallsign(NewSession->Stream, AXCall); - - BPQHOSTVECTOR[NewSession->Stream -1].HOSTSESSION->Secure_Session = NewSession->USER->Secure; - } - else - { - // Already have session from - NewSession = Session; - } - - NewSession->TNC = conn->TNC; - NewSession->sockptr = 0; - NewSession->WebsockTerm = 1; - - USER = NewSession->USER; - - if (TCP && TCP->WebTermCSS) - ReplyLen = sprintf(_REPLYBUFFER, TermPage,NewSession->Key, NewSession->Key, USER->Callsign, USER->Password, USER->Secure, NewSession->HTTPCall, - TCP->WebTermCSS, TCP->WebTermCSS); - else - ReplyLen = sprintf(_REPLYBUFFER, TermPage, NewSession->Key, NewSession->Key, USER->Callsign, USER->Password, USER->Secure, NewSession->HTTPCall, - "font-family:monospace", "font-family:monospace"); - - // if (Appl[0]) - // { - // strcat(Appl, "\r"); - // SendMsg(Session->Stream, Appl, strlen(Appl)); - // } - - return ReplyLen; -} - - diff --git a/Versions.h b/Versions.h index c847884..2a124ac 100644 --- a/Versions.h +++ b/Versions.h @@ -1,4 +1,3 @@ - #ifdef Kernel #define Vers 5,2,9,2