diff --git a/proto.txt b/proto.txt
index 16198309e10f16c56fb864bda651c4d7052e794d..e68ed763285e18df18ccca9862da0b80a0c4d8be 100644
--- 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) ---
diff --git a/src/client/Makefile b/src/client/Makefile
index 8c376c3f28a25640187439acf28b662e915dd449..eda60fe662b1f526c3d3d19ede776a57a6ee3028 100644
--- a/src/client/Makefile
+++ b/src/client/Makefile
@@ -1,6 +1,6 @@
 
 CFLAGS := -Wall -Werror -g
-LDFLAGS := -g -lncurses
+LDFLAGS := -g -lncurses -lssl
 
 BIN := ../../dispense
 OBJ := main.o
diff --git a/src/client/main.c b/src/client/main.c
index 1f38f7ed9ebd13b972eaf6520794ece034fb7426..c82d12d793f1bad6334452d23df3f3b0139d5b8f 100644
--- a/src/client/main.c
+++ b/src/client/main.c
@@ -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);
diff --git a/src/cokebank_basic/main.c b/src/cokebank_basic/main.c
index 96888c0b6c604d1c0b79f8eb6e4baa9862f8cc01..62d49b85d1d7e313b76905c6cb9dafec74943e3f 100644
--- a/src/cokebank_basic/main.c
+++ b/src/cokebank_basic/main.c
@@ -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;
-}
-
diff --git a/src/server/Makefile b/src/server/Makefile
index 10e64eb70f9b8ab9305feeed5972a530fb2d7abf..85678a86d7b252dea55db0fe1d0b6d59e66d155d 100644
--- a/src/server/Makefile
+++ b/src/server/Makefile
@@ -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
diff --git a/src/server/common.h b/src/server/common.h
index d790c8253ae170d4e802523f551062e005b79251..f2eea0cdb066b4cca63a024b834cf2f47b24cce7 100644
--- a/src/server/common.h
+++ b/src/server/common.h
@@ -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
diff --git a/src/server/handler_door.c b/src/server/handler_door.c
index c132e07f8a2b4c46d76303d8095f5bd665e22214..1ffcc857feb599bdb05d0ce9ac03cc4ae05f984d 100644
--- a/src/server/handler_door.c
+++ b/src/server/handler_door.c
@@ -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;
diff --git a/src/server/server.c b/src/server/server.c
index 44f3fa768b583ee0ad7c83c5f894912f149de06c..5d375ee7130719d7ef42a0555cd1c56ce43ab343 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -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)