freedombone-base-email 65KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665
  1. #!/bin/bash
  2. #
  3. # .---. . .
  4. # | | |
  5. # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
  6. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
  7. # ' ' --' --' -' - -' ' ' -' -' -' ' - --'
  8. #
  9. # Freedom in the Cloud
  10. #
  11. # Email functions
  12. #
  13. # License
  14. # =======
  15. #
  16. # Copyright (C) 2014-2018 Bob Mottram <bob@freedombone.net>
  17. #
  18. # This program is free software: you can redistribute it and/or modify
  19. # it under the terms of the GNU Affero General Public License as published by
  20. # the Free Software Foundation, either version 3 of the License, or
  21. # (at your option) any later version.
  22. #
  23. # This program is distributed in the hope that it will be useful,
  24. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. # GNU Affero General Public License for more details.
  27. #
  28. # You should have received a copy of the GNU Affero General Public License
  29. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  30. # the default email address
  31. MY_EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME
  32. # When sending mail to riseup.net route to this onion address
  33. RISEUP_EMAIL_ONION='wy6zk3pmcwiyhiao.onion'
  34. # If you want to run a public mailing list specify its name here.
  35. # There should be no spaces in the name
  36. PUBLIC_MAILING_LIST=
  37. # Optional different domain name for the public mailing list
  38. PUBLIC_MAILING_LIST_DOMAIN_NAME=
  39. # Directory where the public mailing list data is stored
  40. PUBLIC_MAILING_LIST_DIRECTORY="/var/spool/mlmmj"
  41. # If you want to run an encrypted mailing list specify its name here.
  42. # There should be no spaces in the name
  43. PRIVATE_MAILING_LIST=
  44. GPG_KEYSERVER="hkp://keys.gnupg.net"
  45. # whether to encrypt all incoming email with your public key
  46. GPG_ENCRYPT_STORED_EMAIL="yes"
  47. # optionally you can provide your exported GPG key pair here
  48. # Note that the private key file will be deleted after use
  49. # If these are unspecified then a new GPG key will be created
  50. MY_GPG_PUBLIC_KEY=
  51. MY_GPG_PRIVATE_KEY=
  52. # optionally specify your public key ID
  53. MY_GPG_PUBLIC_KEY_ID=
  54. # automatic archiving of email
  55. CLEANUP_MAILDIR_REPO="https://github.com/bashrc/cleanup-maildir"
  56. CLEANUP_MAILDIR_COMMIT='33241d2e3861f901ba17f5c77ada007e1ec06a86'
  57. # email encryption at rest
  58. GPGIT_REPO="https://gitlab.com/mikecardwell/gpgit"
  59. GPGIT_COMMIT='583dc76119f19420f8a33f606744faa7c8922738'
  60. # refresh gpg keys every few hours
  61. REFRESH_GPG_KEYS_HOURS=2
  62. exim_version='4.89'
  63. function rebuild_exim_with_socks {
  64. # shellcheck disable=SC2154
  65. if [ ! -d "$INSTALL_DIR" ]; then
  66. mkdir -p "$INSTALL_DIR/exim4"
  67. fi
  68. cd "$INSTALL_DIR/exim4" || exit 3468356
  69. rm -rf "$INSTALL_DIR/exim4/"*
  70. apt-get source exim4-daemon-heavy
  71. apt-get -qy build-dep exim4-daemon-heavy
  72. cd "${INSTALL_DIR}/exim4/exim4-*" || exit 356835685
  73. { echo 'Description: Socks proxying';
  74. echo ' Support for socks proxying of outgoing mail';
  75. echo ' This is to support onion email addresses, which require support for SOCKS5';
  76. echo ' .';
  77. echo " exim4 (${exim_version}-2+deb9u3) stretch-security; urgency=high";
  78. echo ' .';
  79. echo ' * Non-maintainer upload by the Security Team.';
  80. echo ' * Fix base64d() buffer size (CVE-2018-6789) (Closes: #890000)';
  81. echo 'Author: Salvatore Bonaccorso <carnil@debian.org>';
  82. echo 'Bug-Debian: https://bugs.debian.org/890000';
  83. echo '';
  84. echo '---';
  85. echo 'The information above should follow the Patch Tagging Guidelines, please';
  86. echo 'checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here';
  87. echo 'are templates for supplementary fields that you might want to add:';
  88. echo '';
  89. echo 'Origin: <vendor|upstream|other>, <url of original patch>';
  90. echo 'Bug: <url in upstream bugtracker>';
  91. echo 'Bug-Debian: https://bugs.debian.org/<bugnumber>';
  92. echo 'Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>';
  93. echo 'Forwarded: <no|not-needed|url proving that it has been forwarded>';
  94. echo 'Reviewed-By: <name and email of someone who approved the patch>';
  95. echo "Last-Update: $(date +%Y-%m-%d)";
  96. echo '';
  97. echo '--- /dev/null';
  98. echo "+++ exim4-${exim_version}/Local/Makefile";
  99. echo '@@ -0,0 +1,32 @@';
  100. echo '+BIN_DIRECTORY=/usr/exim/bin';
  101. echo '+CONFIGURE_FILE=/usr/exim/configure';
  102. echo '+EXIM_USER=';
  103. echo '+SPOOL_DIRECTORY=/var/spool/exim';
  104. echo '+ROUTER_ACCEPT=yes';
  105. echo '+ROUTER_DNSLOOKUP=yes';
  106. echo '+ROUTER_IPLITERAL=yes';
  107. echo '+ROUTER_MANUALROUTE=yes';
  108. echo '+ROUTER_QUERYPROGRAM=yes';
  109. echo '+ROUTER_REDIRECT=yes';
  110. echo '+TRANSPORT_APPENDFILE=yes';
  111. echo '+TRANSPORT_AUTOREPLY=yes';
  112. echo '+TRANSPORT_PIPE=yes';
  113. echo '+TRANSPORT_SMTP=yes';
  114. echo '+LOOKUP_DBM=yes';
  115. echo '+LOOKUP_LSEARCH=yes';
  116. echo '+LOOKUP_DNSDB=yes';
  117. echo '+PCRE_CONFIG=yes';
  118. echo '+EXIM_MONITOR=eximon.bin';
  119. echo '+FIXED_NEVER_USERS=root';
  120. echo '+HEADERS_CHARSET="ISO-8859-1"';
  121. echo '+DLOPEN_LOCAL_SCAN=yes';
  122. echo '+LDFLAGS += -rdynamic';
  123. echo '+CFLAGS += -fvisibility=hidden';
  124. echo '+SYSLOG_LOG_PID=yes';
  125. echo '+EXICYCLOG_MAX=10';
  126. echo '+COMPRESS_COMMAND=/usr/bin/gzip';
  127. echo '+COMPRESS_SUFFIX=gz';
  128. echo '+ZCAT_COMMAND=/usr/bin/zcat';
  129. echo '+SUPPORT_SOCKS=yes';
  130. echo '+SYSTEM_ALIASES_FILE=/etc/aliases';
  131. echo '+EXIM_TMPDIR="/tmp"'; } > debian/patches/SOCKS
  132. debuild -us -uc
  133. cd "$INSTALL_DIR/exim4" || exit 3468356
  134. mv exim4_${exim_version}-*.deb exim4_${exim_version}_all.deb
  135. if [ ! -f exim4_${exim_version}_all.deb ]; then
  136. ls -l "$INSTALL_DIR/exim4/exim4_"*.deb
  137. echo "exim4_${exim_version}_all.deb not found"
  138. exit 63857368
  139. fi
  140. apt-mark -q unhold exim4
  141. dpkg -i exim4_${exim_version}_all.deb
  142. apt-mark -q hold exim4
  143. apt-get -yq remove --purge at
  144. }
  145. function email_create_template {
  146. if [ ! -d /etc/skel/log ]; then
  147. mkdir -m 700 /etc/skel/log
  148. fi
  149. if [ ! -d /etc/skel/Maildir ]; then
  150. mkdir -m 700 /etc/skel/.mutt
  151. mkdir -m 700 /etc/skel/Maildir
  152. mkdir -m 700 /etc/skel/Maildir/new
  153. mkdir -m 700 /etc/skel/Maildir/cur
  154. mkdir -m 700 /etc/skel/Maildir/Sent
  155. mkdir -m 700 /etc/skel/Maildir/Sent/tmp
  156. mkdir -m 700 /etc/skel/Maildir/Sent/cur
  157. mkdir -m 700 /etc/skel/Maildir/Sent/new
  158. mkdir -m 700 /etc/skel/Maildir/.learn-spam
  159. mkdir -m 700 /etc/skel/Maildir/.learn-spam/cur
  160. mkdir -m 700 /etc/skel/Maildir/.learn-spam/new
  161. mkdir -m 700 /etc/skel/Maildir/.learn-spam/tmp
  162. mkdir -m 700 /etc/skel/Maildir/.learn-ham
  163. mkdir -m 700 /etc/skel/Maildir/.learn-ham/cur
  164. mkdir -m 700 /etc/skel/Maildir/.learn-ham/new
  165. mkdir -m 700 /etc/skel/Maildir/.learn-ham/tmp
  166. ln -s /etc/skel/Maildir/.learn-spam /etc/skel/Maildir/spam
  167. ln -s /etc/skel/Maildir/.learn-ham /etc/skel/Maildir/ham
  168. fi
  169. if [ ! -d "/home/$MY_USERNAME/Maildir" ]; then
  170. mkdir -m 700 "/home/$MY_USERNAME/.mutt"
  171. mkdir -m 700 "/home/$MY_USERNAME/Maildir"
  172. mkdir -m 700 "/home/$MY_USERNAME/Maildir/cur"
  173. mkdir -m 700 "/home/$MY_USERNAME/Maildir/tmp"
  174. mkdir -m 700 "/home/$MY_USERNAME/Maildir/new"
  175. mkdir -m 700 "/home/$MY_USERNAME/Maildir/Sent"
  176. mkdir -m 700 "/home/$MY_USERNAME/Maildir/Sent/cur"
  177. mkdir -m 700 "/home/$MY_USERNAME/Maildir/Sent/tmp"
  178. mkdir -m 700 "/home/$MY_USERNAME/Maildir/Sent/new"
  179. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-spam"
  180. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-spam/cur"
  181. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-spam/new"
  182. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-spam/tmp"
  183. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-ham"
  184. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-ham/cur"
  185. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-ham/new"
  186. mkdir -m 700 "/home/$MY_USERNAME/Maildir/.learn-ham/tmp"
  187. ln -s "/home/$MY_USERNAME/Maildir/.learn-spam" "/home/$MY_USERNAME/Maildir/spam"
  188. ln -s "/home/$MY_USERNAME/Maildir/.learn-ham" "/home/$MY_USERNAME/Maildir/ham"
  189. chown -R "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/Maildir"
  190. fi
  191. }
  192. function create_email_onion_address {
  193. if ! grep -q "hidden_service_email" /etc/tor/torrc; then
  194. { echo 'HiddenServiceDir /var/lib/tor/hidden_service_email/';
  195. echo 'HiddenServiceVersion 3';
  196. echo 'HiddenServicePort 25 127.0.0.1:25';
  197. echo 'HiddenServicePort 587 127.0.0.1:587';
  198. echo 'HiddenServicePort 465 127.0.0.1:465'; } >> /etc/tor/torrc
  199. function_check onion_update
  200. onion_update
  201. function_check wait_for_onion_service
  202. wait_for_onion_service email
  203. if [ ! -f /var/lib/tor/hidden_service_email/hostname ]; then
  204. echo $"email onion site hostname not found"
  205. systemctl restart tor
  206. exit 782352
  207. fi
  208. onion_address=$(cat /var/lib/tor/hidden_service_email/hostname)
  209. set_completion_param "email onion domain" "${onion_address}"
  210. add_email_hostname "$onion_address"
  211. else
  212. onion_address=$(cat /var/lib/tor/hidden_service_email/hostname)
  213. fi
  214. }
  215. function configure_email_onion {
  216. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  217. return
  218. fi
  219. if [[ "$SYSTEM_TYPE" == "mesh"* ]]; then
  220. return
  221. fi
  222. create_email_onion_address
  223. #apt-get -yq install tinycdb perl
  224. # MX record should be:
  225. # _onion-mx._tcp
  226. # 20:$onion_address
  227. # 3600 IN SRV 0 5 25 $onion_address
  228. # Test with: exim -d -bt $onion_address
  229. #echo "$DEFAULT_DOMAIN_NAME $onion_address" > /etc/exim4/onionrelay.txt
  230. #cdb -m -c -t ~/onionrelay.tmp /etc/exim4/onionrelay.cdb /etc/exim4/onionrelay.txt
  231. { echo "perl_startup = do '/etc/exim4/perl-routines.pl'";
  232. echo "perl_at_start"; } > /etc/exim4/conf.d/main/00_exim4-config_perl
  233. { echo "use Net::DNS::Resolver;";
  234. echo "sub onionLookup {";
  235. echo " my \$hostname = shift;";
  236. echo " my \$res = Net::DNS::Resolver->new(nameservers => [qw(127.0.0.1)],);";
  237. echo " \$res->port(5300);";
  238. echo " my \$query = \$res->search(\$hostname);";
  239. echo " foreach my \$rr (\$query->answer) {";
  240. echo " next unless \$rr->type eq \"A\";";
  241. echo " return \$rr->address;";
  242. echo " }";
  243. echo " return 'no_such_host';";
  244. echo "}"; } > /etc/exim4/perl-routines.pl
  245. #{ echo "ONION_RELAYDB=/etc/exim4/onionrelay.cdb";
  246. # echo "domainlist onion_relays = cdb;ONION_RELAYDB"; } > /etc/exim4/conf.d/main/48_exim4-config_onion_relays
  247. { echo "riseup:";
  248. echo " driver = manualroute";
  249. echo " domains = riseup.net";
  250. echo " transport = onion_relay";
  251. echo " route_data = \${perl{onionLookup}{$RISEUP_EMAIL_ONION}}"
  252. echo " no_more"; } > /etc/exim4/conf.d/router/049_exim4-config-riseup
  253. { echo "onionrelays:";
  254. echo " driver = manualroute";
  255. echo " domains = *.onion";
  256. echo " transport = onion_relay";
  257. #echo " route_data = \${lookup dnsdb{a=\$domain}}";
  258. echo " route_data = \${perl{onionLookup}{\$domain}}"
  259. echo " no_more"; } > /etc/exim4/conf.d/router/050_exim4-config-onionrelays
  260. { echo "onion_relay:";
  261. echo " driver = smtp";
  262. echo " socks_proxy = 127.0.0.1 port=9050"; } > /etc/exim4/conf.d/transport/050_exim4-config_onion_relay
  263. if ! grep -q "AutomapHostsOnResolve" /etc/tor/torrc; then
  264. echo 'AutomapHostsOnResolve 1' >> /etc/tor/torrc
  265. else
  266. sed -i 's|#AutomapHostsOnResolve.*|AutomapHostsOnResolve 1|g' /etc/tor/torrc
  267. sed -i 's|AutomapHostsOnResolve.*|AutomapHostsOnResolve 1|g' /etc/tor/torrc
  268. fi
  269. if ! grep -q "DNSPort " /etc/tor/torrc; then
  270. echo 'DNSPort 5300' >> /etc/tor/torrc
  271. else
  272. sed -i 's|#DNSPort .*|DNSPort 5300|g' /etc/tor/torrc
  273. sed -i 's|DNSPort .*|DNSPort 5300|g' /etc/tor/torrc
  274. fi
  275. if ! grep -q "DNSListenAddress" /etc/tor/torrc; then
  276. echo 'DNSListenAddress 127.0.0.1' >> /etc/tor/torrc
  277. else
  278. sed -i 's|#DNSListenAddress.*|DNSListenAddress 127.0.0.1|g' /etc/tor/torrc
  279. sed -i 's|DNSListenAddress.*|DNSListenAddress 127.0.0.1|g' /etc/tor/torrc
  280. fi
  281. update-exim4.conf.template -r
  282. update-exim4.conf
  283. dpkg-reconfigure --frontend noninteractive exim4-config
  284. systemctl restart tor
  285. systemctl restart exim4
  286. mark_completed "${FUNCNAME[0]}"
  287. }
  288. function check_email_address_exists {
  289. read_config_param ONION_ONLY
  290. read_config_param MY_USERNAME
  291. read_config_param DEFAULT_DOMAIN_NAME
  292. read_config_param MY_EMAIL_ADDRESS
  293. read_config_param DH_KEYLENGTH
  294. if [ ! "$MY_USERNAME" ]; then
  295. echo $'No username for email installation'
  296. exit 73672
  297. fi
  298. if [ ! "$DEFAULT_DOMAIN_NAME" ]; then
  299. echo $'No default domain name for email installation'
  300. exit 57634
  301. fi
  302. my_email="$MY_EMAIL_ADDRESS"
  303. if [ ${#my_email} -lt 3 ]; then
  304. MY_EMAIL_ADDRESS="${MY_USERNAME}@${DEFAULT_DOMAIN_NAME}"
  305. write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS"
  306. fi
  307. if [[ $ONION_ONLY != 'no' ]]; then
  308. my_email=$onion_address
  309. MY_EMAIL_ADDRESS=$onion_address
  310. write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS"
  311. fi
  312. }
  313. function backup_email {
  314. echo ''
  315. }
  316. function configure_firewall_for_email {
  317. if [[ "$INSTALLED_WITHIN_DOCKER" == "yes" ]]; then
  318. # docker does its own firewalling
  319. return
  320. fi
  321. if [[ "$ONION_ONLY" != "no" ]]; then
  322. return
  323. fi
  324. firewall_add Email 25 tcp
  325. firewall_add Email 587 tcp
  326. firewall_add Email 465 tcp
  327. firewall_add Imap 993 tcp
  328. }
  329. function encrypt_incoming_email {
  330. # encrypts incoming mail using your GPG public key
  331. # so even if an attacker gains access to the data at rest they still need
  332. # to know your GPG key password to be able to read anything
  333. if [ ! -d /etc/exim4 ]; then
  334. return
  335. fi
  336. # update to the next commit
  337. function_check set_repo_commit
  338. set_repo_commit "$INSTALL_DIR/gpgit" "gpgit commit" "$GPGIT_COMMIT" "$GPGIT_REPO"
  339. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  340. return
  341. fi
  342. if [[ "$GPG_ENCRYPT_STORED_EMAIL" != "yes" ]]; then
  343. return
  344. fi
  345. if [ ! -f /usr/bin/gpgit.pl ]; then
  346. apt-get -yq install git libmail-gnupg-perl
  347. cd "$INSTALL_DIR" || exit 246824624
  348. function_check git_clone
  349. git_clone "$GPGIT_REPO" "$INSTALL_DIR/gpgit"
  350. cd "$INSTALL_DIR/gpgit" || exit 7246725474
  351. git checkout "$GPGIT_COMMIT" -b "$GPGIT_COMMIT"
  352. set_completion_param "gpgit commit" "$GPGIT_COMMIT"
  353. cp gpgit.pl /usr/bin
  354. fi
  355. # add a procmail rule
  356. if ! grep -q "/usr/bin/gpgit.pl" "/home/$MY_USERNAME/.procmailrc"; then
  357. { echo '';
  358. echo ':0 f';
  359. echo "| /usr/bin/gpgit.pl --encrypt-mode prefer-inline --inline-flatten $MY_EMAIL_ADDRESS"; } >> "/home/$MY_USERNAME/.procmailrc"
  360. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.procmailrc"
  361. { echo '';
  362. echo ':0 f';
  363. echo -n "| /usr/bin/gpgit.pl --encrypt-mode prefer-inline --inline-flatten \$USER@";
  364. echo "$DEFAULT_DOMAIN_NAME"; } >> /etc/skel/.procmailrc
  365. fi
  366. mark_completed "${FUNCNAME[0]}"
  367. }
  368. function encrypt_outgoing_email {
  369. # encrypts outgoing mail using your GPG public key
  370. # so even if an attacker gains access to the data at rest they still need
  371. # to know your GPG key password to be able to read sent mail
  372. if [ ! -d /etc/exim4 ]; then
  373. return
  374. fi
  375. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  376. return
  377. fi
  378. if [[ "$GPG_ENCRYPT_STORED_EMAIL" != "yes" ]]; then
  379. return
  380. fi
  381. if [ ! -d "/home/$MY_USERNAME/.gnupg" ]; then
  382. return
  383. fi
  384. if [ ! -f "/home/$MY_USERNAME/.muttrc" ]; then
  385. return
  386. fi
  387. # obtain your public key ID
  388. if [ ! "$MY_GPG_PUBLIC_KEY_ID" ]; then
  389. MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS")
  390. if [ ! "$MY_GPG_PUBLIC_KEY_ID" ]; then
  391. return
  392. fi
  393. if [ ${#MY_GPG_PUBLIC_KEY_ID} -lt 4 ]; then
  394. return
  395. fi
  396. fi
  397. if ! grep -q "pgp_encrypt_only_command" "/home/$MY_USERNAME/.muttrc"; then
  398. { echo '';
  399. echo $'# Encrypt items in the Sent folder';
  400. echo "set pgp_encrypt_only_command=\"/usr/lib/mutt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\""; } >> "/home/$MY_USERNAME/.muttrc"
  401. else
  402. sed -i "s|set pgp_encrypt_only_command.*|set pgp_encrypt_only_command=\"/usr/lib/mutt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\"|g" "/home/$MY_USERNAME/.muttrc"
  403. fi
  404. if ! grep -q "pgp_encrypt_sign_command" "/home/$MY_USERNAME/.muttrc"; then
  405. echo "set pgp_encrypt_sign_command=\"/usr/lib/mutt/pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\"" >> "/home/$MY_USERNAME/.muttrc"
  406. else
  407. sed -i "s|set pgp_encrypt_sign_command.*|set pgp_encrypt_sign_command=\"/usr/lib/mutt/pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\"|g" "/home/$MY_USERNAME/.muttrc"
  408. fi
  409. mark_completed "${FUNCNAME[0]}"
  410. }
  411. function encrypt_all_email {
  412. if [ ! -d /etc/exim4 ]; then
  413. return
  414. fi
  415. if [[ "$GPG_ENCRYPT_STORED_EMAIL" != "yes" ]]; then
  416. return
  417. fi
  418. if [ -f "/usr/local/bin/${PROJECT_NAME}-encrypt-mail" ]; then
  419. if [ ! -f /usr/bin/encmaildir ]; then
  420. cp "/usr/local/bin/${PROJECT_NAME}-encrypt-mail" /usr/bin/encmaildir
  421. else
  422. HASH1=$(sha256sum "/usr/local/bin/${PROJECT_NAME}-encrypt-mail" | awk -F ' ' '{print $1}')
  423. HASH2=$(sha256sum /usr/bin/encmaildir | awk -F ' ' '{print $1}')
  424. if [[ "$HASH1" != "$HASH2" ]]; then
  425. cp "/usr/local/bin/${PROJECT_NAME}-encrypt-mail" /usr/bin/encmaildir
  426. fi
  427. fi
  428. else
  429. if [ ! -f /usr/bin/encmaildir ]; then
  430. cp "/usr/bin/${PROJECT_NAME}-encrypt-mail" /usr/bin/encmaildir
  431. else
  432. HASH1=$(sha256sum "/usr/bin/${PROJECT_NAME}-encrypt-mail" | awk -F ' ' '{print $1}')
  433. HASH2=$(sha256sum /usr/bin/encmaildir | awk -F ' ' '{print $1}')
  434. if [[ "$HASH1" != "$HASH2" ]]; then
  435. cp "/usr/bin/${PROJECT_NAME}-encrypt-mail" /usr/bin/encmaildir
  436. fi
  437. fi
  438. fi
  439. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  440. return
  441. fi
  442. if [ ! -f "/home/$MY_USERNAME/README" ]; then
  443. touch "/home/$MY_USERNAME/README"
  444. fi
  445. if ! grep -q $"If you have imported legacy email which is not encrypted" "/home/$MY_USERNAME/README"; then
  446. { echo '';
  447. echo '';
  448. echo $'# Encrypting legacy email';
  449. echo $'If you have imported legacy email which is not encrypted';
  450. echo $'then it can be encrypted with the command:';
  451. echo '';
  452. echo ' encmaildir';
  453. echo '';
  454. echo $'But be warned that depending upon how much email you have';
  455. echo $'this could take a seriously LONG time on the Beaglebone';
  456. echo $'and may be better done on a faster machine.'; } >> "/home/$MY_USERNAME/README"
  457. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/README"
  458. chmod 600 "/home/$MY_USERNAME/README"
  459. fi
  460. mark_completed "${FUNCNAME[0]}"
  461. }
  462. function email_client {
  463. if [ ! -d /etc/exim4 ]; then
  464. return
  465. fi
  466. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  467. return
  468. fi
  469. apt-get -yq install lynx abook urlview mutt
  470. if [ ! -f /etc/Muttrc ]; then
  471. echo $"ERROR: Mutt does not appear to have installed. $CHECK_MESSAGE"
  472. exit 49
  473. fi
  474. if [ ! -d "/home/$MY_USERNAME/.mutt" ]; then
  475. mkdir "/home/$MY_USERNAME/.mutt"
  476. fi
  477. echo "text/html; lynx -dump -width=78 -nolist %s | sed ‘s/^ //’; copiousoutput; needsterminal; nametemplate=%s.html" > "/home/$MY_USERNAME/.mutt/mailcap"
  478. cp "/home/$MY_USERNAME/.mutt/mailcap" /etc/skel/.mutt
  479. chown -R "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.mutt"
  480. chown -R root:root /etc/skel/.mutt
  481. { echo 'set mbox_type=Maildir';
  482. echo 'set folder="~/Maildir"';
  483. echo 'set mask="!^\\.[^.]"';
  484. echo 'set mbox="~/Maildir"';
  485. echo 'set record="+Sent"';
  486. echo 'set postponed="+Drafts"';
  487. echo 'set trash="+Trash"';
  488. echo 'set spoolfile="~/Maildir"';
  489. echo 'auto_view text/x-vcard text/html text/enriched';
  490. echo 'set header_cache="+.cache"';
  491. echo 'set markers=no';
  492. echo '';
  493. echo '# ctrl-u to view long URLs';
  494. echo 'macro pager \cu <pipe-entry>"urlview"<enter> "Follow links with urlview"';
  495. echo '';
  496. echo 'macro index S "<tag-prefix><decode-save>=.learn-spam<enter>" "move to learn-spam"';
  497. echo 'macro pager S "<decode-save>=.learn-spam<enter>" "move to learn-spam"';
  498. echo 'macro index H "<tag-prefix><decode-copy>=.learn-ham<enter>" "copy to learn-ham"';
  499. echo 'macro pager H "<decode-copy>=.learn-ham<enter>" "copy to learn-ham"';
  500. echo '';
  501. echo '# set up the sidebar';
  502. echo 'set sidebar_width=22';
  503. echo 'set sidebar_visible=yes';
  504. echo '';
  505. echo 'set rfc2047_parameters';
  506. echo '';
  507. echo '# Show inbox and sent items';
  508. echo 'mailboxes = =admin =Sent =maybe-spam =spam';
  509. echo '';
  510. echo '# Alter these colours as needed for maximum bling';
  511. echo 'color sidebar_new yellow default';
  512. echo 'color normal white default';
  513. echo 'color hdrdefault brightcyan default';
  514. echo 'color signature green default';
  515. echo 'color attachment brightyellow default';
  516. echo 'color quoted green default';
  517. echo 'color quoted1 white default';
  518. echo 'color tilde blue default';
  519. echo '';
  520. echo '# ctrl-n, ctrl-p to select next, prev folder';
  521. echo '# ctrl-o to open selected folder';
  522. echo 'bind index \Cp sidebar-prev';
  523. echo 'bind index \Cn sidebar-next';
  524. echo 'bind index \Co sidebar-open';
  525. echo 'bind pager \Cp sidebar-prev';
  526. echo 'bind pager \Cn sidebar-next';
  527. echo 'bind pager \Co sidebar-open';
  528. echo '';
  529. echo '# ctrl-b toggles sidebar visibility';
  530. echo "macro index,pager \\Cb '<enter-command>toggle sidebar_visible<enter><redraw-screen>' 'toggle sidebar'";
  531. echo '';
  532. echo '# esc-m Mark new messages as read';
  533. echo 'macro index <esc>m "T~N<enter>;WNT~O<enter>;WO\CT~T<enter>" "mark all messages read"';
  534. echo '';
  535. echo '# Collapsing threads';
  536. echo 'macro index [ "<collapse-thread>" "collapse/uncollapse thread"';
  537. echo 'macro index ] "<collapse-all>" "collapse/uncollapse all threads"';
  538. echo '';
  539. echo '# threads containing new messages';
  540. echo 'uncolor index "~(~N)"';
  541. echo 'color index brightblue default "~(~N)"';
  542. echo '';
  543. echo '# new messages themselves';
  544. echo 'uncolor index "~N"';
  545. echo 'color index brightyellow default "~N"';
  546. echo '';
  547. echo '# GPG/PGP integration';
  548. echo '# this set the number of seconds to keep in memory the passphrase used to encrypt/sign';
  549. echo 'set pgp_timeout=1800';
  550. echo '';
  551. echo '# automatically sign and encrypt with PGP/MIME';
  552. echo 'set pgp_autosign # autosign all outgoing mails';
  553. echo 'set pgp_autoencrypt # Try to encrypt automatically';
  554. echo 'set pgp_replyencrypt # autocrypt replies to crypted';
  555. echo 'set pgp_replysign # autosign replies to signed';
  556. echo 'set pgp_auto_decode=yes # decode attachments';
  557. echo 'set fcc_clear=no # Keep encrypted copy of sent encrypted mail';
  558. echo 'unset smime_is_default';
  559. echo '';
  560. echo 'set alias_file=~/.mutt-alias';
  561. echo 'source ~/.mutt-alias';
  562. echo 'set query_command= "abook --mutt-query \"%s\""';
  563. echo 'macro index,pager A "<pipe-message>abook --add-email-quiet<return>" "add the sender address to abook"';
  564. echo '';
  565. echo '# Optional relay of SMTP via ISP';
  566. echo '#set smtp_url="smtps://username:password@isp_mail_domain:465/"'; } > /etc/Muttrc
  567. # For viewing long URLs
  568. echo 'REGEXP (((http|https|ftp|gopher)|mailto)[.:][^ >"\t]*|www\.[-a-z0-9.]+)[^ .,;\t>">\):]' > "/home/$MY_USERNAME/.urlview"
  569. echo 'COMMAND lynx -dump -width=78 -nolist %s' >> "/home/$MY_USERNAME/.urlview"
  570. cp -f /etc/Muttrc "/home/$MY_USERNAME/.muttrc"
  571. cp -f /etc/Muttrc /etc/skel/.muttrc
  572. cp -f "/home/$MY_USERNAME/.urlview" /etc/skel/.urlview
  573. touch "/home/$MY_USERNAME/.mutt-alias"
  574. cp "/home/$MY_USERNAME/.mutt-alias" /etc/skel/.mutt-alias
  575. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.muttrc"
  576. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.mutt-alias"
  577. # default user on generic images
  578. if [ -d "/home/${GENERIC_IMAGE_USERNAME}" ]; then
  579. cp -f /etc/Muttrc "/home/${GENERIC_IMAGE_USERNAME}/.muttrc"
  580. chown "${GENERIC_IMAGE_USERNAME}":"${GENERIC_IMAGE_USERNAME}" "/home/${GENERIC_IMAGE_USERNAME}/.muttrc"
  581. touch "/home/${GENERIC_IMAGE_USERNAME}/.mutt-alias"
  582. chown "${GENERIC_IMAGE_USERNAME}":"${GENERIC_IMAGE_USERNAME}" "/home/${GENERIC_IMAGE_USERNAME}/.mutt-alias"
  583. fi
  584. mark_completed "${FUNCNAME[0]}"
  585. }
  586. function email_archiving {
  587. if [ ! -d /etc/exim4 ]; then
  588. return
  589. fi
  590. # ensure that the mail archive script is up to date
  591. if [ -f "/usr/local/bin/${PROJECT_NAME}-archive-mail" ]; then
  592. if [ ! -f /etc/cron.daily/archivemail ]; then
  593. cp "/usr/local/bin/${PROJECT_NAME}-archive-mail" /etc/cron.daily/archivemail
  594. chmod +x /etc/cron.daily/archivemail
  595. else
  596. HASH1=$(sha256sum "/usr/local/bin/${PROJECT_NAME}-archive-mail" | awk -F ' ' '{print $1}')
  597. HASH2=$(sha256sum /etc/cron.daily/archivemail | awk -F ' ' '{print $1}')
  598. if [[ "$HASH1" != "$HASH2" ]]; then
  599. cp "/usr/local/bin/${PROJECT_NAME}-archive-mail" /etc/cron.daily/archivemail
  600. chmod +x /etc/cron.daily/archivemail
  601. fi
  602. fi
  603. else
  604. if [ -f "/usr/bin/${PROJECT_NAME}-archive-mail" ]; then
  605. if [ ! -f /etc/cron.daily/archivemail ]; then
  606. cp "/usr/bin/${PROJECT_NAME}-archive-mail" /etc/cron.daily/archivemail
  607. chmod +x /etc/cron.daily/archivemail
  608. else
  609. HASH1=$(sha256sum "/usr/local/bin/${PROJECT_NAME}-archive-mail" | awk -F ' ' '{print $1}')
  610. HASH2=$(sha256sum /etc/cron.daily/archivemail | awk -F ' ' '{print $1}')
  611. if [[ "$HASH1" != "$HASH2" ]]; then
  612. cp "/usr/local/bin/${PROJECT_NAME}-archive-mail" /etc/cron.daily/archivemail
  613. chmod +x /etc/cron.daily/archivemail
  614. fi
  615. fi
  616. else
  617. echo "/usr/bin/${PROJECT_NAME}-archive-mail was not found. ${PROJECT_NAME} might not have fully installed."
  618. exit 62379
  619. fi
  620. fi
  621. # update to the next commit
  622. function_check set_repo_commit
  623. set_repo_commit "$INSTALL_DIR/cleanup-maildir" "cleanup-maildir commit" "$CLEANUP_MAILDIR_COMMIT" "$CLEANUP_MAILDIR_REPO"
  624. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  625. return
  626. fi
  627. if [ ! -d "$INSTALL_DIR" ]; then
  628. mkdir "$INSTALL_DIR"
  629. fi
  630. cd "$INSTALL_DIR" || exit 246824245242
  631. function_check git_clone
  632. git_clone "$CLEANUP_MAILDIR_REPO" "$INSTALL_DIR/cleanup-maildir"
  633. cd "$INSTALL_DIR/cleanup-maildir" || exit 6887242572
  634. git checkout $CLEANUP_MAILDIR_COMMIT -b $CLEANUP_MAILDIR_COMMIT
  635. set_completion_param "cleanup-maildir commit" "$CLEANUP_MAILDIR_COMMIT"
  636. if [ ! -f /usr/bin/cleanup-maildir ]; then
  637. cp "$INSTALL_DIR/cleanup-maildir/cleanup-maildir" /usr/bin
  638. else
  639. HASH1=$(sha256sum "$INSTALL_DIR/cleanup-maildir/cleanup-maildir" | awk -F ' ' '{print $1}')
  640. HASH2=$(sha256sum /usr/bin/cleanup-maildir | awk -F ' ' '{print $1}')
  641. if [[ "$HASH1" != "$HASH2" ]]; then
  642. cp "$INSTALL_DIR/cleanup-maildir/cleanup-maildir" /usr/bin
  643. fi
  644. fi
  645. mark_completed "${FUNCNAME[0]}"
  646. }
  647. # Ensure that the from field is correct when sending email from Mutt
  648. function email_from_address {
  649. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  650. return
  651. fi
  652. if [ ! -f "/home/$MY_USERNAME/.muttrc" ]; then
  653. return
  654. fi
  655. if grep -q "set from=" "/home/$MY_USERNAME/.muttrc"; then
  656. sed -i "s|set from=.*|set from='$MY_NAME <$MY_EMAIL_ADDRESS>'|g" "/home/$MY_USERNAME/.muttrc"
  657. else
  658. echo "set from='$MY_NAME <$MY_EMAIL_ADDRESS>'" >> "/home/$MY_USERNAME/.muttrc"
  659. fi
  660. mark_completed "${FUNCNAME[0]}"
  661. }
  662. function create_public_mailing_list {
  663. if [ ! -d /etc/exim4 ]; then
  664. return
  665. fi
  666. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  667. return
  668. fi
  669. if [ ! "$PUBLIC_MAILING_LIST" ]; then
  670. return
  671. fi
  672. # does the mailing list have a separate domain name?
  673. if [ ! "$PUBLIC_MAILING_LIST_DOMAIN_NAME" ]; then
  674. PUBLIC_MAILING_LIST_DOMAIN_NAME="$DEFAULT_DOMAIN_NAME"
  675. fi
  676. PUBLIC_MAILING_LIST_USER="mlmmj"
  677. apt-get -yq install mlmmj
  678. adduser --system "$PUBLIC_MAILING_LIST_USER"
  679. addgroup "$PUBLIC_MAILING_LIST_USER"
  680. adduser "$PUBLIC_MAILING_LIST_USER" "$PUBLIC_MAILING_LIST_USER"
  681. echo ''
  682. echo $"Creating the $PUBLIC_MAILING_LIST mailing list"
  683. echo ''
  684. # create the list
  685. mlmmj-make-ml -a -L "$PUBLIC_MAILING_LIST" -c "$PUBLIC_MAILING_LIST_USER"
  686. { echo 'SYSTEM_ALIASES_PIPE_TRANSPORT = address_pipe';
  687. echo "SYSTEM_ALIASES_USER = $PUBLIC_MAILING_LIST_USER";
  688. echo "SYSTEM_ALIASES_GROUP = $PUBLIC_MAILING_LIST_USER"; } > /etc/exim4/conf.d/main/000_localmacros
  689. # router
  690. { echo 'mlmmj_router:';
  691. echo " debug_print = \"R: mlmmj_router for \$local_part@\$domain\"";
  692. echo ' driver = accept';
  693. echo ' domains = +mlmmj_domains';
  694. echo " #require_files = MLMMJ_HOME/\${lc::\$local_part}";
  695. echo ' # Use this instead, if you dont want to give Exim rx rights to mlmmj spool.';
  696. echo ' # Exim will then spawn a new process running under the UID of "mlmmj".';
  697. echo " require_files = mlmmj:MLMMJ_HOME/\${lc::\$local_part}";
  698. echo ' local_part_suffix = +*';
  699. echo ' local_part_suffix_optional';
  700. echo ' headers_remove = Delivered-To';
  701. echo " headers_add = Delivered-To: \$local_part\$local_part_suffix@\$domain";
  702. echo ' transport = mlmmj_transport'; } > /etc/exim4/conf.d/router/750_exim4-config_mlmmj
  703. # transport
  704. { echo 'mlmmj_transport:';
  705. echo " debug_print = \"T: mlmmj_transport for \$local_part@\$domain\"";
  706. echo ' driver = pipe';
  707. echo ' return_path_add';
  708. echo ' user = mlmmj';
  709. echo ' group = mlmmj';
  710. echo ' home_directory = MLMMJ_HOME';
  711. echo ' current_directory = MLMMJ_HOME';
  712. echo " command = /usr/bin/mlmmj-receive -F -L MLMMJ_HOME/\${lc:\$local_part}"; } > /etc/exim4/conf.d/transport/40_exim4-config_mlmmj
  713. if ! grep -q "MLMMJ_HOME=/var/spool/mlmmj" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then
  714. sed -i '/MAIN CONFIGURATION SETTINGS/a\MLMMJ_HOME=/var/spool/mlmmj' /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
  715. fi
  716. if ! grep -q "domainlist mlmmj_domains =" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then
  717. sed -i "/MLMMJ_HOME/a\\domainlist mlmmj_domains = $PUBLIC_MAILING_LIST_DOMAIN_NAME" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
  718. fi
  719. if ! grep -q "delay_warning_condition =" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then
  720. sed -i "/domainlist mlmmj_domains =/a\\delay_warning_condition = \${if match_domain{\$domain}{+mlmmj_domains}{no}{yes}}" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
  721. fi
  722. if ! grep -q ": +mlmmj_domains" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then
  723. sed -i 's/domainlist relay_to_domains = MAIN_RELAY_TO_DOMAINS/domainlist relay_to_domains = MAIN_RELAY_TO_DOMAINS : +mlmmj_domains/g' /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
  724. fi
  725. if ! grep -q "! +mlmmj_domains" /etc/exim4/conf.d/router/200_exim4-config_primary; then
  726. sed -i 's/domains = ! +local_domains/domains = ! +mlmmj_domains : ! +local_domains/g' /etc/exim4/conf.d/router/200_exim4-config_primary
  727. fi
  728. update-exim4.conf.template -r
  729. update-exim4.conf
  730. systemctl restart exim4
  731. if ! grep -q $"$PUBLIC_MAILING_LIST mailing list" "/home/$MY_USERNAME/README"; then
  732. { echo '';
  733. echo '';
  734. echo $"$PUBLIC_MAILING_LIST mailing list";
  735. echo '=================================';
  736. echo $"To subscribe to the $PUBLIC_MAILING_LIST mailing list send a";
  737. echo $"cleartext email to $PUBLIC_MAILING_LIST+subscribe@$DEFAULT_DOMAIN_NAME"; } >> "/home/$MY_USERNAME/README"
  738. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/README"
  739. chmod 600 "/home/$MY_USERNAME/README"
  740. fi
  741. "${PROJECT_NAME}-addlist" -u "$MY_USERNAME" -l "$PUBLIC_MAILING_LIST" -s "$PUBLIC_MAILING_LIST"
  742. mark_completed "${FUNCNAME[0]}"
  743. }
  744. function split_gpg_key_into_fragments {
  745. # split the gpg key into fragments if social key management is enabled
  746. if [[ "$ENABLE_SOCIAL_KEY_MANAGEMENT" == "yes" ]]; then
  747. if [ "$IMAGE_PASSWORD_FILE" ]; then
  748. if [ -f "$IMAGE_PASSWORD_FILE" ]; then
  749. "${PROJECT_NAME}-splitkey" -u "$MY_USERNAME" -e "$MY_EMAIL_ADDRESS" --fullname "$MY_NAME" --passwordfile "$IMAGE_PASSWORD_FILE"
  750. return
  751. fi
  752. fi
  753. echo 'Splitting GPG key. You may need to enter your passphrase.'
  754. "${PROJECT_NAME}-splitkey" -u "$MY_USERNAME" -e "$MY_EMAIL_ADDRESS" --fullname "$MY_NAME"
  755. if [ ! -d "/home/$MY_USERNAME/.gnupg_fragments" ]; then
  756. echo 'Yhe GPG key could not be split'
  757. exit 86548
  758. fi
  759. fi
  760. }
  761. function import_email {
  762. if [ ! -d /etc/exim4 ]; then
  763. return
  764. fi
  765. EMAIL_COMPLETE_MSG=$"
  766. *** ${PROJECT_NAME} mailbox installation is complete ***
  767. Now on your internet router forward ports
  768. 25, 587, 465, 993 and 2222 to the ${PROJECT_NAME}
  769. "
  770. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  771. if [[ "$SYSTEM_TYPE" == "mail"* ]]; then
  772. function_check backup_to_friends_servers
  773. backup_to_friends_servers
  774. function_check install_tripwire
  775. install_tripwire
  776. function_check split_gpg_key_into_fragments
  777. split_gpg_key_into_fragments
  778. clear
  779. echo ''
  780. echo "$EMAIL_COMPLETE_MSG"
  781. if [ -d "$USB_MOUNT" ]; then
  782. umount "$USB_MOUNT"
  783. rm -rf "$USB_MOUNT"
  784. echo $' You can now remove the USB drive'
  785. fi
  786. exit 0
  787. fi
  788. return
  789. fi
  790. mark_completed "${FUNCNAME[0]}"
  791. if [[ "$SYSTEM_TYPE" == "mail"* ]]; then
  792. function_check backup_to_friends_servers
  793. backup_to_friends_servers
  794. function_check install_tripwire
  795. install_tripwire
  796. function_check split_gpg_key_into_fragments
  797. split_gpg_key_into_fragments
  798. # unmount any attached usb drive
  799. clear
  800. echo ''
  801. echo "$EMAIL_COMPLETE_MSG"
  802. echo ''
  803. if [ -d "$USB_MOUNT" ]; then
  804. umount "$USB_MOUNT"
  805. rm -rf "$USB_MOUNT"
  806. echo $' You can now remove the USB drive'
  807. fi
  808. exit 0
  809. fi
  810. }
  811. function remove_email {
  812. echo ''
  813. }
  814. function install_email_basic {
  815. apt-get -yq remove postfix
  816. apt-get -yq install exim4 sasl2-bin swaks libnet-ssleay-perl procmail
  817. if [ ! -d /etc/exim4 ]; then
  818. echo $"ERROR: Exim does not appear to have installed. $CHECK_MESSAGE"
  819. exit 48
  820. fi
  821. # configure for Maildir format
  822. sed -i 's/MAIL_DIR/#MAIL_DIR/g' /etc/login.defs
  823. sed -i 's|#MAIL_FILE.*|MAIL_FILE Maildir/|g' /etc/login.defs
  824. if ! grep -q "export MAIL" /etc/profile; then
  825. echo 'export MAIL=~/Maildir' >> /etc/profile
  826. fi
  827. sed -i 's|pam_mail.so standard|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/login
  828. sed -i 's|pam_mail.so standard noenv|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/sshd
  829. sed -i 's|pam_mail.so nopen|pam_mail.so dir=~/Maildir nopen|g' /etc/pam.d/su
  830. echo "dc_eximconfig_configtype='internet'" > /etc/exim4/update-exim4.conf.conf
  831. if [[ $ONION_ONLY == 'no' ]]; then
  832. echo "dc_other_hostnames='${DEFAULT_DOMAIN_NAME};mail.${DEFAULT_DOMAIN_NAME}'" >> /etc/exim4/update-exim4.conf.conf
  833. else
  834. echo "dc_other_hostnames='${onion_address}'" >> /etc/exim4/update-exim4.conf.conf
  835. fi
  836. { echo "dc_local_interfaces=''";
  837. echo "dc_readhost=''";
  838. echo "dc_relay_domains=''";
  839. echo "dc_minimaldns='false'"; } >> /etc/exim4/update-exim4.conf.conf
  840. IPv4_address=$(get_ipv4_address)
  841. IPv4_address_base=$(echo "$IPv4_address" | awk -F '.' '{print $1"."$2"."$3}')
  842. RELAY_NETS="${IPv4_address_base}.0/24"
  843. if [ "$LOCAL_NETWORK_STATIC_IP_ADDRESS" ]; then
  844. RELAY_NETS=$(awk "$LOCAL_NETWORK_STATIC_IP_ADDRESS" -F '.' '{print $1 "." $2 "." $3 ".0/24"}')
  845. fi
  846. { echo "dc_relay_nets='$RELAY_NETS'";
  847. echo "dc_smarthost=''";
  848. echo "CFILEMODE='644'";
  849. echo "dc_use_split_config='false'";
  850. echo "dc_hide_mailname=''";
  851. echo "dc_mailname_in_oh='true'";
  852. echo "dc_localdelivery='maildir_home'";
  853. echo "dc_main_log_selector=-all"; } >> /etc/exim4/update-exim4.conf.conf
  854. echo "chunking_advertise_hosts =" > /etc/exim4/conf.d/main/04_exim4-config_chunking
  855. update-exim4.conf
  856. sed -i "s/START=no/START=yes/g" /etc/default/saslauthd
  857. systemctl start saslauthd
  858. email_install_tls
  859. adduser "$MY_USERNAME" sasl
  860. addgroup Debian-exim sasl
  861. systemctl restart exim4
  862. email_create_template
  863. if [ -f /usr/sbin/exim ]; then
  864. chmod u+s /usr/sbin/exim
  865. fi
  866. if [ -f /usr/sbin/exim4 ]; then
  867. chmod u+s /usr/sbin/exim4
  868. fi
  869. function_check configure_firewall_for_email
  870. configure_firewall_for_email
  871. dpkg-reconfigure --frontend noninteractive exim4-config
  872. systemctl restart exim4
  873. }
  874. function email_change_relay {
  875. curr_ip_address="$1"
  876. email_relay_base=$(echo "$curr_ip_address" | awk -F '.' '{print $1"."$2"."$3}')
  877. RELAY_NETS="${email_relay_base}.0/24"
  878. sed -i "s|dc_relay_nets=.*|dc_relay_nets='$RELAY_NETS'|g" /etc/exim4/update-exim4.conf.conf
  879. dpkg-reconfigure --frontend noninteractive exim4-config
  880. }
  881. function create_procmail {
  882. if [ ! -d /etc/exim4 ]; then
  883. return
  884. fi
  885. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  886. return
  887. fi
  888. if [ ! -f "/home/$MY_USERNAME/.procmailrc" ]; then
  889. { echo "MAILDIR=\$HOME/Maildir";
  890. echo "DEFAULT=\$MAILDIR/";
  891. echo "LOGFILE=\$HOME/log/procmail.log";
  892. echo 'LOGABSTRACT=all';
  893. echo '';
  894. echo '# Test for an empty or missing subject line';
  895. echo "SUBJ_=\$(formail -xSubject: \\";
  896. echo " | expand | sed -e 's/^[ ]*//g' -e 's/[ ]*\$//g')";
  897. echo ':0';
  898. echo ' * SUBJ_ ?? ^^^^';
  899. echo '/dev/null';
  900. echo '';
  901. echo $"# Tripwire reports which have no violations don't need to be logged";
  902. echo ':0 BD:'; } > "/home/$MY_USERNAME/.procmailrc"
  903. TRIPWIRE_VIOLATIONS_STR=$'Total violations found: 0'
  904. { echo " * .*$TRIPWIRE_VIOLATIONS_STR";
  905. echo '/dev/null';
  906. echo ''; } >> "/home/$MY_USERNAME/.procmailrc"
  907. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.procmailrc"
  908. fi
  909. mkdir -p "/home/$MY_USERNAME/Maildir/admin/new"
  910. mkdir -p "/home/$MY_USERNAME/Maildir/admin/cur"
  911. chown -R "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/Maildir/admin"
  912. if [ ! -f /etc/skel/.procmailrc ]; then
  913. cp "/home/$MY_USERNAME/.procmailrc" /etc/skel/.procmailrc
  914. chown root:root /etc/skel/.procmailrc
  915. fi
  916. if [ -f /usr/bin/procmail ]; then
  917. chmod 6755 /usr/bin/procmail
  918. fi
  919. mark_completed "${FUNCNAME[0]}"
  920. }
  921. function handle_admin_emails {
  922. # keep emails for root in a separate folder
  923. if [ -d "/home/$MY_USERNAME/Maildir/admin" ]; then
  924. return
  925. fi
  926. "${PROJECT_NAME}-addemail" -u "$MY_USERNAME" -e "root@$DEFAULT_DOMAIN_NAME" -g admin --public no
  927. }
  928. function spam_filtering {
  929. if [ ! -d /etc/exim4 ]; then
  930. return
  931. fi
  932. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  933. return
  934. fi
  935. apt-get -yq install exim4-daemon-heavy
  936. apt-get -yq install spamassassin
  937. if [ ! -f /etc/default/spamassassin ]; then
  938. echo 'Spamassassin was not installed'
  939. exit 72570
  940. fi
  941. sa-update -v
  942. sed -i 's/ENABLED=0/ENABLED=1/g' /etc/default/spamassassin
  943. sed -i 's/# spamd_address = 127.0.0.1 783/spamd_address = 127.0.0.1 783/g' /etc/exim4/exim4.conf.template
  944. # This configuration is based on https://wiki.debian.org/DebianSpamAssassin
  945. sed -i 's/local_parts = postmaster/local_parts = postmaster:abuse/g' /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt
  946. sed -i '/domains = +local_domains : +relay_to_domains/a\ set acl_m0 = rfcnames' /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt
  947. sed -i "s/accept/accept condition = \${if eq{\$acl_m0}{rfcnames} {1}{0}}/g" /etc/exim4/conf.d/acl/40_exim4-config_check_data
  948. { echo "warn message = X-Spam-Score: \$spam_score (\$spam_bar)";
  949. echo ' spam = nobody:true';
  950. echo 'warn message = X-Spam-Flag: YES';
  951. echo ' spam = nobody';
  952. echo "warn message = X-Spam-Report: \$spam_report";
  953. echo ' spam = nobody';
  954. echo '# reject spam at high scores (> 12)';
  955. echo "deny message = This message scored \$spam_score spam points.";
  956. echo ' spam = nobody:true';
  957. echo " condition = \${if >{\$spam_score_int}{120}{1}{0}}"; } >> /etc/exim4/conf.d/acl/40_exim4-config_check_data
  958. # procmail configuration
  959. { echo '# get spamassassin to check emails';
  960. echo ':0fw: .spamassassin.lock';
  961. echo ' * < 256000';
  962. echo '| spamc';
  963. echo '# strong spam are discarded';
  964. echo ':0';
  965. echo ' * ^X-Spam-Level: \*\*\*\*\*\*';
  966. echo '/dev/null';
  967. echo '# weak spam are kept just in case - clear this out every now and then';
  968. echo ':0';
  969. echo ' * ^X-Spam-Level: \*\*\*\*\*';
  970. echo 'maybe-spam/';
  971. echo '# otherwise, marginal spam goes here for revision';
  972. echo ':0';
  973. echo ' * ^X-Spam-Level: \*\*';
  974. echo 'spam/'; } >> "/home/$MY_USERNAME/.procmailrc"
  975. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.procmailrc"
  976. { echo '# get spamassassin to check emails';
  977. echo ':0fw: .spamassassin.lock';
  978. echo ' * < 256000';
  979. echo '| spamc';
  980. echo '# strong spam are discarded';
  981. echo ':0';
  982. echo ' * ^X-Spam-Level: \*\*\*\*\*\*';
  983. echo '/dev/null';
  984. echo '# weak spam are kept just in case - clear this out every now and then';
  985. echo ':0';
  986. echo ' * ^X-Spam-Level: \*\*\*\*\*';
  987. echo 'maybe-spam/';
  988. echo '# otherwise, marginal spam goes here for revision';
  989. echo ':0';
  990. echo ' * ^X-Spam-Level: \*\*';
  991. echo 'spam/'; } >> /etc/skel/.procmailrc
  992. # filtering scripts
  993. { echo '#!/bin/bash';
  994. echo 'for d in /home/*/ ; do';
  995. echo " USERNAME=\$(echo \"\$d\" | awk -F '/' '{print \$3}')";
  996. echo " if [[ \$USERNAME != \"git\" && $USERNAME != \"go\" && \$USERNAME != \"gogs\" && \$USERNAME != \"sync\" && \$USERNAME != \"tahoelafs\" ]]; then";
  997. echo " MAILDIR=/home/\$USERNAME/Maildir/.learn-spam";
  998. echo " if [ ! -d \"\$MAILDIR\" ]; then";
  999. echo ' exit';
  1000. echo ' fi';
  1001. echo " for f in \$(ls \$MAILDIR/cur)";
  1002. echo ' do';
  1003. echo " spamc -L spam < \"\$MAILDIR/cur/\$f\" > /dev/null";
  1004. echo " rm \"\$MAILDIR/cur/\$f\"";
  1005. echo ' done';
  1006. echo " for f in \$(ls \$MAILDIR/new)";
  1007. echo ' do';
  1008. echo " spamc -L spam < \"\$MAILDIR/new/\$f\" > /dev/null";
  1009. echo " rm \"\$MAILDIR/new/\$f\"";
  1010. echo ' done';
  1011. echo ' fi';
  1012. echo 'done';
  1013. echo 'exit 0'; } > /usr/bin/filterspam
  1014. { echo '#!/bin/bash';
  1015. echo 'for d in /home/*/ ; do';
  1016. echo " USERNAME=\$(echo \"\$d\" | awk -F '/' '{print \$3}')";
  1017. echo " if [[ \$USERNAME != \"git\" && \$USERNAME != \"go\" && \$USERNAME != \"gogs\" && \$USERNAME != \"sync\" && \$USERNAME != \"tahoelafs\" ]]; then";
  1018. echo " MAILDIR=/home/\$USERNAME/Maildir/.learn-ham";
  1019. echo " if [ ! -d \"\$MAILDIR\" ]; then";
  1020. echo ' exit';
  1021. echo ' fi';
  1022. echo " for f in \$(ls \$MAILDIR/cur)";
  1023. echo ' do';
  1024. echo " spamc -L ham < \"\$MAILDIR/cur/\$f\" > /dev/null";
  1025. echo " rm \"\$MAILDIR/cur/\$f\"";
  1026. echo ' done';
  1027. echo " for f in \$(ls \$MAILDIR/new)";
  1028. echo ' do';
  1029. echo " spamc -L ham < \"\$MAILDIR/new/\$f\" > /dev/null";
  1030. echo " rm \"\$MAILDIR/new/\$f\"";
  1031. echo ' done';
  1032. echo ' fi';
  1033. echo 'done';
  1034. echo 'exit 0'; } > /usr/bin/filterham
  1035. function_check cron_add_mins
  1036. cron_add_mins 3 '/usr/bin/timeout 120 /usr/bin/filterspam'
  1037. cron_add_mins 3 '/usr/bin/timeout 120 /usr/bin/filterham'
  1038. chmod 655 /usr/bin/filterspam /usr/bin/filterham
  1039. sed -i 's/# use_bayes 1/use_bayes 1/g' /etc/mail/spamassassin/local.cf
  1040. sed -i 's/# bayes_auto_learn 1/bayes_auto_learn 1/g' /etc/mail/spamassassin/local.cf
  1041. # user preferences
  1042. if [ ! -d "/home/$MY_USERNAME/.spamassassin" ]; then
  1043. mkdir "/home/$MY_USERNAME/.spamassassin"
  1044. { echo $'# How many points before a mail is considered spam.';
  1045. echo '# required_score 5';
  1046. echo '';
  1047. echo $'# Whitelist and blacklist addresses are now file-glob-style patterns, so';
  1048. echo $'# "friend@somewhere.com", "*@isp.com", or "*.domain.net" will all work.';
  1049. echo '# whitelist_from someone@somewhere.com';
  1050. echo '';
  1051. echo $'# Add your own customised scores for some tests below. The default scores are';
  1052. echo $'# read from the installed spamassassin rules files, but you can override them';
  1053. echo $'# here. To see the list of tests and their default scores, go to';
  1054. echo '# http://spamassassin.apache.org/tests.html .';
  1055. echo '#';
  1056. echo '# score SYMBOLIC_TEST_NAME n.nn';
  1057. echo '';
  1058. echo $'# Speakers of Asian languages, like Chinese, Japanese and Korean, will almost';
  1059. echo $'# definitely want to uncomment the following lines. They will switch off some';
  1060. echo $'# rules that detect 8-bit characters, which commonly trigger on mails using CJK';
  1061. echo $'# character sets, or that assume a western-style charset is in use. ';
  1062. echo '# ';
  1063. echo '# score HTML_COMMENT_8BITS 0';
  1064. echo '# score UPPERCASE_25_50 0';
  1065. echo '# score UPPERCASE_50_75 0';
  1066. echo '# score UPPERCASE_75_100 0';
  1067. echo '# score OBSCURED_EMAIL 0';
  1068. echo '';
  1069. echo $'# Speakers of any language that uses non-English, accented characters may wish';
  1070. echo $'# to uncomment the following lines. They turn off rules that fire on';
  1071. echo $'# misformatted messages generated by common mail apps in contravention of the';
  1072. echo $'# email RFCs.';
  1073. echo '';
  1074. echo '# score SUBJ_ILLEGAL_CHARS 0'; } > "/home/$MY_USERNAME/.spamassassin/user_prefs"
  1075. fi
  1076. # this must be accessible by root
  1077. chown -R "$MY_USERNAME":root "/home/$MY_USERNAME/.spamassassin"
  1078. # script to keep spamassassin running
  1079. # There is a systemd script from the debian package, but it doesn't restart on failure
  1080. # and also doesn't ensure start after networking is up. If that is eventually fixed
  1081. # then this script and the cron job which runs it can be removed.
  1082. script_name=/usr/bin/run-spamassassin
  1083. { echo '#!/bin/bash';
  1084. echo "current_state=\$(systemctl status spamassassin)";
  1085. echo "if [[ \"\$current_state\" != *\"(running)\"* ]]; then";
  1086. echo ' systemctl restart spamassassin';
  1087. echo 'fi';
  1088. echo 'exit 0'; } > $script_name
  1089. chmod +x $script_name
  1090. systemctl start spamassassin
  1091. systemctl restart exim4
  1092. systemctl restart cron
  1093. function_check cron_add_mins
  1094. cron_add_mins 10 "$script_name 2> /dev/null"
  1095. mark_completed "${FUNCNAME[0]}"
  1096. }
  1097. function configure_imap {
  1098. if [ ! -d /etc/exim4 ]; then
  1099. return
  1100. fi
  1101. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  1102. return
  1103. fi
  1104. apt-get -yq install dovecot-imapd
  1105. if [ ! -d /etc/dovecot ]; then
  1106. echo $"ERROR: Dovecot does not appear to have installed. $CHECK_MESSAGE"
  1107. exit 48
  1108. fi
  1109. if [[ "$(cert_exists dovecot)" == "0" ]]; then
  1110. "${PROJECT_NAME}-addcert" -h dovecot --dhkey "$DH_KEYLENGTH"
  1111. CHECK_HOSTNAME=dovecot
  1112. check_certificates dovecot
  1113. fi
  1114. chmod 600 /etc/shadow
  1115. chmod 600 /etc/gshadow
  1116. groupadd default
  1117. usermod -g default dovecot
  1118. chmod 0000 /etc/shadow
  1119. chmod 0000 /etc/gshadow
  1120. chown root:default /etc/ssl/certs/dovecot.*
  1121. chown root:default /etc/ssl/private/dovecot.*
  1122. chown root:default "/etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.*"
  1123. chown root:default "/etc/ssl/private/${DEFAULT_DOMAIN_NAME}.*"
  1124. if [ ! -f /etc/dovecot/conf.d/10-ssl.conf ]; then
  1125. echo $'Unable to find /etc/dovecot/conf.d/10-ssl.conf'
  1126. exit 83629
  1127. fi
  1128. sed -i 's|#ssl =.*|ssl = no|g' /etc/dovecot/conf.d/10-ssl.conf
  1129. sed -i 's|ssl =.*|ssl = no|g' /etc/dovecot/conf.d/10-ssl.conf
  1130. sed -i "s|#ssl_cert =.*|ssl_cert = </etc/ssl/certs/dovecot.crt|g" /etc/dovecot/conf.d/10-ssl.conf
  1131. sed -i "s|ssl_cert =.*|ssl_cert = </etc/ssl/certs/dovecot.crt|g" /etc/dovecot/conf.d/10-ssl.conf
  1132. sed -i "s|#ssl_key =.*|ssl_key = </etc/ssl/private/dovecot.key|g" /etc/dovecot/conf.d/10-ssl.conf
  1133. sed -i "s|ssl_key =.*|ssl_key = </etc/ssl/private/dovecot.key|g" /etc/dovecot/conf.d/10-ssl.conf
  1134. sed -i "s|#ssl_dh_parameters_length.*|ssl_dh_parameters_length = ${DH_KEYLENGTH}|g" /etc/dovecot/conf.d/10-ssl.conf
  1135. sed -i 's/#ssl_prefer_server_ciphers.*/ssl_prefer_server_ciphers = yes/g' /etc/dovecot/conf.d/10-ssl.conf
  1136. sed -i "s|#ssl_protocols =.*|ssl_protocols = '$SSL_PROTOCOLS'|g" /etc/dovecot/conf.d/10-ssl.conf
  1137. sed -i "s|ssl_protocols =.*|ssl_protocols = '$SSL_PROTOCOLS'|g" /etc/dovecot/conf.d/10-ssl.conf
  1138. echo "ssl_cipher_list = '$SSL_CIPHERS'" >> /etc/dovecot/conf.d/10-ssl.conf
  1139. if [ ! -f /etc/dovecot/conf.d/10-master.conf ]; then
  1140. echo $'Unable to find /etc/dovecot/conf.d/10-master.conf'
  1141. exit 49259
  1142. fi
  1143. sed -i 's/#process_limit =.*/process_limit = 100/g' /etc/dovecot/conf.d/10-master.conf
  1144. if [ ! -f /etc/dovecot/conf.d/10-logging.conf ]; then
  1145. echo $'Unable to find /etc/dovecot/conf.d/10-logging.conf'
  1146. exit 48936
  1147. fi
  1148. sed -i 's/#auth_verbose.*/auth_verbose = yes/g' /etc/dovecot/conf.d/10-logging.conf
  1149. if [ ! -f /etc/dovecot/dovecot.conf ]; then
  1150. echo $'Unable to find /etc/dovecot/dovecot.conf'
  1151. exit 43890
  1152. fi
  1153. sed -i 's/#listen =.*/listen = */g' /etc/dovecot/dovecot.conf
  1154. if [ ! -f /etc/dovecot/conf.d/10-auth.conf ]; then
  1155. echo $'Unable to find /etc/dovecot/conf.d/10-auth.conf'
  1156. exit 843256
  1157. fi
  1158. sed -i 's/#disable_plaintext_auth =.*/disable_plaintext_auth = no/g' /etc/dovecot/conf.d/10-auth.conf
  1159. sed -i 's/auth_mechanisms =.*/auth_mechanisms = plain login/g' /etc/dovecot/conf.d/10-auth.conf
  1160. if [ ! -f /etc/dovecot/conf.d/10-mail.conf ]; then
  1161. echo $'Unable to find /etc/dovecot/conf.d/10-mail.conf'
  1162. exit 42036
  1163. fi
  1164. sed -i 's|mail_location =.*|mail_location = maildir:~/Maildir:LAYOUT=fs|g' /etc/dovecot/conf.d/10-mail.conf
  1165. # This long notify interval makes the system more suited for use with
  1166. # battery powered mobile devices
  1167. sed -i 's|#imap_idle_notify_interval =.*|imap_idle_notify_interval = 29|g' /etc/dovecot/conf.d/20-imap.conf
  1168. if [ -f /var/lib/dovecot/ssl-parameters.dat ]; then
  1169. rm /var/lib/dovecot/ssl-parameters.dat
  1170. fi
  1171. if [ -f /etc/systemd/system/sockets.target.wants/dovecot.socket ]; then
  1172. rm /etc/systemd/system/sockets.target.wants/dovecot.socket
  1173. fi
  1174. # Separate logging, otherwise syslog is used
  1175. if ! grep -q "# logging" /etc/dovecot/dovecot.conf; then
  1176. { echo '';
  1177. echo '# logging';
  1178. echo 'log_path = /var/log/dovecot.log';
  1179. echo 'info_log_path = /var/log/dovecot-info.log';
  1180. echo 'debug_log_path = /var/log/dovecot-debug.log'; } >> /etc/dovecot/dovecot.conf
  1181. fi
  1182. systemctl restart dovecot
  1183. mark_completed "${FUNCNAME[0]}"
  1184. }
  1185. function configure_imap_client_certs {
  1186. if [ ! -d /etc/exim4 ]; then
  1187. return
  1188. fi
  1189. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  1190. return
  1191. fi
  1192. # http://strange.systems/certificate-based-auth-with-dovecot-sendmail/
  1193. sed -i 's|#default_process_limit =.*|default_process_limit = 100|g' /etc/dovecot/conf.d/10-master.conf
  1194. sed -i 's/disable_plaintext_auth =.*/disable_plaintext_auth = yes/g' /etc/dovecot/conf.d/10-auth.conf
  1195. sed -i 's|#auth_ssl_require_client_cert =.*|auth_ssl_require_client_cert = yes|g' /etc/dovecot/conf.d/10-auth.conf
  1196. sed -i 's|#auth_ssl_username_from_cert =.*|auth_ssl_username_from_cert = yes|g' /etc/dovecot/conf.d/10-auth.conf
  1197. sed -i "s|#ssl_ca =.*|ssl_ca = /etc/ssl/certs/ca-$DEFAULT_DOMAIN_NAME.crt|g" /etc/dovecot/conf.d/10-ssl.conf
  1198. sed -i 's|#ssl_cert_username_field =.*|ssl_cert_username_field = commonName|g' /etc/dovecot/conf.d/10-ssl.conf
  1199. sed -i 's|#ssl_verify_client_cert =.*|ssl_verify_client_cert = yes|g' /etc/dovecot/conf.d/10-ssl.conf
  1200. if ! grep -q "passdb {" /etc/dovecot/conf.d/10-auth.conf; then
  1201. { echo '';
  1202. echo 'passdb {';
  1203. echo ' driver = passwd-file';
  1204. echo ' args = /etc/dovecot/passwd-file';
  1205. echo ' deny = no';
  1206. echo ' master = no';
  1207. echo ' pass = no';
  1208. echo '}'; } >> /etc/dovecot/conf.d/10-auth.conf
  1209. fi
  1210. if [[ "$ONION_ONLY" == "no" ]]; then
  1211. # make a CA cert
  1212. if [ ! -f "/etc/ssl/private/ca-$DEFAULT_DOMAIN_NAME.key" ]; then
  1213. if [[ "$LETSENCRYPT_ENABLED" != "yes" ]]; then
  1214. "${PROJECT_NAME}-addcert" -h "$DEFAULT_DOMAIN_NAME" --ca "" --dhkey "$DH_KEYLENGTH"
  1215. else
  1216. "${PROJECT_NAME}-addcert" -e "$DEFAULT_DOMAIN_NAME" -s "$LETSENCRYPT_SERVER" --ca "" --dhkey "$DH_KEYLENGTH" --email "$MY_EMAIL_ADDRESS"
  1217. fi
  1218. fi
  1219. fi
  1220. # CA configuration
  1221. { echo '[ ca ]';
  1222. echo "default_ca = dovecot-ca";
  1223. echo '';
  1224. echo '[ crl_ext ]';
  1225. echo 'authorityKeyIdentifier=keyid:always';
  1226. echo '';
  1227. echo '[ dovecot-ca ]';
  1228. echo 'new_certs_dir = .';
  1229. echo 'unique_subject = no';
  1230. echo "certificate = /etc/ssl/certs/ca-$DEFAULT_DOMAIN_NAME.crt";
  1231. echo 'database = ssldb';
  1232. echo "private_key = /etc/ssl/private/ca-$DEFAULT_DOMAIN_NAME.key";
  1233. echo 'serial = sslserial';
  1234. echo 'default_days = 3650';
  1235. echo 'default_md = sha256';
  1236. echo 'default_bits = 2048';
  1237. echo 'policy = dovecot-ca_policy';
  1238. echo 'x509_extensions = dovecot-ca_extensions';
  1239. echo '';
  1240. echo '[ dovecot-ca_policy ]';
  1241. echo 'commonName = supplied';
  1242. echo 'stateOrProvinceName = supplied';
  1243. echo 'countryName = supplied';
  1244. echo 'emailAddress = optional';
  1245. echo 'organizationName = supplied';
  1246. echo 'organizationalUnitName = optional';
  1247. echo '';
  1248. echo '[ dovecot-ca_extensions ]';
  1249. echo 'basicConstraints = CA:false';
  1250. echo 'subjectKeyIdentifier = hash';
  1251. echo 'authorityKeyIdentifier = keyid:always';
  1252. echo 'keyUsage = digitalSignature,keyEncipherment';
  1253. echo 'extendedKeyUsage = clientAuth'; } > /etc/ssl/dovecot-ca.cnf
  1254. if [ -f /etc/ssl/ssldb ]; then
  1255. rm /etc/ssl/ssldb
  1256. fi
  1257. if [ -f /etc/ssl/sslserial ]; then
  1258. rm /etc/ssl/sslserial
  1259. fi
  1260. touch /etc/ssl/ssldb
  1261. echo 0001 > /etc/ssl/sslserial
  1262. #${PROJECT_NAME}-clientcert -u $MY_USERNAME
  1263. systemctl restart dovecot
  1264. mark_completed "${FUNCNAME[0]}"
  1265. }
  1266. function create_gpg_subkey {
  1267. # Note: currently not used
  1268. if [ ! -d /etc/exim4 ]; then
  1269. return
  1270. fi
  1271. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  1272. return
  1273. fi
  1274. apt-get -yq install gnupg
  1275. GPG_KEY_USAGE=$1
  1276. if [[ "$GPG_KEY_USAGE" != "sign" && "$GPG_KEY_USAGE" != "auth" && "$GPG_KEY_USAGE" != "encrypt" ]]; then
  1277. echo $"Unknown subkey usage: $GPG_KEY_USAGE"
  1278. echo $'Available types: sign|auth|encrypt'
  1279. exit 14783
  1280. fi
  1281. KEYGRIP=$(gpg --fingerprint --fingerprint "$MY_EMAIL_ADDRESS" | grep fingerprint | tail -1 | cut -d= -f2 | sed -e 's/ //g')
  1282. # Generate a GPG subkey
  1283. { echo 'Key-Type: eddsa';
  1284. echo 'Key-Curve: Ed25519';
  1285. echo "Key-Grip: $KEYGRIP";
  1286. echo 'Subkey-Type: eddsa';
  1287. echo "subkey-Usage: $GPG_KEY_USAGE";
  1288. echo "Name-Real: $MY_NAME";
  1289. echo "Name-Email: $MY_EMAIL_ADDRESS";
  1290. echo "Name-Comment: $GPG_KEY_USAGE";
  1291. echo 'Expire-Date: 0';
  1292. echo "Passphrase: $PROJECT_NAME"; } > "/home/$MY_USERNAME/gpg-genkey.conf"
  1293. chown "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/gpg-genkey.conf"
  1294. su -m root -c "gpg --homedir /home/$MY_USERNAME/.gnupg --batch --full-gen-key /home/$MY_USERNAME/gpg-genkey.conf" - "$MY_USERNAME"
  1295. chown -R "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.gnupg"
  1296. shred -zu "/home/$MY_USERNAME/gpg-genkey.conf"
  1297. # shellcheck disable=SC2034
  1298. MY_GPG_SUBKEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS")
  1299. mark_completed "${FUNCNAME[0]}"
  1300. }
  1301. function gpg_key_exists {
  1302. key_owner_username="$1"
  1303. key_search_text="$2"
  1304. if [[ $key_owner_username != "root" ]]; then
  1305. KEY_EXISTS=$(su -c "gpg --list-keys \"${key_search_text}\"" - "$key_owner_username")
  1306. else
  1307. KEY_EXISTS=$(gpg --list-keys "${key_search_text}")
  1308. fi
  1309. if [ ! "$KEY_EXISTS" ]; then
  1310. echo "no"
  1311. return
  1312. fi
  1313. if [[ "$KEY_EXISTS" == *"error"* ]]; then
  1314. echo "no"
  1315. return
  1316. fi
  1317. echo "yes"
  1318. }
  1319. function configure_gpg {
  1320. if [ ! -d /etc/exim4 ]; then
  1321. return
  1322. fi
  1323. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  1324. return
  1325. fi
  1326. apt-get -yq install gnupg dirmngr
  1327. printf '%%Assuan%%\nsocket=/dev/shm/S.dirmngr\n' > ~/.gnupg/S.dirmngr
  1328. check_email_address_exists
  1329. gpg_dir="/home/$MY_USERNAME/.gnupg"
  1330. # if gpg keys directory was previously imported from usb
  1331. if [ -d "$gpg_dir" ]; then
  1332. echo $'GPG directory exists'
  1333. else
  1334. echo $"GPG directory $gpg_dir was not found"
  1335. fi
  1336. if [ -d "$gpg_dir" ]; then
  1337. echo $'GPG keys were imported'
  1338. sed -i "s|keyserver hkp://keys.gnupg.net|keyserver $GPG_KEYSERVER|g" "$gpg_dir/gpg.conf"
  1339. MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS")
  1340. if [ ${#MY_GPG_PUBLIC_KEY_ID} -lt 4 ]; then
  1341. echo $'GPG public key ID could not be obtained'
  1342. else
  1343. if [[ "$MY_GPG_PUBLIC_KEY_ID" == *'error'* ]]; then
  1344. echo $"Can't locate gpg key"
  1345. else
  1346. chown -R "$MY_USERNAME":"$MY_USERNAME" "$gpg_dir"
  1347. chmod 700 "$gpg_dir"
  1348. chmod 600 "$gpg_dir/"*
  1349. printf '%%Assuan%%\nsocket=/dev/shm/S.dirmngr\n' > "/home/$MY_USERNAME/.gnupg/S.dirmngr"
  1350. if [ -d "/home/$MY_USERNAME/.gnupg/crls.d" ]; then
  1351. chmod +x "/home/$MY_USERNAME/.gnupg/crls.d"
  1352. fi
  1353. mark_completed "${FUNCNAME[0]}"
  1354. return
  1355. fi
  1356. fi
  1357. fi
  1358. if [ ! -d "$gpg_dir" ]; then
  1359. mkdir "$gpg_dir"
  1360. echo "keyserver $GPG_KEYSERVER" >> "$gpg_dir/gpg.conf"
  1361. echo 'keyserver-options auto-key-retrieve' >> "$gpg_dir/gpg.conf"
  1362. fi
  1363. sed -i "s|keyserver hkp://keys.gnupg.net|keyserver $GPG_KEYSERVER|g" "$gpg_dir/gpg.conf"
  1364. gpg_agent_setup root
  1365. gpg_agent_setup "$MY_USERNAME"
  1366. if ! grep -q "# default preferences" "$gpg_dir/gpg.conf"; then
  1367. { echo '';
  1368. echo '# default preferences';
  1369. echo 'personal-digest-preferences SHA256';
  1370. echo 'cert-digest-algo SHA256';
  1371. echo 'default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed'; } >> "$gpg_dir/gpg.conf"
  1372. fi
  1373. chown -R "$MY_USERNAME":"$MY_USERNAME" "$gpg_dir"
  1374. chmod 700 "$gpg_dir"
  1375. chmod 600 "$gpg_dir/"*
  1376. printf '%%Assuan%%\nsocket=/dev/shm/S.dirmngr\n' > "$gpg_dir/S.dirmngr"
  1377. if [ -d "$gpg_dir/crls.d" ]; then
  1378. chmod +x "$gpg_dir/crls.d"
  1379. fi
  1380. if [[ "$MY_GPG_PUBLIC_KEY" && "$MY_GPG_PRIVATE_KEY" ]]; then
  1381. echo $'Importing GPG keys from file'
  1382. echo $"Public key: $MY_GPG_PUBLIC_KEY"
  1383. echo $"Private key: $MY_GPG_PRIVATE_KEY"
  1384. # use your existing GPG keys which were exported
  1385. if [ ! -f $MY_GPG_PUBLIC_KEY ]; then
  1386. echo $"GPG public key file $MY_GPG_PUBLIC_KEY was not found"
  1387. exit 2483
  1388. fi
  1389. if [ ! -f $MY_GPG_PRIVATE_KEY ]; then
  1390. echo $"GPG private key file $MY_GPG_PRIVATE_KEY was not found"
  1391. exit 5383
  1392. fi
  1393. gpg_import_public_key "$MY_USERNAME" "$MY_GPG_PUBLIC_KEY"
  1394. gpg_import_private_key "$MY_USERNAME" "$MY_GPG_PRIVATE_KEY"
  1395. KEY_EXISTS=$(gpg_key_exists "$MY_USERNAME" "$MY_EMAIL_ADDRESS")
  1396. if [[ $KEY_EXISTS == "no" ]]; then
  1397. echo $"The GPG key for $MY_EMAIL_ADDRESS could not be imported"
  1398. exit 13821
  1399. fi
  1400. # for security ensure that the private key file doesn't linger around
  1401. shred -zu $MY_GPG_PRIVATE_KEY
  1402. MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS")
  1403. if [ ${#MY_GPG_PUBLIC_KEY_ID} -lt 4 ]; then
  1404. echo $'GPG public key ID could not be obtained'
  1405. fi
  1406. else
  1407. # Generate a GPG key
  1408. if [ -f "$IMAGE_PASSWORD_FILE" ]; then
  1409. gpg_create_key "$MY_USERNAME" "$(printf "%s" "$(cat "$IMAGE_PASSWORD_FILE")")"
  1410. else
  1411. gpg_create_key "$MY_USERNAME" "$PROJECT_NAME"
  1412. fi
  1413. MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS")
  1414. MY_GPG_PUBLIC_KEY=/tmp/public_key.gpg
  1415. gpg_export_public_key "$MY_USERNAME" "$MY_GPG_PUBLIC_KEY_ID" "$MY_GPG_PUBLIC_KEY"
  1416. fi
  1417. if [ ! -d /root/.gnupg ]; then
  1418. cp -r "/home/$MY_USERNAME/.gnupg" /root/
  1419. chmod 700 /root/.gnupg
  1420. chmod 600 /root/.gnupg/*
  1421. printf '%%Assuan%%\nsocket=/dev/shm/S.dirmngr\n' > /root/.gnupg/S.dirmngr
  1422. if [ -d /root/.gnupg/crls.d ]; then
  1423. chmod +x /root/.gnupg/crls.d
  1424. fi
  1425. fi
  1426. mark_completed "${FUNCNAME[0]}"
  1427. }
  1428. function refresh_gpg_keys {
  1429. REFRESH_GPG_KEYS_SCRIPT=/tmp/update-gpg-keys
  1430. { echo '#!/bin/bash';
  1431. echo "if [ -f /usr/local/bin/${PROJECT_NAME}-sec ]; then";
  1432. echo " /usr/bin/timeout 600 /usr/local/bin/${PROJECT_NAME}-sec --refresh yes";
  1433. echo 'else';
  1434. echo " /usr/bin/timeout 600 /usr/bin/${PROJECT_NAME}-sec --refresh yes";
  1435. echo 'fi';
  1436. echo 'exit 0'; } > "$REFRESH_GPG_KEYS_SCRIPT"
  1437. chmod +x "$REFRESH_GPG_KEYS_SCRIPT"
  1438. if [ ! -f /usr/bin/update-gpg-keys ]; then
  1439. cp "$REFRESH_GPG_KEYS_SCRIPT" /usr/bin/update-gpg-keys
  1440. else
  1441. HASH1=$(sha256sum "$REFRESH_GPG_KEYS_SCRIPT" | awk -F ' ' '{print $1}')
  1442. HASH2=$(sha256sum /usr/bin/update-gpg-keys | awk -F ' ' '{print $1}')
  1443. if [[ "$HASH1" != "$HASH2" ]]; then
  1444. cp $REFRESH_GPG_KEYS_SCRIPT /usr/bin/update-gpg-keys
  1445. fi
  1446. rm $REFRESH_GPG_KEYS_SCRIPT
  1447. fi
  1448. REFRESH_GPG_KEYS_SCRIPT=/usr/bin/update-gpg-keys
  1449. if grep -q "${PROJECT_NAME}-sec" /etc/crontab; then
  1450. sed -i "/${PROJECT_NAME}-sec /d" /etc/crontab
  1451. fi
  1452. if ! grep -q "$REFRESH_GPG_KEYS_SCRIPT" /etc/crontab; then
  1453. GPG_REFRESH_TIME=$(( RANDOM % 60 ))
  1454. echo "$GPG_REFRESH_TIME */$REFRESH_GPG_KEYS_HOURS * * * root cronic $REFRESH_GPG_KEYS_SCRIPT" >> /etc/crontab
  1455. systemctl restart cron
  1456. else
  1457. if ! grep "root cronic $REFRESH_GPG_KEYS_SCRIPT" /etc/crontab; then
  1458. sed -i "s|root $REFRESH_GPG_KEYS_SCRIPT.*|root cronic $REFRESH_GPG_KEYS_SCRIPT|g" /etc/crontab
  1459. fi
  1460. fi
  1461. }
  1462. function install_email {
  1463. if [[ $SYSTEM_TYPE == "mesh"* ]]; then
  1464. return
  1465. fi
  1466. if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
  1467. return
  1468. fi
  1469. create_email_onion_address
  1470. check_email_address_exists
  1471. install_email_basic
  1472. configure_email_onion
  1473. mark_completed "${FUNCNAME[0]}"
  1474. }
  1475. # NOTE: deliberately no exit 0