commit af92863

default  ·  2024-11-12 04:38:55 +0000 UTC
parent 36c6538
Added new proxy authorization by token.
3 files changed,  +49, -14
M data.c
M html.c
M snac.h
M data.c
+20, -2
 1@@ -12,6 +12,7 @@
 2 #include "xs_regex.h"
 3 #include "xs_match.h"
 4 #include "xs_unicode.h"
 5+#include "xs_random.h"
 6 
 7 #include "snac.h"
 8 
 9@@ -164,6 +165,23 @@ int srv_open(const char *basedir, int auto_upgrade)
10         write_default_css();
11     }
12 
13+    /* if proxy_media is set but there is no token seed, create one */
14+    if (xs_is_true(xs_dict_get(srv_config, "proxy_media")) &&
15+        xs_is_null(xs_dict_get(srv_config, "proxy_token_seed"))) {
16+        char rnd[16];
17+        xs_rnd_buf(rnd, sizeof(rnd));
18+        xs *pts = xs_hex_enc(rnd, sizeof(rnd));
19+
20+        xs_dict_set(srv_config, "proxy_token_seed", pts);
21+
22+        if ((f = fopen(cfg_file, "w")) != NULL) {
23+            xs_json_dump(srv_config, 4, f);
24+            fclose(f);
25+
26+            srv_log(xs_fmt("Created proxy_token_seed"));
27+        }
28+    }
29+
30     return ret;
31 }
32 
33@@ -3652,13 +3670,13 @@ t_announcement *announcement(const double after)
34 }
35 
36 
37-xs_str *make_url(const char *href, const char *proxy)
38+xs_str *make_url(const char *href, const char *proxy, int by_token)
39 /* makes an URL, possibly including proxying */
40 {
41     xs_str *url = NULL;
42 
43     if (proxy && !xs_startswith(href, srv_baseurl)) {
44-        xs *p = xs_str_cat(xs_dup(proxy), "/proxy/");
45+        xs *p = xs_str_cat(xs_dup(proxy), "/x/");
46         url = xs_replace(href, "https:/" "/", p);
47     }
48     else
M html.c
+28, -11
 1@@ -70,7 +70,7 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p
 2 
 3                 if (n && i) {
 4                     const char *u = xs_dict_get(i, "url");
 5-                    xs *url = make_url(u, proxy);
 6+                    xs *url = make_url(u, proxy, 0);
 7 
 8                     xs_html *img = xs_html_sctag("img",
 9                         xs_html_attr("loading", "lazy"),
10@@ -122,7 +122,7 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date,
11             v = xs_list_get(v, 0);
12 
13         if ((v = xs_dict_get(v, "url")) != NULL)
14-            avatar = make_url(v, proxy);
15+            avatar = make_url(v, proxy, 0);
16     }
17 
18     if (avatar == NULL)
19@@ -1973,7 +1973,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
20             if (content && xs_str_in(content, o_href) != -1)
21                 continue;
22 
23-            xs *href = make_url(o_href, proxy);
24+            xs *href = make_url(o_href, proxy, 0);
25 
26             if (xs_startswith(type, "image/") || strcmp(type, "Image") == 0) {
27                 xs_html_add(content_attachments,
28@@ -2788,7 +2788,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
29     const char *p_path;
30     int cache = 1;
31     int save = 1;
32-    const char *proxy = NULL;
33+    int proxy = 0;
34     const char *v;
35 
36     xs *l = xs_split_n(q_path, "/", 2);
37@@ -2816,7 +2816,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
38     }
39 
40     if (xs_is_true(xs_dict_get(srv_config, "proxy_media")))
41-        proxy = snac.actor;
42+        proxy = 1;
43 
44     /* return the RSS if requested by Accept header */
45     if (accept != NULL) {
46@@ -3194,19 +3194,36 @@ int html_get_handler(const xs_dict *req, const char *q_path,
47         snac_debug(&snac, 1, xs_fmt("serving RSS"));
48     }
49     else
50-    if (xs_startswith(p_path, "proxy/") && proxy) { /** remote media by proxy **/
51-        if (!login(&snac, req)) {
52-            *body  = xs_dup(uid);
53-            status = HTTP_STATUS_UNAUTHORIZED;
54+    if (proxy && (xs_startswith(p_path, "x/") || xs_startswith(p_path, "y/"))) { /** remote media by proxy **/
55+        xs *proxy_prefix = NULL;
56+
57+        if (xs_startswith(p_path, "x/")) {
58+            /* proxy usage authorized by http basic auth */
59+            if (login(&snac, req))
60+                proxy_prefix = xs_str_new("x/");
61+            else {
62+                *body  = xs_dup(uid);
63+                status = HTTP_STATUS_UNAUTHORIZED;
64+            }
65         }
66         else {
67+            /* proxy usage authorized by proxy_token */
68+            xs *tks = xs_fmt("%s:%s", xs_dict_get(srv_config, "proxy_token_seed"), snac.actor);
69+            xs *tk = xs_md5_hex(tks, strlen(tks));
70+            xs *p = xs_fmt("y/%s/", tk);
71+
72+            if (xs_startswith(p_path, p))
73+                proxy_prefix = xs_dup(p);
74+        }
75+
76+        if (proxy_prefix) {
77             /* pick the raw path (including optional ? arguments) */
78             const char *raw_path = xs_dict_get(req, "raw_path");
79 
80             /* skip to where the proxy/ string starts */
81-            raw_path += xs_str_in(raw_path, "proxy/");
82+            raw_path += xs_str_in(raw_path, proxy_prefix);
83 
84-            xs *url = xs_replace(raw_path, "proxy/", "https:/" "/");
85+            xs *url = xs_replace(raw_path, proxy_prefix, "https:/" "/");
86             xs *hdrs = xs_dict_new();
87 
88             hdrs = xs_dict_append(hdrs, "user-agent", USER_AGENT);
M snac.h
+1, -1
1@@ -411,4 +411,4 @@ typedef struct {
2 } t_announcement;
3 t_announcement *announcement(double after);
4 
5-xs_str *make_url(const char *href, const char *proxy);
6+xs_str *make_url(const char *href, const char *proxy, int by_token);