00001 /********************************************************************
00002 Description:
00003 part of the 3Dsia project
00004 created: xandi
00005
00006 History:
00007 date, name, changes, in funtion
00008 180400 StonedBones added dynamic packet length
00009
00010 ********************************************************************/
00011
00012 #include "shadow.h"
00013
00014 #include <string.h>
00015 #include <pwd.h>
00016 #include <shadow.h>
00017 #include <crypt.h>
00018 #include <malloc.h>
00019
00020 #include <stdio.h>
00021
00022 bool AuthenticateShadow (packet* pak, Buffer *in) {
00023 char name[100], password[100];
00024 struct passwd *passwrd;
00025
00026 if ((pak->h.header[0] != PROT_AUTHENTICATE) || (pak->h.header[1] != AUTH_PASSWORD)) {
00027 return false;
00028 }
00029
00030 if (((int) strlen(pak->data.c_str ())) != (pak->h.header[2] + pak->h.header[3])) {
00031 return false;
00032 }
00033
00034 /*this splits the clientPacket-data, which includes the name and the password
00035 into two variables. */
00036 memcpy ( &name, pak->data.c_str (), pak->h.header[2] );
00037 memcpy ( &password, pak->data.c_str () + pak->h.header[2], pak->h.header[3] );
00038
00039 name[pak->h.header[2]] = '\0';
00040 password[pak->h.header[3]] = '\0';
00041
00042 passwrd = getpwnam ( name ); /* returns NULL when the name does not exist. */
00043
00044 if (!passwrd) /* name does not exist */
00045 {
00046 return false;
00047 }
00048
00049 if (strcmp (passwrd->pw_name, "x") == 0) // non-shadowed systems not supported
00050 {
00051 return false;
00052 }
00053
00054 if (CheckShadowed (name, password))
00055 {
00056 packet* temp = new ( packet );
00057
00058 temp->h.header[0] = PROT_REGISTER_ENTITY;
00059 temp->data = name;
00060
00061 in->write(temp);
00062
00063 return true;
00064 }
00065
00066 return false;
00067 }
00068
00069 bool CheckShadowed ( char *name, char *password )
00070 {
00071 struct spwd *shadow;
00072 char *salt;
00073
00074 salt = (char *) malloc ( 2 );
00075
00076 setspent (); /*this is necessary to be read in a clean way */
00077
00078 shadow = getspnam ( name );
00079
00080 if(shadow==NULL) { /* we have a failure then */
00081 return false;
00082 };
00083
00084 endspent ();
00085
00086 salt[0] = shadow->sp_pwdp[0];
00087 salt[1] = shadow->sp_pwdp[1];
00088
00089 if ( strcmp ( shadow->sp_pwdp, crypt ( password, salt ) ) == 0 )
00090 {
00091 return true;
00092 }
00093
00094 return false;
00095 }