diff --git a/proto.txt b/proto.txt
index 4f4da81635f1acf0404f557e39057eb120d189ab..0e2575b72c6d16995d49de1ffbd5856128213ffa 100644
--- a/proto.txt
+++ b/proto.txt
@@ -29,7 +29,7 @@ c	PASS <hash>\n	(Hex-Encoded SHA-512 Hash of <username><salt><password>)
 s	200 Auth OK\n or 401 Auth Failure\n
 User is now authenticated
 --- Alternate Method (Implicit Trust Authentication) ---
-If the client is connecting from a trusted machine on a low port then
+If the client is connecting from a trusted machine on a root port then
 automatic authentication is allowed
 c	AUTOAUTH <username>\n
 s	200 Auth OK\n or 401 Auth Failure\n or 401 Untrusted\n
diff --git a/server/src/cokebank.c b/server/src/cokebank.c
index cb29eaf778320a1e8fe7da8016bc7d56c8664d23..4f7e8cd5ceeebaac1d7f3dc323d08b600c0f9216 100644
--- a/server/src/cokebank.c
+++ b/server/src/cokebank.c
@@ -33,6 +33,9 @@ char *GetUserName(int User)
 	return NULL;
 }
 
+/**
+ * \brief Get the User ID of the named user
+ */
 int GetUserID(const char *Username)
 {
 	return 0;
diff --git a/server/src/server.c b/server/src/server.c
index f97af758b22b07d5e5d103a829cbc2d2a95543a0..e7dbc7078f0513dba01ac022026e641d96287b68 100644
--- a/server/src/server.c
+++ b/server/src/server.c
@@ -19,12 +19,17 @@
 #define MAX_CONNECTION_QUEUE	5
 #define INPUT_BUFFER_SIZE	256
 
+#define HASH_TYPE	SHA512
+#define HASH_LENGTH	64
+
 #define MSG_STR_TOO_LONG	"499 Command too long (limit "EXPSTR(INPUT_BUFFER_SIZE)")\n"
 
 // === TYPES ===
 typedef struct sClient
 {
 	 int	ID;	// Client ID
+	 
+	 int	bIsTrusted;	// Is the connection from a trusted host/port
 	
 	char	*Username;
 	char	Salt[9];
@@ -35,11 +40,12 @@ typedef struct sClient
 
 // === PROTOTYPES ===
 void	Server_Start(void);
-void	Server_HandleClient(int Socket);
+void	Server_HandleClient(int Socket, int bTrusted);
 char	*Server_ParseClientCommand(tClient *Client, char *CommandString);
 // --- Commands ---
 char	*Server_Cmd_USER(tClient *Client, char *Args);
 char	*Server_Cmd_PASS(tClient *Client, char *Args);
+char	*Server_Cmd_AUTOAUTH(tClient *Client, char *Args);
 // --- Helpers ---
 void	HexBin(uint8_t *Dest, char *Src, int BufSize);
 
@@ -52,7 +58,8 @@ struct sClientCommand {
 	char	*(*Function)(tClient *Client, char *Arguments);
 }	gaServer_Commands[] = {
 	{"USER", Server_Cmd_USER},
-	{"PASS", Server_Cmd_PASS}
+	{"PASS", Server_Cmd_PASS},
+	{"AUTOAUTH", Server_Cmd_AUTOAUTH}
 };
 #define NUM_COMMANDS	(sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0]))
 
@@ -95,6 +102,7 @@ void Server_Start(void)
 	for(;;)
 	{
 		uint	len = sizeof(client_addr);
+		 int	bTrusted = 0;
 		
 		client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &len);
 		if(client_socket < 0) {
@@ -105,11 +113,29 @@ void Server_Start(void)
 		if(giDebugLevel >= 2) {
 			char	ipstr[INET_ADDRSTRLEN];
 			inet_ntop(AF_INET, &client_addr.sin_addr, ipstr, INET_ADDRSTRLEN);
-			printf("Client connection from %s\n", ipstr);
+			printf("Client connection from %s:%i\n",
+				ipstr, ntohs(client_addr.sin_port));
+		}
+		
+		// Trusted Connections
+		if( ntohs(client_addr.sin_port) < 1024 )
+		{
+			// TODO: Make this runtime configurable
+			switch( ntohl( client_addr.sin_addr.s_addr ) )
+			{
+			case 0x7F000001:	// 127.0.0.1	localhost
+			//case 0x825E0D00:	// 130.95.13.0
+			case 0x825E0D12:	// 130.95.13.18	mussel
+			case 0x825E0D17:	// 130.95.13.23	martello
+				bTrusted = 1;
+				break;
+			default:
+				break;
+			}
 		}
 		
 		// TODO: Multithread this?
-		Server_HandleClient(client_socket);
+		Server_HandleClient(client_socket, bTrusted);
 		
 		close(client_socket);
 	}
@@ -118,8 +144,9 @@ void Server_Start(void)
 /**
  * \brief Reads from a client socket and parses the command strings
  * \param Socket	Client socket number/handle
+ * \param bTrusted	Is the client trusted?
  */
-void Server_HandleClient(int Socket)
+void Server_HandleClient(int Socket, int bTrusted)
 {
 	char	inbuf[INPUT_BUFFER_SIZE];
 	char	*buf = inbuf;
@@ -129,7 +156,8 @@ void Server_HandleClient(int Socket)
 	
 	// Initialise Client info
 	clientInfo.ID = giServer_NextClientID ++;
-		
+	clientInfo.bIsTrusted = bTrusted;
+	
 	// Read from client
 	/*
 	 * Notes:
@@ -181,7 +209,7 @@ void Server_HandleClient(int Socket)
 	}
 	
 	if(giDebugLevel >= 2) {
-		printf("Client %i disconnected\n", clientInfo.ID);
+		printf("Client %i: Disconnected\n", clientInfo.ID);
 	}
 }
 
@@ -257,6 +285,7 @@ char *Server_Cmd_USER(tClient *Client, char *Args)
 	#endif
 	return ret;
 }
+
 /**
  * \brief Authenticate as a user
  * 
@@ -264,15 +293,15 @@ char *Server_Cmd_USER(tClient *Client, char *Args)
  */
 char *Server_Cmd_PASS(tClient *Client, char *Args)
 {
-	uint8_t	clienthash[64] = {0};
+	uint8_t	clienthash[HASH_LENGTH] = {0};
 	
 	// Read user's hash
-	HexBin(clienthash, Args, 64);
+	HexBin(clienthash, Args, HASH_LENGTH);
 	
 	if( giDebugLevel ) {
 		 int	i;
 		printf("Client %i: Password hash ", Client->ID);
-		for(i=0;i<64;i++)
+		for(i=0;i<HASH_LENGTH;i++)
 			printf("%02x", clienthash[i]&0xFF);
 		printf("\n");
 	}
@@ -280,6 +309,37 @@ char *Server_Cmd_PASS(tClient *Client, char *Args)
 	return strdup("401 Auth Failure\n");
 }
 
+/**
+ * \brief Authenticate as a user without a password
+ * 
+ * Usage: AUTOAUTH <user>
+ */
+char *Server_Cmd_AUTOAUTH(tClient *Client, char *Args)
+{
+	char	*spos = strchr(Args, ' ');
+	if(spos)	*spos = '\0';	// Remove characters after the ' '
+	
+	// Check if trusted
+	if( !Client->bIsTrusted ) {
+		if(giDebugLevel)
+			printf("Client %i: Untrusted client attempting to AUTOAUTH\n", Client->ID);
+		return strdup("401 Untrusted\n");
+	}
+	
+	// Get UID
+	Client->UID = GetUserID( Args );
+	if( Client->UID <= 0 ) {
+		if(giDebugLevel)
+			printf("Client %i: Unknown user '%s'\n", Client->ID, Args);
+		return strdup("401 Auth Failure\n");
+	}
+	
+	if(giDebugLevel)
+		printf("Client %i: Authenticated as '%s' (%i)\n", Client->ID, Args, Client->UID);
+	
+	return strdup("200 Auth OK\n");
+}
+
 // --- INTERNAL HELPERS ---
 // TODO: Move to another file
 void HexBin(uint8_t *Dest, char *Src, int BufSize)
@@ -291,9 +351,9 @@ void HexBin(uint8_t *Dest, char *Src, int BufSize)
 		
 		if('0' <= *Src && *Src <= '9')
 			val |= (*Src-'0') << 4;
-		else if('A' <= *Src && *Src <= 'B')
+		else if('A' <= *Src && *Src <= 'F')
 			val |= (*Src-'A'+10) << 4;
-		else if('a' <= *Src && *Src <= 'b')
+		else if('a' <= *Src && *Src <= 'f')
 			val |= (*Src-'a'+10) << 4;
 		else
 			break;
@@ -301,9 +361,9 @@ void HexBin(uint8_t *Dest, char *Src, int BufSize)
 		
 		if('0' <= *Src && *Src <= '9')
 			val |= (*Src-'0');
-		else if('A' <= *Src && *Src <= 'B')
+		else if('A' <= *Src && *Src <= 'F')
 			val |= (*Src-'A'+10);
-		else if('a' <= *Src && *Src <= 'b')
+		else if('a' <= *Src && *Src <= 'f')
 			val |= (*Src-'a'+10);
 		else
 			break;