summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE_NOTES.md2
-rw-r--r--activitypub.c18
-rw-r--r--examples/snac_netbsd6
-rw-r--r--html.c13
-rw-r--r--xs_openssl.h18
5 files changed, 40 insertions, 17 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 57102c3..ac40ee9 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -18,6 +18,8 @@ Fixed some crashes (special thanks to Louis Merlin for helping me with this).
18 18
19Updated Docker scripts to avoid generating a useless log file. 19Updated Docker scripts to avoid generating a useless log file.
20 20
21Fixed some memory leaks, key generation errors and HTML inconsistencies (contributed by dandelions).
22
21Added a new CONTRIBUTING.md file. Among other guidelines, I explicitly say there that AI contributions are **not** accepted. 23Added a new CONTRIBUTING.md file. Among other guidelines, I explicitly say there that AI contributions are **not** accepted.
22 24
23snac is now available as a Yunohost [app](https://apps.yunohost.org/app/snac). Thank you very much to Bruno Cesar Rocha for this. 25snac is now available as a Yunohost [app](https://apps.yunohost.org/app/snac). Thank you very much to Bruno Cesar Rocha for this.
diff --git a/activitypub.c b/activitypub.c
index 0535269..ed9acf9 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -645,12 +645,13 @@ xs_list *recipient_list(snac *snac, const xs_dict *msg, int expand_public)
645 645
646 while (xs_list_iter(&l, &v)) { 646 while (xs_list_iter(&l, &v)) {
647 if (expand_public) { 647 if (expand_public) {
648 xs *followers_url = xs_fmt("%s/followers", snac->actor);
648 if (strcmp(v, public_address) == 0 || 649 if (strcmp(v, public_address) == 0 ||
649 /* check if it's a followers collection URL */ 650 /* check if it's a followers collection URL */
650 (xs_type(v) == XSTYPE_STRING && 651 (xs_type(v) == XSTYPE_STRING &&
651 strcmp(v, xs_fmt("%s/followers", snac->actor)) == 0) || 652 strcmp(v, followers_url) == 0) ||
652 (xs_type(v) == XSTYPE_LIST && 653 (xs_type(v) == XSTYPE_LIST &&
653 xs_list_in(v, xs_fmt("%s/followers", snac->actor)) != -1)) { 654 xs_list_in(v, followers_url) != -1)) {
654 /* iterate the followers and add them */ 655 /* iterate the followers and add them */
655 xs *fwers = follower_list(snac); 656 xs *fwers = follower_list(snac);
656 const char *actor; 657 const char *actor;
@@ -1624,6 +1625,7 @@ xs_dict *msg_emoji_init(snac *snac, const char *mid, const char *eid_o)
1624 else if (*eid == '%') { 1625 else if (*eid == '%') {
1625 content = xs_url_dec_emoji(xs_dup(eid)); 1626 content = xs_url_dec_emoji(xs_dup(eid));
1626 if (content == NULL) { 1627 if (content == NULL) {
1628 xs_free(n_msg);
1627 return NULL; 1629 return NULL;
1628 } 1630 }
1629 } 1631 }
@@ -1631,8 +1633,10 @@ xs_dict *msg_emoji_init(snac *snac, const char *mid, const char *eid_o)
1631 content = xs_fmt(":%s:", eid); 1633 content = xs_fmt(":%s:", eid);
1632 const char *emo = xs_dict_get(emjs, content); 1634 const char *emo = xs_dict_get(emjs, content);
1633 1635
1634 if (emo == NULL) 1636 if (emo == NULL) {
1637 xs_free(n_msg);
1635 return NULL; 1638 return NULL;
1639 }
1636 1640
1637 if (xs_match(emo, "https://*|http://*")) { /* emoji is an URL to an image */ 1641 if (xs_match(emo, "https://*|http://*")) { /* emoji is an URL to an image */
1638 icon = xs_dict_set(icon, "type", "Image"); 1642 icon = xs_dict_set(icon, "type", "Image");
@@ -1667,9 +1671,10 @@ xs_dict *msg_emoji_init(snac *snac, const char *mid, const char *eid_o)
1667 1671
1668 accounts = xs_list_append(accounts, snac->actor); 1672 accounts = xs_list_append(accounts, snac->actor);
1669 1673
1674 xs *to_duplicate = xs_dup(xs_list_get(xs_dict_get(n_msg, "to"), 1));
1670 n_msg = xs_dict_set(n_msg, "content", content); 1675 n_msg = xs_dict_set(n_msg, "content", content);
1671 n_msg = xs_dict_set(n_msg, "accounts", accounts); 1676 n_msg = xs_dict_set(n_msg, "accounts", accounts);
1672 n_msg = xs_dict_set(n_msg, "attributedTo", xs_list_get(xs_dict_get(n_msg, "to"), 1)); 1677 n_msg = xs_dict_set(n_msg, "attributedTo", to_duplicate);
1673 n_msg = xs_dict_set(n_msg, "accountId", snac->uid); 1678 n_msg = xs_dict_set(n_msg, "accountId", snac->uid);
1674 n_msg = xs_dict_set(n_msg, "tag", tag); 1679 n_msg = xs_dict_set(n_msg, "tag", tag);
1675 1680
@@ -1679,6 +1684,7 @@ xs_dict *msg_emoji_init(snac *snac, const char *mid, const char *eid_o)
1679 return n_msg; 1684 return n_msg;
1680 } 1685 }
1681 1686
1687 xs_free(n_msg);
1682 return NULL; 1688 return NULL;
1683} 1689}
1684 1690
@@ -1710,13 +1716,14 @@ xs_dict *msg_emoji_unreact(snac *user, const char *mid, const char *eid)
1710 if (strlen(eid) == 12 && *eid == '%') { 1716 if (strlen(eid) == 12 && *eid == '%') {
1711 eid = xs_url_dec(eid); 1717 eid = xs_url_dec(eid);
1712 if (eid == NULL) { 1718 if (eid == NULL) {
1719 xs_free(msg);
1713 return NULL; 1720 return NULL;
1714 } 1721 }
1715 } 1722 }
1716 1723
1717 /* lets get all emotes for this msg, and compare it to our content */ 1724 /* lets get all emotes for this msg, and compare it to our content */
1718 while (xs_list_next(emotes, &v, &c)) { 1725 while (xs_list_next(emotes, &v, &c)) {
1719 xs_dict *e = NULL; 1726 xs *e = NULL;
1720 if (valid_status(object_get_by_md5(v, &e))) { 1727 if (valid_status(object_get_by_md5(v, &e))) {
1721 const char *content = xs_dict_get(e, "content"); 1728 const char *content = xs_dict_get(e, "content");
1722 const char *id = xs_dict_get(e, "id"); 1729 const char *id = xs_dict_get(e, "id");
@@ -1730,6 +1737,7 @@ xs_dict *msg_emoji_unreact(snac *user, const char *mid, const char *eid)
1730 } 1737 }
1731 } 1738 }
1732 1739
1740 xs_free(msg);
1733 return NULL; 1741 return NULL;
1734} 1742}
1735 1743
diff --git a/examples/snac_netbsd b/examples/snac_netbsd
index 06991b1..19c221a 100644
--- a/examples/snac_netbsd
+++ b/examples/snac_netbsd
@@ -31,4 +31,8 @@ snac_precmd() {
31} 31}
32 32
33load_rc_config $name 33load_rc_config $name
34run_rc_command "$1" \ No newline at end of file 34
35# increase the number of file descriptors
36ulimit -n 1024
37
38run_rc_command "$1"
diff --git a/html.c b/html.c
index dda387a..9f5ca1d 100644
--- a/html.c
+++ b/html.c
@@ -1451,6 +1451,7 @@ xs_html *html_checkbox(const char *form_name, const char *label, int flag)
1451 xs_html_sctag("input", 1451 xs_html_sctag("input",
1452 xs_html_attr("type", "checkbox"), 1452 xs_html_attr("type", "checkbox"),
1453 xs_html_attr("name", form_name), 1453 xs_html_attr("name", form_name),
1454 xs_html_attr("id", form_name),
1454 xs_html_attr(flag ? "checked" : "", NULL)), 1455 xs_html_attr(flag ? "checked" : "", NULL)),
1455 xs_html_tag("label", 1456 xs_html_tag("label",
1456 xs_html_attr("for", form_name), 1457 xs_html_attr("for", form_name),
@@ -4111,7 +4112,7 @@ void notify_filter(snac *user, const xs_dict *p_vars)
4111 int folreq_on = (v = xs_dict_get(p_vars, "folreqs_on")) ? strcmp(v, "on") == 0 : 0; 4112 int folreq_on = (v = xs_dict_get(p_vars, "folreqs_on")) ? strcmp(v, "on") == 0 : 0;
4112 int blocks_on = (v = xs_dict_get(p_vars, "blocks_on")) ? strcmp(v, "on") == 0 : 0; 4113 int blocks_on = (v = xs_dict_get(p_vars, "blocks_on")) ? strcmp(v, "on") == 0 : 0;
4113 int polls_on = (v = xs_dict_get(p_vars, "polls_on")) ? strcmp(v, "on") == 0 : 0; 4114 int polls_on = (v = xs_dict_get(p_vars, "polls_on")) ? strcmp(v, "on") == 0 : 0;
4114 xs_dict *filter = xs_dict_new(); 4115 xs *filter = xs_dict_new();
4115 filter = xs_dict_set(filter, "likes", xs_stock(likes_on ? XSTYPE_TRUE : XSTYPE_FALSE)); 4116 filter = xs_dict_set(filter, "likes", xs_stock(likes_on ? XSTYPE_TRUE : XSTYPE_FALSE));
4116 filter = xs_dict_set(filter, "reacts", xs_stock(reacts_on ? XSTYPE_TRUE : XSTYPE_FALSE)); 4117 filter = xs_dict_set(filter, "reacts", xs_stock(reacts_on ? XSTYPE_TRUE : XSTYPE_FALSE));
4117 filter = xs_dict_set(filter, "mentions", xs_stock(ments_on ? XSTYPE_TRUE : XSTYPE_FALSE)); 4118 filter = xs_dict_set(filter, "mentions", xs_stock(ments_on ? XSTYPE_TRUE : XSTYPE_FALSE));
@@ -4122,6 +4123,7 @@ void notify_filter(snac *user, const xs_dict *p_vars)
4122 filter = xs_dict_set(filter, "blocks", xs_stock(blocks_on ? XSTYPE_TRUE : XSTYPE_FALSE)); 4123 filter = xs_dict_set(filter, "blocks", xs_stock(blocks_on ? XSTYPE_TRUE : XSTYPE_FALSE));
4123 filter = xs_dict_set(filter, "polls", xs_stock(polls_on ? XSTYPE_TRUE : XSTYPE_FALSE)); 4124 filter = xs_dict_set(filter, "polls", xs_stock(polls_on ? XSTYPE_TRUE : XSTYPE_FALSE));
4124 user->config = xs_dict_set(user->config, "notify_filter", filter); 4125 user->config = xs_dict_set(user->config, "notify_filter", filter);
4126 user->tz = xs_dict_get_def(user->config, "tz", "UTC"); // previous line invalidates user->tz
4125} 4127}
4126 4128
4127xs_str *html_notifications(snac *user, int skip, int show) 4129xs_str *html_notifications(snac *user, int skip, int show)
@@ -4137,7 +4139,9 @@ xs_str *html_notifications(snac *user, int skip, int show)
4137 xs_html *body = html_user_body(user, 0); 4139 xs_html *body = html_user_body(user, 0);
4138 const xs_dict *n_filter = xs_dict_get(user->config, "notify_filter"); 4140 const xs_dict *n_filter = xs_dict_get(user->config, "notify_filter");
4139 if (!n_filter) { 4141 if (!n_filter) {
4140 user->config = xs_dict_set(user->config, "notify_filter", xs_dict_new()); 4142 xs *filter = xs_dict_new();
4143 user->config = xs_dict_set(user->config, "notify_filter", filter);
4144 user->tz = xs_dict_get_def(user->config, "tz", "UTC"); // previous line invalidates user->tz
4141 n_filter = xs_dict_get(user->config, "notify_filter"); 4145 n_filter = xs_dict_get(user->config, "notify_filter");
4142 } 4146 }
4143 xs *n_list = notify_filter_list(user, n_list_unfilt); 4147 xs *n_list = notify_filter_list(user, n_list_unfilt);
@@ -4158,6 +4162,7 @@ xs_str *html_notifications(snac *user, int skip, int show)
4158 body); 4162 body);
4159 4163
4160 xs *filter_notifs_action = xs_fmt("%s/admin/filter-notifications", user->actor); 4164 xs *filter_notifs_action = xs_fmt("%s/admin/filter-notifications", user->actor);
4165 xs *notifs_action = xs_fmt("%s/notifications", user->actor);
4161 xs_html *notifs_form = xs_html_tag("form", 4166 xs_html *notifs_form = xs_html_tag("form",
4162 xs_html_attr("autocomplete", "off"), 4167 xs_html_attr("autocomplete", "off"),
4163 xs_html_attr("method", "post"), 4168 xs_html_attr("method", "post"),
@@ -4167,7 +4172,7 @@ xs_str *html_notifications(snac *user, int skip, int show)
4167 xs_html_sctag("input", 4172 xs_html_sctag("input",
4168 xs_html_attr("type", "hidden"), 4173 xs_html_attr("type", "hidden"),
4169 xs_html_attr("name", "hard-redir"), 4174 xs_html_attr("name", "hard-redir"),
4170 xs_html_attr("value", xs_fmt("%s/notifications", user->actor))), 4175 xs_html_attr("value", notifs_action)),
4171 html_checkbox("likes_on", L("Likes"), n_likes_on), 4176 html_checkbox("likes_on", L("Likes"), n_likes_on),
4172 html_checkbox("reacts_on", L("Emoji reacts"), n_reacts_on), 4177 html_checkbox("reacts_on", L("Emoji reacts"), n_reacts_on),
4173 html_checkbox("mentions_on", L("Mentions"), n_ments_on), 4178 html_checkbox("mentions_on", L("Mentions"), n_ments_on),
@@ -5568,7 +5573,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
5568 5573
5569 eid = xs_strip_chars_i(eid, ":"); 5574 eid = xs_strip_chars_i(eid, ":");
5570 5575
5571 const xs_dict *ret = msg_emoji_init(&snac, id, eid); 5576 xs *ret = msg_emoji_init(&snac, id, eid);
5572 /* fails if either invalid or already reacted */ 5577 /* fails if either invalid or already reacted */
5573 if (!ret) 5578 if (!ret)
5574 ret = msg_emoji_unreact(&snac, id, eid); 5579 ret = msg_emoji_unreact(&snac, id, eid);
diff --git a/xs_openssl.h b/xs_openssl.h
index 64b59dd..6d804f7 100644
--- a/xs_openssl.h
+++ b/xs_openssl.h
@@ -38,7 +38,7 @@ xs_str *xs_base64_enc(const xs_val *data, int sz)
38{ 38{
39 BIO *mem, *b64; 39 BIO *mem, *b64;
40 BUF_MEM *bptr; 40 BUF_MEM *bptr;
41 41
42 b64 = BIO_new(BIO_f_base64()); 42 b64 = BIO_new(BIO_f_base64());
43 mem = BIO_new(BIO_s_mem()); 43 mem = BIO_new(BIO_s_mem());
44 b64 = BIO_push(b64, mem); 44 b64 = BIO_push(b64, mem);
@@ -118,16 +118,16 @@ xs_dict *xs_evp_genkey(int bits)
118/* generates an RSA keypair using the EVP interface */ 118/* generates an RSA keypair using the EVP interface */
119{ 119{
120 xs_dict *keypair = NULL; 120 xs_dict *keypair = NULL;
121 EVP_PKEY_CTX *ctx; 121 EVP_PKEY_CTX *ctx = NULL;
122 EVP_PKEY *pkey = NULL; 122 EVP_PKEY *pkey = NULL;
123 123
124 if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) 124 if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL)
125 goto end; 125 return NULL;
126 126
127 if (EVP_PKEY_keygen_init(ctx) <= 0 || 127 if (EVP_PKEY_keygen_init(ctx) <= 0 ||
128 EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0 || 128 EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0 ||
129 EVP_PKEY_keygen(ctx, &pkey) <= 0) 129 EVP_PKEY_keygen(ctx, &pkey) <= 0)
130 goto end; 130 return NULL;
131 131
132 BIO *bs = BIO_new(BIO_s_mem()); 132 BIO *bs = BIO_new(BIO_s_mem());
133 BIO *bp = BIO_new(BIO_s_mem()); 133 BIO *bp = BIO_new(BIO_s_mem());
@@ -142,13 +142,17 @@ xs_dict *xs_evp_genkey(int bits)
142 142
143 keypair = xs_dict_new(); 143 keypair = xs_dict_new();
144 144
145 keypair = xs_dict_append(keypair, "secret", sptr->data); 145 xs *secret = xs_str_new_sz(sptr->data, sptr->length);
146 keypair = xs_dict_append(keypair, "public", pptr->data); 146 xs *public = xs_str_new_sz(pptr->data, pptr->length);
147 keypair = xs_dict_append(keypair, "secret", secret);
148 keypair = xs_dict_append(keypair, "public", public);
147 149
148 BIO_free(bs); 150 BIO_free(bs);
149 BIO_free(bp); 151 BIO_free(bp);
150 152
151end: 153 EVP_PKEY_free(pkey);
154 EVP_PKEY_CTX_free(ctx);
155
152 return keypair; 156 return keypair;
153} 157}
154 158