freedombone-controlpanel-user 33KB

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