From a792602316553910d71e00b9beba7cc419c08d89 Mon Sep 17 00:00:00 2001 From: g8bpq Date: Thu, 16 Mar 2023 06:52:27 +0000 Subject: [PATCH] 6.0.23.55 --- APRSStdPages.c | 643 ++++++++++++++++++++++++------------------------- BPQMail.c | 5 +- Bpq32.c | 6 +- Cmd.c | 28 ++- CommonCode.c | 16 ++ HFCommon.c | 10 +- HTTPcode.c | 531 ++++++++++++++++++++++++++++++++++++---- RigControl.c | 81 ++++++- TNCEmulators.c | 21 +- VARA.c | 18 ++ Versions.h | 4 +- WebMail.c | 32 ++- tncinfo.h | 8 +- 13 files changed, 1007 insertions(+), 396 deletions(-) diff --git a/APRSStdPages.c b/APRSStdPages.c index 7cb38e1..112e8be 100644 --- a/APRSStdPages.c +++ b/APRSStdPages.c @@ -3226,335 +3226,328 @@ char * get_plane(int * Len) } - - char * get_aprs() { char Msg[] = + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "G8BPQ APRS Display\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + " \n" + "\n" - - -//"\n" -//"\n" -"\n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -"\n" -"\n" -"\n" -"
\n" -"\n" -""; - + "\n" + "function getCookie(cname)\n" + " {\n" + " var name = cname + \"=\";\n" + " var decodedCookie = decodeURIComponent(document.cookie);\n" + " var ca = decodedCookie.split(';');\n" + " \t\n" + " for(var i = 0; i < ca.length; i++)\n" + " {\n" + " var c = ca[i];\n" + " while (c.charAt(0) == ' ')\n" + " {\n" + " c = c.substring(1);\n" + " }\n" + " if (c.indexOf(name) == 0)\n" + " return c.substring(name.length, c.length);\n" + " }\n" + " return \"\";\n" + "}\n" + "\n" + "\n" + "// Refresh map every 60 seconds\n" + " \n" + "setInterval( \"Refresh()\", 60000 );\n" + "\n" + "function Refresh( )\n" + "{\n" + " var latlng = map.getCenter();\n" + " zoom = map.getZoom();\n" + " \n" + " lat = latlng.lat;\n" + " lon = latlng.lng\n" + " \n" + " document.cookie = \"Lat=\" + lat;\n" + " document.cookie = \"Lng=\" + lon;\n" + " document.cookie = \"Zoom=\" + zoom;\n" + " \n" + " \tdocument.cookie = \"aprs=\" + aprs;\n" + " \tdocument.cookie = \"ais=\" + ais;\n" + " \tdocument.cookie = \"adsb=\" + adsb;\n" + "\n" + " GetData();\n" + "}\n" + "\n" + " \n" + "function GetData()\n" + "{\n" + " var N = map.getBounds().getNorth();\n" + " var S = map.getBounds().getSouth();\n" + " var W = map.getBounds().getWest();\n" + " var E = map.getBounds().getEast();\n" + " $.ajax({url: \"aprsdata.txt?\" + N + '|' + S + '|' + W + '|' + E + '|' + aprs + '|' + ais + '|' + adsb, cache: false})\n" + " .done(function(Nodes){processData(Nodes);})\t\n" + " .fail(function(jqXHR, textStatus, errorThrown){alert(\"Failed to load aprs data\");})\n" + " ;\n" + " }\n" + " \n" + "function processData(Nodes)\n" + "{\n" + " var i = 0;\n" + " layergroup.clearLayers();\n" + " \n" + " var lines = Nodes.split(\"|\");\n" + " \n" + " while (i < lines.length)\n" + " {\n" + " if (lines[i].length < 5)\n" + " {\n" + " i++;\n" + " continue;\n" + " }\n" + " \t\n" + " var elements = lines[i].split(\",\");\n" + " i++;\t\n" + " \t\n" + "if (elements[0] == \"H\")\t\t\t\t// Home Position\n" + "{ homeLat = elements[1]; homeLon = elements[2]; homePoint = L.latLng(homeLat, homeLon); var m = L.circleMarker([elements[1], elements[2]], {radius: 6, color: '#000000', fillOpacity: 0.3})\n" + " .addTo(layergroup)\n" + " .bindPopup(elements[3])\n" + " .on('click', function (e) {alert(this.getLatLng());})\n" + " .on('mouseover', function (e) {this.openPopup();})\n" + " .on('mouseout', function (e) {this.closePopup();});\n" + " if (lat == 0 || lat == \"\")\t\t// Not Set\n" + " map.setView([elements[1], elements[2]], 8);\n" + "}\n" + "\n" + " if (elements[0] == \"N\") \t// Navaid\n" + " {\n" + " var m = L.marker([elements[1], elements[2]], {rotationAngle: 0, icon: navIcon})\n" + " .addTo(layergroup)\n" + " .bindPopup(elements[3])\n" + " .on('click', function (e) {alert(this.getLatLng());})\n" + " .on('mouseover', function (e) {this.openPopup();})\n" + " .on('mouseout', function (e) {this.closePopup();});\n" + "\n" + " }\n" + " else if (elements[0] == \"A\") \t// APRS\n" + " {\n" + " var Icon = L.icon({iconUrl: 'Icon' + elements[5] + '.png',iconSize: [22, 22],iconAnchor: [11, 11],popupAnchor: [0, 0]});\n" + " \n" + " var m = L.marker([elements[1], elements[2]], {rotationAngle: 0, icon: Icon})\n" + " .addTo(layergroup)\n" + " .bindPopup(elements[4], {minWidth: 280, maxWidth: 500})\n" + " .bindTooltip(elements[3], {className: 'popup', permanent: true, direction: 'right', offset: [10, 0]}).openTooltip()\t\n" + " .on('click', function (e) {alert(this.getLatLng());})\n" + " .on('mouseover', function (e) {this.openPopup();})\n" + " .on('mouseout', function (e) {this.closePopup();});\n" + "\n" + " }\n" + " else if (elements[0] == \"V\") // Vessel\n" + " {\n" + " var icon;\n" + " \n" + "var dist = homePoint.distanceTo([elements[1], elements[2]]) / 1609.34;\n" + "var popup = elements[3] + '
Distance ' + dist.toFixed(0) + ' Miles'; if (elements[6] < 900)\n" + " \ticon = blueIcon;\n" + " else if (elements[6] < 1800)\n" + " \ticon = redIcon;\n" + " else\n" + " \ticon = whiteIcon;\n" + " \t\n" + " var m = L.marker([elements[1], elements[2]], {rotationAngle: elements[4], icon: icon})\n" + " .addTo(layergroup)\n" + " .bindPopup(popup)\n" + " .on('click', function (e) {alert(this.getLatLng());})\n" + " .on('mouseover', function (e) {this.openPopup();})\n" + " .on('mouseout', function (e) {this.closePopup();});\n" + " }\n" + "\n" + " else if (elements[0] == \"S\") // SAR Aircraft\n" + " {\n" + " var m = L.marker([elements[1], elements[2]], {icon: sarIcon})\n" + " .addTo(layergroup)\n" + " .bindPopup(elements[3])\n" + " .on('click', function (e) {alert(this.getLatLng());})\n" + " .on('mouseover', function (e) {this.openPopup();})\n" + " .on('mouseout', function (e) {this.closePopup();});\n" + " }\n" + " \n" + " else if (elements[0] == \"P\")\n" + " {\n" + "var dist = homePoint.distanceTo([elements[1], elements[2]]) / 1609.34;\n" + "var popup = elements[3] + '
Distance ' + dist.toFixed(0) + ' Miles'; var icon;\n" + " \n" + " if (elements[7] < 120)\n" + " \ticon = greenplaneIcon;\n" + " else\n" + " \ticon = planeIcon;\n" + "\n" + " var m = L.marker([elements[1], elements[2]], {rotationAngle: elements[5], icon: icon})\n" + " .addTo(layergroup)\n" + " .bindPopup(popup)\n" + " .on('mouseover', function (e) {this.openPopup();})\n" + " .on('mouseout', function (e) {this.closePopup();});\n" + " }\n" + " \n" + " else if (elements[0] == \"T\")\n" + " {\n" + " var points = [];\n" + " var point;\n" + " var n = 1;\n" + " var l = elements.length;\n" + " \n" + " while (n < l)\n" + " {\n" + " \tpoint = L.latLng(elements[n], elements[n + 1]);\n" + " \tpoints.push(point);\n" + " \tn += 2;\n" + " }\n" + " points.pop();\t// null entry on end\n" + " \n" + " L.polyline(points, {color: 'black'}).addTo(layergroup);\n" + " }\n" + " }\n" + "\n" + "}\n" + "function resize()\n" + "{}\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "
\n" + "\n" + ""; return _strdup(Msg);; } diff --git a/BPQMail.c b/BPQMail.c index 344dc5f..f5319f9 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -1104,10 +1104,11 @@ // Add auto-refresh option to Webmail index page (25) // Fix displaying help and info files with crlf line endings on Linux (28) // Improve validation of extended FC message (32) -// Improve WP check for SYSTEM as a callsihn (33) +// Improve WP check for SYSTEM as a callsign (33) // Improvements to RMS Relay SYNC mode (47) // Fix BID Hold and Reject filters - +// Fix Webmail auto-refresh when page exceeds 64K bytes (54) +// Fix Webmail send when using both headers/footers and attachmonts (55) #include "bpqmail.h" diff --git a/Bpq32.c b/Bpq32.c index 0308f62..2fdcdd1 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1147,7 +1147,10 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Check L4 connects against EXCLUDE list (47) // Add vaidation of LOC in WL2K Session Reports (49) // Change gpsd support for compatibility with Share Gps (50) - +// Switch APRS Map to my Tiles (52) +// Fix using ; in UNPROTO Mode messages (52) +// Use sha1 code from https://www.packetizer.com/security/sha1/ instead of openssl (53) +// Fix TNC Emulator Monitoring (53) #define CKernel @@ -1162,7 +1165,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #include #include "compatbits.h" - #include "AsmStrucs.h" #include "SHELLAPI.H" diff --git a/Cmd.c b/Cmd.c index f6c3fc1..2157939 100644 --- a/Cmd.c +++ b/Cmd.c @@ -4064,6 +4064,24 @@ noFlip1: checkattachandcall: + // If set freq on attach is defined, do it + + if (TNC && TNC->ActiveRXFreq && TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->ActiveRXFreq); + Rig_Command(-1, Msg); + } + + if (TNC && TNC->ActiveTXFreq && TNC->TXRadio && TNC->TXRadio != TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->ActiveTXFreq); + Rig_Command(-1, Msg); + } + if (ptr) { // we have a call to connect to @@ -4528,7 +4546,15 @@ VOID InnerCommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer) // SendUIModeFrame(Session, (PMESSAGE)Buffer, Session->UNPROTO); ReleaseBuffer((UINT *)Buffer); // Not using buffer for reply - + + // Assume we don't allow multiple lines in buffer with UI + + if (Session->PARTCMDBUFFER) + { + Buffer = Session->PARTCMDBUFFER; + ReleaseBuffer((UINT *)Buffer); // Not using buffer for reply + Session->PARTCMDBUFFER = NULL; + } return; } diff --git a/CommonCode.c b/CommonCode.c index 2abf722..f7e1685 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -772,6 +772,22 @@ NotConnected: CloseComplete(TNC, Stream); + if (TNC->DefaultRXFreq && TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->DefaultRXFreq); + Rig_Command(-1, Msg); + } + + if (TNC->DefaultTXFreq && TNC->TXRadio && TNC->TXRadio != TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->DefaultTXFreq); + Rig_Command(-1, Msg); + } + while(STREAM->BPQtoPACTOR_Q) { buffptr=Q_REM(&STREAM->BPQtoPACTOR_Q); diff --git a/HFCommon.c b/HFCommon.c index 21b7376..0ef6145 100644 --- a/HFCommon.c +++ b/HFCommon.c @@ -1870,8 +1870,14 @@ int standardParams(struct TNCINFO * TNC, char * buf) TNC->RXRadio = atoi(&buf[8]); else if (_memicmp(buf, "TXFreq", 6) == 0) // For PTT Sets Freq mode TNC->TXFreq = strtoll(&buf[7], NULL, 10); - else if (_memicmp(buf, "DefaultFreq", 11) == 0) // For PTT Sets Freq mode - TNC->DefaultFreq = strtoll(&buf[12], NULL, 10); + else if (_memicmp(buf, "DefaultTXFreq", 13) == 0) // Set at end of session + TNC->DefaultTXFreq = atof(&buf[14]); + else if (_memicmp(buf, "DefaultRXFreq", 13) == 0) // Set at end of session + TNC->DefaultRXFreq = atof(&buf[14]); + else if (_memicmp(buf, "ActiveTXFreq", 12) == 0) // Set at start of session + TNC->ActiveTXFreq = atof(&buf[13]); + else if (_memicmp(buf, "ActiveRXFreq", 12) == 0) // Set at start of session + TNC->ActiveRXFreq = atof(&buf[13]); else if (_memicmp(buf, "PTTONHEX", 8) == 0) { // Hex String to use for PTT on for this port diff --git a/HTTPcode.c b/HTTPcode.c index eaf894b..783e55a 100644 --- a/HTTPcode.c +++ b/HTTPcode.c @@ -2035,6 +2035,11 @@ Returnit: return 0; } + // Add tail + + strcpy(&Reply[ReplyLen], Tail); + ReplyLen += strlen(Tail); + // compress if allowed if (allowDeflate) @@ -2096,7 +2101,29 @@ doHeader: 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)); + // Add tail + + strcpy(&_REPLYBUFFER[ReplyLen], Tail); + ReplyLen += strlen(Tail); + + // compress if allowed + + if (allowDeflate) + Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); + else + Compressed = Reply; + + 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); @@ -2124,7 +2151,7 @@ doHeader: send(sock, Tail, (int)strlen(Tail), 0); return 0; - +*/ } if (_memicmp(Context, "/CHAT/", 6) == 0) @@ -4176,54 +4203,97 @@ int ProcessChatSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * R } -#ifdef WIN32 - -#include -#include - #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) { - HCRYPTPROV hCryptProv; // Handle to our context - HCRYPTHASH hCryptHash; // Handle to our hash - BYTE bHashValue[SHA1_HASH_LEN]; // This will hold our SHA-1 hash - DWORD dwSize = SHA1_HASH_LEN; // Size of output - BOOL bSuccess = FALSE; // We change this to TRUE if we complete the operations - // Declare all the variables at the start of our code for C89 compatability - - if(CryptAcquireContext(&hCryptProv, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - { // Initiate usage of the functions - if(CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hCryptHash)) - { // Create a SHA1 hash - if(CryptHashData(hCryptHash, (PBYTE)lpszPassword, lstrlen(lpszPassword) * sizeof(TCHAR), 0)) - { // Update the hash, (process our password) - if(CryptGetHashParam(hCryptHash, HP_HASHVAL, bHashValue, &dwSize, 0)) - { // Extract the hash - - memcpy(Hash, bHashValue, 20); - bSuccess = TRUE; - } - } - CryptDestroyHash(hCryptHash); - } - CryptReleaseContext(hCryptProv, 0); - } - - return bSuccess; + 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; } -#else - -#include - -BOOL SHA1PasswordHash(char * data, char * Hash) -{ - SHA1(data, strlen(data), Hash); - return 1; -} -#endif - int BuildRigCtlPage(char * _REPLYBUFFER) { int ReplyLen; @@ -4341,9 +4411,9 @@ void ProcessWebmailWebSockThread(void * conn) char * URL = sockptr->WebURL; int Loops = 0; int Sent; - int InputLen; struct HTTPConnectionInfo Dummy = {0}; int ReplyLen = 0; + int InputLen = 0; #ifdef LINBPQ @@ -4423,6 +4493,377 @@ void ProcessWebmailWebSockThread(void * 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); +} + + diff --git a/RigControl.c b/RigControl.c index e0d38be..a864c1e 100644 --- a/RigControl.c +++ b/RigControl.c @@ -303,6 +303,8 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) { char FreqString[80]; char * CmdPtr = onString; + UCHAR * Poll = PORT->TXBuffer; + RIG->lastSetFreq = txfreq; @@ -330,6 +332,7 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) *(CmdPtr++) = (FreqString[9] - 48) | ((FreqString[8] - 48) << 4); *(CmdPtr++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4); *(CmdPtr++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4); + if (RIG->IC735) { *(CmdPtr++) = 0xFD; @@ -349,6 +352,40 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) break; + case YAESU: + + *(Poll++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4); + *(Poll++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4); + *(Poll++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4); + *(Poll++) = (FreqString[10] - 48) | ((FreqString[9] - 48) << 4); + *(Poll++) = 1; // Set Freq + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + + + if (RIG->PTTMode & PTTCI_V) + { + Sleep(150); + Poll = PORT->TXBuffer; + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = 0; + + *(Poll++) = 0; + *(Poll++) = PTTState ? 0x08 : 0x88; // CMD = 08 : PTT ON CMD = 88 : PTT OFF + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + } + + PORT->Retries = 1; + PORT->Timeout = 0; + + return; + + + case HAMLIB: // Dont need to save, as we can send strings separately @@ -356,6 +393,9 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) Len = sprintf(cmd, "F %lld\n", txfreq); i = send(PORT->remoteSock, cmd, Len, 0); RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF + + break; + } } } @@ -395,7 +435,8 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) { char FreqString[80]; char * CmdPtr = offString; - + UCHAR * Poll = PORT->TXBuffer; + RIG->lastSetFreq = txfreq; // Convert to CAT string @@ -443,7 +484,41 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) sprintf(cmd, "%lld", txfreq); FLRIGSendCommand(PORT, "rig.set_vfo", cmd); RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF - + + case YAESU: + + // Easier to add PTT string, send and return; + + Len = 0; + + if (RIG->PTTMode & PTTCI_V) + { + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = PTTState ? 0x08 : 0x88; // CMD = 08 : PTT ON CMD = 88 : PTT OFF + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + Poll = PORT->TXBuffer; + Sleep(100); + } + + *(Poll++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4); + *(Poll++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4); + *(Poll++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4); + *(Poll++) = (FreqString[10] - 48) | ((FreqString[9] - 48) << 4); + *(Poll++) = 1; // Set Freq + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + + PORT->Retries = 1; + PORT->Timeout = 0; + + return; + case HAMLIB: // Dont need to save, as we can send strings separately @@ -1633,6 +1708,8 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, int Session, C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr); + saveNewFreq(RIG, Freq, Mode); + return TRUE; diff --git a/TNCEmulators.c b/TNCEmulators.c index 7497419..a4b85c1 100644 --- a/TNCEmulators.c +++ b/TNCEmulators.c @@ -2224,16 +2224,27 @@ VOID DOMONITORING(int NeedTrace) BOOL SaveMTX = MTX; BOOL SaveMCOM = MCOM; BOOL SaveMUI = MUIONLY; + int BPQStream = 0; if (NeedTrace) Tracebit = 0x80; - if (TNC->CONOK) - SetAppl(TNC->BPQPort, TNC->APPLFLAGS | Tracebit, TNC->APPLICATION); - else - SetAppl(TNC->BPQPort, TNC->APPLFLAGS | Tracebit, 0); + if (TNC->Channels[0]) + BPQStream = TNC->Channels[0]->BPQStream; + else if (TNC->TNC2Stream[0]) + BPQStream = TNC->TNC2Stream[0]->BPQPort; + else if (TNC->BPQPort) + BPQStream = TNC->BPQPort; - Stamp = GetRaw(TNC->BPQPort, (char *)&MONITORDATA, &len, &count); + if (BPQStream) + { + if (TNC->CONOK) + SetAppl(BPQStream, TNC->APPLFLAGS | Tracebit, TNC->APPLICATION); + else + SetAppl(BPQStream, TNC->APPLFLAGS | Tracebit, 0); + } + + Stamp = GetRaw(BPQStream, (char *)&MONITORDATA, &len, &count); if (len == 0) return; diff --git a/VARA.c b/VARA.c index 40a02c2..73b4b11 100644 --- a/VARA.c +++ b/VARA.c @@ -2433,6 +2433,24 @@ static VOID CloseComplete(struct TNCINFO * TNC, int Stream) VARASendCommand(TNC, "BW500\r", TRUE); else if (TNC->DefaultMode == 54) VARASendCommand(TNC, "BW2750\r", TRUE); + + // If a default frequency is specified, set it + + if (TNC->DefaultTXFreq && TNC->TXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->DefaultTXFreq); + Rig_Command(-1, Msg); + } + + if (TNC->DefaultRXFreq && TNC->RXRadio && TNC->TXRadio != TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->DefaultRXFreq); + Rig_Command(-1, Msg); + } } diff --git a/Versions.h b/Versions.h index 42c9d9f..0d1f361 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,23,51 -#define KVerstring "6.0.23.51\0" +#define KVers 6,0,23,55 +#define KVerstring "6.0.23.55\0" #ifdef CKernel diff --git a/WebMail.c b/WebMail.c index f76584b..b5d0e6b 100644 --- a/WebMail.c +++ b/WebMail.c @@ -3589,7 +3589,7 @@ char * BuildB2Header(WebMailInfo * WebMail, struct MsgInfo * Msg, char ** ToCall "Mbo: %s\r\n", Msg->title, BBSName); - NewMsg += sprintf(NewMsg, "Body: %d\r\n", (int)strlen(WebMail->Body)); + NewMsg += sprintf(NewMsg, "Body: %d\r\n", (int)strlen(WebMail->Body) + WebMail->HeaderLen + WebMail->FooterLen); Msg->B2Flags = B2Msg; @@ -6063,7 +6063,7 @@ int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer) struct UserInfo * User; int m; struct MsgInfo * Msg; - char * ptr = &OutBuffer[4]; + char * ptr = &OutBuffer[10]; // allow room for full payload length (64 bit) int n = NumberofMessages; char Via[64]; @@ -6145,25 +6145,39 @@ int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer) ptr += sprintf(ptr, "%s \r\n", ptr); - Len = ptr - &OutBuffer[4]; + Len = ptr - &OutBuffer[10]; OutBuffer[0] = 0x81; // Fin, Data if (Len < 126) { OutBuffer[1] = Len; - memmove(&OutBuffer[2], &OutBuffer[4], Len); + memmove(&OutBuffer[2], &OutBuffer[10], Len); return Len + 2; } + else if (Len < 65536) + { + OutBuffer[1] = 126; // Unmasked, Extended Len 16 + OutBuffer[2] = Len >> 8; + OutBuffer[3] = Len & 0xff; + memmove(&OutBuffer[4], &OutBuffer[10], Len); + return Len + 4; + } else { - OutBuffer[1] = 126; // Unmasked, Extended Len - OutBuffer[2] = Len >> 8; - OutBuffer[3] = Len & 0xff; + OutBuffer[1] = 127; // Unmasked, Extended Len 64 bits + // Len is 32 bits, so pad with zeros + OutBuffer[2] = 0; + OutBuffer[3] = 0; + OutBuffer[4] = 0; + OutBuffer[5] = 0; + OutBuffer[6] = (Len >> 24) & 0xff; + OutBuffer[7] = (Len >> 16) & 0xff; + OutBuffer[8] = (Len >> 8) & 0xff; + OutBuffer[9] = Len & 0xff; - return Len + 4; + return Len + 10; } - } diff --git a/tncinfo.h b/tncinfo.h index f795d94..d29886f 100644 --- a/tncinfo.h +++ b/tncinfo.h @@ -538,7 +538,13 @@ typedef struct TNCINFO int RXRadio; // Rigcontrol Radio Number for RX long long int TXFreq; // Freq to set on tx before ptt - long long int DefaultFreq; // Freq to set on tx after ptt + double ActiveTXFreq; // Freq to set on tx after attach + double ActiveRXFreq; // Freq to set on rx after attach + + double DefaultTXFreq; // Freq to set on tx after close + double DefaultRXFreq; // Freq to set on rx after close + + int TXOffset; // Correction to TXFreq int PID; // Process ID for Software TNC