Automatically answer to bash script openvpn command - bash

I need to respond at 3 questions in a script :
yes
password*
password*
This is the output when i use this command :
I don't want to use a specific other script just for this command.
printf "yes\password*\npassword*\n" | docker-compose run --rm openvpn ovpn_revokeclient "ovpn-"$1 remove
Please confirm you wish to revoke the certificate with the following subject:
subject=
commonName = ovpn-toto5
Type the word 'yes' to continue, or any other input to abort.
Continue with revocation: Using configuration from /etc/openvpn/pki/easy-rsa-9.IlcpnJ/tmp.PKMKIm
Enter pass phrase for /etc/openvpn/pki/private/ca.key:
Revoking Certificate 6D9F08EFEB4D6A925969D8829F20A4C0.
Data Base Updated
IMPORTANT!!!
Revocation was successful. You must run gen-crl and upload a CRL to your
infrastructure in order to prevent the revoked cert from being accepted.
Generating the Certificate Revocation List :
Using SSL: openssl OpenSSL 1.1.1g 21 Apr 2020
Using configuration from /etc/openvpn/pki/easy-rsa-47.nEJLBc/tmp.OeLpeI
Enter pass phrase for /etc/openvpn/pki/private/ca.key:
User interface error
139677322186056:error:2807106B:UI routines:UI_process:processing error:crypto/ui/ui_lib.c:545:while reading strings
unable to load CA private key
139677322186056:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto/evp/evp_enc.c:583:
139677322186056:error:0906A065:PEM routines:PEM_do_header:bad decrypt:crypto/pem/pem_lib.c:461:
Easy-RSA error:
CRL Generation failed.
ERROR: 1
I tried with echo too, but same problem..
I just don't understand how i can pass those values..
Thanks for help !
SEXPECT :
/usr/bin/sexpect spawn docker-compose run --rm openvpn easyrsa build-client-full "ovpn-toto" nopass
out=$(sexpect expect_out)
if [[ $out == "Enter pass phrase for /etc/openvpn/pki/private/ca.key:" ]]; then
sexpect send -enter "mypassword*"
continue
fi

Related

SSL/TLS required on the control channel [duplicate]

I'm trying to log into an ftps site. I've tried giving the login creds at the command line (and putting set parameters in ~/.lftprc, then opening an lftp session and typing those parameters with lftp job control statements. Regardless, I keep hitting the same roadblock:
421 Sorry, cleartext sessions are not accepted on this server.
Please reconnect using SSL/TLS security mechanisms.
I got furthest with the following parameters, but keep getting the error above.
How do I get lftp to use SSL/TLS security mechanism from the command line?
The objective is to script the access to this ftps site using bash (programming without using expect).
lftp
lftp :~> set ssl-allow false
lftp :~> set passive-mode yes
lftp :~> open ftp.abc.com
lftp ftp.abc.com:~> login theuser
Password:
lftp theuser#ftp.abc.com:~> cd
`cd' at 0 [Delaying before reconnect: 26]
CTRL-C
lftp theuser#ftp.abc.com:~> debug
lftp theuser#ftp.abc.com:~> cd
---- Connecting to ftp.abc.com (XX.XXX.XX.XX) port 21
<--- 220-Welcome to the Yahoo! Web Hosting FTP server
<--- 220-Need help? Get all details at:
<--- 220-http://help.yahoo.com/help/us/webhosting/gftp/
<--- 220-
<--- 220-No anonymous logins accepted.
<--- 220-Yahoo!
<--- 220-Local time is now 15:30. Server port: 21.
<--- 220-This is a private system - No anonymous login
<--- 220 You will be disconnected after 5 minutes of inactivity.
---> FEAT
<--- 211-Extensions supported:
<--- EPRT
<--- IDLE
<--- MDTM
<--- SIZE
<--- MFMT
<--- REST STREAM
<--- MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
<--- MLSD
<--- XDBG
<--- AUTH TLS
<--- PBSZ
<--- PROT
<--- TVFS
<--- ESTA
<--- PASV
<--- EPSV
<--- SPSV
<--- ESTP
<--- 211 End.
---> OPTS MLST type;size;modify;UNIX.mode;UNIX.uid;UNIX.gid;
<--- 200 MLST OPTS type;size;sizd;modify;UNIX.mode;UNIX.uid;UNIX.gid;unique;
---> USER theuser
<--- 421 Sorry, cleartext sessions are not accepted on this server.
Please reconnect using SSL/TLS security mechanisms.
It seems like lftp is not configured correctly on many systems, which makes it unable to verify server certificates (producing Fatal error: Certificate verification: Not trusted).
The web (and answers in this post) is full of suggestions to fix this by disabling certificate verification or encryption altogether. This is unsecure as it allows man-in-the-middle attacks to pass unnoticed.
The better solution is to configure certificate verification correctly, which is easy, fortunately. To do so, add the following line to /etc/lftp.conf (or alternatively ~/.lftp/rc, or ~/.config/lftp/rc):
set ssl:ca-file "/etc/ssl/certs/ca-certificates.crt"
ca-certificates.crt is a file that contains all CA certificates of the system. The location used above is the one from Ubuntu and may vary on different systems. To generate or update the file, run update-ca-certificates:
sudo update-ca-certificates
If your system does not have this command, you can create one manually like this:
cat /etc/ssl/certs/*.pem | sudo tee /etc/ssl/certs/ca-certificates.crt > /dev/null
lftp :~> set ssl-allow false
You've explicitly set ssl-allow to false. But this must be true if lftp should attempt to use SSL.
You might also need to
set ssl:verify-certificate no
My answer provides access for a single user on your system rather than a system-wide certificate.
lftp uses Transport Layer Security (TLS). So it’s essential to first grab the certificate from the FTP server.
openssl s_client -connect <ftp-hostname>:21 -starttls ftp
I include the entire certificate chain in a new file called cert.crt in my local ~/.lftp folder. At the very least, you're looking to include all the text of the certificate itself: -----BEGIN CERTIFICATE----- <...> -----END CERTIFICATE-----.
I create a file called rc in the local ~/.lftp folder and add the lines
set ssl:ca-file “cert.crt”
set ssl:check-hostname no (this prevents Fatal error: Certificate verification: certificate common name doesn't match requested host name ‘<ftp-hostname>’ when running a command like ls remotely)
Setting ftp:ssl-allow true didn't work for me.
By typing set:
lftp :~> set
I noticed this:
set ftp:ssl-allow true
set ftp:ssl-allow/XXX.XXX.XXX.XXX no
with XXX.XXX.XXX.XXX being the server, I was logging into.
So the final set of commands I needed was:
lftp :~> set ftp:ssl-allow true
lftp :~> set ftp:ssl-allow/XXX.XXX.XXX.XXX true
lftp :~> set ssl:verify-certificate no
lftp version must be >= 4.6.3 (Debian user)
What worked for me step by step with lftp:
get certificate of host with openssl s_client -connect <ftp_hostname>:21 -starttls ftp, at the begining of result I got something like -----BEGIN CERTIFICATE-----
MIIEQzCCAyu.....XjMO
-----END CERTIFICATE-----
copy that -----BEGIN CERTIFICATE-----
MIIEQzCCAyu.....XjMO
-----END CERTIFICATE----- into /etc/ssl/certs/ca-certificates.crt
Into lftp configuration reference this certificate file adding to /etc/lftp.conf for systemwide set ssl:ca-file "/etc/ssl/certs/ca-certificates.crt"
and then do your sync or whatever with lftp, on my case it is lftp -u "${FTP_USER},${FTP_PWD}" ${FTP_HOST} -e "set net:timeout 10;mirror ${EXCLUDES} -R ${LOCAL_SOURCE_PATH} ${REMOTE_DEST_PATH} ; quit"
This worked for me for a FTPS server connection (with port 990, but not necessary to specify) using lftp
code:
lftp ftps://USER:PASSWORD#server.com -c "set ssl:verify-certificate false;"
then:
do stuff
more info at:
how-to-avoid-lftp-certificate-verification-error

download cert with curl, echo cert value into openssl

I'm trying to get an intermediate certificate using curl, and process the certificate without writing it to a file.
I've figured out how to process a leaf cert and get the distribution point, but that's where I'm stuck.
For an example, let's take stackoverflow (seems pertinent). The first intermediate cert for SO is from http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt.
In an interactive shell, I can do something like this to store the value of the certificate into a variable:
DigiCertIntermediateCert=$(curl http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt)
Then I can check the value of the cert by doing something like this:
echo "$DigiCertIntermediateCert" | openssl x509 -inform DER -outform PEM
This outputs the nice and friendly PEM-formed cert. It looks like this:
-----BEGIN CERTIFICATE-----
MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs
...
cPUeybQ=
-----END CERTIFICATE-----
(Note: this will change when the intermediate cert changes, if this isn't exactly the value you're seeing, don't freak out)
Neat! Seems like this should work. Let's throw all this logic into a script with some basic case handling (like if the cert is in a different form, then we should interpret it as that form) and we should be done, right?
#! /bin/bash
cert_content=$(curl -s "$1")
echo "$cert_content"
if echo "$cert_content" | openssl x509 -text -noout; then
echo "Not converting"
echo "$cert_content"
else
echo "Converting"
echo "$cert_content" | openssl x509 -inform DER -outform PEM
fi
What does this output when we feed the url?
...
[binary contents of a certificate]
...
unable to load certificate
4667577964:error:09FFF06C:PEM routines:CRYPTO_internal:no start line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.230.1/libressl-2.6/crypto/pem/pem_lib.c:683:Expecting: TRUSTED CERTIFICATE
Converting
unable to load certificate
4421875308:error:0DFFF08E:asn1 encoding routines:CRYPTO_internal:not enough data:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.230.1/libressl-2.6/crypto/asn1/a_d2i_fp.c:251:
So it's pretty easy to see that the certificate is in DER form (because of the "Converting" line), but it looks like the certificate is not complete - note the error:
unable to load certificate
4421875308:error:0DFFF08E:asn1 encoding routines:CRYPTO_internal:not enough data:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.230.1/libressl-2.6/crypto/asn1/a_d2i_fp.c:251:
says that there is not enough data.
Why is this different between the script and the actions I'm taking in the shell? How can I feed the binary cert through the openssl tool to get the PEM-form cert out?
As the question alludes, I was not strict enough in my shell usage. The "interactive" session was done using zsh, and the script was run under bash. zsh will append an EOF to variables passed through its pipes, while bash (apparently) does not. Now my quest becomes how to append an EOF to a variable in bash (which, apparently, is non-trivial).

aws api error The action DescribeRegions is not valid for this web service

i need to know different aws ec2 regions
i know aws has command line tools for this but i want to use aws api so
i generated following query request for accessing aws ec2 api
https://ec2.amazonaws.com/?Action=DescribeRegions&AWSAccessKeyId=&Version=2013-02-01&Timestamp=2013-05-24T12%3A35%3A00Z&SignatureVersion=2&SignatureMethod=HmacSHA256&Signature=xkw62EsVWEpc3rodXADy4Q3LOquKKfHmVHrrIIGQCg0=
for which i got the following response
<?xml version="1.0" encoding="UTF-8"?>
* Connection #0 to host ec2.amazonaws.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
<Response>
<Errors>
<Error>
<Code>InvalidAction</Code>
<Messaged >The action urn:Post is not valid for this web service.</Message>
</Error></Errors>
<RequestID>4a33917f-3403-4ebc-9a85-4b5393a031c6</RequestID>
</Response>
[1] Done curl -v -get --data-urlencode DATA https://ec2.amazonaws.com/?action=DescribeRegions
[2] Done AWSAccessKeyId=
[3] Done Version=2013-02-01
[4] Done Timestamp=2013-05-24T12%3A35%3A00Z
[5]- Done SignatureVersion=2
[6]+ Done SignatureMethod=HmacSHA256
i signed this request query follwing cmd bash scipt
#!/bin/bash
q='GET
ec2.amazonaws.com
/
AWSAccessKeyId=<aws acces_key>&Action=DescribeRegions&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2013-05-24T12%3A35%3A00Z&Version=2013-02-01'
echo -n "$q" | openssl dgst -sha256 -hmac "<aws secret key>" -binary | openssl enc -base64
output was : xkw62EsVWEpc3rodXADy4Q3LOquKKfHmVHrrIIGQCg0=
and then i gave this curl request separately away from above bash script.
$curl -v -get --data-encode DATA https://ec2.amazonaws.com/?Action=DescribeRegions&AWSAccessKeyId=<aws access key>&Version=2013-02-01&Timestamp=2013-05-24T12%3A35%3A00Z&SignatureVersion=2&SignatureMethod=HmacSHA256&Signature=xkw62EsVWEpc3rodXADy4Q3LOquKKfHmVHrrIIGQCg0=
can any 1 tell me where i m going wrong?
You need to quote the request URL. It contains characters that are being interpreted by your shell.
The clue is in the output lines like "[1] Done ...". The ampersands in the URL are causing fragments of the URL to be executed as background subshells. These lines are the shell reporting that those subshells have finished.

Sending an email from R using the sendmailR package

I am trying to send an email from R, using the sendmailR package. The code below works fine when I run it on my PC, and I recieve the email. However, when I run it with my macbook pro, it fails with the following error:
library(sendmailR)
from <- sprintf("<sendmailR#%s>", Sys.info()[4])
to <- "<myemail#gmail.com>"
subject <- "TEST"
sendmail(from, to, subject, body,
control=list(smtpServer="ASPMX.L.GOOGLE.COM"))
Error in socketConnection(host = server, port = port, blocking = TRUE) :
cannot open the connection
In addition: Warning message:
In socketConnection(host = server, port = port, blocking = TRUE) :
ASPMX.L.GOOGLE.COM:25 cannot be opened
Any ideas as to why this would work on a PC, but not a mac? I turned the firewall off on both machines.
Are you able to send email via the command-line?
So, first of all, fire up a Terminal and then
$ echo “Test 123” | mail -s “Test” user#domain.com
Look into /var/log/mail.log, or better use
$ tail -f /var/log/mail.log
in a different window while you send your email. If you see something like
... setting up TLS connection to smtp.gmail.com[xxx.xx.xxx.xxx]:587
... Trusted TLS connection established to smtp.gmail.com[xxx.xx.xxx.xxx]:587:\
TLSv1 with cipher RC4-MD5 (128/128 bits)
then you succeeded. Otherwise, it means you have to configure you mailing system. I use postfix with Gmail for two years now, and I never had have problem with it. Basically, you need to grab the Equifax certificates, Equifax_Secure_CA.pem from here: http://www.geotrust.com/resources/root-certificates/. (They were using Thawtee certificates before but they changed last year.) Then, assuming you used Gmail,
Create relay_password in /etc/postfix and put a single line like this (with your correct login and password):
smtp.gmail.com login#gmail.com:password
then in a Terminal,
$ sudo postmap /etc/postfix/relay_password
to update Postfix lookup table.
Add the certificates in /etc/postfix/certs, or any folder you like, then
$ sudo c_rehash /etc/postfix/certs/
(i.e., rehash the certificates with Openssl).
Edit /etc/postfix/main.cf so that it includes the following lines (adjust the paths if needed):
relayhost = smtp.gmail.com:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/relay_password
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = may
smtp_tls_CApath = /etc/postfix/certs
smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache
smtp_tls_session_cache_timeout = 3600s
smtp_tls_loglevel = 1
tls_random_source = dev:/dev/urandom
Finally, just reload the Postfix process, with e.g.
$ sudo postfix reload
(a combination of start/stop works too).
You can choose a different port for the SMTP, e.g. 465.
It’s still possible to use SASL without TLS (the above steps are basically the same), but in both case the main problem is that your login informations are available in a plan text file... Also, should you want to use your MobileMe account, just replace the Gmail SMTP server with smtp.me.com.

Sending mail from a Bash shell script

I am writing a Bash shell script for Mac that sends an email notification by opening an automator application that sends email out with the default mail account in Mail.app. The automator application also attaches a text file that the script has written to. The problems with this solution are
It is visible in the GUI when sending
It steals focus if Mail is not the current application
It is dependent on Mail.app's account setup being valid in the future
I figure to get around those shortcomings I should send the mail directly from the script by entering SMTP settings, address to send to, etc. directly in the script. The catch is I would like to deploy this script on multiple computers (10.5 and 10.6) without enabling Postfix on the computer. Is it possible to do this in the script so it will run on a base Mac OS X install of 10.5. and 10.6?
Update: I've found the -bs option for Sendmail which seems to be what I need, but I'm at a loss of how to specify settings.
Also, to clarify, the reason I'd like to specify SMTP settings is that mails from localhost on port 25 sent out via Postfix would be blocked by most corporate firewalls, but if I specify the server and an alternate port I won't run into that problem.
Since Mac OS X includes Python, consider using a Python script instead of a Bash script. I haven't tested the sending portion, but it follows the standard example.
Python script
# Settings
SMTP_SERVER = 'mail.myisp.com'
SMTP_PORT = 25
SMTP_USERNAME = 'myusername'
SMTP_PASSWORD = '$uper$ecret'
SMTP_FROM = 'sender#example.com'
SMTP_TO = 'recipient#example.com'
TEXT_FILENAME = '/script/output/my_attachment.txt'
MESSAGE = """This is the message
to be sent to the client.
"""
# Now construct the message
import smtplib, email
from email import encoders
import os
msg = email.MIMEMultipart.MIMEMultipart()
body = email.MIMEText.MIMEText(MESSAGE)
attachment = email.MIMEBase.MIMEBase('text', 'plain')
attachment.set_payload(open(TEXT_FILENAME).read())
attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(TEXT_FILENAME))
encoders.encode_base64(attachment)
msg.attach(body)
msg.attach(attachment)
msg.add_header('From', SMTP_FROM)
msg.add_header('To', SMTP_TO)
# Now send the message
mailer = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
# EDIT: mailer is already connected
# mailer.connect()
mailer.login(SMTP_USERNAME, SMTP_PASSWORD)
mailer.sendmail(SMTP_FROM, [SMTP_TO], msg.as_string())
mailer.close()
I hope this helps.
Actually, "mail" works just as well.
mail -s "subject line" name#address.ext < filename
works perfectly fine, as long as you have SMTP set up on your machine. I think that most Macs do, by default.
If you don't have SMTP, then the only thing you're going to be able to do is go through Mail.app. An ALTERNATIVE way to go through mail.app is via AppleScript. When you tell Mail.app to send mail via AppleScript you can tell it to not pop up any windows... (this does still require Mail.app to be configured).
Introduction to Scripting Mail has a good description of how to work with mail in AppleScript.
There is a program called Sendmail.
You probably don't want to use the -bs command unless you are sending it as raw SMTP like Martin's example. -bs is for running an SMTP server as a deamon. Sendmail will send directly to the receiving mail server (on port 25) unless you override it in the configuration file. You can specify the configuration file by the -C paramter.
In the configuration, you can specify a relay server (any mail server or sendmail running -bs on another machine)
Using a properly configured relay server is good idea because when IT manages mail servers they implement SPF and domain keys. That keeps your mail out of the junk bin.
If port 25 is blocked you are left with two options.
Use the corporate SMTP server.
Run sendmail -bd on a machine outside of
the corporate firewall that listens
on a port other than 25.
I believe you can add configuration parameters on the command line. What you want is the SMART_HOST option. So call Sendmail like sendmail -OSMART_HOST=nameofhost.com.
Probably the only way you could do this, while keeping the program self-sufficient, is if you have direct access to an SMTP server from the clients.
If you do have direct access to an SMTP server you can use the SMTP example from wikipedia and turn it into something like this:
#!/bin/bash
telnet smtp.example.org 25 <<_EOF
HELO relay.example.org
MAIL FROM:<joe#example.org>
RCPT TO:<jane#example.org>
DATA
From: Joe <joe#example.org>
To: Jane <jane#example.org>
Subject: Hello
Hello, world!
.
QUIT
_EOF
To handle errors I would redirect the output from telnet to a file and then grep that for a "success message" later. I am not sure what format the message should be, but I see something like "250 2.0.0 Ok: queued as D86A226C574" in the output from my SMTP server. This would make me grep for "^250.*queued as".
Send mail from Bash with one line:
echo "your mail body" | mail -s "your subject" yourmail#yourdomain.com -a "From: sender#senderdomain.com"
sendEmail is a script that you can use to send email from the command line using more complicated settings, including connecting to a remote smtp server:
http://caspian.dotconf.net/menu/Software/SendEmail/
On OSX it is easily installable via macports:
http://sendemail.darwinports.com/
Below is the help page for the command, take note of the -s, -xu, -xp flags:
Synopsis: sendEmail -f ADDRESS [options]
Required:
-f ADDRESS from (sender) email address
* At least one recipient required via -t, -cc, or -bcc
* Message body required via -m, STDIN, or -o message-file=FILE
Common:
-t ADDRESS [ADDR ...] to email address(es)
-u SUBJECT message subject
-m MESSAGE message body
-s SERVER[:PORT] smtp mail relay, default is localhost:25
Optional:
-a FILE [FILE ...] file attachment(s)
-cc ADDRESS [ADDR ...] cc email address(es)
-bcc ADDRESS [ADDR ...] bcc email address(es)
Paranormal:
-xu USERNAME authentication user (for SMTP authentication)
-xp PASSWORD authentication password (for SMTP authentication)
-l LOGFILE log to the specified file
-v verbosity, use multiple times for greater effect
-q be quiet (no stdout output)
-o NAME=VALUE see extended help topic "misc" for details
Help:
--help TOPIC The following extended help topics are available:
addressing explain addressing and related options
message explain message body input and related options
misc explain -xu, -xp, and others
networking explain -s, etc
output explain logging and other output options
I whipped this up for the challenge. If you remove the call to 'dig' to obtain the mail relay, it is a 100% native Bash script.
#!/bin/bash
MAIL_FROM="sfinktah#bash.spamtrak.org"
RCPT_TO="sfinktah#bash.spamtrak.org"
MESSAGE=message.txt
SMTP_PORT=25
SMTP_DOMAIN=${RCPT_TO##*#}
index=1
while read PRIORITY RELAY
do
RELAY[$index]=$RELAY
((index++))
done < <( dig +short MX $SMTP_DOMAIN )
RELAY_COUNT=${#RELAY[#]}
SMTP_COMMANDS=( "HELO $HOSTNAME" "MAIL FROM: <$MAIL_FROM>" "RCPT TO: <$RCPT_TO>" "DATA" "." "QUIT" )
SMTP_REPLY=([25]=OK [50]=FAIL [51]=FAIL [52]=FAIL [53]=FAIL [54]=FAIL [55]=FAIL [45]=WAIT [35]=DATA [22]=SENT)
for (( i = 1 ; i < RELAY_COUNT ; i++ ))
do
SMTP_HOST="${RELAY[$i]}"
echo "Trying relay [$i]: $SMTP_HOST..."
exec 5<>/dev/tcp/$SMTP_HOST/$SMTP_PORT
read HELO <&5
echo GOT: $HELO
for COMMAND_ORDER in 0 1 2 3 4 5 6 7
do
OUT=${SMTP_COMMANDS[COMMAND_ORDER]}
echo SENDING: $OUT
echo -e "$OUT\r" >&5
read -r REPLY <&5
echo REPLY: $REPLY
# CODE=($REPLY)
CODE=${REPLY:0:2}
ACTION=${SMTP_REPLY[CODE]}
case $ACTION in
WAIT ) echo Temporarily Fail
break
;;
FAIL ) echo Failed
break
;;
OK ) ;;
SENT ) exit 0
;;
DATA ) echo Sending Message: $MESSAGE
cat $MESSAGE >&5
echo -e "\r" >&5
;;
* ) echo Unknown SMTP code $CODE
exit 2
esac
done
done
Here is a simple Ruby script to do this. Ruby ships on the Mac OS X versions you mentioned.
Replace all the bits marked 'replace'. If it fails, it returns a non-zero exit code and a Ruby back trace.
require 'net/smtp'
SMTPHOST = 'replace.yoursmtpserver.example.com'
FROM = '"Your Email" <youremail#replace.example.com>'
def send(to, subject, message)
body = <<EOF
From: #{FROM}
To: #{to}
Subject: #{subject}
#{message}
EOF
Net::SMTP.start(SMTPHOST) do |smtp|
smtp.send_message body, FROM, to
end
end
send('someemail#replace.example.com', 'testing', 'This is a message!')
You can embed this in a Bash script like so:
ruby << EOF
... script here ...
EOF
For some other ways to send Ruby emails, see Stack Overflow question How do I send mail from a Ruby program?.
You can use other languages that ship with Mac OS X as well:
How do I send email with Perl?
Sending HTML email using Python
1) Why not configure postfix to handle outbound mail only and relay it via a mail gateway? Its biggest advantage is that it is already installed on OS X clients.
2) Install and configure one of the lightweight MTAs that handle only outbound mail, like nullmailer or ssmtp (available via MacPorts).
In both cases use mailx(1) (or mutt if you want to get fancy) to send the mails from a shell script.
There are several questions on Server Fault that go into the details.
sendmail and even postfix may be too big to install if all you want to do is to send a few emails from your scripts.
If you have a Gmail account for example, you can use Google's servers to send email using SMTP. If you don't want to use gGoogle's server, as long as you have access to some SMTP server, it should work.
A very lightweight program that makes it easy to do so is msmtp. They have examples of configuration files in their documentation.
The easiest way to do it would be to set up a system-wide default:
account default
host smtp.gmail.com
from john.doe#gmail.com
user john.doe#gmail.com
password XXX
port 587
msmtp should be very easy to install. In fact, there is a port for it, so it could be as easy as port install msmtp.
After installing and configuring msmtp, you can send email to john.doe#gmail.com using:
mail -s <subject> john.doe#gmail.com <<EOF
<mail text, as many lines as you want. Shell variables will be expanded>.
EOF
You can put the above in a script. See man mail for details.
Here's a modified shells script snip I've used on various UNIX systems...
(echo "${MESSAGE}" | ${uuencode} ${ATTACHMENT}$basename ${ATTACHMENT}) | ${mailx} -s "${SUBJECT}" "${TO_LIST}"
uuencode and mailx are set to the executables. The other variables are from user input parsed using getopts.
This does work but I have to admit more often than not I use a simple Java program to send console emails.
Try mtcmail. Its a fairly complete email sender, completely standalone.

Resources