freedombone-controlpanel-user 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. #!/bin/bash
  2. #
  3. # .---. . .
  4. # | | |
  5. # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
  6. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
  7. # ' ' --' --' -' - -' ' ' -' -' -' ' - --'
  8. #
  9. # Freedom in the Cloud
  10. #
  11. # User control panel
  12. #
  13. # License
  14. # =======
  15. #
  16. # Copyright (C) 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. PROJECT_NAME='freedombone'
  31. export TEXTDOMAIN=${PROJECT_NAME}-controlpanel-user
  32. export TEXTDOMAINDIR="/usr/share/locale"
  33. MY_EMAIL_ADDRESS=$USER@$HOSTNAME
  34. GPG_ID=$(gpg --list-keys "$MY_EMAIL_ADDRESS" | sed -n '2p' | sed 's/^[ \t]*//')
  35. GPG_BACKUP_ID=$(gpg --list-keys "(backup key)" | sed -n '2p' | sed 's/^[ \t]*//')
  36. # If the default key is specified within gpg.conf
  37. if [ -f ~/.gnupg/gpg.conf ]; then
  38. if grep -q "default-key" ~/.gnupg/gpg.conf; then
  39. default_gpg_key=$(grep "default-key" ~/.gnupg/gpg.conf)
  40. if [[ "$default_gpg_key" != *'#'* ]]; then
  41. default_gpg_key=$(grep "default-key" ~/.gnupg/gpg.conf | awk -F ' ' '{print $2}')
  42. if [ ${#default_gpg_key} -gt 3 ]; then
  43. GPG_ID=$(gpg --list-keys "$default_gpg_key" | sed -n '2p' | sed 's/^[ \t]*//')
  44. fi
  45. fi
  46. fi
  47. fi
  48. # Start including files
  49. UTILS_FILES="/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-*"
  50. for f in $UTILS_FILES
  51. do
  52. source "$f"
  53. done
  54. APP_FILES="/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*"
  55. for f in $APP_FILES
  56. do
  57. source "$f"
  58. done
  59. # End including files
  60. function any_key {
  61. echo ' '
  62. # shellcheck disable=SC2034
  63. read -n1 -r -p $"Press any key to continue..." key
  64. }
  65. function remove_user_from_mailing_list {
  66. # shellcheck disable=SC1003
  67. USER_MAILING_LISTS=$(grep '\[' "/home/$USER/.procmailrc" | grep '\]' | awk -F '\[' '{print $2}' | awk -F '\\' '{print $1}')
  68. i=0
  69. W=()
  70. list_name=()
  71. while read -r listname; do
  72. i=$((i+1))
  73. if [[ "$listname" != *']'* && "$listname" != *'['* ]]; then
  74. W+=("$i" "$listname")
  75. list_name+=("$listname")
  76. echo "$listname"
  77. fi
  78. done <<< "$USER_MAILING_LISTS"
  79. i=$((i+1))
  80. W+=("$i" $"Exit back to filtering rules menu")
  81. # shellcheck disable=SC2068
  82. list_selected=$(dialog --default-item "$i" --backtitle $"Freedombone User Control Panel" --title $"Remove yourself from a mailing list" --menu $"Select one of the following:" 24 50 17 ${W[@]} 3>&2 2>&1 1>&3)
  83. # shellcheck disable=SC2181
  84. if [ $? -eq 0 ]; then # Exit with OK
  85. if [ "${list_selected}" -ne "${i}" ]; then
  86. remove_list_name="${list_name[$((list_selected-1))]}"
  87. # find the line number where the list is defined
  88. line_number=0
  89. i=0
  90. while read -r line
  91. do
  92. if [[ "$line" == *"\\[${remove_list_name}\\]"* ]]; then
  93. line_number=${i}
  94. fi
  95. i=$((i+1))
  96. done < "/home/$USER/.procmailrc"
  97. if [ ${line_number} -eq 0 ]; then
  98. # no match was found
  99. return
  100. fi
  101. # recreate the file
  102. if [ -f "/home/${USER}/.procmailrc_new" ]; then
  103. rm "/home/${USER}/.procmailrc_new"
  104. fi
  105. i=0
  106. clip=0
  107. while read -r line
  108. do
  109. i=$((i+1))
  110. if [ ${i} -gt $((line_number-1)) ]; then
  111. if [ ${clip} -eq 0 ]; then
  112. clip=1
  113. fi
  114. if [ ${clip} -eq 1 ]; then
  115. if [ ${i} -lt $((line_number+2)) ]; then
  116. continue
  117. else
  118. if [ ${#line} -lt 1 ]; then
  119. clip=2
  120. continue
  121. fi
  122. if [[ "$line" == ":"* || "$line" == "#"* ]]; then
  123. clip=2
  124. else
  125. continue
  126. fi
  127. fi
  128. fi
  129. fi
  130. echo "$line" >> "/home/${USER}/.procmailrc_new"
  131. if [[ "$line" == *"\\[${remove_list_name}\\]"* ]]; then
  132. line_number=${i}
  133. fi
  134. done < "/home/$USER/.procmailrc"
  135. cp "/home/${USER}/.procmailrc_new" "/home/${USER}/.procmailrc"
  136. rm "/home/${USER}/.procmailrc_new"
  137. chown "${USER}":"${USER}" "/home/${USER}/.procmailrc"
  138. dialog --title $"Remove yourself from mailing list" \
  139. --msgbox $"You have been removed from ${remove_list_name}" 6 50
  140. fi
  141. fi
  142. }
  143. function add_to_mailing_list {
  144. data=$(mktemp 2>/dev/null)
  145. dialog --backtitle $"Freedombone User Control Panel" \
  146. --title $"Subscribe to a mailing list" \
  147. --form $"You can either enter a subject or an email address\\n" 11 68 4 \
  148. $"List folder name:" 1 1 "" 1 35 26 25 \
  149. $"Name between [] on subject line:" 2 1 "" 2 35 26 25 \
  150. $"List email address:" 3 1 "" 3 35 26 25 \
  151. $"Public:" 4 1 $"yes" 4 35 4 25 \
  152. 2> "$data"
  153. sel=$?
  154. case $sel in
  155. 1) rm -f "$data"
  156. return;;
  157. 255) rm -f "$data"
  158. return;;
  159. esac
  160. LIST_NAME=$(sed -n 1p < "$data")
  161. LIST_SUBJECT=$(sed -n 2p < "$data")
  162. LIST_EMAIL=$(sed -n 3p < "$data")
  163. LIST_PUBLIC=$(sed -n 4p < "$data")
  164. if [ ${#LIST_PUBLIC} -lt 1 ]; then
  165. LIST_PUBLIC='no'
  166. fi
  167. if [[ $LIST_PUBLIC == $'y' || $LIST_PUBLIC == $'Y' || $LIST_PUBLIC == $'true' || $LIST_PUBLIC == $'True' || $LIST_PUBLIC == $'yes' || $LIST_PUBLIC == $'Yes' || $LIST_PUBLIC == $'YES' ]]; then
  168. LIST_PUBLIC='yes'
  169. else
  170. LIST_PUBLIC='no'
  171. fi
  172. if [ ${#LIST_NAME} -lt 2 ]; then
  173. dialog --title $"Add mailing list" \
  174. --msgbox $"No mailing list name was given" 6 40
  175. rm -f "$data"
  176. return
  177. fi
  178. if [ ${#LIST_SUBJECT} -lt 2 ]; then
  179. if [ ${#LIST_EMAIL} -lt 2 ]; then
  180. dialog --title $"Add mailing list" \
  181. --msgbox $"No mailing list subject or address was given" 6 40
  182. rm -f "$data"
  183. return
  184. fi
  185. fi
  186. if [ ${#LIST_SUBJECT} -gt 1 ]; then
  187. "${PROJECT_NAME}-addlist" -u "$USER" -l "$LIST_NAME" \
  188. -s "$LIST_SUBJECT" --public "$LIST_PUBLIC"
  189. else
  190. if [[ "$LIST_EMAIL" != *"@"* || "$LIST_EMAIL" != *"."* ]]; then
  191. dialog --title $"Add mailing list" \
  192. --msgbox $"Unrecognised email address" 6 40
  193. rm -f "$data"
  194. return
  195. else
  196. "${PROJECT_NAME}-addlist" -u "$USER" -l "$LIST_NAME" \
  197. -e "$LIST_EMAIL" --public "$LIST_PUBLIC"
  198. fi
  199. fi
  200. dialog --title $"Add mailing list" \
  201. --msgbox $"$LIST_NAME list was added" 6 40
  202. rm -f "$data"
  203. }
  204. function email_rule_address {
  205. data=$(mktemp 2>/dev/null)
  206. dialog --backtitle $"Freedombone User Control Panel" \
  207. --title $"Create an email rule" \
  208. --form "\\n" 9 65 4 \
  209. $"When email arrives from address:" 1 1 "" 1 35 24 28 \
  210. $"Move to folder:" 2 1 "" 2 35 24 28 \
  211. $"Public:" 3 1 $"no" 3 35 4 25 \
  212. 2> "$data"
  213. sel=$?
  214. case $sel in
  215. 1) rm -f "$data"
  216. return;;
  217. 255) rm -f "$data"
  218. return;;
  219. esac
  220. RULE_EMAIL=$(sed -n 1p < "$data")
  221. RULE_FOLDER=$(sed -n 2p < "$data")
  222. RULE_PUBLIC=$(sed -n 3p < "$data")
  223. if [ ${#RULE_PUBLIC} -lt 1 ]; then
  224. RULE_PUBLIC='no'
  225. fi
  226. if [[ $RULE_PUBLIC == $'y' || $RULE_PUBLIC == $'Y' || $RULE_PUBLIC == $'true' || $RULE_PUBLIC == $'True' || $RULE_PUBLIC == $'yes' || $RULE_PUBLIC == $'Yes' || $RULE_PUBLIC == $'YES' ]]; then
  227. RULE_PUBLIC='yes'
  228. else
  229. RULE_PUBLIC='no'
  230. fi
  231. if [ ${#RULE_EMAIL} -lt 2 ]; then
  232. dialog --title $"Create an email rule" \
  233. --msgbox $"No email address was given" 6 40
  234. rm -f "$data"
  235. return
  236. fi
  237. if [ ${#RULE_FOLDER} -lt 2 ]; then
  238. dialog --title $"Create an email rule" \
  239. --msgbox $"No folder name was given" 6 40
  240. rm -f "$data"
  241. return
  242. fi
  243. if [[ "$RULE_EMAIL" != *"@"* || "$RULE_EMAIL" != *"."* ]]; then
  244. dialog --title $"Create an email rule" \
  245. --msgbox $"Unrecognised email address" 6 40
  246. rm -f "$data"
  247. return
  248. fi
  249. "${PROJECT_NAME}-addemail" -u "$USER" -e "$RULE_EMAIL" \
  250. -g "$RULE_FOLDER" --public $RULE_PUBLIC
  251. dialog --title $"Create an email rule" \
  252. --msgbox $"Email rule for $RULE_EMAIL was added" 6 40
  253. rm -f "$data"
  254. }
  255. function gpg_set_trust {
  256. TRUST_ADDRESS=$1
  257. fpr=$(gpg --with-colons --fingerprint "$TRUST_ADDRESS" | grep fpr | head -n 1 | awk -F ':' '{print $10}')
  258. if [ ${#fpr} -gt 2 ]; then
  259. W=(1 $"I don't know or won't say"
  260. 2 $"I do NOT trust"
  261. 3 $"I trust marginally"
  262. 4 $"I trust fully"
  263. 5 $"I trust ultimately")
  264. # shellcheck disable=SC2068
  265. TRUST_LEVEL=$(dialog --backtitle $"Freedombone User Control Panel" --title $"Trust a PGP/GPG key or website domain" --menu $"Set the trust level for $TRUST_ADDRESS:" 18 70 10 "${W[@]}" 3>&2 2>&1 1>&3)
  266. if [ ! "$TRUST_LEVEL" ]; then
  267. return;
  268. fi
  269. if echo -e "trust\\n${TRUST_LEVEL}\\ny\\nsave\\n" | gpg --command-fd 0 --edit-key "$fpr"; then
  270. gpg --update-trustdb
  271. dialog --title $"Trust a PGP/GPG key or website domain" \
  272. --backtitle $"Freedombone User Control Panel" \
  273. --msgbox $"$TRUST_ADDRESS was set to trust level ${TRUST_LEVEL}" 6 50
  274. fi
  275. fi
  276. }
  277. function email_rule_subject {
  278. data=$(mktemp 2>/dev/null)
  279. dialog --backtitle $"Freedombone User Control Panel" \
  280. --title $"Create an email rule" \
  281. --form "\\n" 9 75 4 \
  282. $"When email arrives with subject containing:" 1 1 "" 1 45 24 28 \
  283. $"Move to folder:" 2 1 "" 2 45 24 28 \
  284. $"Public:" 3 1 $"no" 3 45 4 25 \
  285. 2> "$data"
  286. sel=$?
  287. case $sel in
  288. 1) rm -f "$data"
  289. return;;
  290. 255) rm -f "$data"
  291. return;;
  292. esac
  293. RULE_SUBJECT=$(sed -n 1p < "$data")
  294. RULE_FOLDER=$(sed -n 2p < "$data")
  295. RULE_PUBLIC=$(sed -n 3p < "$data")
  296. if [ ${#RULE_PUBLIC} -lt 1 ]; then
  297. RULE_PUBLIC='no'
  298. fi
  299. if [[ $RULE_PUBLIC == $'y' || $RULE_PUBLIC == $'Y' || $RULE_PUBLIC == $'true' || $RULE_PUBLIC == $'True' || $RULE_PUBLIC == $'yes' || $RULE_PUBLIC == $'Yes' || $RULE_PUBLIC == $'YES' ]]; then
  300. RULE_PUBLIC='yes'
  301. else
  302. RULE_PUBLIC='no'
  303. fi
  304. if [ ${#RULE_SUBJECT} -lt 2 ]; then
  305. dialog --title $"Create an email rule" \
  306. --msgbox $"No subject text was given" 6 40
  307. rm -f "$data"
  308. return
  309. fi
  310. if [ ${#RULE_FOLDER} -lt 2 ]; then
  311. dialog --title $"Create an email rule" \
  312. --msgbox $"No folder name was given" 6 40
  313. rm -f "$data"
  314. return
  315. fi
  316. "${PROJECT_NAME}-addemail" -u "$USER" -s "$RULE_SUBJECT" \
  317. -g "$RULE_FOLDER" --public "$RULE_PUBLIC"
  318. dialog --title $"Create an email rule" \
  319. --msgbox $"Email rule for subject '$RULE_SUBJECT' was added" 6 40
  320. rm -f "$data"
  321. }
  322. function block_unblock_email {
  323. blockstr=$"Block or unblock emails from a given address"
  324. data=$(mktemp 2>/dev/null)
  325. dialog --backtitle $"Freedombone User Control Panel" \
  326. --title "$blockstr" \
  327. --form "\\n" 8 65 3 \
  328. $"When email arrives from address:" 1 1 "" 1 35 24 100 \
  329. $"Block it:" 2 1 "yes" 2 35 4 4 \
  330. 2> "$data"
  331. sel=$?
  332. case $sel in
  333. 1) rm -f "$data"
  334. return;;
  335. 255) rm -f "$data"
  336. return;;
  337. esac
  338. BLOCK_EMAIL=$(sed -n 1p < "$data")
  339. BLOCK=$(sed -n 2p < "$data")
  340. if [ ${#BLOCK_EMAIL} -lt 2 ]; then
  341. dialog --title "$blockstr" \
  342. --msgbox $"No email address was given" 6 40
  343. return
  344. fi
  345. if [[ "$BLOCK_EMAIL" != *"@"* || "$BLOCK_EMAIL" != *"."* ]]; then
  346. dialog --title "$blockstr" \
  347. --msgbox $"Unrecognised email address" 6 40
  348. rm -f "$data"
  349. return
  350. fi
  351. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  352. "${PROJECT_NAME}-ignore" -u "$USER" -e "$BLOCK_EMAIL"
  353. dialog --title $"Block an email" \
  354. --msgbox "Email from $BLOCK_EMAIL is now blocked" 6 75
  355. else
  356. "${PROJECT_NAME}-unignore" -u "$USER" -e "$BLOCK_EMAIL"
  357. dialog --title $"Unblock an email" \
  358. --msgbox "Email from $BLOCK_EMAIL is now unblocked" 6 75
  359. fi
  360. rm -f "$data"
  361. }
  362. function block_unblock_subject {
  363. blockstr=$"Block or unblock emails with text in the subject line"
  364. data=$(mktemp 2>/dev/null)
  365. dialog --backtitle $"Freedombone User Control Panel" \
  366. --title "$blockstr" \
  367. --form "\\n" 8 70 3 \
  368. $"When email arrives with subject text:" 1 1 "" 1 40 24 28 \
  369. $"Block it:" 2 1 "yes" 2 40 4 4 \
  370. 2> "$data"
  371. sel=$?
  372. case $sel in
  373. 1) rm -f "$data"
  374. return;;
  375. 255) rm -f "$data"
  376. return;;
  377. esac
  378. BLOCK_SUBJECT=$(sed -n 1p < "$data")
  379. BLOCK=$(sed -n 2p < "$data")
  380. if [ ${#BLOCK_SUBJECT} -lt 2 ]; then
  381. dialog --title "$blockstr" \
  382. --msgbox $"No subject was given" 6 40
  383. rm -f "$data"
  384. return
  385. fi
  386. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  387. "${PROJECT_NAME}-ignore" -u "$USER" -t "$BLOCK_SUBJECT"
  388. dialog --title $"Block an email" \
  389. --msgbox $"Email with subject $BLOCK_SUBJECT is now blocked" 6 40
  390. else
  391. "${PROJECT_NAME}-unignore" -u "$USER" -t "$BLOCK_SUBJECT"
  392. dialog --title $"Unblock an email" \
  393. --msgbox $"Email with subject $BLOCK_SUBJECT is now unblocked" 6 40
  394. fi
  395. rm -f "$data"
  396. }
  397. function show_gpg_key {
  398. GPG_FINGERPRINT=$(gpg --fingerprint "$GPG_ID" | sed -n '2p' | sed 's/^[ \t]*//')
  399. GPG_DATE=$(gpg --fingerprint "$GPG_ID" | grep -i "pub" | head -n 1 | awk -F ' ' '{print $3}')
  400. dialog --title $"My PGP/GPG Key" \
  401. --backtitle $"Freedombone User Control Panel" \
  402. --msgbox $"Email Address: $MY_EMAIL_ADDRESS\\n\\nKey ID: $GPG_ID\\n\\nFingerprint: $GPG_FINGERPRINT\\n\\nCreated: $GPG_DATE" 12 70
  403. }
  404. function show_full_gpg_key {
  405. clear
  406. echo ''
  407. echo ''
  408. echo ''
  409. gpg --armor --export "$GPG_ID"
  410. echo ''
  411. echo ''
  412. echo ''
  413. gpg --armor --export-secret-key "$GPG_ID"
  414. any_key
  415. }
  416. function publish_gpg_key {
  417. gpg --send-key "$GPG_ID"
  418. if [ "$GPG_BACKUP_ID" ]; then
  419. gpg --send-key "$GPG_BACKUP_ID"
  420. fi
  421. dialog --title $"Publish your PGP/GPG key" \
  422. --msgbox $"Your key has now been published" 6 40
  423. }
  424. function refresh_gpg_keys {
  425. gpg --refresh-keys
  426. dialog --title $"Refresh PGP/GPG keys" \
  427. --msgbox $"Your keys have been refreshed" 6 40
  428. }
  429. function add_gpg_key {
  430. data=$(mktemp 2>/dev/null)
  431. dialog --title $"Enter email address, Key ID or full key below" \
  432. --backtitle $"Freedombone User Control Panel" \
  433. --editbox "$data" 8 60
  434. sel=$?
  435. case $sel in
  436. 0)
  437. ADD_EMAIL_ADDRESS=$(<"$data")
  438. if [ ${#ADD_EMAIL_ADDRESS} -gt 2 ]; then
  439. address_is_valid=
  440. if [[ "$ADD_EMAIL_ADDRESS" == *"@"* && "$ADD_EMAIL_ADDRESS" == *"."* ]]; then
  441. address_is_valid=1
  442. fi
  443. if [[ "$ADD_EMAIL_ADDRESS" == "0x"* ]]; then
  444. address_is_valid=1
  445. fi
  446. publicstr=$"BEGIN PGP PUBLIC KEY BLOCK"
  447. if [[ "$ADD_EMAIL_ADDRESS" == *"$publicstr"* ]]; then
  448. address_is_valid=1
  449. fi
  450. if [ $address_is_valid ]; then
  451. clear
  452. if [[ "$ADD_EMAIL_ADDRESS" == *"$publicstr"* ]]; then
  453. echo "$ADD_EMAIL_ADDRESS" | gpg --import
  454. dialog --title $"Add someone's PGP/GPG key" \
  455. --backtitle $"Freedombone User Control Panel" \
  456. --msgbox $"GPG public key was imported" 6 50
  457. else
  458. gpg --search-keys "$ADD_EMAIL_ADDRESS"
  459. gpg_set_trust "$ADD_EMAIL_ADDRESS"
  460. fi
  461. else
  462. dialog --title $"Unrecognised email address" \
  463. --backtitle $"Freedombone User Control Panel" \
  464. --msgbox $"This doesn't look like an email address or key ID" 6 50
  465. fi
  466. fi
  467. ;;
  468. esac
  469. rm "$data"
  470. }
  471. function remove_gpg_key {
  472. data=$(mktemp 2>/dev/null)
  473. dialog --title $"Remove someone's PGP/GPG key" \
  474. --backtitle $"Freedombone User Control Panel" \
  475. --inputbox $"Enter their email address or key ID below" 8 60 2>"$data"
  476. sel=$?
  477. case $sel in
  478. 0)
  479. REMOVE_EMAIL_ADDRESS=$(<"$data")
  480. if [ ${#REMOVE_EMAIL_ADDRESS} -gt 2 ]; then
  481. if [[ $REMOVE_EMAIL_ADDRESS == *"@"* && $REMOVE_EMAIL_ADDRESS == *"."* ]]; then
  482. if [[ "$REMOVE_EMAIL_ADDRESS" != "$MY_EMAIL_ADDRESS" ]]; then
  483. clear
  484. gpg --delete-key "$REMOVE_EMAIL_ADDRESS"
  485. else
  486. dialog --title $"Remove someone's PGP/GPG key" \
  487. --backtitle $"Freedombone User Control Panel" \
  488. --msgbox $"It's not a good idea to remove your own encryption key" 6 65
  489. fi
  490. else
  491. if [[ $REMOVE_EMAIL_ADDRESS == "0x"* ]]; then
  492. clear
  493. gpg --delete-key "$REMOVE_EMAIL_ADDRESS"
  494. else
  495. dialog --title $"Unrecognised email address" \
  496. --backtitle $"Freedombone User Control Panel" \
  497. --msgbox $"This doesn't look like an email address" 6 50
  498. fi
  499. fi
  500. fi
  501. ;;
  502. esac
  503. rm -f "$data"
  504. }
  505. function add_ssh_key {
  506. data=$(mktemp 2>/dev/null)
  507. dialog --title $"Add an ssh key for logging in" \
  508. --backtitle $"Freedombone User Control Panel" \
  509. --inputbox $"This will allow you to log into ${PROJECT_NAME} if you have an ssh key on your system, and provides much stronger security than simply using a login password.\\n\\nWARNING: If you make any mistakes here then you may not be able to log in and will need to get the administrator to clear your ssh authorized_keys file." 15 60 2>"$data"
  510. sel=$?
  511. case $sel in
  512. 0)
  513. SSH_PUBLIC_KEY=$(<"$data")
  514. if [ ${#SSH_PUBLIC_KEY} -gt 20 ]; then
  515. if [[ "$SSH_PUBLIC_KEY" == "ssh-"* ]]; then
  516. if [ ! -d "/home/$USER/.ssh" ]; then
  517. mkdir "/home/$USER/.ssh"
  518. fi
  519. if [ ! -f "/home/$USER/.ssh/authorized_keys" ]; then
  520. touch "/home/$USER/.ssh/authorized_keys"
  521. fi
  522. if ! grep -q "$SSH_PUBLIC_KEY" "/home/$USER/.ssh/authorized_keys"; then
  523. echo "$SSH_PUBLIC_KEY" >> "/home/$USER/.ssh/authorized_keys"
  524. dialog --title $"New ssh key added" \
  525. --backtitle $"Freedombone User Control Panel" \
  526. --msgbox $"Your ssh key has now been added" 6 50
  527. else
  528. dialog --title $"ssh key already added" \
  529. --backtitle $"Freedombone User Control Panel" \
  530. --msgbox $"That ssh key has already been added" 6 50
  531. fi
  532. else
  533. dialog --title $"Unrecognised ssh public key" \
  534. --backtitle $"Freedombone User Control Panel" \
  535. --msgbox $"This doesn't look like an ssh key" 6 50
  536. fi
  537. fi
  538. ;;
  539. esac
  540. rm -f "$data"
  541. }
  542. function remove_ssh_key {
  543. data=$(mktemp 2>/dev/null)
  544. dialog --title $"Remove an ssh key for logging in" \
  545. --backtitle $"Freedombone User Control Panel" \
  546. --inputbox $"Enter the ssh public key which is to be removed. This can be just the address at the end.\\n\\nWARNING: If you make any mistakes here then you may not be able to log in and will need to get the administrator to clear your ssh authorized_keys file." 15 60 2>"$data"
  547. sel=$?
  548. case $sel in
  549. 0)
  550. SSH_PUBLIC_KEY=$(<"$data")
  551. if [ ${#SSH_PUBLIC_KEY} -gt 5 ]; then
  552. if [ -f "/home/$USER/.ssh/authorized_keys" ]; then
  553. sed -i "s|.*${SSH_PUBLIC_KEY}.*||g" "/home/$USER/.ssh/authorized_keys"
  554. dialog --title $"Remove an ssh public key" \
  555. --backtitle $"Freedombone User Control Panel" \
  556. --msgbox $"The ssh key has been removed" 6 50
  557. fi
  558. fi
  559. ;;
  560. esac
  561. rm -f "$data"
  562. }
  563. function smtp_proxy {
  564. MUTTRC_FILE=/home/$USER/.muttrc
  565. if [ ! -f "$MUTTRC_FILE" ]; then
  566. return
  567. fi
  568. SMTP_PROXY_ENABLE=$'no'
  569. SMTP_PROXY_PROTOCOL='smtps'
  570. SMTP_PROXY_SERVER='mail.myispdomain'
  571. SMTP_PROXY_PORT=465
  572. SMTP_PROXY_USERNAME=''
  573. SMTP_PROXY_PASSWORD=''
  574. if grep -q "set smtp_url" "$MUTTRC_FILE"; then
  575. if grep -q "#set smtp_url" "$MUTTRC_FILE"; then
  576. SMTP_PROXY_ENABLE=$'no'
  577. else
  578. SMTP_PROXY_ENABLE=$'yes'
  579. fi
  580. SMTP_PROXY_PROTOCOL=$(grep "set smtp_url" "$MUTTRC_FILE" | awk -F '"' '{print $2}' | awk -F ':' '{print $1}')
  581. SMTP_PROXY_SERVER=$(grep "set smtp_url" "$MUTTRC_FILE" | awk -F '"' '{print $2}' | awk -F '/' '{print $3}' | awk -F ':' '{print $2}' | awk -F '@' '{print $2}')
  582. SMTP_PROXY_PORT=$(grep "set smtp_url" "$MUTTRC_FILE" | awk -F ':' '{print $4}' | awk -F '/' '{print $1}')
  583. SMTP_PROXY_USERNAME=$(grep "set smtp_url" "$MUTTRC_FILE" | awk -F '"' '{print $2}' | awk -F '/' '{print $3}' | awk -F ':' '{print $1}')
  584. SMTP_PROXY_PASSWORD=$(grep "set smtp_url" "$MUTTRC_FILE" | awk -F '"' '{print $2}' | awk -F '/' '{print $3}' | awk -F ':' '{print $2}' | awk -F '@' '{print $1}')
  585. fi
  586. data=$(mktemp 2>/dev/null)
  587. dialog --backtitle $"Freedombone Control Panel" \
  588. --title $"SMTP Proxy for $USER" \
  589. --form $"You may need to proxy outgoing email via your ISP's mail server. If so enter the details below." 14 75 6 \
  590. $"Enable proxy:" 1 1 "$SMTP_PROXY_ENABLE" 1 24 5 5 \
  591. $"Protocol (smtp/smtps):" 2 1 "$SMTP_PROXY_PROTOCOL" 2 24 5 5 \
  592. $"ISP mail server:" 3 1 "$SMTP_PROXY_SERVER" 3 24 40 10000 \
  593. $"Port:" 4 1 "$SMTP_PROXY_PORT" 4 24 5 5 \
  594. $"Username:" 5 1 "$SMTP_PROXY_USERNAME" 5 24 40 10000 \
  595. $"Password:" 6 1 "$SMTP_PROXY_PASSWORD" 6 24 40 10000 \
  596. 2> "$data"
  597. sel=$?
  598. case $sel in
  599. 1) rm -f "$data"
  600. return;;
  601. 255) rm -f "$data"
  602. return;;
  603. esac
  604. SMTP_PROXY_ENABLE=$(sed -n 1p < "$data")
  605. SMTP_PROXY_PROTOCOL=$(sed -n 2p < "$data")
  606. SMTP_PROXY_SERVER=$(sed -n 3p < "$data")
  607. SMTP_PROXY_PORT=$(sed -n 4p < "$data")
  608. SMTP_PROXY_USERNAME=$(sed -n 5p < "$data")
  609. SMTP_PROXY_PASSWORD=$(sed -n 6p < "$data")
  610. # change muttrc
  611. if [ "$SMTP_PROXY_ENABLE" != $'no' ]; then
  612. if ! grep -q "set smtp_url" "$MUTTRC_FILE"; then
  613. echo "set smtp_url=\"${SMTP_PROXY_PROTOCOL}://${SMTP_PROXY_USERNAME}:${SMTP_PROXY_PASSWORD}@${SMTP_PROXY_SERVER}:${SMTP_PROXY_PORT}/\"" >> "$MUTTRC_FILE"
  614. else
  615. sed -i "s|set smtp_url=.*|set smtp_url=\"${SMTP_PROXY_PROTOCOL}://${SMTP_PROXY_USERNAME}:${SMTP_PROXY_PASSWORD}@${SMTP_PROXY_SERVER}:${SMTP_PROXY_PORT}/\"|g" "$MUTTRC_FILE"
  616. fi
  617. sed -i 's|#set smtp_url|set smtp_url|g' "$MUTTRC_FILE"
  618. else
  619. if grep -q "set smtp_url" "$MUTTRC_FILE"; then
  620. sed -i 's|set smtp_url|#set smtp_url|g' "$MUTTRC_FILE"
  621. fi
  622. fi
  623. rm -f "$data"
  624. }
  625. function sign_gpg_key {
  626. data=$(mktemp 2>/dev/null)
  627. dialog --title $"Sign a PGP/GPG key or website domain" \
  628. --backtitle $"Freedombone User Control Panel" \
  629. --inputbox $"Enter the Key ID, address or domain to be signed.\\n\\nIf you are signing a website domain then include the https:// at the beginning.\\n\\nIf you are signing an ssh key then include ssh:// before the domain name." 14 75 2>"$data"
  630. sel=$?
  631. case $sel in
  632. 0)
  633. SIGN_ADDRESS=$(<"$data")
  634. if [ ${#SIGN_ADDRESS} -gt 2 ]; then
  635. clear
  636. gpg --search "$SIGN_ADDRESS"
  637. fpr=$(gpg --with-colons --fingerprint "$SIGN_ADDRESS" | grep fpr | head -n 1 | awk -F ':' '{print $10}')
  638. if [ ${#fpr} -gt 2 ]; then
  639. if gpg --sign-key "$fpr"; then
  640. gpg --update-trustdb
  641. dialog --title $"Sign a PGP/GPG key" \
  642. --backtitle $"Freedombone User Control Panel" \
  643. --msgbox $"$SIGN_ADDRESS was signed" 6 50
  644. fi
  645. fi
  646. fi
  647. ;;
  648. esac
  649. rm -f "$data"
  650. }
  651. function gpg_key_trust {
  652. data=$(mktemp 2>/dev/null)
  653. dialog --title $"Trust a PGP/GPG key or website domain" \
  654. --backtitle $"Freedombone User Control Panel" \
  655. --inputbox $"Enter the Key ID, address or domain to be trusted.\\n\\nIf you are trusting a website domain then include the https:// at the beginning.\\n\\nIf you are trusting an ssh key then include ssh:// before the domain name." 14 75 2>"$data"
  656. sel=$?
  657. case $sel in
  658. 0)
  659. TRUST_ADDRESS=$(<"$data")
  660. if [ ${#TRUST_ADDRESS} -gt 2 ]; then
  661. clear
  662. gpg --search "$TRUST_ADDRESS"
  663. gpg_set_trust "$TRUST_ADDRESS"
  664. fi
  665. ;;
  666. esac
  667. rm -f "$data"
  668. }
  669. function menu_encryption_keys {
  670. while true
  671. do
  672. W=(1 $"Show your PGP/GPG key"
  673. 2 $"Show your full PGP/GPG key, including private key"
  674. 3 $"Publish your PGP/GPG key so that others can find it"
  675. 4 $"Add someone's PGP/GPG key"
  676. 5 $"Remove someone's PGP/GPG key"
  677. 6 $"Sign a PGP/GPG key or website domain"
  678. 7 $"Refresh your PGP/GPG keys"
  679. 8 $"Add an ssh key for logging in"
  680. 9 $"Remove an ssh key for logging in"
  681. 10 $"Set the trust level for a PGP/GPG key")
  682. # shellcheck disable=SC2068
  683. selection=$(dialog --backtitle $"Freedombone User Control Panel" --title $"My Encryption Keys" --menu $"Choose an operation, or ESC for main menu:" 19 70 11 "${W[@]}" 3>&2 2>&1 1>&3)
  684. if [ ! "$selection" ]; then
  685. break
  686. fi
  687. case $selection in
  688. 1) show_gpg_key;;
  689. 2) show_full_gpg_key;;
  690. 3) publish_gpg_key;;
  691. 4) add_gpg_key;;
  692. 5) remove_gpg_key;;
  693. 6) sign_gpg_key;;
  694. 7) refresh_gpg_keys;;
  695. 8) add_ssh_key;;
  696. 9) remove_ssh_key;;
  697. 10) gpg_key_trust;;
  698. esac
  699. done
  700. }
  701. function menu_email {
  702. while true
  703. do
  704. W=(1 $"Add yourself to a mailing list"
  705. 2 $"Remove yourself from a mailing list"
  706. 3 $"Add an email rule for an address"
  707. 4 $"Add an email rule for a subject"
  708. 5 $"Block or unblock an email address"
  709. 6 $"Block or unblock email with subject text")
  710. # shellcheck disable=SC2068
  711. selection=$(dialog --backtitle $"Freedombone User Control Panel" --title $"Change Email Filtering Rules" --menu $"Choose an operation, or ESC for main menu:" 14 70 7 "${W[@]}" 3>&2 2>&1 1>&3)
  712. if [ ! "$selection" ]; then
  713. break
  714. fi
  715. case $selection in
  716. 1) add_to_mailing_list;;
  717. 2) remove_user_from_mailing_list;;
  718. 3) email_rule_address;;
  719. 4) email_rule_subject;;
  720. 5) block_unblock_email;;
  721. 6) block_unblock_subject;;
  722. esac
  723. done
  724. }
  725. function menu_admin {
  726. if [ ! -f /etc/sudoers ]; then
  727. clear
  728. exit 0
  729. fi
  730. sudo /usr/local/bin/control
  731. }
  732. function sign_keys {
  733. if [ ! -f "/home/$USER/.monkeysphere/server_keys" ]; then
  734. return
  735. fi
  736. dialog --title $"Monkeysphere sign server keys" \
  737. --backtitle $"Freedombone Security Configuration" \
  738. --defaultno \
  739. --yesno $"\\nMonkeysphere has been enabled and you will need to sign and trust the server keys. Do you want to do that now?" 8 60
  740. sel=$?
  741. case $sel in
  742. 0) "${PROJECT_NAME}-sec" --sign yes;;
  743. esac
  744. }
  745. function menu_run_client_app {
  746. detect_installable_apps
  747. applist=""
  748. appnames=()
  749. n=1
  750. app_index=0
  751. # shellcheck disable=SC2068
  752. for a in ${APPS_AVAILABLE[@]}
  753. do
  754. if [[ ${APPS_INSTALLED[$app_index]} != "0" ]]; then
  755. if [[ $(function_exists "run_client_${a}") == "1" ]]; then
  756. applist="$applist $n $a off"
  757. n=$((n+1))
  758. appnames+=("$a")
  759. fi
  760. fi
  761. app_index=$((app_index+1))
  762. done
  763. if [ $n -le 1 ]; then
  764. return
  765. fi
  766. backstr=$'Exit'
  767. applist="$applist $n $backstr on"
  768. appnames+=("Exit")
  769. # shellcheck disable=SC2086
  770. choice=$(dialog --stdout --backtitle $"Freedombone" \
  771. --title $"Run an App" \
  772. --radiolist $'Choose:' \
  773. 16 40 20 $applist)
  774. # shellcheck disable=SC2181
  775. if [ $? -eq 0 ]; then
  776. app_index=$((choice-1))
  777. chosen_app=${appnames[$app_index]}
  778. if [[ $chosen_app != "Exit" ]]; then
  779. "run_client_${chosen_app}"
  780. fi
  781. fi
  782. }
  783. function show_your_email_address {
  784. GPG_FINGERPRINT=$(gpg --fingerprint "$GPG_ID" | sed -n '2p' | sed 's/^[ \t]*//')
  785. GPG_DATE=$(gpg --fingerprint "$GPG_ID" | grep -i "pub" | head -n 1 | awk -F ' ' '{print $3}')
  786. onion_domain=
  787. if [ -f "$HOME/.email_onion_domain" ]; then
  788. onion_domain=$(cat "$HOME/.email_onion_domain")
  789. fi
  790. dialog_height=14
  791. onionemailstr=
  792. if [[ "$HOSTNAME" != *'.onion' && "$onion_domain" ]]; then
  793. onionemailstr="\\n\\nOnion Email: ${USER}@${onion_domain}"
  794. dialog_height=$((dialog_height+3))
  795. fi
  796. msgstrbase=$"\\nYou can press SHIFT and then drag the mouse and right click to copy.\\n\\nEmail Address: ${MY_EMAIL_ADDRESS}${onionemailstr}\\n\\nKey ID: ${GPG_ID}\\n\\nFingerprint: ${GPG_FINGERPRINT}\\n\\nCreated: ${GPG_DATE}"
  797. bdsmail_address=
  798. bdsmailstr=
  799. if [ ! -f ~/.mutt/bdsmail ]; then
  800. bdsmail_address=$(grep 'set from=' ~/.mutt/bdsmail | awk -F '=' '{print $2}')
  801. bdsmailstr="\\n\\nI2P Address: ${bdsmail_address}"
  802. dialog_height=$((dialog_height+3))
  803. fi
  804. dialog --title $"Show your Email Address" \
  805. --backtitle $"Freedombone User Control Panel" \
  806. --msgbox "${msgstrbase}${bdsmailstr}" $dialog_height 100
  807. clear
  808. qr_code_shown=
  809. if [ "$onion_domain" ]; then
  810. echo ''
  811. echo $'Your onion email address:'
  812. echo ''
  813. echo -n "${USER}@${onion_domain}" | qrencode -t UTF8
  814. echo ''
  815. qr_code_shown=1
  816. fi
  817. if [ -f ~/.mutt/bdsmail ]; then
  818. echo ''
  819. echo $'Your bdsmail address:'
  820. echo ''
  821. echo -n "${bdsmail_address}" | qrencode -t UTF8
  822. echo ''
  823. qr_code_shown=1
  824. fi
  825. if [ $qr_code_shown ]; then
  826. any_key
  827. fi
  828. }
  829. function menu_top_level {
  830. while true
  831. do
  832. W=(1 $"Use Email"
  833. 2 $"Show your Email Address"
  834. 3 $"Change Email Filtering/Blocking Rules"
  835. 4 $"Run an App"
  836. 5 $"Browse the Web"
  837. 6 $"My Encryption Keys"
  838. 7 $"Set an outgoing email proxy"
  839. 8 $"Administrator controls"
  840. 9 $"Exit to the command line")
  841. # shellcheck disable=SC2068
  842. selection=$(dialog --backtitle $"Freedombone User Control Panel" --title $"User Control Panel" --menu $"Choose an operation, or ESC to log out:" 20 60 13 "${W[@]}" 3>&2 2>&1 1>&3)
  843. if [ ! "$selection" ]; then
  844. kill -HUP "$(pgrep -s 0 -o)"
  845. fi
  846. case $selection in
  847. 1) mutt;;
  848. 2) show_your_email_address;;
  849. 3) menu_email;;
  850. 4) menu_run_client_app;;
  851. 5) torify elinks -no-home;;
  852. 6) menu_encryption_keys;;
  853. 7) smtp_proxy;;
  854. 8) menu_admin;;
  855. 9) break;;
  856. esac
  857. done
  858. }
  859. sign_keys
  860. gpg_agent_enable "$USER"
  861. menu_top_level
  862. clear
  863. # shellcheck disable=SC1090
  864. . ~/.bashrc
  865. cat /etc/motd
  866. echo -e $'Type "sudo su" for root access, or "control" to restart\nthe control panel.'
  867. echo ''
  868. exit 0