Merge pull request 'RRIDs' (#233) from rridport into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/233
This commit is contained in:
commit
dd98ee93e2
28 changed files with 4409 additions and 74 deletions
|
|
@ -1655,6 +1655,38 @@ freely, subject to the following restrictions:
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
2-Clause BSD License
|
||||
applies to:
|
||||
- monocypher
|
||||
Copyright (c) 2017-2020, Loup Vaillant
|
||||
All rights reserved.
|
||||
https://monocypher.org/
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
MIT License
|
||||
applies to:
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@ add_subdirectory(sdl)
|
|||
add_subdirectory(objects)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(acs)
|
||||
add_subdirectory(monocypher)
|
||||
|
||||
# OS macros
|
||||
if (UNIX)
|
||||
|
|
|
|||
711
src/d_clisrv.c
711
src/d_clisrv.c
File diff suppressed because it is too large
Load diff
143
src/d_clisrv.h
143
src/d_clisrv.h
|
|
@ -17,6 +17,7 @@
|
|||
#include "d_net.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "d_net.h"
|
||||
#include "doomdef.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
#include "mserv.h"
|
||||
|
|
@ -138,9 +139,23 @@ typedef enum
|
|||
PT_SAY, // "Hey server, please send this chat message to everyone via XD_SAY"
|
||||
PT_REQMAPQUEUE, // Client requesting a roundqueue operation
|
||||
|
||||
PT_CLIENTKEY, // "Here's my public key"
|
||||
PT_SERVERCHALLENGE, // "Prove it"
|
||||
|
||||
PT_CHALLENGEALL, // Prove to the other clients you are who you say you are, sign this random bullshit!
|
||||
PT_RESPONSEALL, // OK, here is my signature on that random bullshit
|
||||
PT_RESULTSALL, // Here's what everyone responded to PT_CHALLENGEALL with, if this is wrong or you don't receive it disconnect
|
||||
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SIGN_OK,
|
||||
SIGN_BADTIME, // Timestamp differs by too much, suspect reuse of an old challenge.
|
||||
SIGN_BADIP // Asked to sign the wrong IP by an external host, suspect reuse of another server's challenge.
|
||||
} shouldsign_t;
|
||||
|
||||
typedef struct consistancy_s
|
||||
{
|
||||
INT16 checksum; // Total consistancy checksum
|
||||
|
|
@ -172,9 +187,7 @@ void SPrintConsistancy(char *out, consistancy_t *c);
|
|||
void Command_Drop(void);
|
||||
void Command_Droprate(void);
|
||||
#endif
|
||||
#ifdef _DEBUG
|
||||
void Command_Numnodes(void);
|
||||
#endif
|
||||
|
||||
// Client to server packet
|
||||
struct clientcmd_pak
|
||||
|
|
@ -248,10 +261,6 @@ struct serverconfig_pak
|
|||
UINT8 maxplayer;
|
||||
boolean allownewplayer;
|
||||
boolean discordinvites;
|
||||
|
||||
char server_name[MAXSERVERNAME];
|
||||
char server_contact[MAXSERVERCONTACT];
|
||||
char server_description[MAXSERVERDESCRIPTION];
|
||||
} ATTRPACK;
|
||||
|
||||
struct filetx_pak
|
||||
|
|
@ -291,6 +300,7 @@ struct clientconfig_pak
|
|||
UINT8 mode;
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
||||
UINT8 availabilities[MAXAVAILABILITY];
|
||||
uint8_t challengeResponse[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
||||
} ATTRPACK;
|
||||
|
||||
#define SV_SPEEDMASK 0x03 // used to send kartspeed
|
||||
|
|
@ -385,6 +395,32 @@ struct reqmapqueue_pak
|
|||
UINT8 source;
|
||||
} ATTRPACK;
|
||||
|
||||
struct clientkey_pak
|
||||
{
|
||||
uint8_t key[MAXSPLITSCREENPLAYERS][PUBKEYLENGTH];
|
||||
} ATTRPACK;
|
||||
|
||||
struct serverchallenge_pak
|
||||
{
|
||||
uint8_t secret[CHALLENGELENGTH];
|
||||
} ATTRPACK;
|
||||
|
||||
struct challengeall_pak
|
||||
{
|
||||
uint8_t secret[CHALLENGELENGTH];
|
||||
} ATTRPACK;
|
||||
|
||||
struct responseall_pak
|
||||
{
|
||||
uint8_t signature[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
||||
} ATTRPACK;
|
||||
|
||||
struct resultsall_pak
|
||||
{
|
||||
// Maybe use a FAM in the future for space saving?
|
||||
uint8_t signature[MAXPLAYERS][SIGNATURELENGTH];
|
||||
} ATTRPACK;
|
||||
|
||||
struct netinfo_pak
|
||||
{
|
||||
UINT32 pingtable[MAXPLAYERS+1];
|
||||
|
|
@ -410,33 +446,42 @@ struct doomdata_t
|
|||
UINT8 ackreturn; // The return of the ack number
|
||||
|
||||
UINT8 packettype;
|
||||
#ifdef SIGNGAMETRAFFIC
|
||||
uint8_t signature[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
||||
#endif
|
||||
UINT8 packetindex;
|
||||
union
|
||||
{
|
||||
clientcmd_pak clientpak;
|
||||
client2cmd_pak client2pak;
|
||||
client3cmd_pak client3pak;
|
||||
client4cmd_pak client4pak;
|
||||
servertics_pak serverpak;
|
||||
serverconfig_pak servercfg;
|
||||
UINT8 textcmd[MAXTEXTCMD+1];
|
||||
char filetxpak[sizeof (filetx_pak)];
|
||||
char fileack[sizeof (fileack_pak)];
|
||||
UINT8 filereceived;
|
||||
clientconfig_pak clientcfg;
|
||||
char salt[9];
|
||||
UINT8 sha256sum[32];
|
||||
serverinfo_pak serverinfo;
|
||||
serverrefuse_pak serverrefuse;
|
||||
serverinfoupdate_pak serverinfoupdate;
|
||||
askinfo_pak askinfo;
|
||||
msaskinfo_pak msaskinfo;
|
||||
plrinfo playerinfo[MAXPLAYERINFO];
|
||||
INT32 filesneedednum;
|
||||
filesneededconfig_pak filesneededcfg;
|
||||
netinfo_pak netinfo;
|
||||
say_pak say;
|
||||
reqmapqueue_pak reqmapqueue; // Formerly XD_REQMAPQUEUE
|
||||
// NOTICE: UPDATE THE COMMENT SIZES WHEN YOU CHANGE STUFF.
|
||||
clientcmd_pak clientpak; // 96 bytes
|
||||
client2cmd_pak client2pak; // 110 bytes
|
||||
client3cmd_pak client3pak; // 124 bytes
|
||||
client4cmd_pak client4pak; // 138 bytes
|
||||
servertics_pak serverpak; // 633 bytes
|
||||
serverconfig_pak servercfg; // 33 bytes
|
||||
UINT8 textcmd[MAXTEXTCMD+1]; // 257 bytes
|
||||
char filetxpak[sizeof (filetx_pak)]; // 12 bytes
|
||||
char fileack[sizeof (fileack_pak)]; // 3 bytes
|
||||
UINT8 filereceived; // 1 byte
|
||||
clientconfig_pak clientcfg; // 378 bytes
|
||||
char salt[9]; // 9 bytes
|
||||
UINT8 sha256sum[32]; // 32 bytes
|
||||
serverinfo_pak serverinfo; // 1311 bytes
|
||||
serverrefuse_pak serverrefuse; // 255 bytes
|
||||
serverinfoupdate_pak serverinfoupdate; // 1406 bytes
|
||||
askinfo_pak askinfo; // 5 bytes
|
||||
msaskinfo_pak msaskinfo; // 26 bytes
|
||||
plrinfo playerinfo[MAXPLAYERINFO]; // 1056 bytes
|
||||
INT32 filesneedednum; // 4 bytes
|
||||
filesneededconfig_pak filesneededcfg; // 921 bytes
|
||||
netinfo_pak netinfo; // 396 bytes
|
||||
say_pak say; // 227 bytes
|
||||
reqmapqueue_pak reqmapqueue; // 6 bytes. Formerly XD_REQMAPQUEUE
|
||||
clientkey_pak clientkey; // 32 bytes
|
||||
serverchallenge_pak serverchallenge; // 256 bytes
|
||||
challengeall_pak challengeall; // 256 bytes
|
||||
responseall_pak responseall; // 256 bytes
|
||||
resultsall_pak resultsall; // 1024 bytes (2048 bytes in 32P)
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK;
|
||||
|
||||
|
|
@ -478,6 +523,7 @@ extern consvar_t cv_serverinfoscreen;
|
|||
#define KICK_MSG_GRIEF 7
|
||||
#define KICK_MSG_CUSTOM_KICK 8
|
||||
#define KICK_MSG_CUSTOM_BAN 9
|
||||
#define KICK_MSG_SIGFAIL 10
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -505,9 +551,18 @@ extern char connectedservername[MAXSERVERNAME];
|
|||
extern char connectedservercontact[MAXSERVERCONTACT];
|
||||
extern char connectedserverdescription[MAXSERVERDESCRIPTION];
|
||||
|
||||
extern UINT32 ourIP;
|
||||
extern uint8_t lastReceivedKey[MAXNETNODES][MAXSPLITSCREENPLAYERS][PUBKEYLENGTH];
|
||||
extern uint8_t lastSentChallenge[MAXNETNODES][CHALLENGELENGTH];
|
||||
extern uint8_t lastChallengeAll[CHALLENGELENGTH];
|
||||
extern uint8_t lastReceivedSignature[MAXPLAYERS][SIGNATURELENGTH];
|
||||
extern uint8_t knownWhenChallenged[MAXPLAYERS][PUBKEYLENGTH];
|
||||
extern boolean expectChallenge;
|
||||
|
||||
void Command_Ping_f(void);
|
||||
extern tic_t connectiontimeout;
|
||||
extern tic_t jointimeout;
|
||||
extern tic_t freezetimeout[MAXNETNODES];
|
||||
extern UINT16 pingmeasurecount;
|
||||
extern UINT32 realpingtable[MAXPLAYERS];
|
||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
|
|
@ -528,10 +583,25 @@ extern consvar_t cv_joinnextround;
|
|||
|
||||
extern consvar_t cv_discordinvites;
|
||||
|
||||
#ifdef DEVELOP
|
||||
extern consvar_t cv_badjoin;
|
||||
extern consvar_t cv_badtraffic;
|
||||
extern consvar_t cv_badresponse;
|
||||
extern consvar_t cv_noresponse;
|
||||
extern consvar_t cv_nochallenge;
|
||||
extern consvar_t cv_badresults;
|
||||
extern consvar_t cv_noresults;
|
||||
extern consvar_t cv_badtime;
|
||||
extern consvar_t cv_badip;
|
||||
#endif
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||
void D_ClientServerInit(void);
|
||||
|
||||
void GenerateChallenge(uint8_t *buf);
|
||||
shouldsign_t ShouldSignChallenge(uint8_t *message);
|
||||
|
||||
// Initialise the other field
|
||||
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
|
||||
void SendNetXCmdForPlayer(UINT8 playerid, netxcmd_t id, const void *param, size_t nparam);
|
||||
|
|
@ -558,6 +628,8 @@ typedef enum
|
|||
CL_PREPAREHTTPFILES,
|
||||
CL_DOWNLOADHTTPFILES,
|
||||
#endif
|
||||
CL_SENDKEY,
|
||||
CL_WAITCHALLENGE,
|
||||
} cl_mode_t;
|
||||
|
||||
// Create any new ticcmds and broadcast to other players.
|
||||
|
|
@ -673,10 +745,21 @@ void CL_ClearRewinds(void);
|
|||
rewind_t *CL_SaveRewindPoint(size_t demopos);
|
||||
rewind_t *CL_RewindToTime(tic_t time);
|
||||
|
||||
void HandleSigfail(const char *string);
|
||||
|
||||
void DoSayPacket(SINT8 target, UINT8 flags, UINT8 source, char *message);
|
||||
void DoSayPacketFromCommand(SINT8 target, size_t usedargs, UINT8 flags);
|
||||
void SendServerNotice(SINT8 target, char *message);
|
||||
|
||||
// We give clients a chance to verify each other once per race.
|
||||
// When is that challenge sent, and when should clients bail if they don't receive the responses?
|
||||
#define CHALLENGEALL_START (TICRATE*10)
|
||||
#define CHALLENGEALL_KICKUNRESPONSIVE (TICRATE*12)
|
||||
#define CHALLENGEALL_SENDRESULTS (TICRATE*14)
|
||||
#define CHALLENGEALL_CLIENTCUTOFF (TICRATE*16)
|
||||
|
||||
extern uint8_t awaitingChallenge[CHALLENGELENGTH]; // The message the server asked our client to sign when joining;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@
|
|||
#include "m_perfstats.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
#include "monocypher/monocypher.h"
|
||||
#include "stun.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_grandprix.h"
|
||||
#include "k_boss.h"
|
||||
|
|
@ -89,6 +92,10 @@
|
|||
|
||||
#include <tracy/tracy/Tracy.hpp>
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#endif
|
||||
|
||||
// Put hashes here to get them out of header hell.
|
||||
#define ASSET_HASH_SRB2_SRB 0xf3ec1ea4d0eca4a9
|
||||
#define ASSET_HASH_GFX_KART 0xc91b0d43f5ba131f
|
||||
|
|
@ -179,6 +186,10 @@ INT32 eventhead, eventtail;
|
|||
|
||||
boolean dedicated = false;
|
||||
|
||||
// For identity negotiation with netgame servers
|
||||
uint8_t g_public_key[MAXSPLITSCREENPLAYERS][PUBKEYLENGTH];
|
||||
uint8_t g_secret_key[MAXSPLITSCREENPLAYERS][PRIVKEYLENGTH];
|
||||
|
||||
boolean loaded_config = false;
|
||||
|
||||
//
|
||||
|
|
@ -1868,6 +1879,57 @@ void D_SRB2Main(void)
|
|||
ACS_Init();
|
||||
CON_SetLoadingProgress(LOADED_ACSINIT);
|
||||
|
||||
// Read / create RRID key files in srb2home/private_keys
|
||||
// About as obvious as I can make this say DONT SHARE.
|
||||
#define RRIDWARNINGNAME "DO_NOT_SHARE_THESE"
|
||||
#define RRIDWARNINGMESSAGE "This folder contains keys that should not be shared.\nThe base game and mods may use these to keep track of gamedata."
|
||||
static char keyfile[MAXSPLITSCREENPLAYERS][10] = {"bkid1.dat", "bkid2.dat", "bkid3.dat", "bkid4.dat"};
|
||||
INT32 snum;
|
||||
|
||||
for (snum = 0; snum < MAXSPLITSCREENPLAYERS; snum++)
|
||||
{
|
||||
char base_path[MAX_WADPATH];
|
||||
char file[MAX_WADPATH];
|
||||
|
||||
strcpy(base_path, srb2home);
|
||||
strcat(base_path, PATHSEP "private_keys" PATHSEP);
|
||||
M_MkdirEach(base_path, M_PathParts(base_path) - 2, 0755);
|
||||
|
||||
strcpy(file, base_path);
|
||||
strcat(file, keyfile[snum]);
|
||||
|
||||
static uint8_t seed[32];
|
||||
csprng(seed, 32);
|
||||
crypto_eddsa_key_pair(g_secret_key[snum], g_public_key[snum], seed);
|
||||
|
||||
int sk_size = sizeof(g_secret_key[snum]);
|
||||
int pk_size = sizeof(g_public_key[snum]);
|
||||
int totalsize = sk_size + pk_size;
|
||||
|
||||
if (FIL_ReadFileOK(file))
|
||||
{
|
||||
UINT8 *readbuffer = NULL;
|
||||
UINT16 lengthRead = FIL_ReadFile(file, &readbuffer);
|
||||
if (readbuffer == NULL || lengthRead != totalsize)
|
||||
I_Error("Malformed keyfile %d", snum);
|
||||
memcpy(g_secret_key[snum], readbuffer, sk_size);
|
||||
memcpy(g_public_key[snum], readbuffer + sk_size, pk_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *keybuffer = (uint8_t *)malloc(totalsize);
|
||||
memcpy(keybuffer, g_secret_key[snum], sk_size);
|
||||
memcpy(keybuffer + sk_size, g_public_key[snum], pk_size);
|
||||
if (!FIL_WriteFile(file, keybuffer, totalsize))
|
||||
I_Error("Couldn't open key file %d", snum);
|
||||
if (!FIL_WriteFile(va("%s%s",base_path , RRIDWARNINGNAME), RRIDWARNINGMESSAGE, strlen(RRIDWARNINGMESSAGE)))
|
||||
I_Error("Failed to create BKID warning file.");
|
||||
free(keybuffer);
|
||||
}
|
||||
}
|
||||
#undef RRIDWARNINGNAME
|
||||
#undef RRIDWARNINGMESSAGE
|
||||
|
||||
//------------------------------------------------ COMMAND LINE PARAMS
|
||||
|
||||
// this must be done after loading gamedata,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ extern char srb2path[256]; //Alam: SRB2's Home
|
|||
|
||||
const char *D_GetFancyBranchName(void);
|
||||
|
||||
extern uint8_t g_public_key[MAXSPLITSCREENPLAYERS][PUBKEYLENGTH];
|
||||
extern uint8_t g_secret_key[MAXSPLITSCREENPLAYERS][PRIVKEYLENGTH];
|
||||
|
||||
// the infinite loop of D_SRB2Loop() called from win_main for windows version
|
||||
void D_SRB2Loop(void) FUNCNORETURN;
|
||||
|
||||
|
|
|
|||
90
src/d_net.c
90
src/d_net.c
|
|
@ -31,6 +31,7 @@
|
|||
#include "d_main.h" // srb2home
|
||||
#include "stun.h"
|
||||
#include "byteptr.h"
|
||||
#include "monocypher/monocypher.h"
|
||||
|
||||
#include "qs22j.h"
|
||||
|
||||
|
|
@ -81,6 +82,7 @@ boolean (*I_NetOpenSocket)(void) = NULL;
|
|||
boolean (*I_Ban) (INT32 node) = NULL;
|
||||
void (*I_ClearBans)(void) = NULL;
|
||||
const char *(*I_GetNodeAddress) (INT32 node) = NULL;
|
||||
UINT32 (*I_GetNodeAddressInt) (INT32 node) = NULL;
|
||||
const char *(*I_GetBanAddress) (size_t ban) = NULL;
|
||||
const char *(*I_GetBanMask) (size_t ban) = NULL;
|
||||
const char *(*I_GetBanUsername) (size_t ban) = NULL;
|
||||
|
|
@ -90,6 +92,7 @@ boolean (*I_SetBanAddress) (const char *address, const char *mask) = NULL;
|
|||
boolean (*I_SetBanUsername) (const char *username) = NULL;
|
||||
boolean (*I_SetBanReason) (const char *reason) = NULL;
|
||||
boolean (*I_SetUnbanTime) (time_t timestamp) = NULL;
|
||||
boolean (*I_IsExternalAddress) (const void *p) = NULL;
|
||||
bannednode_t *bannednode = NULL;
|
||||
|
||||
|
||||
|
|
@ -470,7 +473,12 @@ static void InitAck(void)
|
|||
ackpak[i].acknum = 0;
|
||||
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
{
|
||||
InitNode(&nodes[i]);
|
||||
|
||||
csprng(lastSentChallenge[i], sizeof(lastSentChallenge[i]));
|
||||
csprng(lastReceivedKey[i], sizeof(lastReceivedKey[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes all acks of a given packet type
|
||||
|
|
@ -547,6 +555,9 @@ void Net_CloseConnection(INT32 node)
|
|||
if (server)
|
||||
SV_AbortLuaFileTransfer(node);
|
||||
I_NetFreeNodenum(node);
|
||||
|
||||
csprng(lastSentChallenge[node], sizeof(lastSentChallenge[node]));
|
||||
csprng(lastReceivedKey[node], sizeof(lastReceivedKey[node]));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -647,12 +658,31 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"TEXTCMD2",
|
||||
"TEXTCMD3",
|
||||
"TEXTCMD4",
|
||||
|
||||
"TELLFILESNEEDED",
|
||||
"MOREFILESNEEDED",
|
||||
|
||||
"CLIENTJOIN",
|
||||
"NODETIMEOUT",
|
||||
|
||||
"LOGIN",
|
||||
"LOGINCHALLENGE",
|
||||
"LOGINAUTH",
|
||||
|
||||
"PING"
|
||||
"PING",
|
||||
|
||||
"SERVERINFOUPDATE",
|
||||
|
||||
"SAY",
|
||||
|
||||
"REQMAPQUEUE",
|
||||
|
||||
"CLIENTKEY",
|
||||
"SERVERCHALLENGE",
|
||||
|
||||
"CHALLENGEALL",
|
||||
"RESPONSEALL",
|
||||
"RESULTSALL"
|
||||
};
|
||||
|
||||
static void DebugPrintpacket(const char *header)
|
||||
|
|
@ -835,6 +865,34 @@ static boolean ShouldDropPacket(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
// Unused because Eidolon correctly pointed out that +512b on every packet was scary.
|
||||
#ifdef SIGNGAMETRAFFIC
|
||||
boolean IsPacketSigned(int packettype)
|
||||
{
|
||||
switch (packettype)
|
||||
{
|
||||
case PT_CLIENTCMD:
|
||||
case PT_CLIENT2CMD:
|
||||
case PT_CLIENT3CMD:
|
||||
case PT_CLIENT4CMD:
|
||||
case PT_CLIENTMIS:
|
||||
case PT_CLIENT2MIS:
|
||||
case PT_CLIENT3MIS:
|
||||
case PT_CLIENT4MIS:
|
||||
case PT_TEXTCMD:
|
||||
case PT_TEXTCMD2:
|
||||
case PT_TEXTCMD3:
|
||||
case PT_TEXTCMD4:
|
||||
case PT_LOGIN:
|
||||
case PT_ASKLUAFILE:
|
||||
case PT_SENDINGLUAFILE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// HSendPacket
|
||||
//
|
||||
|
|
@ -842,6 +900,36 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
|||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
doomcom->datalength = (INT16)(packetlength + BASEPACKETSIZE);
|
||||
|
||||
#ifdef SIGNGAMETRAFFIC
|
||||
if (IsPacketSigned(netbuffer->packettype))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
const void* message = &netbuffer->u;
|
||||
//CONS_Printf("Signing packet type %d of length %d\n", netbuffer->packettype, packetlength);
|
||||
crypto_eddsa_sign(netbuffer->signature[i], g_secret_key[i], message, packetlength);
|
||||
}
|
||||
|
||||
#ifdef DEVELOP
|
||||
if (cv_badtraffic.value)
|
||||
{
|
||||
CV_AddValue(&cv_badtraffic, -1);
|
||||
CONS_Alert(CONS_WARNING, "cv_badtraffic enabled, scrubbing signature from HSendPacket\n");
|
||||
memset(netbuffer->signature, 0, sizeof(netbuffer->signature));
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
//CONS_Printf("NOT signing PT_%d of length %d, it doesn't need to be\n", netbuffer->packettype, packetlength);
|
||||
memset(netbuffer->signature, 0, sizeof(netbuffer->signature));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (node == 0) // Packet is to go back to us
|
||||
{
|
||||
if ((rebound_head+1) % MAXREBOUND == rebound_tail)
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ extern SINT8 nodetoplayer3[MAXNETNODES]; // Say the numplayer for this node if a
|
|||
extern SINT8 nodetoplayer4[MAXNETNODES]; // Say the numplayer for this node if any (splitscreen == 3)
|
||||
extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen
|
||||
extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game
|
||||
extern boolean nodeneedsauth[MAXNETNODES];
|
||||
|
||||
extern boolean serverrunning;
|
||||
|
||||
|
|
@ -72,6 +73,8 @@ void Net_AbortPacketType(UINT8 packettype);
|
|||
void Net_SendAcks(INT32 node);
|
||||
void Net_WaitAllAckReceived(UINT32 timeout);
|
||||
|
||||
boolean IsPacketSigned(int packettype);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -792,6 +792,9 @@ consvar_t cv_nettimeout = CVAR_INIT ("nettimeout", "210", CV_CALL|CV_SAVE, netti
|
|||
consvar_t cv_jointimeout = CVAR_INIT ("jointimeout", "210", CV_CALL|CV_SAVE, nettimeout_cons_t, JoinTimeout_OnChange);
|
||||
consvar_t cv_maxping = CVAR_INIT ("maxdelay", "20", CV_SAVE, CV_Unsigned, NULL);
|
||||
|
||||
consvar_t cv_validate_pubkey= CVAR_INIT ("prevent_duplicate_pubkey", "On", 0, CV_OnOff, NULL); // Validate for duplicate players on Join.
|
||||
|
||||
|
||||
static CV_PossibleValue_t lagless_cons_t[] = {{-1, "Worst"}, {0, "Best"}, {1, "Lagless"}, {0, NULL}};
|
||||
consvar_t cv_lagless = CVAR_INIT ("lagless", "Lagless", CV_SAVE|CV_NETVAR|CV_CALL, lagless_cons_t, Lagless_OnChange);
|
||||
|
||||
|
|
@ -1147,6 +1150,7 @@ void D_RegisterServerCommands(void)
|
|||
COM_AddCommand("ping", Command_Ping_f);
|
||||
CV_RegisterVar(&cv_nettimeout);
|
||||
CV_RegisterVar(&cv_jointimeout);
|
||||
CV_RegisterVar(&cv_validate_pubkey);
|
||||
CV_RegisterVar(&cv_kicktime);
|
||||
CV_RegisterVar(&cv_skipmapcheck);
|
||||
CV_RegisterVar(&cv_sleep);
|
||||
|
|
@ -1348,6 +1352,18 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_netticbuffer);
|
||||
CV_RegisterVar(&cv_mindelay);
|
||||
|
||||
#ifdef DEVELOP
|
||||
CV_RegisterVar(&cv_badjoin);
|
||||
CV_RegisterVar(&cv_badtraffic);
|
||||
CV_RegisterVar(&cv_badresponse);
|
||||
CV_RegisterVar(&cv_noresponse);
|
||||
CV_RegisterVar(&cv_nochallenge);
|
||||
CV_RegisterVar(&cv_badresults);
|
||||
CV_RegisterVar(&cv_noresults);
|
||||
CV_RegisterVar(&cv_badtime);
|
||||
CV_RegisterVar(&cv_badip);
|
||||
#endif
|
||||
|
||||
// HUD
|
||||
CV_RegisterVar(&cv_itemfinder);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@
|
|||
#include "m_misc.h"
|
||||
#include "m_menu.h"
|
||||
#include "filesrch.h"
|
||||
#include "stun.h"
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
|
@ -1339,6 +1341,45 @@ void PT_FileReceived(SINT8 node)
|
|||
SV_EndFileSend(doomcom->remotenode);
|
||||
}
|
||||
|
||||
// Someone knocked on the door with their public key.
|
||||
// Give them a challenge to sign in their PT_CLIENTJOIN.
|
||||
void PT_ClientKey(INT32 node)
|
||||
{
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
clientkey_pak *packet = (void*)&netbuffer->u.clientkey;
|
||||
|
||||
memcpy(lastReceivedKey[node], packet->key, sizeof(lastReceivedKey[node]));
|
||||
|
||||
netbuffer->packettype = PT_SERVERCHALLENGE;
|
||||
GenerateChallenge(lastSentChallenge[node]);
|
||||
|
||||
memcpy(&netbuffer->u.serverchallenge, lastSentChallenge[node], sizeof(serverchallenge_pak));
|
||||
HSendPacket(node, true, 0, sizeof (serverchallenge_pak));
|
||||
|
||||
// Client's not in the server yet, but we still need to lock up the node.
|
||||
// Otherwise, someone else could request a challenge on the same node and trash it.
|
||||
nodeneedsauth[node] = true;
|
||||
freezetimeout[node] = I_GetTime() + jointimeout;
|
||||
}
|
||||
|
||||
void PT_ServerChallenge(INT32 node, cl_mode_t *cl_mode)
|
||||
{
|
||||
if (server && serverrunning && node != servernode)
|
||||
{
|
||||
Net_CloseConnection(node);
|
||||
return;
|
||||
}
|
||||
if (*cl_mode != CL_WAITCHALLENGE)
|
||||
return;
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
memcpy(awaitingChallenge, netbuffer->u.serverchallenge.secret, sizeof(awaitingChallenge));
|
||||
*cl_mode = CL_ASKJOIN;
|
||||
}
|
||||
|
||||
|
||||
static void SendAckPacket(fileack_pak *packet, UINT8 fileid)
|
||||
{
|
||||
size_t packetsize;
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@ boolean CL_CheckDownloadable(void);
|
|||
boolean CL_SendFileRequest(void);
|
||||
void PT_RequestFile(INT32 node);
|
||||
|
||||
void PT_ClientKey(INT32 node);
|
||||
|
||||
void PT_ServerChallenge(INT32 node, cl_mode_t *cl_mode);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LFTNS_NONE, // This node is not connected
|
||||
|
|
|
|||
|
|
@ -891,6 +891,8 @@ struct player_t
|
|||
boolean walltransfered;
|
||||
UINT8 walltransferboost;
|
||||
|
||||
uint8_t public_key[PUBKEYLENGTH];
|
||||
|
||||
#ifdef HWRENDER
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -528,6 +528,12 @@ extern int compuncommitted;
|
|||
|
||||
#define MAX_VOLUME 100
|
||||
|
||||
// Crypto/RRID primitives
|
||||
#define PUBKEYLENGTH 32 // Enforced by Monocypher EdDSA
|
||||
#define PRIVKEYLENGTH 64 // Enforced by Monocypher EdDSA
|
||||
#define SIGNATURELENGTH 64 // Enforced by Monocypher EdDSA
|
||||
#define CHALLENGELENGTH 64 // Servers verify client identity by giving them messages to sign. How long are these messages?
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
#define MASTERSERVER
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -778,6 +778,7 @@ extern consvar_t cv_forceskin; // force clients to use the server's skin
|
|||
extern consvar_t cv_downloading; // allow clients to downloading WADs.
|
||||
extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu
|
||||
extern consvar_t cv_jointimeout;
|
||||
extern consvar_t cv_validate_pubkey;
|
||||
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
||||
extern INT32 serverplayer;
|
||||
extern INT32 adminplayers[MAXPLAYERS];
|
||||
|
|
|
|||
|
|
@ -925,13 +925,14 @@ const char *blancredits[] = {
|
|||
"\"hayaunderscore\" aka \"DeltaKanyx\"",
|
||||
"\"Guilmon35249vr\"",
|
||||
"Vivian \"toaster\" Grannell", // Horncode
|
||||
"AJ \"Tyron\" Martinez", // Horncode, PT_SAY
|
||||
"AJ \"Tyron\" Martinez", // Horncode, PT_SAY, RRID
|
||||
"\"Superstarxalien\"", // Horncode
|
||||
"\"Freaky Mutant Man\"", // Color profiles menu
|
||||
"\"blondedradio\"", // Screen-tracking item roulette, lifted near-directly from RadioRacers
|
||||
"\"Antoine De Grandpré\"", // Zero Deadzone fix
|
||||
"\"Skirlez\"", // PT_SAY packet fixes
|
||||
"Sally \"TehRealSalt\" Cochenour", // Map Buffer rewrite, Voting rewrites
|
||||
"\"Jartha\"", // Various bugfixes, RRID
|
||||
"",
|
||||
"\1Item Design",
|
||||
"\"NepDisk\"",
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
#include "f_dscredits.hpp"
|
||||
#include "strbuf.h"
|
||||
#include "k_vote.h"
|
||||
#include "d_clisrv.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
|
|
@ -3174,6 +3175,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
SINT8 xtralife;
|
||||
|
||||
uint8_t public_key[PUBKEYLENGTH];
|
||||
|
||||
// SRB2kart
|
||||
INT32 itemtype;
|
||||
INT32 itemamount;
|
||||
|
|
@ -3255,6 +3258,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_FLIPCAM));
|
||||
|
||||
memcpy(&public_key, &players[player].public_key, sizeof(public_key));
|
||||
|
||||
// SRB2kart
|
||||
if (betweenmaps || leveltime <= starttime || spectator == true)
|
||||
{
|
||||
|
|
@ -3531,6 +3536,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
K_BotReborn(p);
|
||||
|
||||
memcpy(&p->public_key, &public_key, sizeof(p->public_key));
|
||||
|
||||
if (follower)
|
||||
P_RemoveMobj(follower);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
/// \def MAXPACKETLENGTH
|
||||
/// For use in a LAN
|
||||
#define MAXPACKETLENGTH 2048
|
||||
#define MAXPACKETLENGTH 2063
|
||||
/// \def INETPACKETLENGTH
|
||||
/// For use on the internet
|
||||
#define INETPACKETLENGTH 1450
|
||||
|
|
@ -157,6 +157,7 @@ extern void (*I_NetRegisterHolePunch)(void);
|
|||
extern boolean (*I_Ban) (INT32 node);
|
||||
extern void (*I_ClearBans)(void);
|
||||
extern const char *(*I_GetNodeAddress) (INT32 node);
|
||||
extern UINT32 (*I_GetNodeAddressInt) (INT32 node);
|
||||
extern const char *(*I_GetBanAddress) (size_t ban);
|
||||
extern const char *(*I_GetBanMask) (size_t ban);
|
||||
extern const char *(*I_GetBanUsername) (size_t ban);
|
||||
|
|
@ -166,6 +167,7 @@ extern boolean (*I_SetBanAddress) (const char *address,const char *mask);
|
|||
extern boolean (*I_SetBanUsername) (const char *username);
|
||||
extern boolean (*I_SetBanReason) (const char *reason);
|
||||
extern boolean (*I_SetUnbanTime) (time_t timestamp);
|
||||
extern boolean (*I_IsExternalAddress) (const void *p);
|
||||
|
||||
struct bannednode_t
|
||||
{
|
||||
|
|
|
|||
44
src/i_tcp.c
44
src/i_tcp.c
|
|
@ -457,6 +457,20 @@ static const char *SOCK_GetNodeAddress(INT32 node)
|
|||
return SOCK_AddrToStr(&clientaddress[node]);
|
||||
}
|
||||
|
||||
static UINT32 SOCK_GetNodeAddressInt(INT32 node)
|
||||
{
|
||||
if (nodeconnected[node] && clientaddress[node].any.sa_family == AF_INET)
|
||||
{
|
||||
return clientaddress[node].ip4.sin_addr.s_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error("SOCK_GetNodeAddressInt: Node %d is not IPv4!\n", node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *SOCK_GetBanAddress(size_t ban)
|
||||
{
|
||||
if (ban >= numbans)
|
||||
|
|
@ -549,7 +563,7 @@ static void cleanupnodes(void)
|
|||
|
||||
// Why can't I start at zero?
|
||||
for (j = 1; j < MAXNETNODES; j++)
|
||||
if (!(nodeingame[j] || SendingFile(j)))
|
||||
if (!(nodeingame[j] || nodeneedsauth[j] || SendingFile(j)))
|
||||
nodeconnected[j] = false;
|
||||
}
|
||||
|
||||
|
|
@ -579,7 +593,6 @@ static SINT8 getfreenode(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
void Command_Numnodes(void)
|
||||
{
|
||||
INT32 connected = 0;
|
||||
|
|
@ -617,7 +630,6 @@ void Command_Numnodes(void)
|
|||
"Ingame: %d\n",
|
||||
connected, ingame);
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean hole_punch(ssize_t c)
|
||||
{
|
||||
|
|
@ -1691,6 +1703,30 @@ static void SOCK_ClearBans(void)
|
|||
banned = NULL;
|
||||
}
|
||||
|
||||
// https://github.com/jameds/holepunch/blob/master/holepunch.c#L75
|
||||
static int SOCK_IsExternalAddress (const void *p)
|
||||
{
|
||||
const int a = ((const unsigned char*)p)[0];
|
||||
const int b = ((const unsigned char*)p)[1];
|
||||
|
||||
if (*(const UINT32*)p == (UINT32)~0)/* 255.255.255.255 */
|
||||
return 0;
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case 0:
|
||||
case 10:
|
||||
case 127:
|
||||
return 0;
|
||||
case 172:
|
||||
return (b & ~15) != 16;/* 16 - 31 */
|
||||
case 192:
|
||||
return b != 168;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
boolean I_InitTcpNetwork(void)
|
||||
{
|
||||
char serverhostname[255];
|
||||
|
|
@ -1782,6 +1818,7 @@ boolean I_InitTcpNetwork(void)
|
|||
I_Ban = SOCK_Ban;
|
||||
I_ClearBans = SOCK_ClearBans;
|
||||
I_GetNodeAddress = SOCK_GetNodeAddress;
|
||||
I_GetNodeAddressInt = SOCK_GetNodeAddressInt;
|
||||
I_GetBanAddress = SOCK_GetBanAddress;
|
||||
I_GetBanMask = SOCK_GetBanMask;
|
||||
I_GetBanUsername = SOCK_GetBanUsername;
|
||||
|
|
@ -1791,6 +1828,7 @@ boolean I_InitTcpNetwork(void)
|
|||
I_SetBanUsername = SOCK_SetBanUsername;
|
||||
I_SetBanReason = SOCK_SetBanReason;
|
||||
I_SetUnbanTime = SOCK_SetUnbanTime;
|
||||
I_IsExternalAddress = SOCK_IsExternalAddress;
|
||||
bannednode = SOCK_bannednode;
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // hook_cmd_running errors
|
||||
#include "m_misc.h" // GetPrettyRRID
|
||||
|
||||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
|
|
@ -465,7 +466,8 @@ static int lib_lenLocalplayers(lua_State *L)
|
|||
X(recoverydashcharge) \
|
||||
X(recoverydash) \
|
||||
X(tripwireunstuck) \
|
||||
X(bumpunstuck)
|
||||
X(bumpunstuck) \
|
||||
X(public_key)
|
||||
|
||||
enum player_e
|
||||
{
|
||||
|
|
@ -1194,6 +1196,9 @@ static int player_get(lua_State *L)
|
|||
case player_ping:
|
||||
lua_pushinteger(L, playerpingtable[( plr - players )]);
|
||||
break;
|
||||
case player_public_key:
|
||||
lua_pushstring(L, GetPrettyRRID(plr->public_key, false));
|
||||
break;
|
||||
case player_packetloss:
|
||||
lua_pushinteger(L, playerpacketlosstable[plr - players]);
|
||||
break;
|
||||
|
|
@ -1949,8 +1954,7 @@ static int player_set(lua_State *L)
|
|||
case player_botvars:
|
||||
return NOSET;
|
||||
case player_jointime:
|
||||
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
return NOSET;
|
||||
case player_spectatorreentry:
|
||||
plr->spectatorreentry = (tic_t)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2589,3 +2589,27 @@ int M_RoundUp(double number)
|
|||
|
||||
return (int)number;
|
||||
}
|
||||
|
||||
static char rrid_buf[256];
|
||||
|
||||
char *GetPrettyRRID(const unsigned char *bin, boolean brief)
|
||||
{
|
||||
size_t i;
|
||||
size_t len = PUBKEYLENGTH;
|
||||
|
||||
if (brief)
|
||||
len = 8;
|
||||
|
||||
if (bin == NULL || len == 0)
|
||||
return NULL;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
rrid_buf[i*2] = "0123456789ABCDEF"[bin[i] >> 4];
|
||||
rrid_buf[i*2+1] = "0123456789ABCDEF"[bin[i] & 0x0F];
|
||||
}
|
||||
|
||||
rrid_buf[len*2] = '\0';
|
||||
|
||||
return rrid_buf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@ boolean M_IsStringEmpty(const char *s);
|
|||
|
||||
int M_RoundUp(double number);
|
||||
|
||||
char *GetPrettyRRID(const unsigned char *bin, boolean brief);
|
||||
|
||||
#include "w_wad.h"
|
||||
extern char configfile[MAX_WADPATH];
|
||||
|
||||
|
|
|
|||
4
src/monocypher/CMakeLists.txt
Normal file
4
src/monocypher/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
target_sources(BLANKART PRIVATE
|
||||
monocypher.c
|
||||
monocypher.h
|
||||
)
|
||||
2938
src/monocypher/monocypher.c
Normal file
2938
src/monocypher/monocypher.c
Normal file
File diff suppressed because it is too large
Load diff
321
src/monocypher/monocypher.h
Normal file
321
src/monocypher/monocypher.h
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
// Monocypher version 4.0.0
|
||||
//
|
||||
// This file is dual-licensed. Choose whichever licence you want from
|
||||
// the two licences listed below.
|
||||
//
|
||||
// The first licence is a regular 2-clause BSD licence. The second licence
|
||||
// is the CC-0 from Creative Commons. It is intended to release Monocypher
|
||||
// to the public domain. The BSD licence serves as a fallback option.
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
|
||||
//
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017-2019, Loup Vaillant
|
||||
// All rights reserved.
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
// Written in 2017-2019 by Loup Vaillant
|
||||
//
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along
|
||||
// with this software. If not, see
|
||||
// <https://creativecommons.org/publicdomain/zero/1.0/>
|
||||
|
||||
#ifndef MONOCYPHER_H
|
||||
#define MONOCYPHER_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef MONOCYPHER_CPP_NAMESPACE
|
||||
namespace MONOCYPHER_CPP_NAMESPACE {
|
||||
#elif defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Constant time comparisons
|
||||
// -------------------------
|
||||
|
||||
// Return 0 if a and b are equal, -1 otherwise
|
||||
int crypto_verify16(const uint8_t a[16], const uint8_t b[16]);
|
||||
int crypto_verify32(const uint8_t a[32], const uint8_t b[32]);
|
||||
int crypto_verify64(const uint8_t a[64], const uint8_t b[64]);
|
||||
|
||||
|
||||
// Erase sensitive data
|
||||
// --------------------
|
||||
void crypto_wipe(void *secret, size_t size);
|
||||
|
||||
|
||||
// Authenticated encryption
|
||||
// ------------------------
|
||||
void crypto_aead_lock(uint8_t *cipher_text,
|
||||
uint8_t mac [16],
|
||||
const uint8_t key [32],
|
||||
const uint8_t nonce[24],
|
||||
const uint8_t *ad, size_t ad_size,
|
||||
const uint8_t *plain_text, size_t text_size);
|
||||
int crypto_aead_unlock(uint8_t *plain_text,
|
||||
const uint8_t mac [16],
|
||||
const uint8_t key [32],
|
||||
const uint8_t nonce[24],
|
||||
const uint8_t *ad, size_t ad_size,
|
||||
const uint8_t *cipher_text, size_t text_size);
|
||||
|
||||
// Authenticated stream
|
||||
// --------------------
|
||||
typedef struct {
|
||||
uint64_t counter;
|
||||
uint8_t key[32];
|
||||
uint8_t nonce[8];
|
||||
} crypto_aead_ctx;
|
||||
|
||||
void crypto_aead_init_x(crypto_aead_ctx *ctx,
|
||||
const uint8_t key[32], const uint8_t nonce[24]);
|
||||
void crypto_aead_init_djb(crypto_aead_ctx *ctx,
|
||||
const uint8_t key[32], const uint8_t nonce[8]);
|
||||
void crypto_aead_init_ietf(crypto_aead_ctx *ctx,
|
||||
const uint8_t key[32], const uint8_t nonce[12]);
|
||||
|
||||
void crypto_aead_write(crypto_aead_ctx *ctx,
|
||||
uint8_t *cipher_text,
|
||||
uint8_t mac[16],
|
||||
const uint8_t *ad , size_t ad_size,
|
||||
const uint8_t *plain_text, size_t text_size);
|
||||
int crypto_aead_read(crypto_aead_ctx *ctx,
|
||||
uint8_t *plain_text,
|
||||
const uint8_t mac[16],
|
||||
const uint8_t *ad , size_t ad_size,
|
||||
const uint8_t *cipher_text, size_t text_size);
|
||||
|
||||
|
||||
// General purpose hash (BLAKE2b)
|
||||
// ------------------------------
|
||||
|
||||
// Direct interface
|
||||
void crypto_blake2b(uint8_t *hash, size_t hash_size,
|
||||
const uint8_t *message, size_t message_size);
|
||||
|
||||
void crypto_blake2b_keyed(uint8_t *hash, size_t hash_size,
|
||||
const uint8_t *key, size_t key_size,
|
||||
const uint8_t *message, size_t message_size);
|
||||
|
||||
// Incremental interface
|
||||
typedef struct {
|
||||
// Do not rely on the size or contents of this type,
|
||||
// for they may change without notice.
|
||||
uint64_t hash[8];
|
||||
uint64_t input_offset[2];
|
||||
uint64_t input[16];
|
||||
size_t input_idx;
|
||||
size_t hash_size;
|
||||
} crypto_blake2b_ctx;
|
||||
|
||||
void crypto_blake2b_init(crypto_blake2b_ctx *ctx, size_t hash_size);
|
||||
void crypto_blake2b_keyed_init(crypto_blake2b_ctx *ctx, size_t hash_size,
|
||||
const uint8_t *key, size_t key_size);
|
||||
void crypto_blake2b_update(crypto_blake2b_ctx *ctx,
|
||||
const uint8_t *message, size_t message_size);
|
||||
void crypto_blake2b_final(crypto_blake2b_ctx *ctx, uint8_t *hash);
|
||||
|
||||
|
||||
// Password key derivation (Argon2)
|
||||
// --------------------------------
|
||||
#define CRYPTO_ARGON2_D 0
|
||||
#define CRYPTO_ARGON2_I 1
|
||||
#define CRYPTO_ARGON2_ID 2
|
||||
|
||||
typedef struct {
|
||||
uint32_t algorithm; // Argon2d, Argon2i, Argon2id
|
||||
uint32_t nb_blocks; // memory hardness, >= 8 * nb_lanes
|
||||
uint32_t nb_passes; // CPU hardness, >= 1 (>= 3 recommended for Argon2i)
|
||||
uint32_t nb_lanes; // parallelism level (single threaded anyway)
|
||||
} crypto_argon2_config;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t *pass;
|
||||
const uint8_t *salt;
|
||||
uint32_t pass_size;
|
||||
uint32_t salt_size; // 16 bytes recommended
|
||||
} crypto_argon2_inputs;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t *key; // may be NULL if no key
|
||||
const uint8_t *ad; // may be NULL if no additional data
|
||||
uint32_t key_size; // 0 if no key (32 bytes recommended otherwise)
|
||||
uint32_t ad_size; // 0 if no additional data
|
||||
} crypto_argon2_extras;
|
||||
|
||||
extern const crypto_argon2_extras crypto_argon2_no_extras;
|
||||
|
||||
void crypto_argon2(uint8_t *hash, uint32_t hash_size, void *work_area,
|
||||
crypto_argon2_config config,
|
||||
crypto_argon2_inputs inputs,
|
||||
crypto_argon2_extras extras);
|
||||
|
||||
|
||||
// Key exchange (X-25519)
|
||||
// ----------------------
|
||||
|
||||
// Shared secrets are not quite random.
|
||||
// Hash them to derive an actual shared key.
|
||||
void crypto_x25519_public_key(uint8_t public_key[32],
|
||||
const uint8_t secret_key[32]);
|
||||
void crypto_x25519(uint8_t raw_shared_secret[32],
|
||||
const uint8_t your_secret_key [32],
|
||||
const uint8_t their_public_key [32]);
|
||||
|
||||
// Conversion to EdDSA
|
||||
void crypto_x25519_to_eddsa(uint8_t eddsa[32], const uint8_t x25519[32]);
|
||||
|
||||
// scalar "division"
|
||||
// Used for OPRF. Be aware that exponential blinding is less secure
|
||||
// than Diffie-Hellman key exchange.
|
||||
void crypto_x25519_inverse(uint8_t blind_salt [32],
|
||||
const uint8_t private_key[32],
|
||||
const uint8_t curve_point[32]);
|
||||
|
||||
// "Dirty" versions of x25519_public_key().
|
||||
// Use with crypto_elligator_rev().
|
||||
// Leaks 3 bits of the private key.
|
||||
void crypto_x25519_dirty_small(uint8_t pk[32], const uint8_t sk[32]);
|
||||
void crypto_x25519_dirty_fast (uint8_t pk[32], const uint8_t sk[32]);
|
||||
|
||||
|
||||
// Signatures
|
||||
// ----------
|
||||
|
||||
// EdDSA with curve25519 + BLAKE2b
|
||||
void crypto_eddsa_key_pair(uint8_t secret_key[64],
|
||||
uint8_t public_key[32],
|
||||
uint8_t seed[32]);
|
||||
void crypto_eddsa_sign(uint8_t signature [64],
|
||||
const uint8_t secret_key[64],
|
||||
const uint8_t *message, size_t message_size);
|
||||
int crypto_eddsa_check(const uint8_t signature [64],
|
||||
const uint8_t public_key[32],
|
||||
const uint8_t *message, size_t message_size);
|
||||
|
||||
// Conversion to X25519
|
||||
void crypto_eddsa_to_x25519(uint8_t x25519[32], const uint8_t eddsa[32]);
|
||||
|
||||
// EdDSA building blocks
|
||||
void crypto_eddsa_trim_scalar(uint8_t out[32], const uint8_t in[32]);
|
||||
void crypto_eddsa_reduce(uint8_t reduced[32], const uint8_t expanded[64]);
|
||||
void crypto_eddsa_mul_add(uint8_t r[32],
|
||||
const uint8_t a[32],
|
||||
const uint8_t b[32],
|
||||
const uint8_t c[32]);
|
||||
void crypto_eddsa_scalarbase(uint8_t point[32], const uint8_t scalar[32]);
|
||||
int crypto_eddsa_check_equation(const uint8_t signature[64],
|
||||
const uint8_t public_key[32],
|
||||
const uint8_t h_ram[32]);
|
||||
|
||||
|
||||
// Chacha20
|
||||
// --------
|
||||
|
||||
// Specialised hash.
|
||||
// Used to hash X25519 shared secrets.
|
||||
void crypto_chacha20_h(uint8_t out[32],
|
||||
const uint8_t key[32],
|
||||
const uint8_t in [16]);
|
||||
|
||||
// Unauthenticated stream cipher.
|
||||
// Don't forget to add authentication.
|
||||
uint64_t crypto_chacha20_djb(uint8_t *cipher_text,
|
||||
const uint8_t *plain_text,
|
||||
size_t text_size,
|
||||
const uint8_t key[32],
|
||||
const uint8_t nonce[8],
|
||||
uint64_t ctr);
|
||||
uint32_t crypto_chacha20_ietf(uint8_t *cipher_text,
|
||||
const uint8_t *plain_text,
|
||||
size_t text_size,
|
||||
const uint8_t key[32],
|
||||
const uint8_t nonce[12],
|
||||
uint32_t ctr);
|
||||
uint64_t crypto_chacha20_x(uint8_t *cipher_text,
|
||||
const uint8_t *plain_text,
|
||||
size_t text_size,
|
||||
const uint8_t key[32],
|
||||
const uint8_t nonce[24],
|
||||
uint64_t ctr);
|
||||
|
||||
|
||||
// Poly 1305
|
||||
// ---------
|
||||
|
||||
// This is a *one time* authenticator.
|
||||
// Disclosing the mac reveals the key.
|
||||
// See crypto_lock() on how to use it properly.
|
||||
|
||||
// Direct interface
|
||||
void crypto_poly1305(uint8_t mac[16],
|
||||
const uint8_t *message, size_t message_size,
|
||||
const uint8_t key[32]);
|
||||
|
||||
// Incremental interface
|
||||
typedef struct {
|
||||
// Do not rely on the size or contents of this type,
|
||||
// for they may change without notice.
|
||||
uint8_t c[16]; // chunk of the message
|
||||
size_t c_idx; // How many bytes are there in the chunk.
|
||||
uint32_t r [4]; // constant multiplier (from the secret key)
|
||||
uint32_t pad[4]; // random number added at the end (from the secret key)
|
||||
uint32_t h [5]; // accumulated hash
|
||||
} crypto_poly1305_ctx;
|
||||
|
||||
void crypto_poly1305_init (crypto_poly1305_ctx *ctx, const uint8_t key[32]);
|
||||
void crypto_poly1305_update(crypto_poly1305_ctx *ctx,
|
||||
const uint8_t *message, size_t message_size);
|
||||
void crypto_poly1305_final (crypto_poly1305_ctx *ctx, uint8_t mac[16]);
|
||||
|
||||
|
||||
// Elligator 2
|
||||
// -----------
|
||||
|
||||
// Elligator mappings proper
|
||||
void crypto_elligator_map(uint8_t curve [32], const uint8_t hidden[32]);
|
||||
int crypto_elligator_rev(uint8_t hidden[32], const uint8_t curve [32],
|
||||
uint8_t tweak);
|
||||
|
||||
// Easy to use key pair generation
|
||||
void crypto_elligator_key_pair(uint8_t hidden[32], uint8_t secret_key[32],
|
||||
uint8_t seed[32]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MONOCYPHER_H
|
||||
|
|
@ -860,6 +860,8 @@ static void P_NetSyncPlayers(savebuffer_t *save)
|
|||
|
||||
SYNC(players[i].itemusecooldown);
|
||||
SYNC(players[i].itemusecooldownmax);
|
||||
|
||||
P_SyncMem(save, players[i].public_key, PUBKEYLENGTH);
|
||||
}
|
||||
TracyCZoneEnd(__zone);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ STUN_node (void)
|
|||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
csprng
|
||||
(
|
||||
void * const buffer,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ extern "C" {
|
|||
|
||||
typedef void (*stun_callback_t)(UINT32 address);
|
||||
|
||||
void csprng (void * const buffer, const size_t size);
|
||||
|
||||
void STUN_bind (stun_callback_t);
|
||||
boolean STUN_got_response (const char * const buffer, const size_t size);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,11 @@ TYPEDEF (rewind_t);
|
|||
TYPEDEF (netinfo_pak);
|
||||
TYPEDEF (say_pak);
|
||||
TYPEDEF (reqmapqueue_pak);
|
||||
TYPEDEF (clientkey_pak);
|
||||
TYPEDEF (serverchallenge_pak);
|
||||
TYPEDEF (challengeall_pak);
|
||||
TYPEDEF (responseall_pak);
|
||||
TYPEDEF (resultsall_pak);
|
||||
|
||||
// d_event.h
|
||||
TYPEDEF (event_t);
|
||||
|
|
|
|||
Loading…
Reference in a new issue