commit 3d96c57

shtrophic  ·  2025-01-24 21:24:05 +0000 UTC
parent 1c4c155
enforce tls when supported && add tests
5 files changed,  +51, -10
+2, -1
1@@ -1,2 +1,3 @@
2-*.o
3+**/*.o
4+tests/smtp
5 snac
+2, -1
 1@@ -2538,8 +2538,9 @@ int send_email(const xs_dict *mailinfo)
 2         *from = xs_dict_get(mailinfo, "from"),
 3         *to   = xs_dict_get(mailinfo, "to"),
 4         *body = xs_dict_get(mailinfo, "body");
 5+    int smtp_port = parse_port(url, NULL);
 6 
 7-    return xs_smtp_request(url, user, pass, from, to, body);
 8+    return xs_smtp_request(url, user, pass, from, to, body, smtp_port == 465 || smtp_port == 587);
 9 }
10 
11 
+24, -0
 1@@ -0,0 +1,24 @@
 2+/* snac - A simple, minimalistic ActivityPub instance */
 3+/* copyright (c) 2022 - 2025 grunfink et al. / MIT license */
 4+
 5+#define XS_IMPLEMENTATION
 6+#include "../xs.h"
 7+#include "../xs_curl.h"
 8+
 9+#define FROM "<snac-smtp-test@locahost>"
10+
11+int main(void) {
12+    xs *to   = xs_fmt("<%s@localhost>", getenv("USER")),
13+       *body = xs_fmt(""
14+        "To: %s \r\n"
15+        "From: " FROM "\r\n"
16+        "Subject: snac smtp test\r\n"
17+        "\r\n"
18+        "If you read this as an email, it probably worked!\r\n",
19+        to);
20+
21+    return xs_smtp_request("smtp://localhost", NULL, NULL, 
22+        FROM,
23+        to,
24+        body, 0);
25+}
+7, -2
 1@@ -931,6 +931,7 @@ int parse_port(const char *url, const char **errstr)
 2 	if (!(col = strchr(url, ':'))) {
 3         if (errstr)
 4 		    *errstr = "bad url";
 5+
 6 		return -1;
 7 	}
 8 	
 9@@ -950,13 +951,17 @@ int parse_port(const char *url, const char **errstr)
10             if (ret != -1) 
11                 return ret;
12             
13-            *errstr = strerror(errno);
14+            if (errstr)
15+                *errstr = strerror(errno);
16+
17             return -1;
18         }
19 		
20 		return tmp;
21 	}
22 
23-	*errstr = "unknown protocol";
24+    if (errstr)
25+	    *errstr = "unknown protocol";
26+
27 	return -1;
28 }
+16, -6
 1@@ -10,7 +10,8 @@ xs_dict *xs_http_request(const char *method, const char *url,
 2                         xs_str **payload, int *p_size, int timeout);
 3 
 4 int xs_smtp_request(const char *url, const char *user, const char *pass,
 5-                   const char *from, const char *to, const xs_str *body);
 6+                   const char *from, const char *to, const xs_str *body,
 7+                   int use_ssl);
 8 
 9 #ifdef XS_IMPLEMENTATION
10 
11@@ -198,7 +199,8 @@ xs_dict *xs_http_request(const char *method, const char *url,
12 }
13 
14 int xs_smtp_request(const char *url, const char *user, const char *pass,
15-                   const char *from, const char *to, const xs_str *body)
16+                   const char *from, const char *to, const xs_str *body,
17+                   int use_ssl)
18 {
19     CURL *curl;
20     CURLcode res = CURLE_OK;
21@@ -212,11 +214,19 @@ int xs_smtp_request(const char *url, const char *user, const char *pass,
22     curl = curl_easy_init();
23 
24     curl_easy_setopt(curl, CURLOPT_URL, url);
25-    curl_easy_setopt(curl, CURLOPT_USERNAME, user);
26-    curl_easy_setopt(curl, CURLOPT_PASSWORD, pass);
27+    if (user && pass) {
28+        /* allow authless connections, to, e.g. localhost */
29+        curl_easy_setopt(curl, CURLOPT_USERNAME, user);
30+        curl_easy_setopt(curl, CURLOPT_PASSWORD, pass);
31+    }
32+
33+    if (use_ssl)
34+        curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
35     
36     curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);
37-    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt = curl_slist_append(rcpt, to));
38+
39+    rcpt = curl_slist_append(rcpt, to);
40+    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt);
41 
42     curl_easy_setopt(curl, CURLOPT_READDATA, &pd);
43     curl_easy_setopt(curl, CURLOPT_READFUNCTION, _post_callback);
44@@ -224,8 +234,8 @@ int xs_smtp_request(const char *url, const char *user, const char *pass,
45 
46     res = curl_easy_perform(curl);
47     
48-    curl_slist_free_all(rcpt);
49     curl_easy_cleanup(curl);
50+    curl_slist_free_all(rcpt);
51 
52     return (int)res;
53 }