Commit 32896c9b authored by John Hodge's avatar John Hodge
Browse files

Server - add MIFARE cards

parent 857e7c75
......@@ -29,6 +29,7 @@ numbers.
404 Bad other username
406 Bad Item ID
407 Invalid arguments
408 Already exists
500 Unknown Dispense Failure
501 Action Rejected
......
......@@ -69,6 +69,7 @@ void Server_Cmd_USER(tClient *Client, char *Args);
void Server_Cmd_PASS(tClient *Client, char *Args);
void Server_Cmd_AUTOAUTH(tClient *Client, char *Args);
void Server_Cmd_AUTHIDENT(tClient *Client, char *Args);
void Server_Cmd_AUTHCARD(tClient* Client, char *Args);
void Server_Cmd_SETEUSER(tClient *Client, char *Args);
void Server_Cmd_ENUMITEMS(tClient *Client, char *Args);
void Server_Cmd_ITEMINFO(tClient *Client, char *Args);
......@@ -86,6 +87,7 @@ void Server_Cmd_USERFLAGS(tClient *Client, char *Args);
void Server_Cmd_UPDATEITEM(tClient *Client, char *Args);
void Server_Cmd_PINCHECK(tClient *Client, char *Args);
void Server_Cmd_PINSET(tClient *Client, char *Args);
void Server_Cmd_CARDADD(tClient *Client, char *Args);
// --- Helpers ---
void Debug(tClient *Client, const char *Format, ...);
int sendf(int Socket, const char *Format, ...);
......@@ -102,6 +104,7 @@ const struct sClientCommand {
{"PASS", Server_Cmd_PASS},
{"AUTOAUTH", Server_Cmd_AUTOAUTH},
{"AUTHIDENT", Server_Cmd_AUTHIDENT},
{"AUTHCARD", Server_Cmd_AUTHCARD},
{"SETEUSER", Server_Cmd_SETEUSER},
{"ENUM_ITEMS", Server_Cmd_ENUMITEMS},
{"ITEM_INFO", Server_Cmd_ITEMINFO},
......@@ -117,7 +120,8 @@ const struct sClientCommand {
{"USER_FLAGS", Server_Cmd_USERFLAGS},
{"UPDATE_ITEM", Server_Cmd_UPDATEITEM},
{"PIN_CHECK", Server_Cmd_PINCHECK},
{"PIN_SET", Server_Cmd_PINSET}
{"PIN_SET", Server_Cmd_PINSET},
{"CARD_ADD", Server_Cmd_CARDADD},
};
#define NUM_COMMANDS ((int)(sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0])))
......@@ -476,6 +480,62 @@ void Server_Cmd_USER(tClient *Client, char *Args)
#endif
}
/// UID: User ID (must be valid)
/// username: Optional username
bool authenticate(tClient* Client, int UID, const char* username)
{
Client->UID = UID;
int flags = Bank_GetFlags(Client->UID);
if( flags & USER_FLAG_DISABLED ) {
Client->UID = -1;
sendf(Client->Socket, "403 Authentication failure: account disabled\n");
return false;
}
// You can't be an internal account
if( flags & USER_FLAG_INTERNAL ) {
if(giDebugLevel)
Debug(Client, "IDENT auth as '%s', not allowed", username);
Client->UID = -1;
sendf(Client->Socket, "403 Authentication failure: that account is internal\n");
return false;
}
// Save username
if(Client->Username != username)
{
if(Client->Username)
{
free(Client->Username);
}
// Fetch username (if not provided)
if( username )
{
Client->Username = strdup(username);
}
else
{
Client->Username = Bank_GetAcctName(UID);
}
}
Client->bIsAuthed = 1;
if(giDebugLevel)
Debug(Client, "Auto authenticated as '%s' (%i)", Client->Username, Client->UID);
return true;
}
bool require_auth(tClient* Client)
{
// Check authentication
if( !Client->bIsAuthed ) {
sendf(Client->Socket, "401 Not Authenticated\n");
return false;
}
return true;
}
/**
* \brief Authenticate as a user
*
......@@ -484,7 +544,6 @@ void Server_Cmd_USER(tClient *Client, char *Args)
void Server_Cmd_PASS(tClient *Client, char *Args)
{
char *passhash;
int flags;
if( Server_int_ParseArgs(0, Args, &passhash, NULL) )
{
......@@ -493,26 +552,17 @@ void Server_Cmd_PASS(tClient *Client, char *Args)
}
// Pass on to cokebank
Client->UID = Bank_GetUserAuth(Client->Salt, Client->Username, passhash);
if( Client->UID == -1 ) {
sendf(Client->Socket, "401 Auth Failure\n");
return ;
}
flags = Bank_GetFlags(Client->UID);
if( flags & USER_FLAG_DISABLED ) {
Client->UID = -1;
sendf(Client->Socket, "403 Account Disabled\n");
int uid = Bank_GetUserAuth(Client->Salt, Client->Username, passhash);
if( uid < 0 ) {
if(giDebugLevel)
Debug(Client, "Unknown user '%s'", Client->Username);
sendf(Client->Socket, "403 Authentication failure: unknown account\n");
return ;
}
if( flags & USER_FLAG_INTERNAL ) {
Client->UID = -1;
sendf(Client->Socket, "403 Internal account\n");
return ;
if( ! authenticate(Client, uid, Client->Username) )
{
return;
}
Client->bIsAuthed = 1;
sendf(Client->Socket, "200 Auth OK\n");
}
......@@ -524,7 +574,6 @@ void Server_Cmd_PASS(tClient *Client, char *Args)
void Server_Cmd_AUTOAUTH(tClient *Client, char *Args)
{
char *username;
int userflags;
if( Server_int_ParseArgs(0, Args, &username, NULL) )
{
......@@ -541,40 +590,17 @@ void Server_Cmd_AUTOAUTH(tClient *Client, char *Args)
}
// Get UID
Client->UID = Bank_GetAcctByName( username, 0 );
if( Client->UID < 0 ) {
int uid = Bank_GetAcctByName( username, /*bCreate=*/0 );
if( uid < 0 ) {
if(giDebugLevel)
Debug(Client, "Unknown user '%s'", username);
sendf(Client->Socket, "403 Auth Failure\n");
return ;
}
userflags = Bank_GetFlags(Client->UID);
// You can't be an internal account
if( userflags & USER_FLAG_INTERNAL ) {
if(giDebugLevel)
Debug(Client, "Autoauth as '%s', not allowed", username);
Client->UID = -1;
sendf(Client->Socket, "403 Account is internal\n");
sendf(Client->Socket, "403 Authentication failure: unknown account\n");
return ;
}
// Disabled accounts
if( userflags & USER_FLAG_DISABLED ) {
Client->UID = -1;
sendf(Client->Socket, "403 Account disabled\n");
return ;
if( ! authenticate(Client, uid, username) )
{
return;
}
// Save username
if(Client->Username)
free(Client->Username);
Client->Username = strdup(username);
Client->bIsAuthed = 1;
if(giDebugLevel)
Debug(Client, "Auto authenticated as '%s' (%i)", username, Client->UID);
sendf(Client->Socket, "200 Auth OK\n");
}
......@@ -587,8 +613,7 @@ void Server_Cmd_AUTOAUTH(tClient *Client, char *Args)
void Server_Cmd_AUTHIDENT(tClient *Client, char *Args)
{
char *username;
int userflags;
const int ident_timeout = 5;
const int IDENT_TIMEOUT = 5;
if( Args != NULL && strlen(Args) ) {
sendf(Client->Socket, "407 AUTHIDENT takes no arguments\n");
......@@ -604,54 +629,63 @@ void Server_Cmd_AUTHIDENT(tClient *Client, char *Args)
}
// Get username via IDENT
username = ident_id(Client->Socket, ident_timeout);
username = ident_id(Client->Socket, IDENT_TIMEOUT);
if( !username ) {
perror("AUTHIDENT - IDENT timed out");
sendf(Client->Socket, "403 Authentication failure: IDENT auth timed out\n");
return ;
}
// Get UID
Client->UID = Bank_GetAcctByName( username, 0 );
if( Client->UID < 0 ) {
int uid = Bank_GetAcctByName(username, /*bCreate=*/0);
if( uid < 0 ) {
if(giDebugLevel)
Debug(Client, "Unknown user '%s'", username);
sendf(Client->Socket, "403 Authentication failure: unknown account\n");
free(username);
return ;
}
userflags = Bank_GetFlags(Client->UID);
// You can't be an internal account
if( userflags & USER_FLAG_INTERNAL ) {
if(giDebugLevel)
Debug(Client, "IDENT auth as '%s', not allowed", username);
Client->UID = -1;
sendf(Client->Socket, "403 Authentication failure: that account is internal\n");
if( ! authenticate(Client, uid, username) )
{
free(username);
return ;
}
free(username);
// Disabled accounts
if( userflags & USER_FLAG_DISABLED ) {
Client->UID = -1;
sendf(Client->Socket, "403 Authentication failure: account disabled\n");
free(username);
sendf(Client->Socket, "200 Auth OK\n");
}
void Server_Cmd_AUTHCARD(tClient* Client, char *Args)
{
char* card_id;
if( Server_int_ParseArgs(0, Args, &card_id, NULL) )
{
sendf(Client->Socket, "407 AUTHCARD takes 1 argument\n");
return ;
}
// Save username
if(Client->Username)
free(Client->Username);
Client->Username = strdup(username);
Client->bIsAuthed = 1;
// Check if trusted
if( !Client->bTrustedHost )
{
if(giDebugLevel)
Debug(Client, "Untrusted client attempting to AUTHCARD");
sendf(Client->Socket, "401 Untrusted\n");
return ;
}
if(giDebugLevel)
Debug(Client, "IDENT authenticated as '%s' (%i)", username, Client->UID);
free(username);
int uid = Bank_GetAcctByCard(card_id);
if( uid < 0 )
{
if(giDebugLevel)
Debug(Client, "Unknown MIFARE '%s'", card_id);
sendf(Client->Socket, "403 Authentication failure: unknown MIFARE ID\n");
return ;
}
if( ! authenticate(Client, uid, NULL) )
{
return ;
}
sendf(Client->Socket, "200 Auth OK\n");
sendf(Client->Socket, "200 Auth Ok, username=%s\n", Client->Username);
}
/**
......@@ -1462,10 +1496,7 @@ void Server_Cmd_USERFLAGS(tClient *Client, char *Args)
}
// Check authentication
if( !Client->bIsAuthed ) {
sendf(Client->Socket, "401 Not Authenticated\n");
return ;
}
if(!require_auth(Client)) return;
// Check permissions
if( !(Bank_GetFlags(Client->UID) & USER_FLAG_ADMIN) ) {
......@@ -1509,11 +1540,8 @@ void Server_Cmd_UPDATEITEM(tClient *Client, char *Args)
sendf(Client->Socket, "407 UPDATE_ITEM takes 3 arguments\n");
return ;
}
if( !Client->bIsAuthed ) {
sendf(Client->Socket, "401 Not Authenticated\n");
return ;
}
if(!require_auth(Client)) return;
// Check user permissions
if( !(Bank_GetFlags(Client->UID) & (USER_FLAG_COKE|USER_FLAG_ADMIN)) ) {
......@@ -1560,11 +1588,7 @@ void Server_Cmd_PINCHECK(tClient *Client, char *Args)
}
pin = atoi(pinstr);
// Not authenticated? go away!
if( !Client->bIsAuthed ) {
sendf(Client->Socket, "401 Not Authenticated\n");
return ;
}
if(!require_auth(Client)) return;
// Get user
int uid = Bank_GetAcctByName(username, 0);
......@@ -1590,7 +1614,7 @@ void Server_Cmd_PINCHECK(tClient *Client, char *Args)
last_wrong_pin_time = time(NULL);
if( !Bank_IsPinValid(uid, pin) )
{
sendf(Client->Socket, "201 Pin incorrect\n");
sendf(Client->Socket, "401 Pin incorrect\n");
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
char ipstr[INET6_ADDRSTRLEN];
......@@ -1625,10 +1649,7 @@ void Server_Cmd_PINSET(tClient *Client, char *Args)
}
pin = atoi(pinstr);
if( !Client->bIsAuthed ) {
sendf(Client->Socket, "401 Not Authenticated\n");
return ;
}
if(!require_auth(Client)) return;
int uid = Client->EffectiveUID;
if(uid == -1)
......@@ -1638,6 +1659,23 @@ void Server_Cmd_PINSET(tClient *Client, char *Args)
sendf(Client->Socket, "200 Pin updated\n");
return ;
}
void Server_Cmd_CARDADD(tClient* Client, char* Args)
{
char* card_id;
if( Server_int_ParseArgs(0, Args, &card_id, NULL) ) {
sendf(Client->Socket, "407 CARD_ADD takes 1 argument\n");
return ;
}
if(!require_auth(Client)) return;
if( Bank_AddAcctCard(Client->UID, card_id) )
{
sendf(Client->Socket, "408 Card already exists\n");
return ;
}
sendf(Client->Socket, "200 Card added\n");
}
// --- INTERNAL HELPERS ---
void Debug(tClient *Client, const char *Format, ...)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment