From 794cefe2a6af5c4e09b1bd7c9c575ed6039e1c56 Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 11 Feb 2018 18:24:21 -0700 Subject: clean up and documentation --- README.md | 34 +++++++---- autoconf/makedefault.sh | 10 ++++ makedefault.sh | 10 ---- mutt-wizard.sh | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ mutt_install.sh | 153 ------------------------------------------------ 5 files changed, 185 insertions(+), 175 deletions(-) create mode 100755 autoconf/makedefault.sh delete mode 100755 makedefault.sh create mode 100755 mutt-wizard.sh delete mode 100755 mutt_install.sh diff --git a/README.md b/README.md index e7c40ae..23ba238 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,37 @@ -# neomutt Offline email setup +# Luke's mutt Wizard for automatic Neomutt and OfflineIMAP configuration! Mutt is one of the most rewarding programs one can use, but can be a pain in the ass to configure. Since my job is making power-user tools available for the masses I want to create a tool that automates most of mutt configuration so that users can simply give their email address and get a /comfy/ setup. At that, I don't just want a mutt wizard, but an offlineIMAP wizard, so users can easily access their mail offline as well, and a wizard that makes it easy to store passwords securely using gpg. -## Dependencies +## User interface -dialog, neomutt and offlineimap installed. The contents of this repo should go directly in `~/.config/mutt/` and run from there. - -## Progress - -* The main scripts `mutt_install.sh` can create or add an account from a domain in `domain.csv` to `~/.offlineimaprc` without a problem. +* The main scripts `mutt-wizard.sh` has options to add new email accounts, or remove unwanted ones. For email providers listed in the `autoconf/domains.csv` file, this will be 100% automatic and for other email addresses it will simply prompt you for you email's SMTP and IMAP server settings (which you can easily look up). +* The scripts will take that information and autogenerate mutt and offlineimap config files so you don't have to worry about them. * It also creates a email-specific settings for your muttrc, which are outputed in the `accounts/` directory in your mutt directory. * The script will automatically handle multiple accounts. Each will be assigned a number 1-9, and you can jump from one to another in mutt by pressing `i` and then that number. You can change the numbers by manually editing the macros in `personal.muttrc`. * For most accounts, you can jump to sent mail with `gs`, drafts with `gd` and the inbox with `gi`. I haven't worked this out for every domain. * It uses your gpg encryption to store your encrypted password in `credentials/`, where there are also two scripts that allow mutt and offlineIMAP to decrypt the passwords when needed. -### Verified to be working with +### Will it work on my email? (95% yes) Gmail accounts, cock.li accounts, teknik.io, mail.com accounts should work 100% already. Still, email me at [luke@lukesmith.xyz](mailto:luke@lukesmith.xyz) if you run into something. -Accounts with Yandex, Yahoo, Aol, Outlook, Office 365 and iCloud should work, but the hotkeys to jump from inbox to sent to drafts, etc. won't be automatic because I don't yet know the folder structures of these accounts. If you try the script on these accounts, please check what the structure looks like in `~/.mail//` and tell me what you see and I can automate this! +Accounts with Yandex, Yahoo, AOL, Outlook, Office 365 and iCloud should work, but the hotkeys to jump from inbox to sent to drafts, etc. won't be automatic because I don't yet know the folder structures of these accounts. If you try the script on these accounts, please check what the structure looks like in `~/.mail//` and tell me what you see and I can automate this! + +For all other accounts, the wizard will prompt you to put in your SMTP and IMAP server information; obviously it will know exactly what to do with everything, you just have to give it the info. + +The email accounts that *won't* work with the script would include Proton Mail accounts (which I believe are totally encrypted and only available by the web client) and possibly some University emails. In the latter case, you may just have to search your university's website for the specifics. I'll just say I redirect my university email to another account to avoid this problem and others. + +## Installation and Dependencies + +dialog, neomutt and offlineimap should be installed. The contents of this repo should go directly in `~/.config/mutt/` and run from there. You also need to have a GPG public/private key pair for the wizard to automatically store your passwords. Otherwise you'll have to store them insecurely in plaintext files without the help of the wizard. + +Just run `mutt-wizard.sh` for all the options. + +Once you successfully run the script, you should be able to simply run `offlineimap` to start your mail sync (which will be big at first). Opening `neomutt`, you should see your mail. + +### "Wait? The script asks for my passwords?" + +Look at the code. The script takes the passwords you give it, encrypts them immediately with your own GPG key, and shreds the leftovers. Nothing malicious; it's all there. If it makes you comfortable you can even run the script offline at first. ## You can help! @@ -33,6 +46,3 @@ Mail is stored in `~/.mail`. mutt configs and caches for each account are in `~/ ## Todo * Expand the list of server information in `domains.csv`, including adding spoolfiles/records/postponed folders for each account. -* An ncurses menu for inputing server settings if not available in `domains.csv`. (Soon, see `manual.sh`) -* Configure notmuch with all accounts. -* Move all scripts into one wizard script, integrating all the options. diff --git a/autoconf/makedefault.sh b/autoconf/makedefault.sh new file mode 100755 index 0000000..e8b1536 --- /dev/null +++ b/autoconf/makedefault.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Give this script the abstract name of an account and it will make it the default. + +title=$1 +muttdir="$HOME/.config/mutt/" +muttdirsed=$(echo $muttdir | sed -e 's/\//\\\//g') + +grep "$muttdir"personal.muttrc -e "^source .*accounts.*" >/dev/null && \ + sed -i "s/^source .*accounts.*/source ${muttdirsed}accounts\/$title.muttrc/g" "$muttdir"personal.muttrc diff --git a/makedefault.sh b/makedefault.sh deleted file mode 100755 index e8b1536..0000000 --- a/makedefault.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Give this script the abstract name of an account and it will make it the default. - -title=$1 -muttdir="$HOME/.config/mutt/" -muttdirsed=$(echo $muttdir | sed -e 's/\//\\\//g') - -grep "$muttdir"personal.muttrc -e "^source .*accounts.*" >/dev/null && \ - sed -i "s/^source .*accounts.*/source ${muttdirsed}accounts\/$title.muttrc/g" "$muttdir"personal.muttrc diff --git a/mutt-wizard.sh b/mutt-wizard.sh new file mode 100755 index 0000000..0cdac48 --- /dev/null +++ b/mutt-wizard.sh @@ -0,0 +1,153 @@ +#!/bin/bash + +muttdir="$HOME/.config/mutt/" + +# Sees what accounts have been generated bny the wizard +# by checking ~/.offlineimap and yields a menu of them. +inventory() { \ + cat ~/.offlineimaprc | grep "^accounts =" | sed -e 's/accounts =\( \)//g;s/\(,\) /\n/g;' | nl --number-format=ln > /tmp/numbered + accounts=() + while read n s ; do + accounts+=($n "$s" off) + done < /tmp/numbered + + choices=$(dialog --separate-output --checklist "Choose an email account." 22 76 16 "${accounts[@]}" 2>&1 >/dev/tty) + + if [ -z "$choices" ]; + then + clear + else + userchoices=$(IFS="|"; keys="${choices[*]}"; keys="${keys//|/\\|}"; grep -w "${keys}" /tmp/numbered | awk '{print $2}') + fi ;} + + +removeAccount() { sed -ie " + /Account $1]/,/Account/{//!d} + /Account $1]/d + s/ $1\(,\|$\)//g + s/=$1\(,\|$\)/=/g + s/,$//g + " ~/.offlineimaprc + rm "$muttdir"accounts/$1.muttrc + rm "$muttdir"credentials/$1.gpg + rm -rf "$muttdir"accounts/$1 + echo $1 deleted. ;} + +manual() { \ + imap=$( dialog --inputbox "Insert the IMAP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- ) + iport=$(dialog --inputbox "What is your server's IMAP port number? (Usually 993)" 10 60 3>&1 1>&2 2>&3 3>&-) + smtpserver=$( dialog --inputbox "Insert the SMTP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- ) + sport=$( dialog --inputbox "What is your server's SMTP port number? (Usually 587 or 465)" 10 60 3>&1 1>&2 2>&3 3>&- ) ;} + + +addloop() { fulladdr=$( dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Insert the full email address for the account you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) +# Check to see if domain is in domain list +serverinfo=$(cat "$muttdir"autoconf/domains.csv | grep -w ^${fulladdr##*@}) +if [ -z "$serverinfo" ]; + then + manual + else +# Read in server data as variables +IFS=, read service imap iport smtp sport spoolfile postponed record <&1 1>&2 2>&3 3>&- ) +title=$( dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Give a short, one-word name for this email account that will differentiate it from other email accounts." 10 60 3>&1 1>&2 2>&3 3>&- ) +# Sets the repo type and other variables for the sed regex. +if [[ "$service" == "gmail.com" ]]; + then + type="Gmail" + delet="remotehost" + else + type="IMAP" + delet="Gmail]\/" +fi +# The replacements +replacement=" + s/\$realname/$realname/g; + s/\$title/$title/g; + s/\$fulladdr/$fulladdr/g; + s/\$imap/$imap/g; + s/\$iport/$iport/g; + s/\$smtp/$smtp/g; + s/\$sport/$sport/g; + s/\$spoolfile/$spoolfile/g; + s/\$postponed/$postponed/g; + s/\$record/$record/g; + s/\$type/$type/g; + /$delet/d" + +# Gets the first unused shortcut number in the muttrc and puts it in $idnum. +cat "$muttdir"personal.muttrc | grep i[0-9] | awk '{print $3}' | sed -e 's/i//g' > /tmp/mutt_used +echo -e "1\n2\n3\n4\n5\n6\n7\n8\n9" > /tmp/mutt_all_possible +idnum=$(diff /tmp/mutt_all_possible /tmp/mutt_used | sed -n 2p | awk '{print $2}') +addAccount \ +;} + +addAccount() { + # First, adding the encrypted password. + dialog --title "Luke's mutt/offlineIMAP password wizard" --passwordbox "Enter the password for the \"$title\" account." 10 60 2> /tmp/$title + gpg -r $gpgemail --encrypt /tmp/$title + shred -u /tmp/$title + mv /tmp/$title.gpg ~/.config/mutt/credentials/ + + # Creating the offlineimaprc if it doesn't exist already. + if [ ! -f ~/.offlineimaprc ]; then cp "$muttdir"autoconf/offlineimap_header ~/.offlineimaprc; fi + cat "$muttdir"autoconf/offlineimap_profile | sed -e "$replacement" >> ~/.offlineimaprc + + # Add the mutt profile. + cat "$muttdir"autoconf/mutt_profile | sed -e "$replacement" > "$muttdir"accounts/$title.muttrc + # Add a numbered shortcut in the muttrc + echo "macro index,pager i$idnum 'source "$muttdir"accounts/$title.muttrc!'" >> "$muttdir"personal.muttrc + + # Adding directory structure for cache. + mkdir -p "$muttdir"accounts/$title/cache/bodies + + # Add to offlineimaprc sync list. + sed -i "s/^accounts =.*[a-zA-Z]$/&, $title/g;s/^accounts =$/accounts = $title/g" ~/.offlineimaprc + + # Makes account default if there is no default account. + grep "$muttdir"personal.muttrc -e "^source .*accounts.*" >/dev/null && echo there || \ + echo "source ${muttdir}accounts/$title.muttrc" >> "$muttdir"personal.muttrc ;} + +# This is run when a user chooses to add an account. +addChosen() { \ + mkdir -p "$muttdir"credentials/ "$muttdir"accounts/ + gpgemail=$( dialog --title "Luke's mutt/offlineIMAP password wizard" --inputbox "Insert the email address with which you originally created your GPG key pair. This is NOT necessarily the email you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) + addloop + while : ; + do + dialog --title "Luke's mutt/offlineIMAP password wizard" --yesno "Would you like to add another email account?" 10 60 || break + addloop + done ;} + +wipe () { rm $HOME/.offlineimaprc + rm -rf "$muttdir"/accounts + rm -f "$muttdir"credentials/*gpg + rm "$muttdir"personal.muttrc ;} + + + +while : ; + do +choice=$(dialog --title "Luke's mutt/offlineIMAP wizard" \ + --menu "What would you like to do?" 14 45 5 \ + 0 "List all email accounts configured." \ + 1 "Add an email account." \ + 2 "Remove an email account." \ + 3 "Remove all email accounts." \ + 4 "Exit this wizard." \ + 3>&1 1>&2 2>&3 3>&1 ) + + +case $choice in +0) dialog --title "Accounts detected" --msgbox "The following accounts have been detected: +$(grep ~/.offlineimaprc -e "^accounts =" | sed 's/accounts =//g') +" 6 60;; +1) addChosen;; +2) inventory && for i in $userchoices; do removeAccount $i ; done;; +3) (dialog --defaultno --title "Wipe all custom neomutt/offlineIMAP settings?" --yesno "Would you like to wipe all of the mutt/offlineIMAP settings generated by the system?" 6 60 && wipe) ;; +4) clear && break +esac +done diff --git a/mutt_install.sh b/mutt_install.sh deleted file mode 100755 index 0cdac48..0000000 --- a/mutt_install.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/bin/bash - -muttdir="$HOME/.config/mutt/" - -# Sees what accounts have been generated bny the wizard -# by checking ~/.offlineimap and yields a menu of them. -inventory() { \ - cat ~/.offlineimaprc | grep "^accounts =" | sed -e 's/accounts =\( \)//g;s/\(,\) /\n/g;' | nl --number-format=ln > /tmp/numbered - accounts=() - while read n s ; do - accounts+=($n "$s" off) - done < /tmp/numbered - - choices=$(dialog --separate-output --checklist "Choose an email account." 22 76 16 "${accounts[@]}" 2>&1 >/dev/tty) - - if [ -z "$choices" ]; - then - clear - else - userchoices=$(IFS="|"; keys="${choices[*]}"; keys="${keys//|/\\|}"; grep -w "${keys}" /tmp/numbered | awk '{print $2}') - fi ;} - - -removeAccount() { sed -ie " - /Account $1]/,/Account/{//!d} - /Account $1]/d - s/ $1\(,\|$\)//g - s/=$1\(,\|$\)/=/g - s/,$//g - " ~/.offlineimaprc - rm "$muttdir"accounts/$1.muttrc - rm "$muttdir"credentials/$1.gpg - rm -rf "$muttdir"accounts/$1 - echo $1 deleted. ;} - -manual() { \ - imap=$( dialog --inputbox "Insert the IMAP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- ) - iport=$(dialog --inputbox "What is your server's IMAP port number? (Usually 993)" 10 60 3>&1 1>&2 2>&3 3>&-) - smtpserver=$( dialog --inputbox "Insert the SMTP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- ) - sport=$( dialog --inputbox "What is your server's SMTP port number? (Usually 587 or 465)" 10 60 3>&1 1>&2 2>&3 3>&- ) ;} - - -addloop() { fulladdr=$( dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Insert the full email address for the account you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) -# Check to see if domain is in domain list -serverinfo=$(cat "$muttdir"autoconf/domains.csv | grep -w ^${fulladdr##*@}) -if [ -z "$serverinfo" ]; - then - manual - else -# Read in server data as variables -IFS=, read service imap iport smtp sport spoolfile postponed record <&1 1>&2 2>&3 3>&- ) -title=$( dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Give a short, one-word name for this email account that will differentiate it from other email accounts." 10 60 3>&1 1>&2 2>&3 3>&- ) -# Sets the repo type and other variables for the sed regex. -if [[ "$service" == "gmail.com" ]]; - then - type="Gmail" - delet="remotehost" - else - type="IMAP" - delet="Gmail]\/" -fi -# The replacements -replacement=" - s/\$realname/$realname/g; - s/\$title/$title/g; - s/\$fulladdr/$fulladdr/g; - s/\$imap/$imap/g; - s/\$iport/$iport/g; - s/\$smtp/$smtp/g; - s/\$sport/$sport/g; - s/\$spoolfile/$spoolfile/g; - s/\$postponed/$postponed/g; - s/\$record/$record/g; - s/\$type/$type/g; - /$delet/d" - -# Gets the first unused shortcut number in the muttrc and puts it in $idnum. -cat "$muttdir"personal.muttrc | grep i[0-9] | awk '{print $3}' | sed -e 's/i//g' > /tmp/mutt_used -echo -e "1\n2\n3\n4\n5\n6\n7\n8\n9" > /tmp/mutt_all_possible -idnum=$(diff /tmp/mutt_all_possible /tmp/mutt_used | sed -n 2p | awk '{print $2}') -addAccount \ -;} - -addAccount() { - # First, adding the encrypted password. - dialog --title "Luke's mutt/offlineIMAP password wizard" --passwordbox "Enter the password for the \"$title\" account." 10 60 2> /tmp/$title - gpg -r $gpgemail --encrypt /tmp/$title - shred -u /tmp/$title - mv /tmp/$title.gpg ~/.config/mutt/credentials/ - - # Creating the offlineimaprc if it doesn't exist already. - if [ ! -f ~/.offlineimaprc ]; then cp "$muttdir"autoconf/offlineimap_header ~/.offlineimaprc; fi - cat "$muttdir"autoconf/offlineimap_profile | sed -e "$replacement" >> ~/.offlineimaprc - - # Add the mutt profile. - cat "$muttdir"autoconf/mutt_profile | sed -e "$replacement" > "$muttdir"accounts/$title.muttrc - # Add a numbered shortcut in the muttrc - echo "macro index,pager i$idnum 'source "$muttdir"accounts/$title.muttrc!'" >> "$muttdir"personal.muttrc - - # Adding directory structure for cache. - mkdir -p "$muttdir"accounts/$title/cache/bodies - - # Add to offlineimaprc sync list. - sed -i "s/^accounts =.*[a-zA-Z]$/&, $title/g;s/^accounts =$/accounts = $title/g" ~/.offlineimaprc - - # Makes account default if there is no default account. - grep "$muttdir"personal.muttrc -e "^source .*accounts.*" >/dev/null && echo there || \ - echo "source ${muttdir}accounts/$title.muttrc" >> "$muttdir"personal.muttrc ;} - -# This is run when a user chooses to add an account. -addChosen() { \ - mkdir -p "$muttdir"credentials/ "$muttdir"accounts/ - gpgemail=$( dialog --title "Luke's mutt/offlineIMAP password wizard" --inputbox "Insert the email address with which you originally created your GPG key pair. This is NOT necessarily the email you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) - addloop - while : ; - do - dialog --title "Luke's mutt/offlineIMAP password wizard" --yesno "Would you like to add another email account?" 10 60 || break - addloop - done ;} - -wipe () { rm $HOME/.offlineimaprc - rm -rf "$muttdir"/accounts - rm -f "$muttdir"credentials/*gpg - rm "$muttdir"personal.muttrc ;} - - - -while : ; - do -choice=$(dialog --title "Luke's mutt/offlineIMAP wizard" \ - --menu "What would you like to do?" 14 45 5 \ - 0 "List all email accounts configured." \ - 1 "Add an email account." \ - 2 "Remove an email account." \ - 3 "Remove all email accounts." \ - 4 "Exit this wizard." \ - 3>&1 1>&2 2>&3 3>&1 ) - - -case $choice in -0) dialog --title "Accounts detected" --msgbox "The following accounts have been detected: -$(grep ~/.offlineimaprc -e "^accounts =" | sed 's/accounts =//g') -" 6 60;; -1) addChosen;; -2) inventory && for i in $userchoices; do removeAccount $i ; done;; -3) (dialog --defaultno --title "Wipe all custom neomutt/offlineIMAP settings?" --yesno "Would you like to wipe all of the mutt/offlineIMAP settings generated by the system?" 6 60 && wipe) ;; -4) clear && break -esac -done -- cgit v1.2.3