Working on password-based user auth
authorJohn Hodge <[email protected]>
Sat, 4 Dec 2010 09:43:22 +0000 (17:43 +0800)
committerJohn Hodge <[email protected]>
Sat, 4 Dec 2010 09:43:22 +0000 (17:43 +0800)
proto.txt
src/client/Makefile
src/client/main.c
src/cokebank_basic/main.c
src/server/Makefile
src/server/common.h
src/server/handler_door.c
src/server/server.c

index 1619830..e68ed76 100644 (file)
--- a/proto.txt
+++ b/proto.txt
@@ -27,7 +27,7 @@ general they will be limited to the standard alpha-numeric set
 === User Auth ===
 c      USER <username>\n
 s      100 SALT <string>\n or 100 User Set\n   (If no salt used)
-c      PASS <hash>\n   (Hex-Encoded SHA-512 Hash of <username><salt><password>)
+c      PASS <hash>\n   (Hex-Encoded SHA-1 Hash of <username><salt><password>)
 s      200 Auth OK\n or 401 Auth Failure\n
 User is now authenticated
 --- Alternate Method (Implicit Trust Authentication) ---
index 8c376c3..eda60fe 100644 (file)
@@ -1,6 +1,6 @@
 
 CFLAGS := -Wall -Werror -g
-LDFLAGS := -g -lncurses
+LDFLAGS := -g -lncurses -lssl
 
 BIN := ../../dispense
 OBJ := main.o
index 1f38f7e..c82d12d 100644 (file)
@@ -22,6 +22,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <openssl/sha.h>       // SHA1
 
 // === TYPES ===
 typedef struct sItem {
@@ -46,8 +47,7 @@ char  *gsDispenseServer = "localhost";
  int   giDispensePort = 11020;
 tItem  *gaItems;
  int   giNumItems;
-regex_t        gArrayRegex;
-regex_t        gItemRegex;
+regex_t        gArrayRegex, gItemRegex, gSaltRegex;
 
 // === CODE ===
 int main(int argc, char *argv[])
@@ -61,6 +61,8 @@ int main(int argc, char *argv[])
        CompileRegex(&gArrayRegex, "^([0-9]{3})\\s+([A-Za-z]+)\\s+([0-9]+)", REG_EXTENDED);     //
        // > Code Type Ident Price Desc
        CompileRegex(&gItemRegex, "^([0-9]{3})\\s+(.+?)\\s+(.+?)\\s+([0-9]+)\\s+(.+)$", REG_EXTENDED);
+       // > Code 'SALT' salt
+       CompileRegex(&gSaltRegex, "^([0-9]{3})\\s+(.+)\\s+(.+)$", REG_EXTENDED);
        
        // Connect to server
        sock = OpenConnection(gsDispenseServer, giDispensePort);
@@ -156,8 +158,6 @@ int main(int argc, char *argv[])
                printf("%3i %s\n", gaItems[i].Price, gaItems[i].Desc);
        }
        
-       Authenticate(sock);
-       
        // and choose what to dispense
        // TODO: ncurses interface (with separation between item classes)
        // - Hmm... that would require standardising the item ID to be <class>:<index>
@@ -194,6 +194,8 @@ int main(int argc, char *argv[])
        }
        #endif
        
+       Authenticate(sock);
+       
        if( i >= 0 )
        {       
                // Dispense!
@@ -483,6 +485,8 @@ void Authenticate(int Socket)
        struct passwd   *pwd;
        char    buf[512];
         int    responseCode;
+       char    salt[32];
+       regmatch_t      matches[4];
        
        // Get user name
        pwd = getpwuid( getuid() );
@@ -500,6 +504,50 @@ void Authenticate(int Socket)
        case 200:       // Authenticated, return :)
                return ;
        case 401:       // Untrusted, attempt password authentication
+               sendf(Socket, "USER %s\n", pwd->pw_name);
+               printf("Using username %s\n", pwd->pw_name);
+               
+               recv(Socket, buf, 511, 0);
+               trim(buf);
+               // TODO: Get Salt
+               // Expected format: 100 SALT <something> ...
+               // OR             : 100 User Set
+               printf("string = '%s'\n", buf);
+               RunRegex(&gSaltRegex, buf, 4, matches, "Malformed server response");
+               if( atoi(buf) != 100 ) {
+                       exit(-1);       // ERROR
+               }
+               if( memcmp( buf+matches[2].rm_so, "SALT", matches[2].rm_eo - matches[2].rm_so) == 0) {
+                       // Set salt
+                       memcpy( salt, buf + matches[3].rm_so, matches[3].rm_eo - matches[3].rm_so );
+                       salt[ matches[3].rm_eo - matches[3].rm_so ] = 0;
+                       printf("Salt: '%s'\n", salt);
+               }
+               
+               fflush(stdout);
+               {
+                        int    ofs = strlen(pwd->pw_name)+strlen(salt);
+                       char    tmp[ofs+20];
+                       char    *pass = getpass("Password: ");
+                       uint8_t h[20];
+                       
+                       strcpy(tmp, pwd->pw_name);
+                       strcat(tmp, salt);
+                       SHA1( (unsigned char*)pass, strlen(pass), h );
+                       memcpy(tmp+ofs, h, 20);
+                       
+                       // Hash all that
+                       SHA1( (unsigned char*)tmp, ofs+20, h );
+                       sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+                               h[ 0], h[ 1], h[ 2], h[ 3], h[ 4], h[ 5], h[ 6], h[ 7], h[ 8], h[ 9],
+                               h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19]
+                               );
+                       printf("Final hash: '%s'\n", buf);
+                       fflush(stdout); // Debug
+               }
+               
+               sendf(Socket, "PASS %s\n", buf);
+               recv(Socket, buf, 511, 0);
                break;
        case 404:       // Bad Username
                fprintf(stderr, "Bad Username '%s'\n", pwd->pw_name);
index 96888c0..62d49b8 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <pwd.h>
 #include <string.h>
+#include <openssl/sha.h>
 #include "common.h"
 
 #define HACK_TPG_NOAUTH        1
@@ -132,16 +133,3 @@ int GetUserID(const char *Username)
        return ret;
 }
 
-/**
- * \brief Authenticate a user
- * \return User ID, or -1 if authentication failed
- */
-int GetUserAuth(const char *Username, const char *Password)
-{
-       #if HACK_TPG_NOAUTH
-       if( strcmp(Username, "tpg") == 0 )
-               return GetUserID("tpg");
-       #endif
-       return -1;
-}
-
index 10e64eb..85678a8 100644 (file)
@@ -3,7 +3,7 @@
 
 OBJ := main.o server.o logging.o
 OBJ += dispense.o itemdb.o
-OBJ += handler_coke.o handler_snack.o
+OBJ += handler_coke.o handler_snack.o handler_door.o
 BIN := ../../dispsrv
 
 LINKFLAGS := -g ../../cokebank.so
index d790c82..f2eea0c 100644 (file)
@@ -73,6 +73,5 @@ extern int    Transfer(int SourceUser, int DestUser, int Ammount, const char *Reaso
 extern int     GetBalance(int User);
 extern char    *GetUserName(int User);
 extern int     GetUserID(const char *Username);
-extern int     GetUserAuth(const char *Username, const char *Password);
 
 #endif
index c132e07..1ffcc85 100644 (file)
@@ -57,12 +57,12 @@ int Door_CanDispense(int User, int Item)
  */
 int Door_DoDispense(int User, int Item)
 {
-       char    tmp[32], *status;
-       regmatch_t      matches[4];
 
        // Sanity please
        if( Item != 0 ) return -1;
        
+       // Check if user is in door
+       
        // llogin or other
 
        return 0;
index 44f3fa7..5d375ee 100644 (file)
@@ -50,6 +50,7 @@ char  *Server_Cmd_ENUMITEMS(tClient *Client, char *Args);
 char   *Server_Cmd_ITEMINFO(tClient *Client, char *Args);
 char   *Server_Cmd_DISPENSE(tClient *Client, char *Args);
 // --- Helpers ---
+ int   GetUserAuth(const char *Salt, const char *Username, const uint8_t *Hash);
 void   HexBin(uint8_t *Dest, char *Src, int BufSize);
 
 // === GLOBALS ===
@@ -307,7 +308,7 @@ char *Server_Cmd_PASS(tClient *Client, char *Args)
        
        // TODO: Decrypt password passed
        
-       Client->UID = GetUserAuth(Client->Username, "");
+       Client->UID = GetUserAuth(Client->Salt, Client->Username, clienthash);
 
        if( Client->UID != -1 ) {
                Client->bIsAuthed = 1;
@@ -503,6 +504,43 @@ char *Server_Cmd_GIVE(tClient *Client, char *Args)
        }
 }
 
+/**
+ * \brief Authenticate a user
+ * \return User ID, or -1 if authentication failed
+ */
+int GetUserAuth(const char *Salt, const char *Username, const uint8_t *ProvidedHash)
+{
+       #if 0
+       uint8_t h[20];
+        int    ofs = strlen(Username) + strlen(Salt);
+       char    input[ ofs + 40 + 1];
+       char    tmp[4 + strlen(Username) + 1];  // uid=%s
+       #endif
+       
+       #if HACK_TPG_NOAUTH
+       if( strcmp(Username, "tpg") == 0 )
+               return GetUserID("tpg");
+       #endif
+       
+       #if 0
+       //
+       strcpy(input, Username);
+       strcpy(input, Salt);
+       // TODO: Get user's SHA-1 hash
+       sprintf(tmp, "uid=%s", Username);
+       ldap_search_s(ld, "", LDAP_SCOPE_BASE, tmp, "userPassword", 0, res);
+       
+       sprintf(input+ofs, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+               h[ 0], h[ 1], h[ 2], h[ 3], h[ 4], h[ 5], h[ 6], h[ 7], h[ 8], h[ 9],
+               h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19]
+               );
+       // Then create the hash from the provided salt
+       // Compare that with the provided hash
+       #endif
+       
+       return -1;
+}
+
 // --- INTERNAL HELPERS ---
 // TODO: Move to another file
 void HexBin(uint8_t *Dest, char *Src, int BufSize)

UCC git Repository :: git.ucc.asn.au