Skip to content
Snippets Groups Projects
Commit 41f3be92 authored by John Hodge's avatar John Hodge
Browse files

Server - Implimented pins in server code

parent 612db258
Branches
No related merge requests found
......@@ -180,6 +180,21 @@ extern void Bank_DelIterator(tAcctIterator *It);
*/
extern int Bank_GetUserAuth(const char *Salt, const char *Username, const char *Password);
/**
* \brief Checks the validity of a pin against a username
* \param AcctID Account ID
* \param Pin Integer version of the pin
* \return Boolean correct
*/
extern int Bank_IsPinValid(int AcctID, int Pin);
/**
* \brief Update a user's pin
* \param AcctID Account ID
* \param NewPin New pin for the account
*/
extern void Bank_SetPin(int AcctID, int NewPin);
/**
* \brief Get an account ID from a MIFARE card ID
* \param CardID MIFARE card ID
......
......@@ -63,6 +63,8 @@ struct sAcctIterator // Unused really, just used as a void type
int Bank_SetFlags(int AcctID, int Mask, int Value);
int Bank_GetBalance(int AcctID);
char *Bank_GetAcctName(int AcctID);
int Bank_IsPinValid(int AcctID, int Pin);
void Bank_SetPin(int AcctID, int Pin);
sqlite3_stmt *Bank_int_MakeStatemnt(sqlite3 *Database, const char *Query);
int Bank_int_QueryNone(sqlite3 *Database, const char *Query, char **ErrorMessage);
sqlite3_stmt *Bank_int_QuerySingle(sqlite3 *Database, const char *Query);
......@@ -354,6 +356,34 @@ int Bank_CreateAcct(const char *Name)
return sqlite3_last_insert_rowid(gBank_Database);
}
int Bank_IsPinValid(int AcctID, int Pin)
{
char *query = mkstr("SELECT acct_id FROM accounts WHERE acct_id=%i AND acct_pin=%i LIMIT 1", AcctID, Pin);
sqlite3_stmt *statement = Bank_int_QuerySingle(gBank_Database, query);
free(query);
if( statement ) {
sqlite3_finalize(statement);
}
return (statement != NULL);
}
void Bank_SetPin(int AcctID, int Pin)
{
char *errmsg;
char *query = mkstr("UPDATE accounts SET acct_pin=%i WHERE acct_id=%i", Pin, AcctID);
int rv = Bank_int_QueryNone(gBank_Database, query, &errmsg);
if( rv != SQLITE_OK )
{
fprintf(stderr, "Bank_CreateAcct - SQLite Error: '%s'\n", errmsg);
fprintf(stderr, "Query = '%s'\n", query);
sqlite3_free(errmsg);
free(query);
return ;
}
free(query);
}
/*
* Create an iterator for user accounts
*/
......
......@@ -54,6 +54,8 @@ void sigint_handler()
void PrintUsage(const char *progname)
{
fprintf(stderr, "Usage: %s\n", progname);
fprintf(stderr, " -f,--configfile\n");
fprintf(stderr, " Set the config file path (default `dispsrv.conf')\n");
fprintf(stderr, " -d Set debug level (0 - 2, default 0)\n");
fprintf(stderr, " --[dont-]daemonise\n");
fprintf(stderr, " Run (or explicitly don't run) the server disconnected from the terminal\n");
......@@ -83,6 +85,7 @@ int main(int argc, char *argv[])
break;
default:
// Usage Error
fprintf(stderr, "Unknown option '-%c'\n", arg[1]);
PrintUsage(argv[0]);
return -1;
}
......@@ -101,6 +104,7 @@ int main(int argc, char *argv[])
}
else {
// Usage error
fprintf(stderr, "Unknown option '%s'\n", arg);
PrintUsage(argv[0]);
return -1;
}
......
......@@ -21,6 +21,7 @@
#include <signal.h> // Signal handling
#include <ident.h> // AUTHIDENT
#include <time.h> // time(2)
#include <ctype.h>
#define DEBUG_TRACE_CLIENT 0
#define HACK_NO_REFUNDS 1
......@@ -82,6 +83,8 @@ void _SendUserInfo(tClient *Client, int UserID);
void Server_Cmd_USERADD(tClient *Client, char *Args);
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);
// --- Helpers ---
void Debug(tClient *Client, const char *Format, ...);
int sendf(int Socket, const char *Format, ...);
......@@ -111,7 +114,9 @@ const struct sClientCommand {
{"USER_INFO", Server_Cmd_USERINFO},
{"USER_ADD", Server_Cmd_USERADD},
{"USER_FLAGS", Server_Cmd_USERFLAGS},
{"UPDATE_ITEM", Server_Cmd_UPDATEITEM}
{"UPDATE_ITEM", Server_Cmd_UPDATEITEM},
{"PIN_CHECK", Server_Cmd_PINCHECK},
{"PIN_SET", Server_Cmd_PINSET}
};
#define NUM_COMMANDS ((int)(sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0])))
......@@ -1540,6 +1545,95 @@ void Server_Cmd_UPDATEITEM(tClient *Client, char *Args)
}
}
void Server_Cmd_PINCHECK(tClient *Client, char *Args)
{
char *username, *pinstr;
int pin;
if( Server_int_ParseArgs(0, Args, &username, &pinstr, NULL) ) {
sendf(Client->Socket, "407 PIN_CHECK takes 2 arguments\n");
return ;
}
if( !isdigit(pinstr[0]) || !isdigit(pinstr[1]) || !isdigit(pinstr[2]) || !isdigit(pinstr[3]) || pinstr[4] != '\0' ) {
sendf(Client->Socket, "407 PIN should be four digits\n");
return ;
}
pin = atoi(pinstr);
// Not strictly needed, but ensures that randoms don't do brute forcing
if( !Client->bIsAuthed ) {
sendf(Client->Socket, "401 Not Authenticated\n");
return ;
}
// Check user permissions
if( !(Bank_GetFlags(Client->UID) & (USER_FLAG_COKE|USER_FLAG_ADMIN)) ) {
sendf(Client->Socket, "403 Not in coke\n");
return ;
}
// Get user
int uid = Bank_GetAcctByName(username, 0);
if( uid == -1 ) {
sendf(Client->Socket, "404 User '%s' not found\n", username);
return ;
}
// Get the pin
static time_t last_wrong_pin_time;
static int backoff = 1;
if( time(NULL) - last_wrong_pin_time < backoff ) {
sendf(Client->Socket, "407 Rate limited (%i seconds remaining)\n",
backoff - (time(NULL) - last_wrong_pin_time));
return ;
}
last_wrong_pin_time = time(NULL);
if( !Bank_IsPinValid(uid, pin) )
{
sendf(Client->Socket, "403 Pin incorrect\n");
if( backoff < 5)
backoff ++;
return ;
}
last_wrong_pin_time = 0;
backoff = 1;
sendf(Client->Socket, "200 Pin correct\n");
return ;
}
void Server_Cmd_PINSET(tClient *Client, char *Args)
{
char *pinstr;
int pin;
if( Server_int_ParseArgs(0, Args, &pinstr, NULL) ) {
sendf(Client->Socket, "407 PIN_SET takes 2 arguments\n");
return ;
}
if( !isdigit(pinstr[0]) || !isdigit(pinstr[1]) || !isdigit(pinstr[2]) || !isdigit(pinstr[3]) || pinstr[4] != '\0' ) {
sendf(Client->Socket, "407 PIN should be four digits\n");
return ;
}
pin = atoi(pinstr);
// Not strictly needed, but ensures that randoms don't do brute forcing
if( !Client->bIsAuthed ) {
sendf(Client->Socket, "401 Not Authenticated\n");
return ;
}
int uid = Client->EffectiveUID;
if(uid == -1)
uid = Client->UID;
// Can only pinset yourself (well, the effective user)
Bank_SetPin(uid, pin);
sendf(Client->Socket, "200 Pin updated\n");
return ;
}
// --- INTERNAL HELPERS ---
void Debug(tClient *Client, const char *Format, ...)
{
......@@ -1716,3 +1810,4 @@ int Server_int_ParseFlags(tClient *Client, const char *Str, int *Mask, int *Valu
return 0;
}
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