Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ ROM ➜ Running the server ➜ Encrypting Player Passwords

Encrypting Player Passwords

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by YoshoFyre   (29 posts)  Bio
Date Tue 15 Mar 2022 01:20 AM (UTC)
Message
Hello again.

I am still, slowly, working on my Mud. As per my last post, I have completed expanding the code to the point that i feel comfortable with the game being playable with the level increase. In that respect, i am just down to building areas to support the extra levels.

I have lately been fixing known bugs and things that have been irritating me.

One of the things that is irritating me is that I have noticed that the player passwords are stored in plain text in the pfile. (Well actually ive noticed this from day one, but I haven't until now got to a point to correct this).

A little history. My mud was originally compiled to run under CGYWIN on a windows 98 box back in the year 2001. I started making changes to make it my own over that year, but eventually put it on the back burner. In 2010 i found a CD containing a backup of my entire code, and so i installed Ubuntu Server on a spare box and loaded up the mud. (GCC 3.4 installed)... this was short lived and again the mud went on the back burner. In 2019, I picked it up again. and have kept the box powered and connected ever since. Ive updated Ubuntu Server to the latest version, and kept GCC 3.4 installed. The mud runs and compiles. The server has been online for nearly 30 months without interruption.

I am wondering if the changes (which i don't really remember what all i did) i needed to make to make the mud compile 20 years ago on cygwin is what forced the mud to use plain text passwords, or if there something i need to enable, add to the code to make it work. Google is not being my friend here.

in comm.c this is the password code
	if ( strcmp( crypt( argument, ch->pcdata->pwd ), ch->pcdata->pwd ))
	{
	    write_to_buffer( d, "Wrong password.\n\r", 0 );
	    close_socket( d );
	    return;
	}
 
	write_to_buffer( d, echo_on_str, 0 );

	if (check_playing(d,ch->name))
	    return;

	ch->pcdata->socket = str_dup( d->host );
	if ( check_reconnect( d, ch->name, TRUE ) )
	    return;

	sprintf( log_buf, "%s@%s has connected.", ch->name, d->host );
	log_string( log_buf );
	wiznet(log_buf,NULL,NULL,WIZ_SITES,0,get_trust(ch));
	ch->pcdata->socket = str_dup( d->host );


in merc.h i see

/*
 * OS-dependent declarations.
 * These are all very standard library functions,
 *   but some systems have incomplete or non-ansi header files.
 */
#if	defined(_AIX)
char *	crypt		args( ( const char *key, const char *salt ) );
#endif

#if	defined(apollo)
int	atoi		args( ( const char *string ) );
void *	calloc		args( ( unsigned nelem, size_t size ) );
char *	crypt		args( ( const char *key, const char *salt ) );
#endif

#if	defined(hpux)
char *	crypt		args( ( const char *key, const char *salt ) );
#endif

#if	defined(linux)
char *	crypt		args( ( const char *key, const char *salt ) );
#endif

#if	defined(macintosh)
#define NOCRYPT
#if	defined(unix)
#define NOCRYPT
#undef	unix
#endif
#endif

#if	defined(MIPS_OS)
char *	crypt		args( ( const char *key, const char *salt ) );
#endif

#if	defined(MSDOS)
#define NOCRYPT
#if	defined(unix)
#undef	unix
#endif
#endif

#if	defined(NeXT)
char *	crypt		args( ( const char *key, const char *salt ) );
#endif

#if	defined(sequent)
char *	crypt		args( ( const char *key, const char *salt ) );
int	fclose		args( ( FILE *stream ) );
int	fprintf		args( ( FILE *stream, const char *format, ... ) );
int	fread		args( ( void *ptr, int size, int n, FILE *stream ) );
int	fseek		args( ( FILE *stream, long offset, int ptrname ) );
void	perror		args( ( const char *s ) );
int	ungetc		args( ( int c, FILE *stream ) );
#endif

#if	defined(sun)
char *	crypt		args( ( const char *key, const char *salt ) );
int	fclose		args( ( FILE *stream ) );
int	fprintf		args( ( FILE *stream, const char *format, ... ) );
#if	defined(SYSV)
siz_t	fread		args( ( void *ptr, size_t size, size_t n, 
			    FILE *stream) );
#else
int	fread		args( ( void *ptr, int size, int n, FILE *stream ) );
#endif
int	fseek		args( ( FILE *stream, long offset, int ptrname ) );
void	perror		args( ( const char *s ) );
int	ungetc		args( ( int c, FILE *stream ) );
#endif

#if	defined(ultrix)
char *	crypt		args( ( const char *key, const char *salt ) );
#endif



/*
 * The crypt(3) function is not available on some operating systems.
 * In particular, the U.S. Government prohibits its export from the
 *   United States to foreign countries.
 * Turn on NOCRYPT to keep passwords in plain text.
 */
/*
#if	defined(NOCRYPT)
#define crypt(s1, s2)	(s1)
#endif
*/


I appear to have nocrypt commented out so it should be turned off.

What am i missing? I appreciate the help!!
Top

Posted by YoshoFyre   (29 posts)  Bio
Date Reply #1 on Tue 15 Mar 2022 01:55 AM (UTC)

Amended on Tue 15 Mar 2022 01:57 AM (UTC) by YoshoFyre

Message
if this helps

my entire merc.h file is here

https://pastebin.com/raw/STVxccWY
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #2 on Tue 15 Mar 2022 04:47 AM (UTC)
Message
Quote:

What am i missing?


You haven't said exactly what the problem is. Are you getting error messages?

Maybe crypt is defined somewhere else to do nothing.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by YoshoFyre   (29 posts)  Bio
Date Reply #3 on Tue 15 Mar 2022 11:06 AM (UTC)

Amended on Tue 15 Mar 2022 11:09 AM (UTC) by YoshoFyre

Message
Nick Gammon said:

Quote:

What am i missing?


You haven't said exactly what the problem is. Are you getting error messages?

Maybe crypt is defined somewhere else to do nothing.

No error messages. Everything runs just fine, the passwords are just in plain text. I originally had assumed crypting the passwords was something that i would need to add to the code, but when i saw that section in merc.h, i realized that that feature is there, but it not working (or turned on).

the mud is storing passwords in plain text and checking/verifying passwords in plain text.

I guess I am asking how it is supposed to be setup? as well as asking if the the code is good, if this is possibly an issue with linux that I need to correct.

when i get home today, i'll search every file for the crypt function and see if it is defined to do nothing somewhere.
Top

Posted by YoshoFyre   (29 posts)  Bio
Date Reply #4 on Wed 16 Mar 2022 12:20 AM (UTC)
Message
ok, so i searched every file and found nothing that would make crypt() do nothing.

Researching how crypt() works, it appears that (for example)

pwd = crypt("usertext" "two char salt")


pwd = crypt("mypass" "ab");


which should return a salted hash that would compare against "mypass" whenever mypass is passed in to the function.

I found this in my code, and checked and also found it in the stock ROM 2.4b code (unmodified)


  if ( strcmp( crypt( arg1, ch->pcdata->pwd ), ch->pcdata->pwd ) )
    {
	WAIT_STATE( ch, 40 );
	send_to_char( "Wrong password.  Wait 10 seconds.\n\r", ch );
	return;
    }


this code compares the user input against the pwd in the pfile, where "arg1" is the user input.

however, it appears that instead of using the 2 character salt for the second argument of crypt(), it is using the existing password. Then strcmp compares the result of crypt() against the stored password.

later in the code, for changing the password, this is used


pwdnew = crypt( arg2, ch->name );
    for ( p = pwdnew; *p != '\0'; p++ )
    {
	if ( *p == '~' )
	{
	    send_to_char(
		"New password not acceptable, try again.\n\r", ch );
	    return;
	}
    }

    free_string( ch->pcdata->pwd );
    ch->pcdata->pwd = str_dup( pwdnew );
    save_char_obj( ch );


specifically

pwdnew = crypt( arg2, ch->name );

where "arg2" is the new password typed by the user. It seems now for the salt argument, it is using the user's name.

Am i right in thinking that the usage of crypt() is incorrect in these examples, and that i need to rework every use of it?
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #5 on Wed 16 Mar 2022 05:42 AM (UTC)
Message
The code you posted certainly seems wrong. The argument to crypt should be the password and some salt, and in the case you showed it appears to be what the user typed, and the current password, which doesn't make any sense, UNLESS crypt is not doing anything meaningful.

I made up a test case:


#include <crypt.h>
#include <stdio.h>

int main (void)
  {
  printf ("Encrypted pw is %s\n", crypt ("swordfish", "nick"));
  return 0;
  }


Compiling that:


gcc crypttest.c -lcrypt


And running it, I get:


Encrypted pw is ni8xGPF.piRm6


So it seems my version of crypt is working. Are you linking against the crypt library? Maybe you are, without realising it, linking against a "do nothing" implementation of crypt.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by YoshoFyre   (29 posts)  Bio
Date Reply #6 on Mon 21 Mar 2022 07:56 PM (UTC)

Amended on Tue 22 Mar 2022 01:05 AM (UTC) by YoshoFyre

Message
Nick Gammon said:
So it seems my version of crypt is working. Are you linking against the crypt library? Maybe you are, without realising it, linking against a "do nothing" implementation of crypt.

Found it!!!

I verified that crypt was in fact working on my box.

I then noticed that at the top of merc.h, crypt was in fact defined to do nothing.

I removed it, and changed the salted argument in act_info.c and comm.c to match.

I then found in my Makefile that although -lcrypt was listed in the LIBS section, the actual command did not include $(LIBS) at the end of it.

I found i can no longer log in, but when i make a new character, its password is crypted and can login as it pleases.

Now to create a function so that when an older pfile attempts to log in, it will force them to update their password so that it will be crypted.

Thanks for the help!

Edit: Just to document, this is what i did to migrate my pfiles to crypted passwords. I found that the pfiles have a Vers (version) number. So i set the version number up 1 from where it was in save.c, and then in comm.c after the password is entered, i have it check the pfile for the orig version number. If the orig version number is found in the pfile, it verifies the password entered matches the password in the pfile (plain text), and if it matches, it crypts the current password, and updates the pfile version to the new version and saves the pfile.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


10,441 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.