Commits

M6 KVM committed ba5991d

Entire changeset 0.0.19 -> 0.1.0

Comments (0)

Files changed (480)

File contents unchanged.

 
 Total Konfuzion <tk@digiserv.net>
 OC32 client
+
+Ken Upright <meanmogitta@yahoo.com>
+Sound effects and glpyhs for Oberchatten
 at http://www.daybologic.co.uk/overchat/ChangeLog.txt
 at least every server release.
 
+
+0.1.0
+-----
+DDRP: Disable DPCRTLMM log by default
+DDRP: Remove sending and getting of formatted IPs directly from the network
+DDRP: Add 'message2' Blake text based sub-protocol packet
+DDRP: Fix explicit calls to gmake from makefiles, always use $(TMAKE)
+DDRP: Fix crash in daybodep during build process
+DDRP: Fix autodependencies
+DDRP: Database uses checksums on records
+DDRP: DB1 (.ini) legacy code retired
+DDRP: blakedb_GetUserInfo() protected against NULL parameters
+DDRP: Warn about Blake database handle leaks
+DDRP: Add blakeFileTruncated error
+DDRP: Add db2fix tool to fix corrupt databases.
+DDRP: Increase OVERCHAT_CONNECT_AUTH_MAXTIME to 60
+DDRP: Add message cipher code and reserved field to IM messages
+DDRP: Fix mrproper rule not to break stuff
+DDRP: Configure now supports an --interactive mode
+DDRP: Support for counting number of registered users (local)
+DDRP: Removed convdb2 tool
+DDRP: Add crack, countregusers & md5pwd helper tools
+DDRP: Add blake_hashes.c and testbed component for it
+DDRP: Removed redundant use of current time in displaying title
+DDRP: Add double MD5 one way hash secure authentication, mandatory
+
 0.0.19
 ------
 DDRP: Ensure ocquery does not allow gods to kill higher level users
 # OverChat master build for for private source tree
-# Maintainer: <Overlord@DayboLogic.co.uk>
+# Maintainer: <www.daybologic.co.uk/mailddrp>
 # Please report problems with _FULL_ output, using the script utility
 
 include MasterMake.gnu
 	@echo "                                                "
 	@echo "------------------------------------------------"
 	@echo
+	cd ads && $(TMAKE) -f $(THISFILE) depend
 	cd blake && $(TMAKE) -f $(THISFILE) depend
 	cd buildnum && $(TMAKE) -f $(THISFILE) depend
 	cd buildtimer && $(TMAKE) -f $(THISFILE) depend
+	cd c2raw && $(TMAKE) -f $(THISFILE) depend
 	cd cgi-bin && $(TMAKE) -f $(THISFILE) depend
 	cd clients && $(TMAKE) -f $(THISFILE) depend
+	cd committee && $(TMAKE) -f $(THISFILE) depend
+	cd configure && $(TMAKE) -f $(THISFILE) depend
 	cd daybodep && $(TMAKE) -f Makefile_oc.gnu depend
+	cd daybocrypt && $(TMAKE) depend
+	cd db2fix && $(TMAKE) -f Makefile.gnu depend
 	cd dlini && $(TMAKE) -f $(THISFILE) depend
 	cd dpcrtlmm && $(TMAKE) -f $(THISFILE) depend
 	cd mailall && $(TMAKE) -f $(THISFILE) depend
+	cd NetBuffer && $(TMAKE) -f $(THISFILE) depend
+	cd occdtk && $(TMAKE) -f $(THISFILE) depend
+	cd ocquery && $(TMAKE) depend
 	cd raw2c && $(TMAKE) -f $(THISFILE) depend
 	cd rmw32 && $(TMAKE) -f $(THISFILE) depend
 	cd src && $(TMAKE) -f $(THISFILE) depend
 	cd testbed && $(TMAKE) -f $(THISFILE) depend
+	cd tools && $(TMAKE) -f $(THISFILE) depend
 	cd watchproc && $(TMAKE) -f $(THISFILE) depend
 
 basictools:
 	@echo "------------------------------------------------"
 	@echo "                                                "
 	@echo "  Stage 2                                       "
-	@echo "  Basic tools                                   "
+	@echo "  Essential tools                               "
 	@echo "                                                "
 	@echo "------------------------------------------------"
 	@echo
 	cd blake \
 	&& $(TMAKE) -f $(THISFILE)
 
-libs : dlini_lib
+libs : dlini_lib daybocrypt_lib
 
 dlini_lib:
 	cd dlini && $(TMAKE) -f $(THISFILE)
 
+daybocrypt_lib:
+	cd daybocrypt && $(TMAKE) run
+
 overchat : overchatd
 
 overchatd : src/$(THISFILE) src/*$(H) src/*$(C)
 	cd testbed && $(TMAKE) -f $(THISFILE) run
 
 mrproper : clean
-	-rm -rf .depend .resp
+	-rm -rf .resp
 
-clean : testbed_clean advtools_clean supdae_clean clients_clean cgi_clean overchat_clean blake_lib_clean dlini_lib_clean memory_debugger_clean basictools_clean daybodep_clean
+clean : testbed_clean advtools_clean supdae_clean clients_clean cgi_clean overchat_clean blake_lib_clean dlini_lib_clean memory_debugger_clean daybocrypt_clean basictools_clean daybodep_clean
 	-rm -f core overchatd.core
 
 overchat_clean:
 dlini_lib_clean:
 	cd dlini ; $(TMAKE) -f $(THISFILE) clean
 
+daybocrypt_clean:
+	cd daybocrypt ; $(TMAKE) clean
+
 basictools_clean:
 	cd buildnum ; $(TMAKE) -f $(THISFILE) clean
 	cd raw2c ; $(TMAKE) -f $(THISFILE) clean
 	cd dpcrtlmm \
 	&& $(TMAKE) -f $(THISFILE) config \
 	&& ./config --disable-threads \
-                    --enable-debug \
-                    --enable-log \
+                    --disable-debug \
+                    --disable-log \
                     --maxport \
-	&& $(TMAKE) -f $(THISFILE)
+	&& $(TMAKE) -f $(THISFILE) example
 
 memory_debugger_clean:
 	cd dpcrtlmm ; $(TMAKE) -f $(THISFILE) clean
 	@echo "------------------------------------------------"
 	@echo "                                                "
 	@echo "  Stage 9                                       "
-	@echo "  Advanced tools                                "
+	@echo "  Supplementry tools                            "
 	@echo "                                                "
 	@echo "------------------------------------------------"
-	cd convdb2 && $(TMAKE) -f $(THISFILE) all
+	cd db2fix && $(TMAKE) -f $(THISFILE) all
+	cd tools && $(TMAKE) -f $(THISFILE) all
 
 advtools_clean:
-	cd convdb2 && $(TMAKE) -f $(THISFILE) clean
+	cd db2fix && $(TMAKE) -f $(THISFILE) clean
+	cd tools && $(TMAKE) -f $(THISFILE) clean
 
 _testbed:
 	@echo "------------------------------------------------"

File contents unchanged.

NetBuffer/Makefile.gnu

+# Placeholder Makefile for basic tree operations required for every
+# branch.  Should any new operations be needed, add dummies here.
+
+all:
+
+depend:
+	@echo "No dependencies for this branch"

NetBuffer/NetBuffer.diff

---- NetBuffer.cpp~	Sat May  4 23:09:12 2002
-+++ NetBuffer.cpp	Tue May 14 05:58:42 2002
-@@ -234,9 +234,7 @@
-     else { /* Already got length, read packet */
-       /* Read in up to the the packet size, if the length is malicious or
-       corrupt cap at size of the RX buffer. */
--      int maxRead;
--      expectSz = expectSz % ((OVERCHAT_NET_PKTMAXSZ-2)+1); /* Cap packet length field to what we can handle */
--      maxRead = BLAKE_MIN((expectSz+2) - marker, sizeof(buff));
-+      int maxRead = BLAKE_MIN((expectSz+2) - marker, sizeof(buff));
-        /* Do some error/warning checking for diagnostics and for safety */
-       if ( !expectSz ) goto setandunlock; /* Get out if no packet */
-       if ( expectSz < 2 ) { /* Not enough room to have even sent the length */
-@@ -322,7 +320,7 @@
-     /* Now do a swap */
-     sz = network_NetToHostShort((unsigned short int)sz);
-     /* Now cap */
--    sz = sz % ((OVERCHAT_NET_PKTMAXSZ-2)+1);
-+    sz = BLAKE_MIN(sz, OVERCHAT_NET_PKTMAXSZ - 2);
-   }
- #ifdef DEBUG
-   printf("DEBUG: sz==%u  TESTRAW(%c%c)\n", sz, test[0], test[1]);

File contents unchanged.

+# Placeholder Makefile for basic tree operations required for every
+# branch.  Should any new operations be needed, add dummies here.
+
+all:
+
+depend:
+	@echo "No dependencies for this branch"

File contents unchanged.

File contents unchanged.

File contents unchanged.

File contents unchanged.

File contents unchanged.

File contents unchanged.

File contents unchanged.

blake/Makefile.gnu

 # . is a backward reference for those files to get to Blake headers
 # ../dpcrtlmm is because Blake relies on DPCRTLMM for debugging.
 # ../dlini is for the Daybo Logic INI support library
+# ../daybocrypt is for the cryptographic features
 
 ifdef WITH_PTH
 THREAD_LIBRARY=$(PTH_LIB)
 THREAD_PTHINCLUDE=
 endif
 
-IPATH=-I../src -I. -I../dpcrtlmm -I../dlini $(THREAD_PTHINCLUDE)
+IPATH=-I../src -I. -I../dpcrtlmm -I../dlini $(THREAD_PTHINCLUDE) -I../daybocrypt
 CFLAGS=$(MASTER_CFLAGS) $(IPATH)
-LFLAGS=$(MASTER_LFLAGS) ../libblake.a ../dpcrtlmm/libdpcrtlmm.a ../dlini/libdlini.a $(THREAD_LIBRARY)
+LFLAGS=$(MASTER_LFLAGS) ../libblake$(LIB) ../dpcrtlmm/libdpcrtlmm$(LIB) ../dlini/libdlini$(LIB) $(THREAD_LIBRARY) ../daybocrypt/libdaybocrypt$(LIB)
 COMPILE=$(CC) $(CFLAGS)
 
-#BLAKEDB_R2 is the new binary database revsion 2 which is a lot faster
-#than the old ini system
-ifdef BLAKEDB_R2
-BLAKEDBO=blakedb2.o
-else
-BLAKEDBO=blakedb1.o
-endif
-
 OBJECTS=blake$(O) \
         blake_cb$(O) \
         blake_fastqueue$(O) \
         blake_safeallocate$(O) \
         blake_panic$(O) \
         blake_debugtables$(O) \
-        $(BLAKEDBO) \
+        blake_hashes$(O) \
+        blakedb$(O) \
         criticalinteger$(O) \
         recursivemutant$(O)
 
 blake_lib : ../libblake.a
 
 blake_res:
-	cd res ; gmake -f $(THISFILE)
+	cd res ; $(TMAKE) -f $(THISFILE)
 
 queuetest : queuetest$(O) ../libblake$(LIB) ../dlini/libdlini$(LIB)
 	@echo Linking queuetest
 	@echo Linking dllclient
 	@$(CC) -odllclient dllclient$(O) $(LFLAGS)
 
-../libblake$(LIB) : $(OBJECTS) blake_res
-	@echo Building archive ../libblake$(LIB)
-	@ar cru ../libblake$(LIB) $(OBJECTS) $(RESFILES)
+../libblake$(LIB) : $(OBJECTS) blake_res    # Unfortunately this means libblake.a is _always_ rebuilt
+	#@echo Building archive ../libblake$(LIB)
+	ar cru ../libblake$(LIB) $(OBJECTS) $(RESFILES)
 
 
 # Automatic rule for all the rest of the C files in Blake
 	-$(RM) ../libblake$(LIB)
 	-$(RM) queuetest queuetest$(O)
 	-$(RM) dllclient dllclient$(O)
-	cd res ; gmake -f $(THISFILE) clean
+	cd res ; $(TMAKE) -f $(THISFILE) clean
 
 depend:
 	$(DIR) *$(C) *$(H) *.rh > .resp

File contents unchanged.

File contents unchanged.

File contents unchanged.

   Maintainer:
   David Duncan Ross Palmer <http://www.daybologic.co.uk/mailddrp>
 
-  Portions of the protocol were designed by
-  Total Konfuzion <TotalK@DayboLogic.co.uk>
-
   Disassembly of the internal workings of the protocol are prohibited.
 */
 
 #define OVERCHAT_NET_RXSZ (OVERCHAT_NET_TXSZ)
 
 /*
+  We don't want users of Blake to be dependent on hashing hardcoded lengths
+  in the DayboCrypt library incase the source is not available to them,
+  therefore Blake independently hard codes the well known, supported hash
+  lengths in bytes.  These don't conflict with DayboCrypt and I recommend
+  you use these if your code depends on Blake and not DayboCrypt's header.
+  These values do not change, anybody caught changing them will be in trouble.
+*/
+#define BLAKE_MD5HASHLEN (16) /* 128-bit hash */
+
+/*
   C and C++ mixing macros.  For any function which is a C callable function
   existing in a C++ module, OVERCHAT_C_IN_CPP must be placed _before_ the
   declaration.  In C++, void in a prototype is not expected, in C it is.
   blakeDbAccessWrite,         /* Unable to write to the database at this time */
   blakeDbAccessRead,          /* Unable to access the database (read) */
   blakeExclusiveFileFailure,  /* Can't open a file for exclusive access */
-  blakeBadSAHandle            /* The SafeAllocator handle is unrecognised */
+  blakeBadSAHandle,           /* The SafeAllocator handle is unrecognised */
+  blakeDbRecordCorrupt,       /* Database record is corrupt (checksum) */
+  blakeFileTruncated          /* File is too short! */
 };
 
 /*
   bccchum_add,               /* Adds a chum to keep in contact with */
   bccchum_remove,            /* Removes a chum, terrible pitty */
   bccidle,                   /* Come out of or enter an idle state */
-  bccisonline                /* Test if a given user is online */
+  bccisonline,               /* Test if a given user is online */
+  bccmessage2                /* Sub-protocol message */
 };
 
 enum blakeErrorCodes {    /* These error are returned with serverCodes::goterror type packets */
   blrRespect,                /* OverChat is closed as a mark of respect for the dead */
   blrHoliday,                /* OverChat does not operate on this holiday */
   blr911Respect,             /* OverChat closed on aniversary of terrorist attack on USA */
-  blrDatabaseFailure         /* The server can't access the database */
+  blrDatabaseFailure,        /* The server can't access the database */
+  blrRecordCorrupt,          /* Return this if possible (ie. record not so corrupt we couldn't get the username) */
+  blrUnknownHash             /* The hash used to give the password to the server cannot be handled/unknown */
+};
+
+enum blakeCipherID {
+  bcidPlain,                 /* Plaintext, no cipher */
+  bcidCaesar,                /* Caesar's Cipher */
+  bcidTKModulator,           /* TK's modulator cipher */
+  bcidFixedStreamSub         /* DDRP's fixed stream substitution cipher */
+};
+
+enum blakeHashType {
+  bhtMd5,                    /* Normal, attackable MD5 hash */
+  bhtDoubleMd5,              /* Double hash, will take months to crack */
+  bhtSha,                    /* Secure Hash Algorithm (will support later) */
+  bhtSha1                    /* PGP SHA1 */
 };
 
 /*
 
 struct blakeChallenge {
   blake_word16_t secs; /* Maximum time for client to AUTH before client is killed */
-  blake_word32_t reserved; /* Send zero for now */
+  blake_word32_t _reserved; /* Send zero for now */
+  blake_byte_t rnum[16]; /* MD5 hash of a gaurenteed random number */
 };
 
 struct blakeGotError {
 /* -------- */
 
 struct blakeLogin {                           /* Client side */
-  blake_byte_t username[OVERCHAT_NICK_LIMIT]; /* Your username, use padding, no NULL terminator is full length */
-  blake_byte_t password[OVERCHAT_PASS_LIMIT]; /* Your password (sorry it's plaintext at the moment).  Same format as above */
+  blake_byte_t _username[OVERCHAT_NICK_LIMIT]; /* Your username, use padding, no NULL terminator is full length */
+  blake_word8_t hashtype; /* enum blakeHashType */
+  blake_byte_t passworddigest[256]; /* Large space to allow expansion of hashtype */
   blake_byte_t language; /* This will be supported in the future, at the moment it's zero, meaning English (of course) */
 };
 
 
 struct blakeMessage {
   blake_byte_t username[OVERCHAT_NICK_LIMIT];
+  blake_word8_t cipher; /* 0=plaintext, anything else is a code identifying a cipher */
+  blake_byte_t reserved[128]; /* Should I need to add anything else */
   /* message follows as extended packet */
 };
 
+struct blakeMessage2 {
+  blake_word8_t reserved0;
+  blake_word8_t reserved1;
+  blake_word8_t reserved2;
+  /* Message follows as extended packet */
+};
+
 struct blakeChatMsg {
   blake_byte_t chatname[OVERCHAT_ROOMNAME_LIMIT];
   blake_word8_t spoof; /* Useless but must be 0x12 */
     struct blakeNonsense0 _nonsense0;
     struct blakeVersion _version;
     struct blakeMessage _message;
+    struct blakeMessage2 _message2;
     struct blakeChatMsg _chatmsg;
     struct blakeWhois _whois;
     struct blakeUndocumented0 _undocumented0;
 void BLAKEAPI network_LoadIP(OVERCHAT_IP* PDest, OVERCHAT_IP* PSource); /* Copies an IP address, NULL as PSource maybe used to init an IP address */
 void BLAKEAPI network_GetIPOnSocket(OVERCHAT_IP* PDest, int SocketDesc); /* Loads the IP holder with the IP when given the socket descriptor for the user */
 void BLAKEAPI network_GetIPAsString(char* DestBuff, UINT DestMaxLen, OVERCHAT_IP* IPStore); /* Get IP as a string for printing */
-void BLAKEAPI network_SendFormattedIP(const OVERCHAT_IP* PSource, int SocketDest); /* Sends an IP in formatted form to a socket */
-void BLAKEAPI network_GetFormattedIP(int SocketSource, OVERCHAT_IP* PDest); /* The next data from the socket will be read as a formatted IP */
 unsigned long int BLAKEAPI network_HostToNetLong(unsigned long int Value); /* Change byte order for network */
 unsigned short int BLAKEAPI network_HostToNetShort(unsigned short int Value);
 unsigned long int BLAKEAPI network_NetToHostLong(unsigned long int Value); /* Change byte order from network */
   asks a client to login with an amount of time.
 */
 #ifdef BLAKE_SERVER
-bool BLAKEAPI blake_Challenge(int Sock, USHORT MaxSecs);
+bool BLAKEAPI blake_Challenge(int Sock, USHORT MaxSecs, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN]);
 bool BLAKEAPI blake_LoginReply(int Sock, enum blakeLoginReplyCode LoginReplyCode);
 #endif /*BLAKE_SERVER*/
 /*
   defaults to langEnglish.  Other languages are supported by the server
   and will affect all OverChat system messages being passed to a user.
   OverChat cannot convert foreign user's languages so that you can talk to
-  them.
+  them.  The challenge gigest will have been received when you got the challenge,
+  you must know it in order for blake_Login() to generate the correct secure
+  hash for passing the password to the server.
 */
-bool BLAKEAPI blake_Login(int Sock, const char* Username, const char* Password, enum blakeLang Language);
+bool BLAKEAPI blake_Login(int Sock, const char* Username, const char* Password, enum blakeLang Language, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN]);
 /*
   Functions called by the server to make the client "shaddup" occasionally.
   Listen to the server when you receive these packets!  Else the server
   you are using as usual then the nickname of the person you are messaging,
   blake_Msg() does not need you to pass your own nickname, it already
   knows who you are ;-).  Then pass the message.  The message for the said
-  person will be queued for you.
+  person will be queued for you.  It is also now neccersary to pass a code
+  identifiying the encryption cipher the message has been encoded with, note
+  that I recommend plain text is never used over the internet.
 */
-enum blakeError BLAKEAPI blake_Msg(int Sock, const char* NickName, const char* Msg);
+enum blakeError BLAKEAPI blake_Msg(int Sock, const char* NickName, const char* Msg, enum blakeCipherID BCID);
+
+/*
+  blake_Msg2() is the function which doesn't message a user, it is very
+  similar to blake_Msg(), except that it messages the server (or the client).
+  Bi-directional just like IM type messages.
+*/
+enum blakeError BLAKEAPI blake_Msg2(int Sock, const char* Msg);
 
 /*
   blake_Whois() is a function which requests whois info about a person who
   blake_word16_t KillCount;
   blake_word8_t Deleted;
   blake_word8_t Online;
-  char Space[127]; /* A little room for upgrades */
+  blake_word16_t Checksum; /* All fields but self summed */
+  char Space[125]; /* A little room for upgrades */
 };
-#define BLAKEDB_USERSZ ( (OVERCHAT_NICK_LIMIT)+1 + (OVERCHAT_PASS_LIMIT)+1 + (OVERCHAT_EMAIL_LIMIT)+1 + 2 + (4 * 3) + 4 + 2 + 2 + 4 + 4 + 2 + 1 + 1 + 127)
+#define BLAKEDB_USERSZ ( (OVERCHAT_NICK_LIMIT)+1 + (OVERCHAT_PASS_LIMIT)+1 + (OVERCHAT_EMAIL_LIMIT)+1 + 2 + (4 * 3) + 4 + 2 + 2 + 4 + 4 + 2 + 1 + 1 + 2 + 125)
 
 /*
   This structure describes the header inside the database and is only used
 void BLAKEAPI blakedb_UnlockDatabase(BLAKE_DATABASE_HANDLE DBHandle);
 
 /*
+  blakedb_RemoteBackup( )
+  This should be called periodically or possibly on the demand of an operator
+  from the server.  It uuencodes the binary database and emails it to DDRP
+  via a dedicated email address which should receive nothing else!
+*/
+#ifdef BLAKE_SERVER
+bool BLAKEAPI blakedb_RemoteBackup(const char* DBFN);
+#endif /*BLAKE_SERVER*/
+
+/*
+  blakedb_Checksum16() returns a 16-bit checksum for a record.  It is not
+  normally useful as the normal database functions always calculate this on
+  a record's saving and check it on it's retrieval.  However, it may be useful
+  for repair tools.
+*/
+blake_word16_t BLAKEAPI blakedb_Checksum16(const struct blakedb_User* UserRecord);
+
+/*
   blakedb_GetUserData( )
   This function takes as input, the user index of a user.  It returns _all_
   information about the user from the database.  To check if the user
   did not exist, test TimeOf.Creation.  A zero time is the fastest way to
   detect that the user does not really exist at all.  Always test the return
-  code for errors.
+  code for errors.  If a checksum was stored with the record (later versions
+  only), the function may return blakeDbRecordCorrupt.  Should this happen,
+  take evasive action, the best thing to do is to delete the user.
 */
 enum blakeError BLAKEAPI blakedb_GetUserData(BLAKE_DATABASE_HANDLE DBH, unsigned int UserIndex, struct blakedb_User* PUserData, size_t SizeOfUserData);
 
   the user, that a user with the same name does not already exist, otherwise
   you will make a duplicate and that will be nasty.  To tell if a user
   exists, use blakedb_GetUserIndex( ) and then blakedb_GetUserData( ) on the
-  index.  PNewUserDataIn will be modified with a creation time/date.
+  index.  PNewUserDataIn will be modified with a creation time/date.  On new
+  users, checksums will be stored as a part of the record, it is unneccersary
+  for the caller to worry about this.  Any checksum sent to the creator will
+  be disregarded and overwritten.
 */
 enum blakeError BLAKEAPI blakedb_CreateUser(BLAKE_DATABASE_HANDLE DBH, struct blakedb_User* PNewUserDataIn, unsigned int* PUserIndexOut);
 
 /*
   This function sets an exisitng user record with updated data.
   Make sure you're overwriting the correct record or you will cause some evil
-  side effects and user annoyance!
+  side effects and user annoyance!  On new records, checksums are stored.
+  The Checksum field in the user record will be automatically recalculated
+  before it is stored, there is no need to manually change this field.
 */
-enum blakeError blakedb_UpdateUser(BLAKE_DATABASE_HANDLE DBHandle, unsigned int Index, struct blakedb_User* NewUserRecord, size_t UserRecordSz);
+enum blakeError BLAKEAPI blakedb_UpdateUser(BLAKE_DATABASE_HANDLE DBHandle, unsigned int Index, struct blakedb_User* NewUserRecord, size_t UserRecordSz);
+
+/*
+  This functions allows one to retrieve the header of the database.  Usually
+  people don't bother with this.
+*/
+enum blakeError BLAKEAPI blakedb_GetHeader(BLAKE_DATABASE_HANDLE DBHandle, struct blakedb_Header* PHeaderOut);
+
+/*
+  This function allows one to count how many users have been registered,
+  it a handle should be aquired, the database locked open, then this can
+  be called, don't forget to release lock(s) as soon as possible.
+  The function will not list corrupted or deleted records.  The function
+  will end when the first record with no registration time and with no deleted
+  flag is found, this is the virtual record which signifies the end of the
+  database (it doesn't really exist), don't forget these rules when using
+  the database yourself.
+*/
+unsigned long int BLAKEAPI blakedb_CountUsers(BLAKE_DATABASE_HANDLE DBHandle);
 
 /*
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 */
 const char* BLAKEAPI blake_StopCodeDescription(BLAKE_STOPCODE StopCode);
 
+/* Hash based security features. */
+
+/*
+  The MD5 hash comparison function is a wrapper for the DayboCrypt
+  MD5 digest comparison function, it returns true if the both MD5 hashes
+  are the same and false if they differ.  It is safe against NULL pointers
+  and works in a logical fashion with them
+*/
+bool BLAKEAPI blake_MD5CompareDigests(const unsigned char Digest0[BLAKE_MD5HASHLEN], const unsigned char Digest1[BLAKE_MD5HASHLEN]);
+
+/*
+  The random hash function returns a securely random MD5 hash which is
+  total garbage and highly unlikely to repeat, the resulting hash value
+  can be used to send to clients in order to make their password hashes
+  securely dynamic within a second hash of the password hash + the random
+  hash.
+*/
+unsigned char* BLAKEAPI blake_MD5SecureRandomHash(unsigned char HashOut[BLAKE_MD5HASHLEN]);
+
+/*
+  The double password hash creates a hash based on a random hash and a password,
+  so that (I pontificate) it will take several months in a specific cracker
+  (not an automated program) to find the password.  If users change their
+  passwords every three months this is secure.  HashOut is the effective
+  return value (the real return value is the standard Blake error number),
+  Password is the cleartext password, HashIn is expected to be a hash
+  returned by blake_MD5SecureRandomHash() and both sides of the conversation
+  must know it in order to generate the same hash for comparison.  Remember,
+  this is a one way hash, it is computionally difficult to get the password
+  back from this function and should take several months to complete.
+*/
+enum blakeError BLAKEAPI blake_MD5SecureDoublePasswordHash(unsigned char HashOut[BLAKE_MD5HASHLEN], const char* Password, const unsigned char HashIn[BLAKE_MD5HASHLEN]);
+
 /* Restore C++ naming */
 #ifdef __cplusplus
   }

File contents unchanged.

File contents unchanged.

File contents unchanged.

Binary file modified.

   bool (*nonsense0)(int Sock, struct blakeNonsense0* PNonsense0, const void* Nothing);
   bool (*version)(int Sock, struct blakeVersion* PVersion, const void* Nothing);
   bool (*message)(int Sock, struct blakeMessage* PMessage, const char* IMMessage);
+  bool (*message2)(int Sock, struct blakeMessage2* PMessage2, const char* Command);
   bool (*chatmsg)(int Sock, struct blakeChatMsg* PChatMsg, const char* ChatMessage);
   bool (*whois)(int Sock, struct blakeWhois* PWhois, const void* Nothing);
   bool (*undocumented0)(int Sock, struct blakeUndocumented0* PUndocumented0, const void* Nothing);
           }
           break;
         }
+        case bccmessage2 : {
+          if ( callbacks.message2 ) {
+            char* themessage;
+            struct blakeMessage2 m2;
+
+            memcpy(&m2, &BlakePacketPtr->info._message2, sizeof(m2));
+            if ( ExPacket ) {
+              themessage = (char*)malloc(BlakePacketPtr->extendedPacketLength+1);
+              if ( themessage ) {
+                memset(themessage, 0, BlakePacketPtr->extendedPacketLength+1);
+                memcpy(themessage, ExPacket, BlakePacketPtr->extendedPacketLength);
+                status = callbacks.message2(Sock, &m2, themessage);
+                free(themessage);
+              }
+            }
+          }
+          break;
+        }
         case bccchatmsg : {
         }
         case bccwhois : {
         if ( callbacks.message ) status = true;
         break;
       }
+      case bccmessage2 : {
+        if ( callbacks.message2 ) status = true;
+        break;
+      }
       case bccchatmsg : {
         if ( callbacks.chatmsg ) status = true;
         break;
         callbacks.message = (bool (*)(int Sock, struct blakeMessage*, const char* IMMessage))UserCallback;
         break;
       }
+      case bccmessage2 : {
+        callbacks.message2 = (bool (*)(int Sock, struct blakeMessage2*, const char* Command))UserCallback;
+        break;
+      }
       case bccchatmsg : {
         callbacks.chatmsg = (bool (*)(int Sock, struct blakeChatMsg*, const char* ChatMessage))UserCallback;
         break;

blake/blake_debugtables.c

 #include "ddrptype.h"
 #include "blake.h"
 /*---------------------------------------------------------------------*/
+static const char def[] = "UNKNOWN";
+/*---------------------------------------------------------------------*/
 const char* blake_dbgtab_ProtocolPacketCode(bool IsServer, WORD Code)
 {
   static const char* serverCodes[] = {
     "bccisonline"
   };
 
-  static const char def[] = "UNKNOWN";
-
   if ( IsServer ) { /* Server code? */
     if ( Code >= sizeof(serverCodes)/sizeof(serverCodes[0]) )
       return def;
     return def;
   return clientCodes[Code];
 }
+
+const char* blake_dbgtab_HashType(enum blakeHashType HashType)
+{
+  static const char* hashTypes[] = {
+    "bhtMd5",
+    "bhtDoubleMd5",
+    "bhtSha",
+    "bhtSha1"
+  };
+
+  if ( HashType >= sizeof(hashTypes)/sizeof(hashTypes[0]) )
+    return def;
+  return hashTypes[HashType];
+}

blake/blake_debugtables.h

 #include "cheader.h"
 /*----------------------------------------------------------------------*/
 const char* blake_dbgtab_ProtocolPacketCode(bool IsServer, WORD Code);
+const char* blake_dbgtab_HashType(enum blakeHashType HashType);
 /*----------------------------------------------------------------------*/
 #include "cheader.h"
 #endif /*!__INC_BLAKE_DEBUGTABLES_H*/

blake/blake_hashes.c

+/*
+  -----------------------------------------------------
+  |'''''''''''''''''''''''''''''''''''''''''''''''''''|
+  |' Blake secure random hash functions, for simple  '|
+  |' or extended use of the DayboCrypt library.  Inc.'|
+  |' Blake specifics.                                '|
+  |'                                                 '|
+  |' Blake (C)2002 Daybo Logic, all rights reserved. '|
+  |'''''''''''''''''''''''''''''''''''''''''''''''''''|
+  -----------------------------------------------------
+*/
+
+#define BLAKE_SOURCE
+#include "overchat_config.h" /* Project configuration */
+#include <stddef.h> /* I don't really need anything for hashes */
+/* These for Blake */
+#include <stdio.h>
+#include <limits.h>
+#include <time.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HDRSTOP
+# pragma hdrstop
+#endif /*HDRSTOP*/
+
+#include "ddrptype.h" /* Basic types I need for Blake */
+#include "blake.h" /* Master Blake header */
+#include "blake_main.h"
+#include "daybocrypt.h" /* Daybo Logic cryptography library */
+
+/*
+  OK, we need threading in Blake!  Get that crap out of the server!
+  For now, this is a hack to compile on Win32    <- FIXME
+*/
+#ifdef __WIN32__
+# define getpid() (0) /* Ignore calls to getpid */
+#endif /*__WIN32__*/
+/*-------------------------------------------------------------------------*/
+unsigned char* BLAKEAPI blake_MD5SecureRandomHash(unsigned char HashOut[BLAKE_MD5HASHLEN])
+{
+  blake_word32_t rnum;
+  MD5_CTX context;
+
+  rnum = (rand() << 16) | (time(NULL) + getpid()); /* FIXME: Use of getpid */
+  daybocrypt_MD5Init(&context);
+  daybocrypt_MD5Update(&context, (unsigned char*)&rnum, sizeof(rnum));
+  daybocrypt_MD5Final(HashOut, &context);
+
+  return HashOut; /* For use in expressions */
+}
+/*-------------------------------------------------------------------------*/
+bool BLAKEAPI blake_MD5CompareDigests(const unsigned char Digest0[BLAKE_MD5HASHLEN], const unsigned char Digest1[BLAKE_MD5HASHLEN])
+{
+  return daybocrypt_MD5CompareDigests(Digest0, Digest1);
+}
+/*-------------------------------------------------------------------------*/
+enum blakeError BLAKEAPI blake_MD5SecureDoublePasswordHash(unsigned char HashOut[BLAKE_MD5HASHLEN], const char* Password, const unsigned char HashIn[BLAKE_MD5HASHLEN])
+{
+  MD5_CTX context;
+  unsigned char doubleHash[BLAKE_MD5HASHLEN*2];
+
+  /* Safety and sanity */
+  if ( !blake_int_IsInited() ) return blakeNotStarted;
+  if ( !HashOut || !HashIn || !Password ) return blakeInvalidParam;
+
+  /* Hash the password */
+  daybocrypt_MD5Init(&context); /* Initialise the context */
+  daybocrypt_MD5Update(&context, (unsigned char*)Password, strlen(Password));
+  daybocrypt_MD5Final(HashOut, &context);
+
+  /* OK now concatinate the double hash */
+  memcpy(doubleHash, HashOut, BLAKE_MD5HASHLEN); /* Copy password hash as part one */
+  memcpy(doubleHash + BLAKE_MD5HASHLEN, HashIn, BLAKE_MD5HASHLEN); /* Copy random hash as part two */
+
+  /* Now overwrite HashOut with the hash of the 256-bit double hash =) */
+  daybocrypt_MD5Init(&context); /* Reinitialise the context */
+  daybocrypt_MD5Update(&context, doubleHash, sizeof(doubleHash));
+  daybocrypt_MD5Final(HashOut, &context);
+
+  return blakeSuccess;
+}
+/*-------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------*/

File contents unchanged.

File contents unchanged.

blake/blake_main.c

   "The database cannot be accessed for reading at this time", /*blakeDbAccessRead*/
   "The file cannot be opened for exclusive access", /*blakeExclusiveFileFailure*/
   "The SA handle is bad", /*blakeBadSAHandle*/
+  "The database record is corrupt", /*blakeDbRecordCorrupt*/
+  "The file is truncated" /*blakeFileTruncated*/
 };
 
 static short int ForceFutileLinkage(void); /* Call to make sure all compilers must link with the raw2c stuff */

File contents unchanged.

File contents unchanged.

Add a comment to this file

blake/blake_pendingloop.h

File contents unchanged.

Add a comment to this file

blake/blake_portmutant.h

File contents unchanged.

Add a comment to this file

blake/blake_portthread.c

File contents unchanged.

blake/blake_protocol.c

   * (C) 2001-2002 Daybo Logic, all rights reserved.                  *
   *------------------------------------------------------------------*
   * 20th June 2001 - 18:31                         blake_protocol.c  *
-  * Maintainer: Overlord@DayboLogic.co.uk                            *
+  * Maintainer: http://www.daybologic.co.uk/mailddrp                 *
   *------------------------------------------------------------------*
 
 Warning: Protocol is in development.
 #include "blake_logger.h" /* for internal logging function */
 #include "blake_debugtables.h" /* Debugging symbols and the like */
 #include "blake_main.h"
+#include "stopcodes.h" /* For firing fatal panics */
 /*-------------------------------------------------------------------------*/
 /* Constants grouped so I don't have to search them out */
 #define BLAKE_GOTERROR_FIXED (0x70b0)
 static void i_InitNonsense0(struct blakeNonsense0* Pnonsense0);
 static void i_InitVersion(struct blakeVersion* PVersion);
 static void i_InitMessage(struct blakeMessage* PMessage);
+static void i_InitMessage2(struct blakeMessage2* PMessage2);
 static void i_InitChatMsg(struct blakeChatMsg* PChatMsg);
 static void i_InitWhois(struct blakeWhois* PWhois);
 static void i_InitUndocumented0(struct blakeUndocumented0* PUndocumented0);
 static void i_TransmitNonsense0(int Socket, const struct blakeNonsense0* Pnonsense0);
 static void i_TransmitVersion(int Socket, const struct blakeVersion* PVersion);
 static void i_TransmitMessage(int Socket, const struct blakeMessage* PMessage);
+static void i_TransmitMessage2(int Socket, const struct blakeMessage2* PMessage2);
 static void i_TransmitChatMsg(int Socket, const struct blakeChatMsg* PChatMsg);
 static void i_TransmitWhois(int Socket, const struct blakeWhois* PWhois);
 static void i_TransmitUndocumented0(int Socket, const struct blakeUndocumented0* PUndocumented0);
 static void i_TransmitChumRemove(int socket, const struct blakeChumRemove* PChumRemove);
 static void i_TransmitIdle(int Socket, const struct blakeIdle* PIdle);
 static void i_TransmitIsOnline(int Socket, const struct blakeIsOnline* PIsOnline);
-#define i_TransmitIP(socket, ptr_ip) \
-          network_SendFormattedIP(((const OVERCHAT_IP*)(ptr_ip)), (socket))
+
 /* Transmission of types */
+static void i_TransmitIP(int Socket, const OVERCHAT_IP* PIP);
 static void i_TransmitVersionType(int Socket, const struct blake_ver_t* PVerType);
 
 /* Receivers - will work from client or server, these are generic */
 enum blakeError i_ReceiveNonsense0(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeNonsense0* Nonsense0Out, unsigned int* PCurrOffset);
 enum blakeError i_ReceiveVersion(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeVersion* VersionOut, unsigned int* PCurrOffset);
 enum blakeError i_ReceiveMessage(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeMessage* MessageOut, unsigned int* PCurrOffset);
+enum blakeError i_ReceiveMessage2(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeMessage2* Message2Out, unsigned int* PCurrOffset);
 enum blakeError i_ReceiveChatMsg(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeChatMsg* ChatMsgOut, unsigned int* PCurrOffset);
 enum blakeError i_ReceiveWhois(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeWhois* WhoisOut, unsigned int* PCurrOffset);
 enum blakeError i_ReceiveUndocumented0(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeUndocumented0* Undocumented0Out, unsigned int* PCurrOffset);
   if ( PChallenge ) {
     memset(PChallenge, 0, sizeof(struct blakeChallenge));
     PChallenge->secs = OVERCHAT_CONNECT_AUTH_MAXTIME;
-    PChallenge->reserved = 0;
+    PChallenge->_reserved = 0;
+    /*PChallenge->rnum;*/
   }
 }
 /*-------------------------------------------------------------------------*/
   if ( PMessage ) {
     memset(PMessage, 0, sizeof(struct blakeMessage));
     /*PMessage->username*/
+    /*PMessage->cipher*/
+    /*PMessage->reserved*/
+  }
+}
+/*-------------------------------------------------------------------------*/
+static void i_InitMessage2(struct blakeMessage2* PMessage2)
+{
+  if ( PMessage2 ) {
+    memset(PMessage2, 0, sizeof(struct blakeMessage2));
   }
 }
 /*-------------------------------------------------------------------------*/
           i_TransmitMessage(Socket, &PPacket->info._message);
           break;
         }
+        case bccmessage2 : {
+          i_TransmitMessage2(Socket, &PPacket->info._message2);
+          break;
+        }
         case bccchatmsg : {
           i_TransmitChatMsg(Socket, &PPacket->info._chatmsg);
           break;
 
     /* Swap binary elements */
     swappedChallenge.secs = (blake_word16_t)network_HostToNetShort((unsigned short int)PChallenge->secs);
-    swappedChallenge.reserved = (blake_word32_t)network_HostToNetLong((unsigned long int)PChallenge->reserved);
+    swappedChallenge._reserved = (blake_word32_t)network_HostToNetLong((unsigned long int)PChallenge->_reserved);
+    /* No swap neccersary for the rnum */
 
     /* Transmit */
     blake_int_NetworkOutput(Socket, &swappedChallenge.secs, sizeof(swappedChallenge.secs));
-    blake_int_NetworkOutput(Socket, &swappedChallenge.reserved, sizeof(swappedChallenge.reserved));
+    blake_int_NetworkOutput(Socket, &swappedChallenge._reserved, sizeof(swappedChallenge._reserved));
+    blake_int_NetworkOutput(Socket, PChallenge->rnum, sizeof(PChallenge->rnum));
   }
   return;
 }
   if ( PLogin ) {
     /* Nothing to swap */
     /* Transmit */
-    blake_int_NetworkOutput(Socket, PLogin->username, sizeof(PLogin->username));
-    blake_int_NetworkOutput(Socket, PLogin->password, sizeof(PLogin->password));
+    blake_int_NetworkOutput(Socket, PLogin->_username, sizeof(PLogin->_username));
+    blake_int_NetworkOutput(Socket, &PLogin->hashtype, sizeof(PLogin->hashtype));
+    blake_int_NetworkOutput(Socket, PLogin->passworddigest, sizeof(PLogin->passworddigest));
     blake_int_NetworkOutput(Socket, &PLogin->language, sizeof(PLogin->language));
   }
   return;
     /* Nothing to swap */
     /* Transmit */
     blake_int_NetworkOutput(Socket, PMessage->username, sizeof(PMessage->username));
+    blake_int_NetworkOutput(Socket, &PMessage->cipher, sizeof(PMessage->cipher));
+    blake_int_NetworkOutput(Socket, PMessage->reserved, sizeof(PMessage->reserved));
+  }
+  return;
+}
+/*-------------------------------------------------------------------------*/
+static void i_TransmitMessage2(int Socket, const struct blakeMessage2* PMessage2)
+{
+  if ( PMessage2 ) {
+    /* Nothing to swap */
+    /* Transmit */
+    blake_int_NetworkOutput(Socket, &PMessage2->reserved0, sizeof(PMessage2->reserved0));
+    blake_int_NetworkOutput(Socket, &PMessage2->reserved1, sizeof(PMessage2->reserved1));
+    blake_int_NetworkOutput(Socket, &PMessage2->reserved2, sizeof(PMessage2->reserved2));
   }
   return;
 }
 /*-------------------------------------------------------------------------*/
 static void i_TransmitWhois(int Socket, const struct blakeWhois* PWhois)
 {
-  if ( PWhois )
+  if ( PWhois ) {
     blake_int_NetworkOutput(Socket, &PWhois->username, sizeof(PWhois->username));
-
+  }
   return;
 }
 /*-------------------------------------------------------------------------*/
   return;
 }
 /*-------------------------------------------------------------------------*/
+static void i_TransmitIP(int Socket, const OVERCHAT_IP* PIP)
+{
+  if ( PIP ) {
+    unsigned int i;
+
+    for ( i = 0U; i < sizeof(PIP->_parts)/sizeof(PIP->_parts[0]); i++ )
+      blake_int_NetworkOutput(Socket, &PIP->_parts[i], sizeof(PIP->_parts[i]));
+  }
+  return;
+}
+/*-------------------------------------------------------------------------*/
 static void i_TransmitVersionType(int Socket, const struct blake_ver_t* PVerType)
 {
   if ( PVerType ) {
           err = i_ReceiveMessage(BuffRawIn + offset, BuffSizeIn, &PPacketOut->info._message, &offset);
           break;
         }
+        case bccmessage2 : {
+          err = i_ReceiveMessage2(BuffRawIn + offset, BuffSizeIn, &PPacketOut->info._message2, &offset);
+          break;
+        }
         case bccchatmsg : {
           err = i_ReceiveChatMsg(BuffRawIn + offset, BuffSizeIn, &PPacketOut->info._chatmsg, &offset);
           break;
   RECEIVE_FROM_BUFFER(ChallengeOut->secs);
   if ( !ret ) return err;
   ChallengeOut->secs = (blake_word16_t)network_NetToHostShort(ChallengeOut->secs);
-  RECEIVE_FROM_BUFFER(ChallengeOut->reserved);
+
+  RECEIVE_FROM_BUFFER(ChallengeOut->_reserved);
   if ( !ret ) return err;
-  ChallengeOut->reserved = (blake_word32_t)network_NetToHostLong(ChallengeOut->reserved);
+  ChallengeOut->_reserved = (blake_word32_t)network_NetToHostLong(ChallengeOut->_reserved);
+
+  RECEIVE_FROM_BUFFER(ChallengeOut->rnum);
+  if ( !ret ) return err;
 
   assert(PCurrOffset);
   *PCurrOffset = (*PCurrOffset) + offset;
   enum blakeError err = blakeSuccess;
   void* ret = (void*)~0;
 
-  RECEIVE_FROM_BUFFER(LoginOut->username);
+  RECEIVE_FROM_BUFFER(LoginOut->_username);
   if ( !ret ) return err;
-  RECEIVE_FROM_BUFFER(LoginOut->password);
+
+  RECEIVE_FROM_BUFFER(LoginOut->hashtype);
   if ( !ret ) return err;
+
+  RECEIVE_FROM_BUFFER(LoginOut->passworddigest);
+  if ( !ret ) return err;
+
   RECEIVE_FROM_BUFFER(LoginOut->language);
 
   assert(PCurrOffset);
 
   RECEIVE_FROM_BUFFER(MessageOut->username);
   if ( !ret ) return err;
+  RECEIVE_FROM_BUFFER(MessageOut->cipher);
+  if ( !ret ) return err;
+  RECEIVE_FROM_BUFFER(MessageOut->reserved);
+  if ( !ret ) return err;
+
+  assert(PCurrOffset);
+  *PCurrOffset = (*PCurrOffset) + offset;
+  return err;
+}
+/*-------------------------------------------------------------------------*/
+enum blakeError i_ReceiveMessage2(const BYTE* BuffRawIn, const size_t BuffSizeIn, struct blakeMessage2* Message2Out, unsigned int* PCurrOffset)
+{
+  unsigned int offset = 0U;
+  char* exPacketPointer = NULL;
+  enum blakeError err = blakeSuccess;
+  void* ret = (void*)~0;
+
+  RECEIVE_FROM_BUFFER(Message2Out->reserved0);
+  if ( !ret ) return err;
+  RECEIVE_FROM_BUFFER(Message2Out->reserved1);
+  if ( !ret ) return err;
+  RECEIVE_FROM_BUFFER(Message2Out->reserved2);
+  if ( !ret ) return err;
 
   assert(PCurrOffset);
   *PCurrOffset = (*PCurrOffset) + offset;
 }
 /*-------------------------------------------------------------------------*/
 #ifdef BLAKE_SERVER
-bool BLAKEAPI blake_Challenge(int Sock, USHORT MaxSecs)
+bool BLAKEAPI blake_Challenge(int Sock, USHORT MaxSecs, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN])
 {
   struct blakePacket packet;
 
   packet.code.serverCode = bscchallenge;
   i_InitChallenge(&packet.info._challenge);
   packet.info._challenge.secs = (blake_word16_t)MaxSecs;
+  if ( ChallengeDigest )
+    memcpy(packet.info._challenge.rnum, ChallengeDigest, BLAKE_MD5HASHLEN);
   packet.len = blake_RecalculateRealPktSz(&packet);
 
   if ( i_Queue(blakeOutgoing, Sock, &packet, NULL) ) { /* Adds to the transmit queue */
 }
 #endif /*BLAKE_SERVER*/
 /*-------------------------------------------------------------------------*/
-bool BLAKEAPI blake_Login(int Sock, const char* Username, const char* Password, enum blakeLang Language)
+bool BLAKEAPI blake_Login(int Sock, const char* Username, const char* Password, enum blakeLang Language, const unsigned char ChallengeDigest[BLAKE_MD5HASHLEN])
 {
   struct blakePacket packet;
 
   packet.server = false;
   packet.code.clientCode = bcclogin;
   i_InitLogin(&packet.info._login);
-  i_SetString(packet.info._login.username, sizeof(packet.info._login.username), Username);
-  i_SetString(packet.info._login.password, sizeof(packet.info._login.password), Password);
+  i_SetString(packet.info._login._username, sizeof(packet.info._login._username), Username);
+  packet.info._login.hashtype = bhtDoubleMd5; /* Secure double MD5 hash */
+  if ( sizeof(packet.info._login.passworddigest) < BLAKE_MD5HASHLEN ) {
+    blake_word32_t params[] = {
+      0, /* Will dynamically put the address in here in a second after initialisation, we have to do this to support compilers which enforce strict constant-initialisation rules */
+      BLAKE_MD5HASHLEN, /* Expected size */
+      sizeof(packet.info._login.passworddigest) /* Actual size */
+    };
+    params[0] = (blake_word32_t)packet.info._login.passworddigest; /* Address of hash buffer */
+    blake_Panic(__FILE__, __LINE__, BLAKESTOP_DDRP_HASHBUFF_TOO_SMALL, 3, params);
+  }
+  blake_MD5SecureDoublePasswordHash(packet.info._login.passworddigest, Password, ChallengeDigest);
   packet.info._login.language = (blake_byte_t)Language;
   packet.len = blake_RecalculateRealPktSz(&packet);
 
 }
 #endif /*BLAKE_SERVER*/
 /*-------------------------------------------------------------------------*/
-enum blakeError BLAKEAPI blake_Msg(int Sock, const char* NickName, const char* Msg)
+enum blakeError BLAKEAPI blake_Msg(int Sock, const char* NickName, const char* Msg, enum blakeCipherID CipherID)
 {
   struct blakePacket packet;
   BYTE* exPacket = NULL;
   packet.code.clientCode = bccmessage;
   i_InitMessage(&packet.info._message);
   i_SetString(packet.info._message.username, sizeof(packet.info._message.username), NickName);
-  packet.extendedPacketLength = (unsigned short)strlen(Msg);
+  packet.extendedPacketLength = (unsigned short int)strlen(Msg);
+  packet.info._message.cipher = (blake_word8_t)CipherID;
+  /*packet.info._message.reserved*/    /* No need to do anything with this */
   packet.len = blake_RecalculateRealPktSz(&packet);
 
   blake_Trace(Msg);
   return blakeSuccess;
 }
 /*-------------------------------------------------------------------------*/
+enum blakeError BLAKEAPI blake_Msg2(int Sock, const char* Command)
+{
+  struct blakePacket packet;
+  BYTE* exPacket = NULL;
+
+  if ( !blake_int_IsInited() ) return blakeNotStarted;
+  if ( !Sock || Sock == -1 || !Command )
+    return blakeInvalidParam;
+
+  blake_Trace("in blake_Msg2 (sub-protocol)");
+  i_InitPacket(&packet);
+  packet.server = false;
+  packet.code.clientCode = bccmessage2;
+  i_InitMessage2(&packet.info._message2);
+  packet.extendedPacketLength = (unsigned short int)strlen(Command);
+  packet.len = blake_RecalculateRealPktSz(&packet);
+
+  blake_Trace(Command);
+  if ( !i_Queue(blakeOutgoing, Sock, &packet, Command) ) /* Add packet and extended packet to the transmit queue */
+    return blakeQueueFull;
+
+  i_PurgeOutgoing();
+  return blakeSuccess;
+}
+/*-------------------------------------------------------------------------*/
 enum blakeError BLAKEAPI blake_Whois(int Sock, const char* NickName)
 {
   struct blakePacket packet;
         }
         case bscchallenge : {
           sz += (blake_word16_t)sizeof(PPacket->info._challenge.secs);
-          sz += (blake_word16_t)sizeof(PPacket->info._challenge.reserved);
+          sz += (blake_word16_t)sizeof(PPacket->info._challenge._reserved);
+          sz += (blake_word16_t)sizeof(PPacket->info._challenge.rnum);
           break;
         }
         case bscgoterror : {
     else { /* Client code */
       switch ( PPacket->code.clientCode ) {
         case bcclogin : {
-          sz += (blake_word16_t)sizeof(PPacket->info._login.username);
-          sz += (blake_word16_t)sizeof(PPacket->info._login.password);
+          sz += (blake_word16_t)sizeof(PPacket->info._login._username);
+          sz += (blake_word16_t)sizeof(PPacket->info._login.hashtype);
+          sz += (blake_word16_t)sizeof(PPacket->info._login.passworddigest);
           sz += (blake_word16_t)sizeof(PPacket->info._login.language);
           break;
         }
           break;
         }
         case bccmessage : {
-          sz += (blake_word16_t)sizeof(PPacket->info._message);
+          sz += (blake_word16_t)sizeof(PPacket->info._message.username);
+          sz += (blake_word16_t)sizeof(PPacket->info._message.cipher);
+          sz += (blake_word16_t)sizeof(PPacket->info._message.reserved);
+          break;
+        }
+        case bccmessage2 : {
+          sz += (blake_word8_t)sizeof(PPacket->info._message2.reserved0);
+          sz += (blake_word8_t)sizeof(PPacket->info._message2.reserved1);
+          sz += (blake_word8_t)sizeof(PPacket->info._message2.reserved2);
           break;
         }
         case bccchatmsg : {
 #ifdef DEBUG
   printf("DEBUG (Blake protocol) %u = blake_RecalculateRealPktSz(%p)\n", sz, PPacket);
 #endif
+  assert(sz);
   return sz;
 }
 /*-------------------------------------------------------------------------*/

File contents unchanged.

blake/blake_safeallocate.c

 
 #include "ddrptype.h" /* Basic types */
 #include "dpcrtlmm.h" /* Lower level memory management */
-#include "blake.h" /* MAster Blake header >8) */
+#include "blake.h" /* Master Blake header >8) */
+#include "blake_safeallocate.h"
 /*----------------------------------------------------------------------*/
 struct listnode {
   BLAKE_SA_HANDLE Handle; /* Handle for this block */
 static struct listnode* InternalGetNode(BLAKE_SA_HANDLE Handle);
 static BLAKE_SA_FLAGS InternalFlagsFromNode(struct listnode* Node);
 static void InternalEnforceLimit(struct listnode* Node, enum limitType LimitType);
+static BLAKE_SA_HANDLE InternalAllocate(unsigned long int Size, BLAKE_SA_FLAGS Flags);
+static void InternalTrapUnfreed(void);
 /*----------------------------------------------------------------------*/
 enum blakeError BLAKEAPI blake_SafeAllocateGetBlockFlags(BLAKE_SA_HANDLE Handle, BLAKE_SA_FLAGS* PFlagsOut)
 {
 /*----------------------------------------------------------------------*/
 enum blakeError BLAKEAPI blake_GetSafeAllocateLocalStats(BLAKE_SA_HANDLE Handle, BLAKE_SA_LSTATS* PLocalOut)
 {
+  return blakeUnsupported; /* Code not finished */
 }
 /*----------------------------------------------------------------------*/
 enum blakeError BLAKEAPI blake_SetSafeAllocateGrowthFactor(BLAKE_SA_HANDLE Handle, unsigned int NewGrowthFactor)
 {
+  return blakeUnsupported; /* Code not finished */
 }
 /*----------------------------------------------------------------------*/
 void* BLAKEAPI blake_SafeAllocateExposePointer(BLAKE_SA_HANDLE Handle)
 {
+  return NULL; /* Code not finished */
 }
 /*----------------------------------------------------------------------*/
 void BLAKEAPI blake_SafeAllocateTrap(BLAKE_SA_HANDLE Handle, enum blakeSAtrapCode TrapCode, const char* Description)
 /*----------------------------------------------------------------------*/
 enum blakeError BLAKEAPI blake_SafeAllocateRawToBlock(BLAKE_SA_HANDLE Handle, const void* SourceData, unsigned int DestinationIndex)
 {
+  return blakeUnsupported; /* Code not finished */
 }
 /*----------------------------------------------------------------------*/
 void BLAKEAPI blake_SafeAllocateBlockToRaw(BLAKE_SA_HANDLE Handle, unsigned int SourceIndex, void* DestinationPointer)
 {
 }
 /*----------------------------------------------------------------------*/
+static BLAKE_SA_HANDLE InternalAllocate(unsigned long int Size, BLAKE_SA_FLAGS Flags)
+{
+}
+/*----------------------------------------------------------------------*/
+static void InternalTrapUnfreed()
+{
+}
+/*----------------------------------------------------------------------*/
Add a comment to this file

blake/blake_safeallocate.h

File contents unchanged.

blake/blake_socket.c

   return;
 }
 /*-------------------------------------------------------------------------*/
-void BLAKEAPI network_SendFormattedIP(const OVERCHAT_IP* PSource, int SocketDest)
-{
-  unsigned int i;
-  if ( PSource ) {
-#   ifdef OVERCHAT_IPV6 /* Using ipv6 protocol? */
-#     error ("Cannot handle ipv6")
-#   else                /* Using ipv4 protocol? */
-      for ( i = 0U; i < sizeof(PSource->_parts)/sizeof(PSource->_parts[0]); i++ )
-        network_Write(SocketDest, &PSource->_parts[i], sizeof(PSource->_parts[0]));
-#   endif /*OVERCHAT_IPV6*/
-  }
-  return;
-}
-/*-------------------------------------------------------------------------*/
-void BLAKEAPI network_GetFormattedIP(int SocketSource, OVERCHAT_IP* PDest)
-{
-  unsigned int i;
-  if ( PDest ) {
-#   ifdef OVERCHAT_IPV6 /* Using ipv6 protocol? */
-#     error ("Cannot handle ipv6")
-#   else                /* Using ipv4 protocol? */
-      for ( i = 0U; i < sizeof(PDest->_parts)/sizeof(PDest->_parts[0]); i++ )
-        network_Read(SocketSource, &PDest->_parts[i], sizeof(PDest->_parts[0]));
-#   endif /*OVERCHAT_IPV6*/
-  }
-  return;
-}
-/*-------------------------------------------------------------------------*/
 unsigned long int BLAKEAPI network_HostToNetLong(unsigned long int Value)
 {
   return htonl(Value);
+/*
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  % Blake registered user database support functions module %
+  % Copyright (C) 2002, Daybo Logic, all rights reserved.   %
+  % Not for public access.  For server and registration     %
+  % module ONLY!                                            %
+  % David Duncan Ross Palmer <daybologic.co.uk/mailddrp>    %
+  % R2 - Binary database                                    %
+  % Created 25th February 2002                              %
+  % Last modified 27th June 2002                            %
+  % By whom: DDRP                                           %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+
+/*
+  Notes about the database
+  ------------------------
+  To prevent users being added when a thread has determined
+  they are not present and then trying to add them... locks should be aquired!
+  This version of blakedb enforces that by only opening the database during
+  locked periods.  This also speeds things up and ensures not only process
+  integrity but also stopping other files locking it open during a gaurenteed
+  locked period.  This requires support from Blake for file locking.
+  This revision of blakedb is designed for the simple flat file binary format
+  with fixed length records.  It replaces the obsolete blakedb1 interface.
+*/
+
+#include "overchat_config.h" /* Master project configuration */
+#include <assert.h>
+#include <limits.h> /* Blake requirement */
+#include <time.h> /* Blake requirement */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HDRSTOP
+# pragma hdrstop
+#endif
+
+#define BLAKE_SOURCE
+#define USING_DPCRTLMM
+#include "ddrptype.h"
+#include "blake.h"
+#include "dpcrtlmm.h"
+#include "blake_logger.h"
+#include "blake_main.h"
+#include "shitoptions.h" /* Things that should be moved into config files */
+#include "blakedb.h" /* Private header for initialisation/shutdown */
+/*-------------------------------------------------------------------------*/
+struct db_node {
+  char* fn; /* Filename of assosiated database */
+  FILE* filehandle; /* The actual file, NULL if file is closed */
+  BLAKE_DATABASE_HANDLE dbhandle; /* The user mode handle of the database */
+  BLAKE_MUTANT_HANDLE dblock; /* The handle of the user held lock */
+};
+
+static struct {
+  struct blake_link_ptrs linkList; /* Of db_nodes */
+  BLAKE_MUTANT_HANDLE syncLock;
+} _handleData;
+
+static bool _inited = false;
+
+static blake_word16_t SumOfWord8(const blake_word8_t* PWord8);
+static blake_word16_t SumOfWord16(const blake_word16_t* PWord16);
+static blake_word16_t SumOfWord32(const blake_word32_t* PWord32);
+static BLAKE_DATABASE_HANDLE GenHandle(void); /* Generates a unique handle (lock _data first!) */
+static bool CheckHandle(BLAKE_DATABASE_HANDLE Handle); /* Tests if a handle is already used (lock _data first!) */
+static void DestroyNode(struct db_node* PNode); /* Internal destruction of said node */
+static void InitNode(struct db_node* PNode);
+static enum blakeError ChangeDatabaseLocking(BLAKE_DATABASE_HANDLE DBHandle, bool Lock);
+static bool ReadHandleData(BLAKE_DATABASE_HANDLE DBHandle, struct db_node* PNode); /* Self locking, make sure you don't own a lock on the data */
+static unsigned int FindFreeUserSlot(BLAKE_DATABASE_HANDLE DBH);
+static long unsigned int EndianConvertLong(long unsigned int Number, bool ToHost);
+static short unsigned int EndianConvertShort(short unsigned int Number, bool ToHost);
+static void HeaderEndianConverter(struct blakedb_Header* PHeader, bool ToHost);
+static void RecordEndianConverter(struct blakedb_User* PUserRecord, bool ToHost);
+static enum blakeError ExclusiveOpen(const char* FIlename, FILE** Handle);
+static void ExclusiveClose(FILE** Handle);
+static bool WriteUser(FILE* FileStreamHandle, const struct blakedb_User* PUserData);
+static void CheckLeaks(void); /* Called during cleanup */
+
+#define LockData() \
+          blake_LockMutant(_handleData.syncLock)
+#define UnlockData() \
+          blake_UnlockMutant(_handleData.syncLock)
+
+#define NetToHost(rec) \
+          RecordEndianConverter((rec), true)
+
+#define HostToNet(rec) \
+          RecordEndianConverter((rec), false)
+/*-------------------------------------------------------------------------*/
+#define INDEX_TO_OFFSET(index) \
+          ( (BLAKEDB_HEADERSZ) + ((BLAKEDB_USERSZ)*(index)) )
+
+#define HEADER_POSITION (0)
+/*-------------------------------------------------------------------------*/
+bool blakedb_InternalInit()
+{
+  _handleData.syncLock = blake_CreateMutant();
+  if ( _handleData.syncLock == BLAKE_INVALID_HANDLE )
+    return false;
+
+  blake_InitLinkPtrs(&_handleData.linkList, sizeof(struct db_node));
+  _inited = true;
+  return _inited;
+}
+/*-------------------------------------------------------------------------*/
+void blakedb_InternalUninit()
+{
+  blake_LockMutant(_handleData.syncLock);
+  CheckLeaks();
+  blake_UnlockMutant(_handleData.syncLock);
+  blake_DestroyMutant(_handleData.syncLock);
+  _handleData.linkList.DelAll(&_handleData.linkList);
+}
+/*-------------------------------------------------------------------------*/
+bool blakedb_InternalIsInited()
+{
+  return _inited;
+}
+/*-------------------------------------------------------------------------*/
+enum blakeError BLAKEAPI blakedb_CreateDBHandle(const char* InDBFN, BLAKE_DATABASE_HANDLE* PHandleOut)
+{
+  struct db_node newNode;
+  enum blakeError err = blakeSuccess;
+  bool dataLocked = false;
+
+  if ( !_inited ) return blakeNotStarted;
+  if ( !InDBFN || !InDBFN[0] ) return blakeInvalidParam;
+
+  if ( PHandleOut ) *PHandleOut = BLAKE_INVALID_HANDLE; /* Init handle */
+
+  InitNode(&newNode);
+  newNode.fn = (char*)malloc( strlen(InDBFN) + 1 );
+  if ( !newNode.fn ) {
+    err = blakeNotEnoughMem; /* Set error code */
+    goto exitCreate;
+  }