-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsending-email-in-common-lisp.html
166 lines (140 loc) · 8.37 KB
/
sending-email-in-common-lisp.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2024-09-16 Mon 19:28 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Sending email in common-lisp</title>
<meta name="generator" content="Org Mode" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="index.css">
<meta name="author" content="Wade Mealing" />
<meta name="description" content="Wade Mealings documentation" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self' ajax.googleapis.com;"" />
</head>
<body>
<div id="content" class="content">
<h1 class="title">Sending email in common-lisp</h1>
<div id="outline-container-orgfafbbdd" class="outline-2">
<h2 id="orgfafbbdd">Summary:</h2>
<div class="outline-text-2" id="text-orgfafbbdd">
<p>
This page covers how to send an email from your common-lisp coding using the cl-smtp library using googles gmail servers.
</p>
</div>
</div>
<div id="outline-container-org551a7e3" class="outline-2">
<h2 id="org551a7e3">Introduction</h2>
<div class="outline-text-2" id="text-org551a7e3">
<p>
This post covers a working example on how to send email from the common-lisp (cl) language using googles servers. The provided
example has been tested as an individual, and regularly used from the 'google workspace' account.
</p>
</div>
</div>
<div id="outline-container-org298502d" class="outline-2">
<h2 id="org298502d">Requirements:</h2>
<div class="outline-text-2" id="text-org298502d">
<p>
An Application password.
</p>
<p>
<a href="https://knowledge.workspace.google.com/kb/how-to-create-app-passwords-000009237">Google detailed getting one here.</a> One fact that was missed is that you now need 2FA
configured for the account or you can not make app passwords.
</p>
</div>
</div>
<div id="outline-container-org2af1223" class="outline-2">
<h2 id="org2af1223">The code:</h2>
<div class="outline-text-2" id="text-org2af1223">
<p>
Listed below is the common-lisp code that is required to send email. The "password" is stored
in the environment variable GMAIL_KEY, as a single string. Google often displays on the 'app password'
page as 4 sets of 4 characters, aka xxxx xxxx xxxx xxxx , however experience shows that there was no space required.
</p>
<div class="org-src-container">
<pre class="src src-lisp">
<span style="color: #eaeaea;">(</span>ql:quickload <span style="color: #70c0b1;">"cl-smtp"</span><span style="color: #eaeaea;">)</span>
<span style="color: #eaeaea;">(</span>ql:quickload <span style="color: #70c0b1;">"cl-mime"</span><span style="color: #eaeaea;">)</span>
<span style="color: #eaeaea;">(</span><span style="color: #b9ca4a;">defun</span> <span style="color: #e78c45;">email-report</span> <span style="color: #70c0b1;">(</span><span style="color: #7aa6da;">&key</span> to cc subject html<span style="color: #70c0b1;">)</span>
<span style="color: #c397d8;">"Generic send SMTP mail with some TEXT to RECIEPIENTS"</span>
<span style="color: #70c0b1;">(</span><span style="color: #b9ca4a;">let</span> <span style="color: #e7c547;">(</span><span style="color: #b9ca4a;">(</span>login <span style="color: #70c0b1;">"youraccount@gmail.com"</span><span style="color: #b9ca4a;">)</span>
<span style="color: #b9ca4a;">(</span>passwd <span style="color: #7aa6da;">(</span>uiop:getenv <span style="color: #70c0b1;">"GMAIL_KEY"</span><span style="color: #7aa6da;">)</span><span style="color: #b9ca4a;">)</span><span style="color: #e7c547;">)</span>
<span style="color: #e7c547;">(</span><span style="color: #b9ca4a;">cl-smtp:with-smtp-mail</span> <span style="color: #b9ca4a;">(</span>out <span style="color: #70c0b1;">"smtp.gmail.com"</span> to cc
<span style="color: #c397d8;">:ssl</span> <span style="color: #c397d8;">:tls</span>
<span style="color: #c397d8;">:authentication</span> `<span style="color: #7aa6da;">(</span>,login ,passwd<span style="color: #7aa6da;">)</span><span style="color: #b9ca4a;">)</span>
<span style="color: #b9ca4a;">(</span>format out <span style="color: #70c0b1;">"To: ~A~%"</span> to <span style="color: #b9ca4a;">)</span>
<span style="color: #b9ca4a;">(</span>format out <span style="color: #70c0b1;">"Subject: ~A~%"</span> subject<span style="color: #b9ca4a;">)</span>
<span style="color: #b9ca4a;">(</span>cl-mime:print-mime out <span style="color: #7aa6da;">(</span>make-instance 'cl-mime:mime
<span style="color: #c397d8;">:type</span> <span style="color: #70c0b1;">"text"</span> <span style="color: #c397d8;">:subtype</span> <span style="color: #70c0b1;">"html"</span>
<span style="color: #c397d8;">:encoding</span> <span style="color: #c397d8;">:base64</span>
<span style="color: #c397d8;">:content</span> html<span style="color: #7aa6da;">)</span> <span style="color: #d54e53; font-weight: bold;">t t</span><span style="color: #b9ca4a; font-weight: bold;">)</span><span style="color: #e7c547; font-weight: bold;">)</span><span style="color: #70c0b1; font-weight: bold;">)</span><span style="color: #eaeaea; font-weight: bold;">)</span>
<span style="color: #eaeaea;">(</span>devar html-mail-content <span style="color: #70c0b1;">"<html><h1> THis is html, but not really. </h1></html>"</span><span style="color: #eaeaea;">)</span>
<span style="color: #eaeaea;">(</span>email-report <span style="color: #c397d8;">:to</span> <span style="color: #70c0b1;">"someone@example.com"</span>
<span style="color: #c397d8;">:cc</span> *cc-list*
<span style="color: #c397d8;">:subject</span> email-subject
<span style="color: #c397d8;">:html</span> html-content<span style="color: #eaeaea;">)</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgaed93e4" class="outline-2">
<h2 id="orgaed93e4">Ideas for improvement.</h2>
<div class="outline-text-2" id="text-orgaed93e4">
</div>
<div id="outline-container-orgf334639" class="outline-3">
<h3 id="orgf334639">1. Secret Storage mechanism.</h3>
<div class="outline-text-3" id="text-orgf334639">
<p>
The application password needs to be stored somewhere, my advice is not to have it stored in plaintext.
</p>
<p>
If your application is hosted on a containerized platform, you can pass it as environment variables, or
some of them have secrets file.
</p>
</div>
</div>
<div id="outline-container-orgb2c5bb8" class="outline-3">
<h3 id="orgb2c5bb8">2. Preventing secret leaks.</h3>
<div class="outline-text-3" id="text-orgb2c5bb8">
<p>
After the secret is loaded into memory, destroy the file or environment setting so it is harder for attackers
to abuse the information.
</p>
<div class="org-src-container">
<pre class="src src-lisp"><span style="color: #eaeaea;">(</span>setf <span style="color: #70c0b1;">(</span>uiop:getenv <span style="color: #70c0b1;">"SOME_ENVIRONMENT_VARIABLE"</span><span style="color: #70c0b1;">)</span> <span style="color: #70c0b1;">"PASSWORD-REMOVED-FOR-SECURITY-REASONS"</span><span style="color: #eaeaea;">)</span>
</pre>
</div>
<p>
When it is loaded, use <a href="https://github.com/rotatef/secret-values">Secret Values</a> which will prevent passwords appearing in backtraces or logs.
</p>
</div>
</div>
<div id="outline-container-org4aaffd1" class="outline-3">
<h3 id="org4aaffd1">3. Preventing accidental/intention spamming.</h3>
<div class="outline-text-3" id="text-org4aaffd1">
<p>
Your application may accidentally send out hundreds of mail if a function is run repeatedly accidentally.
It is important that the program keep an accurate, reliable mechanism to know when a limits are abused.
</p>
</div>
</div>
</div>
<div id="outline-container-org96293c8" class="outline-2">
<h2 id="org96293c8">Conclusion</h2>
</div>
<div id="outline-container-org7c01fdf" class="outline-2">
<h2 id="org7c01fdf">Resources:</h2>
<div class="outline-text-2" id="text-org7c01fdf">
<p>
<a href="https://gitlab.common-lisp.net/cl-smtp/cl-smtp">https://gitlab.common-lisp.net/cl-smtp/cl-smtp</a>
</p>
</div>
</div>
</div>
</body>
</html>