Advanced Namespace Tools blog
12 January 2018
Guide to configuring Plan 9 upas to work with gmail
It has been a few years since I was using Plan 9 for my email. I took a break from Plan 9 during 2014 and during that time fell back into the habit of using the web-gmail interface. I decided it was time to fix this, which meant figuring out, for the 3rd time or so, how to get 9front talking with gmail's servers. It only took a couple hours of feverish manpage and guide reading and debugging to get the config worked out. This particular configuration process is not the most graceful aspect of Plan 9, but the mail environment is very nice once it is set up. In general, configuring systems to work with non-plan 9 protocols is always going to be more of a hassle than staying entirely within the ecosystem, so I'm not saying I see a better way to do all this. I understand that the whole system was originally designed and intended for running your own mail server, not retrieving things from gmail, so the awkardness seems related to that.
Receiving and reading email - the easy part
Just being able to receive and read messages is easy. Step one - log into your gmail via the web interface, go to the account options, and tell it to allow less-secure login methods. Now, in your plan9 system, enter a command like this:
upas/fs -f /imaps/imap.gmail.com/myname@mydomain.com
This will spit out an error that looks like:
upas/fs: opening /imaps/imap.gmail.com/myname@mydomain.com: \
imap.gmail.com/imaps:cert for imap.gmail.com not recognized: \
sha256=x9n2C90RHrd4e97E/i21h9Ios0mKZJ9w3WDg9OE9Ud9
Now you can make that hash be recognized. Note the x509 prefix in the echo statement:
echo 'x509 sha256=x9n2C90RHrd4e97E/i21h9Ios0mKZJ9w3WDg9OE9Ud9' >>/sys/lib/tls/mail
Now rerun the same upas/fs command as above, and factotum will prompt you for your password. Enter it, and upas will spend some time (which varies depending on the size of your mailbox) setting things up. Now you can start the mail program to read messages with the command
mail
The tricky part: configuration for sending mail
Given how nice and easy that was, one might hope sending mail would be equally simple. Not quite. The configuration for sending is considerably more involved. A first step:
echo 'key proto=pass server=smtp.gmail.com service=smtp user=myname@mydomain.com !password=yourpassword' >/mnt/factotum/ctl
With that done, we have two files to configure in /mail/lib. The first is /mail/lib/rewrite. There is a template to use located at /mail/lib/rewrite.gateway. The easiest thing to do is just append the template to the blank-except-for-comments original.
cat /mail/lib/rewrite.gateway >> /mail/lib/rewrite
Editing the rewrite file is pretty simple. The only section that usually needs to be changed is shown below, and the change is obvious.
# append the local domain to addresses without a domain
local!"(.+)" alias \1@mydomain.com
local!(.*) alias \1@mydomain.com
With that done, we are ready to configure /mail/lib/remotemail. The configuration shown below may not be perfectly well-constructed, but works in practice.
#!/bin/rc
shift
sender=myname@mydomain.com
shift
addr=smtp.gmail.com
shift
fd=`{/bin/upas/aliasmail -f $sender}
switch($fd){
case *.*
;
case *
fd=mydomain.com
}
echo exec /bin/upas/smtp -u myname@mydomain.com -a -h $fd $addr $sender $* >>/sys/log/remotemail
exec /bin/upas/smtp -u myname@mydomain.com -a -h $fd $addr $sender $*
Note the addition of the -a flag to the pre-existing upas/smtp command. The echo statement is purely optional extra logging. We are almost done! You can try sending some mail with
mail someone@somedomain
Note that the mail program makes use of rio's "hold" mode, so you need to enter your message, then press escape, then hit ctrl-d to EOF the data you are sending. Sending this first message will fail because we need to add another bit of tls related info.
cat /sys/log/smtp
Will show an error that looks like
Jan 11 20:40:43 cert for gmail-smtp-msa.l.google.com not recognized: sha256=gE9IwK9spTR9613V92I5+sVI9R0U9PLKyaZjr8OiNH9
Again, you need to add this in the right place, which in this case is /sys/lib/tls/smtp.
echo 'x509 sha256=gE9IwK9spTR9613V92I5+sVI9R0U9PLKyaZjr8OiNH9' >>/sys/lib/tls/smtp
If all of this is done correctly, you should now be able to send mail successfully using the mail command.
Namespaces for your faces
Assuming you got all this done correctly and you can send and receive mail, you probably want to use Plan9's famous "faces" program to help out. It shows new mails as they arrive, and if you right click on the face icon, it will open them for you in a new window. However, you have to have a plumber running underneath your current rio, and faces needs to be in a namespace with access to upas/fs. You want to see a namespace stack like this within the rio you are working within:
mount '#s/plumb.user.15857' /mnt/plumb
mount '#|/data1' /mail/fs
mount '#s/rio.user.15869' /mnt/wsys 6
In other words, plumber first, then upas/fs, then start rio, then start faces within the rio. The conventional way to do this is having the plumber and upas started on your terminal from /usr/name/lib/profile.
Troubleshooting: check the logs
If something is misconfigured, you can often find out the problem from the logfiles. /sys/log/mail, /sys/log/runq, /sys/log/smtp, /sys/log/smtp.fail may all be relevant. I also added another log via the echo statement shown in remotemail, /sys/log/remotemail. Here is a summary of what needs to be done - check above for full details.
Reading mail
-
change your gmail settings to allow less-secure devices
-
add x509 crypto hash to /sys/lib/tls/mail after upas/fs -f to gmail imap
-
run upas/fs -f to gmail imap and answer factotum prompt for password
-
run mail program to read mail
Sending mail
-
Add key to factotum manually
-
Configure /mail/lib/rewrite based on /mail/lib/rewrite.gateway
-
Configure /mail/lib/remotemail script with appropriate variables
-
Add x509 crypto hash to /sys/lib/tls/smtp
-
run mail tosomeone@somewhere to send mail
Using multiple accounts
(The following information was provided by qwx)
I need to monitor multiple mailboxes, and be able to select from which one I should send. In order to select a different account from which to send from, you need to:
- set $upasname
- make /mail/lib/remotemail select the smtp user and server you need to send from.
My hacky solution so far is to just add a switch-case statement to remotemail, like:
; cat /mail/lib/remotemail
#!/bin/rc
shift
sender=$1
shift
addr=$1
shift
if(~ gmail.com `{echo $sender | sed 's/^[^@]+@//'}){
fd=gmail.com
addr=tcp!smtp.gmail.com!ssmtp
user=(-tu $sender)
}
if not{
fd=other.server.net
addr=other.server.net # WHY
user=()
}
exec /bin/upas/smtp -dah $fd $user $addr $sender $*
Then, I can do:
; upasname=seymour@gmail.com mail -s 'whatever' butts@gmail.com
and this sends a mail from seymour@gmail.com to butts@gmail.com as expected. The user allegedly needs to be set as 'seymour@gmail.com', not just 'seymour'. The other thing is connecting to an SMTPS port: to do this, you can add -t to the upas/smtp command line, and specify !ssmtp in the address.