diff options
Diffstat (limited to 'examples/redis-unstable/tests/modules/auth.c')
| -rw-r--r-- | examples/redis-unstable/tests/modules/auth.c | 286 |
1 files changed, 0 insertions, 286 deletions
diff --git a/examples/redis-unstable/tests/modules/auth.c b/examples/redis-unstable/tests/modules/auth.c deleted file mode 100644 index cc2378e..0000000 --- a/examples/redis-unstable/tests/modules/auth.c +++ /dev/null @@ -1,286 +0,0 @@ -/* define macros for having usleep */ -#define _BSD_SOURCE -#define _DEFAULT_SOURCE - -#include "redismodule.h" - -#include <string.h> -#include <unistd.h> -#include <pthread.h> - -#define UNUSED(V) ((void) V) - -// A simple global user -static RedisModuleUser *global = NULL; -static long long client_change_delta = 0; -static pthread_t tid; - -void UserChangedCallback(uint64_t client_id, void *privdata) { - REDISMODULE_NOT_USED(privdata); - REDISMODULE_NOT_USED(client_id); - client_change_delta++; -} - -int Auth_CreateModuleUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - if (global) { - RedisModule_FreeModuleUser(global); - } - - global = RedisModule_CreateModuleUser("global"); - RedisModule_SetModuleUserACL(global, "allcommands"); - RedisModule_SetModuleUserACL(global, "allkeys"); - RedisModule_SetModuleUserACL(global, "on"); - - return RedisModule_ReplyWithSimpleString(ctx, "OK"); -} - -int Auth_AuthModuleUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - uint64_t client_id; - RedisModule_AuthenticateClientWithUser(ctx, global, UserChangedCallback, NULL, &client_id); - - return RedisModule_ReplyWithLongLong(ctx, (uint64_t) client_id); -} - -int Auth_AuthRealUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - if (argc != 2) return RedisModule_WrongArity(ctx); - - size_t length; - uint64_t client_id; - - RedisModuleString *user_string = argv[1]; - const char *name = RedisModule_StringPtrLen(user_string, &length); - - if (RedisModule_AuthenticateClientWithACLUser(ctx, name, length, - UserChangedCallback, NULL, &client_id) == REDISMODULE_ERR) { - return RedisModule_ReplyWithError(ctx, "Invalid user"); - } - - return RedisModule_ReplyWithLongLong(ctx, (uint64_t) client_id); -} - -/* This command redacts every other arguments and returns OK */ -int Auth_RedactedAPI(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - for(int i = argc - 1; i > 0; i -= 2) { - int result = RedisModule_RedactClientCommandArgument(ctx, i); - RedisModule_Assert(result == REDISMODULE_OK); - } - return RedisModule_ReplyWithSimpleString(ctx, "OK"); -} - -int Auth_ChangeCount(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - long long result = client_change_delta; - client_change_delta = 0; - return RedisModule_ReplyWithLongLong(ctx, result); -} - -/* The Module functionality below validates that module authentication callbacks can be registered - * to support both non-blocking and blocking module based authentication. */ - -/* Non Blocking Module Auth callback / implementation. */ -int auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) { - const char *user = RedisModule_StringPtrLen(username, NULL); - const char *pwd = RedisModule_StringPtrLen(password, NULL); - if (!strcmp(user,"foo") && !strcmp(pwd,"allow")) { - RedisModule_AuthenticateClientWithACLUser(ctx, "foo", 3, NULL, NULL, NULL); - return REDISMODULE_AUTH_HANDLED; - } - else if (!strcmp(user,"foo") && !strcmp(pwd,"deny")) { - RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11); - RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH); - RedisModule_FreeString(ctx, log); - const char *err_msg = "Auth denied by Misc Module."; - *err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg)); - return REDISMODULE_AUTH_HANDLED; - } - return REDISMODULE_AUTH_NOT_HANDLED; -} - -int test_rm_register_auth_cb(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - RedisModule_RegisterAuthCallback(ctx, auth_cb); - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -/* - * The thread entry point that actually executes the blocking part of the AUTH command. - * This function sleeps for 0.5 seconds and then unblocks the client which will later call - * `AuthBlock_Reply`. - * `arg` is expected to contain the RedisModuleBlockedClient, username, and password. - */ -void *AuthBlock_ThreadMain(void *arg) { - usleep(500000); - void **targ = arg; - RedisModuleBlockedClient *bc = targ[0]; - int result = 2; - const char *user = RedisModule_StringPtrLen(targ[1], NULL); - const char *pwd = RedisModule_StringPtrLen(targ[2], NULL); - if (!strcmp(user,"foo") && !strcmp(pwd,"block_allow")) { - result = 1; - } - else if (!strcmp(user,"foo") && !strcmp(pwd,"block_deny")) { - result = 0; - } - else if (!strcmp(user,"foo") && !strcmp(pwd,"block_abort")) { - RedisModule_BlockedClientMeasureTimeEnd(bc); - RedisModule_AbortBlock(bc); - goto cleanup; - } - /* Provide the result to the blocking reply cb. */ - void **replyarg = RedisModule_Alloc(sizeof(void*)); - replyarg[0] = (void *) (uintptr_t) result; - RedisModule_BlockedClientMeasureTimeEnd(bc); - RedisModule_UnblockClient(bc, replyarg); -cleanup: - /* Free the username and password and thread / arg data. */ - RedisModule_FreeString(NULL, targ[1]); - RedisModule_FreeString(NULL, targ[2]); - RedisModule_Free(targ); - return NULL; -} - -/* - * Reply callback for a blocking AUTH command. This is called when the client is unblocked. - */ -int AuthBlock_Reply(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) { - REDISMODULE_NOT_USED(password); - void **targ = RedisModule_GetBlockedClientPrivateData(ctx); - int result = (uintptr_t) targ[0]; - size_t userlen = 0; - const char *user = RedisModule_StringPtrLen(username, &userlen); - /* Handle the success case by authenticating. */ - if (result == 1) { - RedisModule_AuthenticateClientWithACLUser(ctx, user, userlen, NULL, NULL, NULL); - return REDISMODULE_AUTH_HANDLED; - } - /* Handle the Error case by denying auth */ - else if (result == 0) { - RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11); - RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH); - RedisModule_FreeString(ctx, log); - const char *err_msg = "Auth denied by Misc Module."; - *err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg)); - return REDISMODULE_AUTH_HANDLED; - } - /* "Skip" Authentication */ - return REDISMODULE_AUTH_NOT_HANDLED; -} - -/* Private data freeing callback for Module Auth. */ -void AuthBlock_FreeData(RedisModuleCtx *ctx, void *privdata) { - REDISMODULE_NOT_USED(ctx); - RedisModule_Free(privdata); -} - -/* Callback triggered when the engine attempts module auth - * Return code here is one of the following: Auth succeeded, Auth denied, - * Auth not handled, Auth blocked. - * The Module can have auth succeed / denied here itself, but this is an example - * of blocking module auth. - */ -int blocking_auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) { - REDISMODULE_NOT_USED(username); - REDISMODULE_NOT_USED(password); - REDISMODULE_NOT_USED(err); - /* Block the client from the Module. */ - RedisModuleBlockedClient *bc = RedisModule_BlockClientOnAuth(ctx, AuthBlock_Reply, AuthBlock_FreeData); - int ctx_flags = RedisModule_GetContextFlags(ctx); - if (ctx_flags & REDISMODULE_CTX_FLAGS_MULTI || ctx_flags & REDISMODULE_CTX_FLAGS_LUA) { - /* Clean up by using RedisModule_UnblockClient since we attempted blocking the client. */ - RedisModule_UnblockClient(bc, NULL); - return REDISMODULE_AUTH_HANDLED; - } - - /* Another blocking auth cb may have spawned a thread, we'll just wait for it - * to finish here */ - if (tid) pthread_join(tid, NULL); - - RedisModule_BlockedClientMeasureTimeStart(bc); - - /* Allocate memory for information needed. */ - void **targ = RedisModule_Alloc(sizeof(void*)*3); - targ[0] = bc; - targ[1] = RedisModule_CreateStringFromString(NULL, username); - targ[2] = RedisModule_CreateStringFromString(NULL, password); - - /* Create bg thread and pass the blockedclient, username and password to it. */ - if (pthread_create(&tid, NULL, AuthBlock_ThreadMain, targ) != 0) { - RedisModule_AbortBlock(bc); - - /* These are freed in AuthBlock_ThreadMain but since we failed to spawn - * the thread need to free them here. */ - RedisModule_FreeString(NULL, targ[1]); - RedisModule_FreeString(NULL, targ[2]); - RedisModule_Free(targ); - } - - return REDISMODULE_AUTH_HANDLED; -} - -int test_rm_register_blocking_auth_cb(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - RedisModule_RegisterAuthCallback(ctx, blocking_auth_cb); - RedisModule_ReplyWithSimpleString(ctx, "OK"); - return REDISMODULE_OK; -} - -/* This function must be present on each Redis module. It is used in order to - * register the commands into the Redis server. */ -int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - REDISMODULE_NOT_USED(argv); - REDISMODULE_NOT_USED(argc); - - if (RedisModule_Init(ctx,"testacl",1,REDISMODULE_APIVER_1) - == REDISMODULE_ERR) return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"auth.authrealuser", - Auth_AuthRealUser,"no-auth",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"auth.createmoduleuser", - Auth_CreateModuleUser,"",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"auth.authmoduleuser", - Auth_AuthModuleUser,"no-auth",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"auth.changecount", - Auth_ChangeCount,"",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"auth.redact", - Auth_RedactedAPI,"",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"testmoduleone.rm_register_auth_cb", - test_rm_register_auth_cb,"",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - if (RedisModule_CreateCommand(ctx,"testmoduleone.rm_register_blocking_auth_cb", - test_rm_register_blocking_auth_cb,"",0,0,0) == REDISMODULE_ERR) - return REDISMODULE_ERR; - - return REDISMODULE_OK; -} - -int RedisModule_OnUnload(RedisModuleCtx *ctx) { - UNUSED(ctx); - - if (tid) pthread_join(tid, NULL); - - if (global) - RedisModule_FreeModuleUser(global); - - return REDISMODULE_OK; -} |
