Added a simple tool to create and manipulate the uhub sqlite authentication database.
This commit is contained in:
parent
ba26f4c5e2
commit
ec3afc3a44
11
GNUmakefile
11
GNUmakefile
@ -182,6 +182,9 @@ libadc_client_SOURCES := \
|
|||||||
|
|
||||||
uhub_SOURCES := src/core/main.c
|
uhub_SOURCES := src/core/main.c
|
||||||
|
|
||||||
|
uhub-passwd_SOURCES := src/tools/uhub-passwd.c
|
||||||
|
uhub-passwd_LIBS := -lsqlite3
|
||||||
|
|
||||||
adcrush_SOURCES := src/tools/adcrush.c
|
adcrush_SOURCES := src/tools/adcrush.c
|
||||||
|
|
||||||
admin_SOURCES := src/tools/admin.c
|
admin_SOURCES := src/tools/admin.c
|
||||||
@ -229,6 +232,7 @@ libadc_client_OBJECTS := $(libadc_client_SOURCES:.c=.o)
|
|||||||
libadc_common_OBJECTS := $(libadc_common_SOURCES:.c=.o)
|
libadc_common_OBJECTS := $(libadc_common_SOURCES:.c=.o)
|
||||||
|
|
||||||
uhub_OBJECTS := $(uhub_SOURCES:.c=.o)
|
uhub_OBJECTS := $(uhub_SOURCES:.c=.o)
|
||||||
|
uhub-passwd_OBJECTS := $(uhub-passwd_SOURCES:.c=.o)
|
||||||
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
||||||
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
||||||
|
|
||||||
@ -236,6 +240,7 @@ all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(libutils_OBJECTS) $(adcr
|
|||||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_chat_history_TARGET)
|
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_chat_history_TARGET)
|
||||||
|
|
||||||
uhub_BINARY=uhub$(BIN_EXT)
|
uhub_BINARY=uhub$(BIN_EXT)
|
||||||
|
uhub-passwd_BINARY=uhub-passwd$(BIN_EXT)
|
||||||
adcrush_BINARY=adcrush$(BIN_EXT)
|
adcrush_BINARY=adcrush$(BIN_EXT)
|
||||||
admin_BINARY=uhub-admin$(BIN_EXT)
|
admin_BINARY=uhub-admin$(BIN_EXT)
|
||||||
autotest_BINARY=autotest/test$(BIN_EXT)
|
autotest_BINARY=autotest/test$(BIN_EXT)
|
||||||
@ -250,7 +255,7 @@ endif
|
|||||||
%.o: %.c version.h revision.h
|
%.o: %.c version.h revision.h
|
||||||
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
all: $(uhub_BINARY) plugins
|
all: $(uhub_BINARY) $(uhub-passwd_BINARY) plugins
|
||||||
|
|
||||||
plugins: $(uhub_BINARY) $(all_plugins)
|
plugins: $(uhub_BINARY) $(all_plugins)
|
||||||
|
|
||||||
@ -278,6 +283,10 @@ $(admin_BINARY): $(admin_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libad
|
|||||||
$(uhub_BINARY): $(uhub_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS)
|
$(uhub_BINARY): $(uhub_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS)
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||||
|
|
||||||
|
$(uhub-passwd_BINARY): $(uhub-passwd_OBJECTS)
|
||||||
|
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(uhub-passwd_LIBS)
|
||||||
|
|
||||||
|
|
||||||
autotest.c: $(autotest_SOURCES)
|
autotest.c: $(autotest_SOURCES)
|
||||||
$(shell exotic --standalone $(autotest_SOURCES) > $@)
|
$(shell exotic --standalone $(autotest_SOURCES) > $@)
|
||||||
|
|
||||||
|
340
src/tools/uhub-passwd.c
Normal file
340
src/tools/uhub-passwd.c
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2011, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
// #define DEBUG_SQL
|
||||||
|
|
||||||
|
static sqlite3* db = NULL;
|
||||||
|
static const char* command = NULL;
|
||||||
|
static const char* filename = NULL;
|
||||||
|
static const char* binary = NULL;
|
||||||
|
|
||||||
|
typedef int (*command_func_t)(size_t, const char**);
|
||||||
|
|
||||||
|
static int create(size_t argc, const char** argv);
|
||||||
|
static int list(size_t argc, const char** argv);
|
||||||
|
static int pass(size_t argc, const char** argv);
|
||||||
|
static int add(size_t argc, const char** argv);
|
||||||
|
static int del(size_t argc, const char** argv);
|
||||||
|
static int mod(size_t argc, const char** argv);
|
||||||
|
|
||||||
|
static struct commands
|
||||||
|
{
|
||||||
|
command_func_t handle;
|
||||||
|
const char* command;
|
||||||
|
const char* usage;
|
||||||
|
} COMMANDS[6] = {
|
||||||
|
{ &create, "create", "" },
|
||||||
|
{ &list, "list", "" },
|
||||||
|
{ &add, "add", "username password [credentials = user]" },
|
||||||
|
{ &del, "del", "username" },
|
||||||
|
{ &mod, "mod", "username credentials" },
|
||||||
|
{ &pass, "pass", "username password" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void print_usage(const char* str)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s filename %s %s\n", binary, command, str);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape an SQL statement and return a pointer to the string.
|
||||||
|
* NOTE: The returned value needs to be free'd.
|
||||||
|
*
|
||||||
|
* @return an escaped string.
|
||||||
|
*/
|
||||||
|
static char* sql_escape_string(const char* str)
|
||||||
|
{
|
||||||
|
size_t i, n, size;
|
||||||
|
|
||||||
|
for (n = 0, size = strlen(str); n < strlen(str); n++)
|
||||||
|
if (str[n] == '\'')
|
||||||
|
size++;
|
||||||
|
|
||||||
|
char* buf = malloc(size+1);
|
||||||
|
for (n = 0, i = 0; n < strlen(str); n++)
|
||||||
|
{
|
||||||
|
if (str[n] == '\'')
|
||||||
|
buf[i++] = '\'';
|
||||||
|
buf[i++] = str[n];
|
||||||
|
}
|
||||||
|
buf[i++] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate credentials.
|
||||||
|
*/
|
||||||
|
static const char* validate_cred(const char* cred_str)
|
||||||
|
{
|
||||||
|
if (!strcmp(cred_str, "admin"))
|
||||||
|
return "admin";
|
||||||
|
|
||||||
|
if (!strcmp(cred_str, "super"))
|
||||||
|
return "super";
|
||||||
|
|
||||||
|
if (!strcmp(cred_str, "op"))
|
||||||
|
return "op";
|
||||||
|
|
||||||
|
if (!strcmp(cred_str, "user"))
|
||||||
|
return "user";
|
||||||
|
|
||||||
|
fprintf(stderr, "Invalid user credentials. Must be one of: 'admin', 'super', 'op' or 'user'\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void open_database()
|
||||||
|
{
|
||||||
|
int res = sqlite3_open(filename, &db);
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to open database: %s (result=%d)\n", filename, res);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sql_callback(void* ptr, int argc, char **argv, char **colName) { return 0; }
|
||||||
|
|
||||||
|
static int sql_execute(const char* sql, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char query[1024];
|
||||||
|
char* errMsg;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
va_start(args, sql);
|
||||||
|
vsnprintf(query, sizeof(query), sql, args);
|
||||||
|
|
||||||
|
#ifdef DEBUG_SQL
|
||||||
|
printf("SQL: %s\n", query);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
open_database();
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, query, sql_callback, NULL, &errMsg);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "ERROR: %s\n", errMsg);
|
||||||
|
sqlite3_free(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_changes(db);
|
||||||
|
sqlite3_close(db);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create(size_t argc, const char** argv)
|
||||||
|
{
|
||||||
|
const char* sql = "CREATE TABLE users"
|
||||||
|
"("
|
||||||
|
"nickname CHAR NOT NULL UNIQUE,"
|
||||||
|
"password CHAR NOT NULL,"
|
||||||
|
"credentials CHAR NOT NULL DEFAULT 'user',"
|
||||||
|
"created TIMESTAMP DEFAULT (DATETIME('NOW')),"
|
||||||
|
"activity TIMESTAMP DEFAULT (DATETIME('NOW'))"
|
||||||
|
");";
|
||||||
|
|
||||||
|
sql_execute(sql);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sql_callback_list(void* ptr, int argc, char **argv, char **colName)
|
||||||
|
{
|
||||||
|
int* found = (int*) ptr;
|
||||||
|
uhub_assert(strcmp(colName[0], "nickname") == 0 && strcmp(colName[2], "credentials") == 0);
|
||||||
|
printf("%s\t%s\n", argv[2], argv[0]);
|
||||||
|
(*found)++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int list(size_t argc, const char** argv)
|
||||||
|
{
|
||||||
|
char* errMsg;
|
||||||
|
int found = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
open_database();
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, "SELECT * FROM users;", sql_callback_list, &found, &errMsg);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
#ifdef DEBUG_SQL
|
||||||
|
fprintf(stderr, "SQL: ERROR: %s (%d)\n", errMsg, rc);
|
||||||
|
#endif
|
||||||
|
sqlite3_free(errMsg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_close(db);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int add(size_t argc, const char** argv)
|
||||||
|
{
|
||||||
|
char* user = NULL;
|
||||||
|
char* pass = NULL;
|
||||||
|
const char* cred = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
print_usage("username password [credentials = user]");
|
||||||
|
|
||||||
|
user = sql_escape_string(argv[0]);
|
||||||
|
pass = sql_escape_string(argv[1]);
|
||||||
|
cred = validate_cred(argv[2] ? argv[2] : "user");
|
||||||
|
|
||||||
|
rc = sql_execute("INSERT INTO users (nickname, password, credentials) VALUES('%s', '%s', '%s');", user, pass, cred);
|
||||||
|
|
||||||
|
free(user);
|
||||||
|
free(pass);
|
||||||
|
|
||||||
|
if (rc != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to add user \"%s\"\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mod(size_t argc, const char** argv)
|
||||||
|
{
|
||||||
|
char* user = NULL;
|
||||||
|
const char* cred = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
print_usage("username credentials");
|
||||||
|
|
||||||
|
user = sql_escape_string(argv[0]);
|
||||||
|
cred = validate_cred(argv[1]);
|
||||||
|
|
||||||
|
rc = sql_execute("UPDATE users SET credentials = '%s' WHERE nickname = '%s';", cred, user);
|
||||||
|
|
||||||
|
free(user);
|
||||||
|
|
||||||
|
if (rc != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to set credentials for user \"%s\"\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pass(size_t argc, const char** argv)
|
||||||
|
{
|
||||||
|
char* user = NULL;
|
||||||
|
char* pass = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
print_usage("username password");
|
||||||
|
|
||||||
|
user = sql_escape_string(argv[0]);
|
||||||
|
pass = sql_escape_string(argv[1]);
|
||||||
|
|
||||||
|
rc = sql_execute("UPDATE users SET password = '%s' WHERE nickname = '%s';", pass, user);
|
||||||
|
|
||||||
|
free(user);
|
||||||
|
free(pass);
|
||||||
|
|
||||||
|
if (rc != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to change password for user \"%s\"\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int del(size_t argc, const char** argv)
|
||||||
|
{
|
||||||
|
char* user = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
print_usage("username");
|
||||||
|
|
||||||
|
user = sql_escape_string(argv[0]);
|
||||||
|
|
||||||
|
rc = sql_execute("DELETE FROM users WHERE nickname = '%s';", user);
|
||||||
|
free(user);
|
||||||
|
|
||||||
|
if (rc != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to delete user \"%s\".\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_usage(const char* binary)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"Usage: %s filename command [...]\n"
|
||||||
|
"\n"
|
||||||
|
"Command syntax:\n"
|
||||||
|
" create\n"
|
||||||
|
" add username password [credentials = user]\n"
|
||||||
|
" del username\n"
|
||||||
|
" mod username credentials\n"
|
||||||
|
" pass username password\n"
|
||||||
|
" list\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters:\n"
|
||||||
|
" 'filename' is a database file\n"
|
||||||
|
" 'username' is a nickname (UTF-8, up to 64 bytes)\n"
|
||||||
|
" 'password' is a password (UTF-8, up to 64 bytes)\n"
|
||||||
|
" 'credentials' is one of 'admin', 'super', 'op', 'user'\n"
|
||||||
|
"\n"
|
||||||
|
, binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
binary = argv[0];
|
||||||
|
filename = argv[1];
|
||||||
|
command = argv[2];
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
main_usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; n < sizeof(COMMANDS) / sizeof(COMMANDS[0]); n++)
|
||||||
|
{
|
||||||
|
if (!strcmp(command, COMMANDS[n].command))
|
||||||
|
return COMMANDS[n].handle(argc - 2, (const char**) &argv[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown command!
|
||||||
|
main_usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user