From 4cf2c14f35c7e1a2fd2806b7c2c2a6dcfe62f3d4 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 7 Jan 2011 09:54:05 +0800 Subject: [PATCH] Added new user command (wheel only) --- proto.txt | 12 +++- src/client/main.c | 146 ++++++++++++++++++++++++++++++++++++-- src/cokebank.h | 1 + src/cokebank_basic/main.c | 16 +++-- src/server/server.c | 97 +++++++++++++++++++++++-- 5 files changed, 254 insertions(+), 18 deletions(-) diff --git a/proto.txt b/proto.txt index 6e7c5cf..3adcaf2 100644 --- a/proto.txt +++ b/proto.txt @@ -55,17 +55,25 @@ c ENUM_ITEMS\n s 201 Items \n s 202 Item \n ... -s 200 List End\n +s 200 List End\n --- Get Item Information --- c ITEM_INFO \n s 202 Item \n + --- Get Users' Balances --- and can be '-' to indicate "none" c ENUM_USERS[ []]\n s 201 Users \n s 202 User \n ... -s 200 List End\n +s 200 List End\n --- Get a User's Balance --- c USER_INFO\n s 202 User \n + +--- Add a new user --- +c USER_ADD \n +s 200 User Added\n or 403 Not Wheel\n or 404 User Exists\n +--- Set user flags --- +c USER_FLAGS \n +s 200 User Updated\n or 403 Not Wheel\n or 404 Bad User\n or 407 Unknown Flags\n diff --git a/src/client/main.c b/src/client/main.c index f095096..d3adeee 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -52,6 +52,8 @@ void PopulateItemList(int Socket); int Dispense_EnumUsers(int Socket); int Dispense_ShowUser(int Socket, const char *Username); void _PrintUserLine(const char *Line); + int Dispense_AddUser(int Socket, const char *Username); + int Dispense_SetUserType(int Socket, const char *Username, const char *TypeString); // --- Helpers --- char *ReadLine(int Socket); int sendf(int Socket, const char *Format, ...); @@ -68,6 +70,7 @@ tItem *gaItems; regex_t gArrayRegex, gItemRegex, gSaltRegex, gUserInfoRegex; int gbIsAuthenticated = 0; +char *gsItemPattern; //!< Item pattern char *gsOverrideUser; //!< '-u' Dispense as another user int gbUseNCurses = 0; //!< '-G' Use the NCurses GUI? int giMinimumBalance = INT_MIN; //!< '-m' Minumum balance for `dispense acct` @@ -125,7 +128,6 @@ int main(int argc, char *argv[]) if( strcmp(arg, "acct") == 0 ) { - // Connect to server sock = OpenConnection(gsDispenseServer, giDispensePort); if( sock < 0 ) return -1; @@ -140,14 +142,15 @@ int main(int argc, char *argv[]) // Alter account? if( i + 2 < argc ) - { + { if( i + 3 >= argc ) { fprintf(stderr, "Error: `dispense acct' needs a reason\n"); exit(1); } // Authentication required - Authenticate(sock); + if( Authenticate(sock) ) + return -1; // argv[i+1]: Username // argv[i+2]: Ammount @@ -168,8 +171,56 @@ int main(int argc, char *argv[]) close(sock); return 0; } + else if( strcmp(arg, "user") == 0 ) + { + // Check argument count + if( i + 1 >= argc ) { + fprintf(stderr, "Error: `dispense user` requires arguments\n"); + ShowUsage(); + exit(1); + } + + // Connect to server + sock = OpenConnection(gsDispenseServer, giDispensePort); + if( sock < 0 ) return -1; + + // Attempt authentication + if( Authenticate(sock) ) + return -1; + + // Add new user? + if( strcmp(argv[i+1], "add") == 0 ) + { + if( i + 2 >= argc ) { + fprintf(stderr, "Error: `dispense user add` requires an argument\n"); + ShowUsage(); + exit(1); + } + + Dispense_AddUser(sock, argv[i+2]); + } + // Update a user + else if( strcmp(argv[i+1], "type") == 0 ) + { + if( i + 3 >= argc ) { + fprintf(stderr, "Error: `dispense user type` requires two arguments\n"); + ShowUsage(); + exit(1); + } + + Dispense_SetUserType(sock, argv[i+2], argv[i+3]); + } + else + { + fprintf(stderr, "Error: Unknown sub-command for `dispense user`\n"); + ShowUsage(); + exit(1); + } + return 0; + } else { // Item name / pattern + gsItemPattern = arg; break; } } @@ -184,7 +235,11 @@ int main(int argc, char *argv[]) // Get items PopulateItemList(sock); - if( gbUseNCurses ) + if( gsItemPattern ) + { + + } + else if( gbUseNCurses ) { i = ShowNCursesUI(); } @@ -999,6 +1054,89 @@ void _PrintUserLine(const char *Line) } } +int Dispense_AddUser(int Socket, const char *Username) +{ + char *buf; + int responseCode, ret; + + sendf(Socket, "USER_ADD %s\n", Username); + + buf = ReadLine(Socket); + responseCode = atoi(buf); + + switch(responseCode) + { + case 200: + printf("User '%s' added\n", Username); + ret = 0; + break; + + case 403: + printf("Only wheel can add users\n"); + ret = 1; + break; + + case 404: + printf("User '%s' already exists\n", Username); + ret = 0; + break; + + default: + fprintf(stderr, "Unknown response code %i '%s'\n", responseCode, buf); + ret = -1; + break; + } + + free(buf); + + return ret; +} + +int Dispense_SetUserType(int Socket, const char *Username, const char *TypeString) +{ + char *buf; + int responseCode, ret; + + // TODO: Pre-validate the string + + sendf(Socket, "USER_FLAGS %s %s\n", Username, TypeString); + + buf = ReadLine(Socket); + responseCode = atoi(buf); + + switch(responseCode) + { + case 200: + printf("User '%s' updated\n", Username); + ret = 0; + break; + + case 403: + printf("Only wheel can modify users\n"); + ret = 1; + break; + + case 404: + printf("User '%s' does not exist\n", Username); + ret = 0; + break; + + case 407: + printf("Flag string is invalid\n"); + ret = 0; + break; + + default: + fprintf(stderr, "Unknown response code %i '%s'\n", responseCode, buf); + ret = -1; + break; + } + + free(buf); + + return ret; +} + // --------------- // --- Helpers --- // --------------- diff --git a/src/cokebank.h b/src/cokebank.h index 2771462..85a4b8a 100644 --- a/src/cokebank.h +++ b/src/cokebank.h @@ -30,6 +30,7 @@ extern int GetFlags(int User); extern int GetBalance(int User); extern char *GetUserName(int User); extern int GetUserID(const char *Username); +extern int CreateUser(const char *Username); extern int GetMaxID(void); #endif diff --git a/src/cokebank_basic/main.c b/src/cokebank_basic/main.c index 9892231..fe16f6f 100644 --- a/src/cokebank_basic/main.c +++ b/src/cokebank_basic/main.c @@ -99,15 +99,17 @@ char *GetUserName(int User) */ int GetUserID(const char *Username) { - int ret; + return Bank_GetUserByName(Username); +} - // Get internal ID (or create new user) +int CreateUser(const char *Username) +{ + int ret; + ret = Bank_GetUserByName(Username); - if( ret == -1 ) { - ret = Bank_AddUser(Username); - } - - return ret; + if( ret != -1 ) return -1; + + return Bank_AddUser(Username); } int GetMaxID(void) diff --git a/src/server/server.c b/src/server/server.c index 3dc1786..9ca0be9 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -65,6 +65,8 @@ void Server_Cmd_ADD(tClient *Client, char *Args); void Server_Cmd_ENUMUSERS(tClient *Client, char *Args); void Server_Cmd_USERINFO(tClient *Client, char *Args); void _SendUserInfo(tClient *Client, int UserID); +void Server_Cmd_USERADD(tClient *Client, char *Args); +void Server_Cmd_USERFLAGS(tClient *Client, char *Args); // --- Helpers --- int sendf(int Socket, const char *Format, ...); int GetUserAuth(const char *Salt, const char *Username, const uint8_t *Hash); @@ -87,7 +89,9 @@ struct sClientCommand { {"GIVE", Server_Cmd_GIVE}, {"ADD", Server_Cmd_ADD}, {"ENUM_USERS", Server_Cmd_ENUMUSERS}, - {"USER_INFO", Server_Cmd_USERINFO} + {"USER_INFO", Server_Cmd_USERINFO}, + {"USER_ADD", Server_Cmd_USERADD}, + {"USER_FLAGS", Server_Cmd_USERFLAGS} }; #define NUM_COMMANDS (sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0])) int giServer_Socket; @@ -261,6 +265,10 @@ void Server_ParseClientCommand(tClient *Client, char *CommandString) { char *space, *args; int i; + #if 0 + char **argList; + int numArgs = 0; + #endif // Split at first space space = strchr(CommandString, ' '); @@ -270,8 +278,28 @@ void Server_ParseClientCommand(tClient *Client, char *CommandString) else { *space = '\0'; args = space + 1; + while( *space == ' ' ) space ++; + + #if 0 + // Count arguments + numArgs = 1; + for( i = 0; args[i]; ) + { + while( CommandString[i] != ' ' ) { + if( CommandString[i] == '"' ) { + while( !(CommandString[i] != '\\' CommandString[i+1] == '"' ) ) + i ++; + i ++; + } + i ++; + } + numArgs ++; + while( CommandString[i] == ' ' ) i ++; + } + #endif } + // Find command for( i = 0; i < NUM_COMMANDS; i++ ) { @@ -374,7 +402,7 @@ void Server_Cmd_AUTOAUTH(tClient *Client, char *Args) } // Get UID - Client->UID = GetUserID( Args ); + Client->UID = GetUserID( Args ); if( Client->UID < 0 ) { if(giDebugLevel) printf("Client %i: Unknown user '%s'\n", Client->ID, Args); @@ -658,7 +686,6 @@ void Server_Cmd_ENUMUSERS(tClient *Client, char *Args) if( bal < minBal ) continue; if( bal > maxBal ) continue; - // TODO: User flags _SendUserInfo(Client, i); } @@ -709,6 +736,62 @@ void _SendUserInfo(tClient *Client, int UserID) ); } +void Server_Cmd_USERADD(tClient *Client, char *Args) +{ + char *username, *space; + + // Check permissions + if( (GetFlags(Client->UID) & USER_FLAG_TYPEMASK) < USER_TYPE_WHEEL ) { + sendf(Client->Socket, "403 Not Wheel\n"); + return ; + } + + // Read arguments + username = Args; + while( *username == ' ' ) username ++; + space = strchr(username, ' '); + if(space) *space = '\0'; + + // Try to create user + if( CreateUser(username) == -1 ) { + sendf(Client->Socket, "404 User exists\n"); + return ; + } + + sendf(Client->Socket, "200 User Added\n"); +} + +void Server_Cmd_USERFLAGS(tClient *Client, char *Args) +{ + char *username, *flags; + char *space; + + // Check permissions + if( (GetFlags(Client->UID) & USER_FLAG_TYPEMASK) < USER_TYPE_WHEEL ) { + sendf(Client->Socket, "403 Not Wheel\n"); + return ; + } + + // Read arguments + // - Username + username = Args; + while( *username == ' ' ) username ++; + space = strchr(username, ' '); + if(!space) { + sendf(Client->Socket, "407 USER_FLAGS requires 2 arguments, 1 given\n"); + return ; + } + // - Flags + flags = space + 1; + while( *flags == ' ' ) flags ++; + space = strchr(flags, ' '); + if(space) *space = '\0'; + + printf("Username = '%s', flags = '%s'\n", username, flags); + + sendf(Client->Socket, "200 User Updated\n"); +} + /** * \brief Authenticate a user * \return User ID, or -1 if authentication failed @@ -727,8 +810,12 @@ int GetUserAuth(const char *Salt, const char *Username, const uint8_t *ProvidedH return GetUserID("tpg"); #endif #if HACK_ROOT_NOAUTH - if( strcmp(Username, "root") == 0 ) - return GetUserID("root"); + if( strcmp(Username, "root") == 0 ) { + int ret = GetUserID("root"); + if( ret == -1 ) + return CreateUser("root"); + return ret; + } #endif #if 0 -- 2.20.1