From 253e7f9eaa3f3279f2a8639949f74acf0797de33 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 13 Oct 2023 06:33:12 +0200 Subject: [PATCH] Don't allow creating users which user name strings only differ in case. --- Makefile | 2 +- data.c | 30 ++++++++++++++++++++++++++---- snac.c | 3 +++ utils.c | 2 +- webfinger.c | 29 ++++++++++++++++------------- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 9288dcc..e32730b 100644 --- a/Makefile +++ b/Makefile @@ -53,4 +53,4 @@ snac.o: snac.c xs.h xs_io.h xs_unicode.h xs_json.h xs_curl.h xs_openssl.h \ upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \ xs_random.h snac.h -webfinger.o: webfinger.c xs.h xs_json.h xs_curl.h snac.h +webfinger.o: webfinger.c xs.h xs_json.h xs_curl.h xs_mime.h snac.h diff --git a/data.c b/data.c index 02e5234..f06e99c 100644 --- a/data.c +++ b/data.c @@ -154,12 +154,34 @@ int user_open(snac *snac, const char *uid) memset(snac, '\0', sizeof(struct _snac)); if (validate_uid(uid)) { - xs *cfg_file; + xs *cfg_file = NULL; FILE *f; - snac->uid = xs_str_new(uid); + xs *t = xs_fmt("%s/user/%s", srv_basedir, uid); - snac->basedir = xs_fmt("%s/user/%s", srv_basedir, uid); + if (mtime(t) == 0.0) { + /* user folder does not exist; try with a different case */ + xs *lcuid = xs_tolower_i(xs_dup(uid)); + xs *ulist = user_list(); + xs_list *p = ulist; + xs_str *v; + + while (xs_list_iter(&p, &v)) { + xs *v2 = xs_tolower_i(xs_dup(v)); + + if (strcmp(lcuid, v2) == 0) { + snac->uid = xs_dup(v); + break; + } + } + } + else + snac->uid = xs_str_new(uid); + + if (snac->uid == NULL) + return ret; + + snac->basedir = xs_fmt("%s/user/%s", srv_basedir, snac->uid); cfg_file = xs_fmt("%s/user.json", snac->basedir); @@ -176,7 +198,7 @@ int user_open(snac *snac, const char *uid) fclose(f); if (snac->key != NULL) { - snac->actor = xs_fmt("%s/%s", srv_baseurl, uid); + snac->actor = xs_fmt("%s/%s", srv_baseurl, snac->uid); snac->md5 = xs_md5_hex(snac->actor, strlen(snac->actor)); /* everything is ok right now */ diff --git a/snac.c b/snac.c index 683ff40..1ea61ff 100644 --- a/snac.c +++ b/snac.c @@ -79,6 +79,9 @@ double ftime(void) int validate_uid(const char *uid) /* returns if uid is a valid identifier */ { + if (!uid || *uid == '\0') + return 0; + while (*uid) { if (!(isalnum(*uid) || *uid == '_')) return 0; diff --git a/utils.c b/utils.c index c77e31a..dd09be6 100644 --- a/utils.c +++ b/utils.c @@ -244,7 +244,7 @@ int adduser(const char *uid) } if (user_open(&snac, uid)) { - printf("ERROR: user '%s' already exists\n", uid); + printf("ERROR: user '%s' already exists\n", snac.uid); return 1; } diff --git a/webfinger.c b/webfinger.c index 46867e9..13a6e6c 100644 --- a/webfinger.c +++ b/webfinger.c @@ -4,6 +4,7 @@ #include "xs.h" #include "xs_json.h" #include "xs_curl.h" +#include "xs_mime.h" #include "snac.h" @@ -128,20 +129,11 @@ int webfinger_get_handler(xs_dict *req, char *q_path, if (xs_startswith(resource, "https:/" "/")) { /* actor search: find a user with this actor */ - xs *list = user_list(); - char *p, *uid; + xs *l = xs_split(resource, "/"); + char *uid = xs_list_get(l, -1); - p = list; - while (xs_list_iter(&p, &uid)) { - if (user_open(&snac, uid)) { - if (strcmp(snac.actor, resource) == 0) { - found = 1; - break; - } - - user_free(&snac); - } - } + if (uid) + found = user_open(&snac, uid); } else if (xs_startswith(resource, "acct:")) { @@ -180,6 +172,17 @@ int webfinger_get_handler(xs_dict *req, char *q_path, links = xs_list_append(links, aaj); + char *avatar = xs_dict_get(snac.config, "avatar"); + if (!xs_is_null(avatar) && *avatar) { + xs *d = xs_dict_new(); + + d = xs_dict_append(d, "rel", "http:/" "/webfinger.net/rel/avatar"); + d = xs_dict_append(d, "type", xs_mime_by_ext(avatar)); + d = xs_dict_append(d, "href", avatar); + + links = xs_list_append(links, d); + } + obj = xs_dict_append(obj, "subject", acct); obj = xs_dict_append(obj, "links", links);