From f2e4de7f9046533795b54a5930b4186506f538e0 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 22 Sep 2022 11:28:13 +0200 Subject: [PATCH] More webfinger work. --- main.c | 22 ++++++++++++++++++ webfinger.c | 64 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/main.c b/main.c index 9ea17b2..2a62816 100644 --- a/main.c +++ b/main.c @@ -18,6 +18,7 @@ int main(int argc, char *argv[]) { char *cmd; char *basedir; + char *user; int argi = 1; argc--; @@ -45,6 +46,27 @@ int main(int argc, char *argv[]) return 0; } + if (argc < argi) + return usage(); + + user = argv[argi++]; + + if (strcmp(cmd, "webfinger") == 0) { + xs *actor = NULL; + xs *uid = NULL; + int status; + + webfinger_request(user, &status, &actor, &uid); + + printf("status: %d\n", status); + if (actor != NULL) + printf("actor: %s\n", actor); + if (uid != NULL) + printf("uid: %s\n", uid); + + return 0; + } + return 0; } diff --git a/webfinger.c b/webfinger.c index bcc5982..aeaf754 100644 --- a/webfinger.c +++ b/webfinger.c @@ -13,21 +13,23 @@ void webfinger_request(char *qs, int *status, char **actor, char **user) { xs *payload = NULL; int p_size = 0; - xs *url = NULL; xs *headers = xs_dict_new(); + xs *l = NULL; + d_char *host = NULL; + xs *resource = NULL; if (xs_startswith(qs, "https:/" "/")) { /* actor query: pick the host */ xs *s = xs_replace(qs, "https:/" "/", ""); - xs *l = xs_split_n(s, "/", 1); - url = xs_fmt("https:/" "/%s/.well-known/webfinger?resource=%s", - xs_list_get(l, 0), qs); + l = xs_split_n(s, "/", 1); + + host = xs_list_get(l, 0); + resource = xs_dup(qs); } else { /* it's a user */ xs *s = xs_dup(qs); - xs *l; if (xs_startswith(s, "@")) s = xs_crop(s, 1, 0); @@ -35,19 +37,61 @@ void webfinger_request(char *qs, int *status, char **actor, char **user) l = xs_split_n(s, "@", 1); if (xs_list_len(l) == 2) { - url = xs_fmt("https:/" "/%s/.well-known/webfinger?resource:acct:%s", - xs_list_get(l, 1), qs); + host = xs_list_get(l, 1); + resource = xs_fmt("acct:%s", qs); } } - if (url == NULL) { + if (host == NULL || resource == NULL) { *status = 400; return; } headers = xs_dict_append(headers, "accept", "application/json"); - xs_http_request("GET", url, headers, NULL, 0, status, &payload, &p_size); + /* is it a query about one of us? */ + if (strcmp(host, xs_dict_get(srv_config, "host")) == 0) { + /* route internally */ + xs *req = xs_dict_new(); + xs *q_vars = xs_dict_new(); + char *ctype; + + q_vars = xs_dict_append(q_vars, "resource", resource); + req = xs_dict_append(req, "q_vars", q_vars); + + webfinger_get_handler(req, "/.well-known/webfinger", + status, &payload, &p_size, &ctype); + } + else { + xs *url = xs_fmt("https:/" "/%s/.well-known/webfinger?resource=%s", host, resource); + + printf("url: %s\n", url); + xs_http_request("GET", url, headers, NULL, 0, status, &payload, &p_size); + } + + if (*status >= 200 && *status <= 299) { + xs *obj = xs_json_loads(payload); + + if (user != NULL) { + *user = xs_replace(xs_dict_get(obj, "subject"), "acct:", ""); + } + + if (actor != NULL) { + char *list = xs_dict_get(obj, "links"); + char *v; + + while (xs_list_iter(&list, &v)) { + if (xs_type(v) == XSTYPE_SOD) { + char *type = xs_dict_get(v, "type"); + + if (type && strcmp(type, "application/activity+json") == 0) { + *actor = xs_dup(xs_dict_get(v, "href")); + break; + } + } + } + } + } } @@ -135,4 +179,6 @@ void webfinger_get_handler(d_char *req, char *q_path, int *status, *body = j; *ctype = "application/json"; } + else + *status = 404; }