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 }