freedombone-controlpanel-user 30KB

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