-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbashmail.sh
More file actions
executable file
·345 lines (295 loc) · 10.4 KB
/
bashmail.sh
File metadata and controls
executable file
·345 lines (295 loc) · 10.4 KB
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#!/bin/bash
#This script sends an email using as little dependencies as possible
#Copyright (C) 2019 Eduardo Diaz Comellas - ediaz@ultreia.es
#
#This program is free software: you can redistribute it and/or modify it
#under the terms of the GNU General Public License as published by the
#Free Software Foundation, either version 3 of the License, or (at your
#option) any later version.
#
#This program is distributed in the hope that it will be useful, but
#WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
#or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
#for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program. If not, see http://www.gnu.org/licenses/.
# Several ideas taken from dldnh at
#https://stackoverflow.com/questions/9998710/is-it-possible-to-send-mails-by-bash-script-via-smtp
#Contribution by eXtremeSHOK
#Customize smtp server, protocol, port, login and password.
#Server to use as MTA
SMTPSERVER=my.mail.server.com
#Port (can be left blank and will be deduced). We rather use 587 for submission,
#as 25 is usually firewalled
SMTPPORT=
#USESSL=1 -> send using SSL, USESSL=2 -> send with STARTTLS
#USESSL=0 -> no encryption... beware that password will be sent in plaintext
#If USESSL is different to [012], will use no encryption and default to port 25
USESSL=2
#Auth type to use, can be login, plain or none. If left empty, "none" is selected
USEAUTH=login
#Login and password to use
LOGIN=mylogincredential
PASSWORD=mypassword
#How much seconds to wait for an SMTP answer from the server
#Beware that a value under 5 may cause timeouts in normal operation
SMTPTIMEOUT=10
#How will we identify ourselves at the HELO time. Leave empty for system hostname
HELOHOSTNAME=
#Optional openssl command modifiers
OPENSSLOPTIONS=""
#Override system config file
#If set to 1, we will not read the /etc/bashmail.conf file
SYSCONFOVERRIDE=0
#Now we try to discover several variables if they are not previously declared
#No modifications below this line should be neccesary . Jump to the section
#called #MYEMAILMESSAGEHERE
# If there is a system configuration file and we can read it, then source it
if [ ${SYSCONFOVERRIDE:=0} -eq 0 ]
then
if [ -r bashmail.conf ]
then
echo "Reading system variables from bashmail.con"
. bashmail.conf
elif [ -r /etc/bashmail.conf ]
then
echo "Reading system variables from /etc/bashmail.conf"
. /etc/bashmail.conf
fi
fi
#Deduce hostname, if not previously set
DHELOHOSTNAME=${HELOHOSTNAME:-$(hostname)}
#Set a default for USESSL (SSL, port 465)
DUSESSL=${USESSL:-1}
#Provide a SMTPPORT, if empty
if [ -z $SMTPPORT ]
then
case $DUSESSL in
0)
SMTPPORT=587
;;
1)
SMTPPORT=465
;;
2)
SMTPPORT=587
;;
*)
echo >&2 "Warning: USESSL has unrecognized value. Defaulting to port 25 and no encryption"
SMTPPORT=25
;;
esac
fi
if [ $DUSESSL -eq 2 ]
then
OPENSSLOPTIONS=" -starttls smtp $OPENSSLOPTIONS "
fi
if [ $SMTPPORT -eq 25 ]
then
echo >&2 "Warning: using port 25 can be problematic. Consider 587"
fi
if [ -z $USEAUTH ]
then
USEAUTH=none
elif [ $USEAUTH != "none" ] && [ $USEAUTH != "login" ] && [ $USEAUTH != "plain" ]
then
echo >&2 "ERROR: Unrecognized value for USEAUTH. Please set it to none, plain or login"
exit 1
fi
#Make sure we have an SMTPTIMEOUT value
DSMTPTIMEOUT=${SMTPTIMEOUT:-4}
# Check that we have cut and grep. Should be in any sensible UNIX-like system anyway
hash cut 2>/dev/null || { echo >&2 "ERROR: cut command is required but not available. Aborting."; exit 1; }
hash grep 2>/dev/null || { echo >&2 "ERROR: grep command is required but not available. Aborting."; exit 1; }
# Check if we have base64 (needed for auth)
if [ $USEAUTH == "plain" ] || [ $USEAUTH == "login" ]
then
hash base64 2>/dev/null || { echo >&2 "ERROR: base64 command is required but not available. Aborting."; exit 1; }
fi
#Some other things needed if we use ssl
if [ $USESSL -eq 1 -o $USESSL -eq 2 ]
then
hash openssl 2>/dev/null || { echo >&2 "ERROR: Encryption required but openssl is not available. Aborting."; exit 1; }
hash mkfifo 2>/dev/null || { echo >&2 "ERROR: mkfifo command is required but not available. Aborting."; exit 1; }
hash mktemp 2>/dev/null || { echo >&2 "ERROR: mktemp command is required but not available. Aborting."; exit 1; }
fi
#Function used to check the SMTP status
function checkStatus {
#echo call: checkStatus $1 $2
expect=250
code=`echo $1 | cut -d- -f1`
line=$2
numparams=$#
if [ $numparams -eq 3 ] ; then
expect="${3}"
else
if [ $numparams -ne 2 ] ; then
echo >&2 "Error on call to checkStatus. Incorrect number of parameters $#"
exit 2
fi
fi
if [ -z $code ]
then
echo >&2 "Error: was expecting ${expect} but received blank. ${1} ${2}"
exit 2
elif [ $code -ne $expect ]
then
echo >&2 "Error: was expecting ${expect} but received ${1}: ${2}"
exit 2
fi
}
#Where all the magic happens
bashmail () {
from_addr="$1"
to_addr="$2"
cc_addr="$3"
subject="$4"
body="$5"
#This vars are initialized at the top of the script
myhostname=$DHELOHOSTNAME
smtpserver=$SMTPSERVER
smtpport=$SMTPPORT
ssl=$USESSL
auth=$USEAUTH
username=$LOGIN
password=$PASSWORD
timeout=$DSMTPTIMEOUT
#Flag initialization. Dont modify
loginsupported=0
plainsupported=0
if [ $ssl -eq 1 ] || [ $ssl -eq 2 ]
then
FIFODIR=`mktemp -d`
mkfifo ${FIFODIR}/sto
mkfifo ${FIFODIR}/ots
#This has to be in background
openssl s_client -connect ${smtpserver}:${smtpport} ${OPENSSLOPTIONS} -ign_eof -quiet -verify_quiet >& ${FIFODIR}/ots < ${FIFODIR}/sto &
#This is tricky... dont change order
exec 4< ${FIFODIR}/ots
exec 3> ${FIFODIR}/sto
OUTFD=3
INFD=4
else
exec 3<>/dev/tcp/${smtpserver}/${smtpport}
OUTFD=3
INFD=3
fi
read -t ${timeout} -u ${INFD} line
#If using openssl and connection fails, an error line is captured
echo $line | grep -i error > /dev/null
if [ $? -eq 0 ]
then
echo >&2 "ERROR: Connection to ${smtpserver}:${smtpport} failed"
exit 4
fi
#checkStatus "$sts" "$line" 220
echo "EHLO ${myhostname}" >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line"
SAL=0
while [ $SAL -eq 0 ]
do
#We are going to read all the remainder lines, one at a time
#until it timeouts (1sec)
read -u ${INFD} -t 1 linea
SAL=$?
#Check if auth login is supported
echo $linea |grep -i auth | grep -i login > /dev/null
if [ $? -eq 0 ]; then
loginsupported=1
fi
echo $linea |grep -i auth | grep -i plain > /dev/null
if [ $? -eq 0 ]; then
plainsupported=1
fi
done
if [ ${auth} == "login" ]
then
if [ ${loginsupported} -ne 1 ]
then
echo >&2 "ERROR: AUTH LOGIN requested, but not advertised"
exit 3
fi
#echo "Voy a autenticarme ${sts} ${line}"
userB64=`echo -ne ${username} | base64`
passB64=`echo -ne ${password} | base64`
echo "AUTH LOGIN" >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line" 334
echo ${userB64} >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line" 334
echo ${passB64} >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line" 235
elif [ ${auth} == "plain" ]
then
if [ ${plainsupported} -ne 1 ]
then
echo >&2 "ERROR: PLAIN LOGIN requested, but not advertised"
exit 3
fi
#echo "Voy a autenticarme ${sts} ${line}"
userpassB64=`echo -ne "\0${username}\0${password}" | base64`
echo "AUTH PLAIN ${userpassB64}" >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line" 235
fi
echo "MAIL FROM: ${from_addr}" >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line"
echo "RCPT TO: ${to_addr}" >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line"
echo "DATA" >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line" 354
if [ ! -z "${cc_addr}" ]
then
echo "Cc: ${cc_addr}" >&${OUTFD}
fi
echo "Subject: ${subject}" >&${OUTFD}
echo "" >&${OUTFD}
echo "${body}" >&${OUTFD}
echo "." >&${OUTFD}
read -t ${timeout} -u ${INFD} sts line
checkStatus "$sts" "$line"
#Clean up and go home
exec {OUTFD}>&-
if [ $ssl -eq 1 -o $ssl -eq 2 ]
then
exec {INFD}<&-
rm ${FIFODIR}/sto ${FIFODIR}/ots
rm -d ${FIFODIR}
fi
}
#MYEMAILMESSAGEHERE
#The sintax is: bashmail from to cc subject body
#You can substitute this variables, set them outside of the script or
#write the command directly below. Comment out the option you don't want
## OPTION1
## If you substitute this variables, please leave the "-" before the default value
FROMADDRESS=${FROMADDRESS:-fromaddress@mydomain.com}
TOADDRESS=${TOADDRESS:-toaddress@receiversdomain.com}
## BEWARE the CC. It you don't want to set a default, just comment out the next line
CCADDRESS=${CCADDRESS:-ccaddress@ccreceiversdomain.com}
SUBJECT=${SUBJECT:-Test mail at `date`}
if [ -z $BODY ]
then
read -r -d '' BODY << BODYDELIMITER
In a village of La Mancha, the name of which I have no desire to call
to mind, there lived not long since one of those gentlemen that keep
a lance in the lance-rack, an old buckler, a lean hack, and a greyhound
for coursing.
An olla of rather more beef than mutton, a salad on most nights, scraps
on Saturdays, lentils on Fridays, and a pigeon or so extra on Sundays,
made away with three-quarters of his income.
BODYDELIMITER
fi
bashmail "${FROMADDRESS}" "${TOADDRESS}" "${CCADDRESS}" "${SUBJECT}" "${BODY}"
## OPTION 2
## If you wish, just write the email below as shown
#bashmail "fromaddress@mydomain.com" "toaddress@receiversdomain.com" "ccaddress@ccreceiversdomain.com" "test mail at: `date`" "In a village of La Macha
#the name of which I have no desire to call to mind
#there lived not long since one of those gentlemen..."