freedombone-controlpanel 50KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  1. #!/bin/bash
  2. #
  3. # .---. . .
  4. # | | |
  5. # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
  6. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
  7. # ' ' --' --' -' - -' ' ' -' -' -' ' - --'
  8. #
  9. # Freedom in the Cloud
  10. #
  11. # Administrator control panel for the Freedombone system
  12. #
  13. # License
  14. # =======
  15. #
  16. # Copyright (C) 2015-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 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 General Public License for more details.
  27. #
  28. # You should have received a copy of the GNU 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
  32. export TEXTDOMAINDIR="/usr/share/locale"
  33. COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt
  34. SELECTED_USERNAME=
  35. SIP_CONFIG_FILE=/etc/sipwitch.conf
  36. ADMIN_USER=
  37. UPGRADE_SCRIPT_NAME="${PROJECT_NAME}-upgrade"
  38. UPDATE_DATE_SCRIPT=/usr/bin/updatedate
  39. # Minimum number of characters in a password
  40. MINIMUM_PASSWORD_LENGTH=8
  41. USB_DRIVE=sdb
  42. # get default USB from config file
  43. CONFIG_FILE=$HOME/${PROJECT_NAME}.cfg
  44. if [ -f $CONFIG_FILE ]; then
  45. if grep -q "USB_DRIVE=" $CONFIG_FILE; then
  46. USB_DRIVE=$(cat $CONFIG_FILE | grep "USB_DRIVE=" | awk -F '=' '{print $2}')
  47. if [[ $USB_DRIVE == *"dev"* ]]; then
  48. USB_DRIVE=$(echo ${USB_DRIVE} | awk -F '/' '{print $3}' | sed 's|1||g' | sed 's|2||g')
  49. fi
  50. fi
  51. fi
  52. function any_key {
  53. echo ' '
  54. read -n1 -r -p $"Press any key to continue..." key
  55. }
  56. function check_for_updates {
  57. if [ ! -f /etc/cron.weekly/$UPGRADE_SCRIPT_NAME ]; then
  58. dialog --title $"Check for updates" \
  59. --msgbox $"Upgrade script was not found" 6 40
  60. return
  61. fi
  62. clear
  63. . /etc/cron.weekly/$UPGRADE_SCRIPT_NAME
  64. any_key
  65. }
  66. function add_user {
  67. data=$(tempfile 2>/dev/null)
  68. trap "rm -f $data" 0 1 2 5 15
  69. dialog --backtitle $"Freedombone Control Panel" \
  70. --title $"Add new user" \
  71. --form "\n" 8 40 3 \
  72. $"Username:" 1 1 "" 1 11 16 15 \
  73. $"ssh public key (optional):" 2 1 "" 3 1 40 10000 \
  74. 2> $data
  75. sel=$?
  76. case $sel in
  77. 1) return;;
  78. 255) return;;
  79. esac
  80. new_user_username=$(cat $data | sed -n 1p)
  81. new_user_ssh_public_key=$(cat $data | sed -n 2p)
  82. if [ ${#new_user_username} -lt 2 ]; then
  83. dialog --title $"New username" \
  84. --msgbox $"No username was given" 6 40
  85. return
  86. fi
  87. if [[ "$new_user_username" == *" "* ]]; then
  88. dialog --title $"Invalid username" \
  89. --msgbox $"The username should not contain any spaces" 6 40
  90. return
  91. fi
  92. if [ ${#new_user_ssh_public_key} -lt 20 ]; then
  93. clear
  94. ${PROJECT_NAME}-adduser "$new_user_username"
  95. any_key
  96. else
  97. if [[ "$new_user_ssh_public_key" == "ssh-"* ]]; then
  98. clear
  99. ${PROJECT_NAME}-adduser "$new_user_username" "$new_user_ssh_public_key"
  100. any_key
  101. else
  102. dialog --title $"ssh public key" \
  103. --msgbox $"This does not look like an ssh public key" 6 40
  104. fi
  105. fi
  106. }
  107. function pad_string {
  108. echo -n -e "$1" | sed -e :a -e 's/^.\{1,25\}$/& /;ta'
  109. }
  110. function show_domains {
  111. echo 'Domains'
  112. echo '======='
  113. echo ''
  114. echo -n -e "$(pad_string 'Name')"
  115. echo -n -e "$(pad_string 'ICANN')"
  116. echo -n -e "$(pad_string 'Tor')"
  117. echo ''
  118. echo '--------------------------------------------------------------------------'
  119. if grep -q "Email onion domain" $COMPLETION_FILE; then
  120. echo -n -e "$(pad_string 'Email')"
  121. echo -n -e "$(pad_string ' ')"
  122. echo "$(cat ${COMPLETION_FILE} | grep 'Email onion domain' | awk -F ':' '{print $2}')"
  123. fi
  124. if grep -q "Wiki domain" $COMPLETION_FILE; then
  125. echo -n -e "$(pad_string 'Wiki')"
  126. WIKIDOM=$(cat ${COMPLETION_FILE} | grep 'Wiki domain' | awk -F ':' '{print $2}')
  127. echo -n -e "$(pad_string ${WIKIDOM})"
  128. if [ -d /var/lib/tor/hidden_service_wiki ]; then
  129. echo -n "$(cat /var/lib/tor/hidden_service_wiki/hostname)"
  130. fi
  131. echo ''
  132. fi
  133. if grep -q "Hubzilla domain" $COMPLETION_FILE; then
  134. echo -n -e "$(pad_string 'Hubzilla')"
  135. HUBZILLADOM=$(cat ${COMPLETION_FILE} | grep 'Hubzilla domain' | awk -F ':' '{print $2}')
  136. echo -n -e "$(pad_string ${HUBZILLADOM})"
  137. if [ -d /var/lib/tor/hidden_service_hubzilla ]; then
  138. echo -n "$(cat /var/lib/tor/hidden_service_hubzilla/hostname)"
  139. fi
  140. echo ''
  141. fi
  142. if grep -q "Blog domain" $COMPLETION_FILE; then
  143. echo -n -e "$(pad_string 'Blog')"
  144. BLOGDOM=$(cat ${COMPLETION_FILE} | grep 'Blog domain' | awk -F ':' '{print $2}')
  145. echo -n -e "$(pad_string ${BLOGDOM})"
  146. if [ -d /var/lib/tor/hidden_service_blog ]; then
  147. echo -n "$(cat /var/lib/tor/hidden_service_blog/hostname)"
  148. fi
  149. echo ''
  150. fi
  151. if grep -q "GNU Social domain" $COMPLETION_FILE; then
  152. echo -n -e "$(pad_string 'GNU Social')"
  153. GNUSOCIALDOM=$(cat ${COMPLETION_FILE} | grep 'GNU Social domain' | awk -F ':' '{print $2}')
  154. echo -n -e "$(pad_string ${GNUSOCIALDOM})"
  155. if [ -d /var/lib/tor/hidden_service_microblog ]; then
  156. echo -n "$(cat /var/lib/tor/hidden_service_microblog/hostname)"
  157. fi
  158. echo ''
  159. fi
  160. if grep -q "Owncloud domain" $COMPLETION_FILE; then
  161. echo -n -e "$(pad_string 'Owncloud')"
  162. OWNCLOUDDOM=$(cat ${COMPLETION_FILE} | grep 'Owncloud domain' | awk -F ':' '{print $2}')
  163. echo -n -e "$(pad_string ${OWNCLOUDDOM})"
  164. if [ -d /var/lib/tor/hidden_service_owncloud ]; then
  165. echo -n "$(cat /var/lib/tor/hidden_service_owncloud/hostname)"
  166. fi
  167. echo ''
  168. fi
  169. if grep -q "Gogs domain" $COMPLETION_FILE; then
  170. echo -n -e "$(pad_string 'Gogs')"
  171. GOGSDOM=$(cat ${COMPLETION_FILE} | grep 'Gogs domain' | awk -F ':' '{print $2}')
  172. echo -n -e "$(pad_string ${GOGSDOM})"
  173. if [ -d /var/lib/tor/hidden_service_gogs ]; then
  174. echo -n "$(cat /var/lib/tor/hidden_service_gogs/hostname)"
  175. fi
  176. echo ''
  177. fi
  178. if grep -q "XMPP domain" $COMPLETION_FILE; then
  179. echo -n -e "$(pad_string 'XMPP')"
  180. XMPPDOM=$(cat ${COMPLETION_FILE} | grep 'XMPP domain' | awk -F ':' '{print $2}')
  181. echo -n -e "$(pad_string ${XMPPDOM})"
  182. if [ -d /var/lib/tor/hidden_service_xmpp ]; then
  183. echo -n "$(cat /var/lib/tor/hidden_service_xmpp/hostname)"
  184. fi
  185. echo ''
  186. fi
  187. echo ''
  188. }
  189. function show_users {
  190. echo 'Users'
  191. echo '====='
  192. echo ''
  193. echo -n -e "$(pad_string 'Name')"
  194. echo -n -e "$(pad_string 'SIP ext')"
  195. echo -n -e "$(pad_string 'Data')"
  196. echo ''
  197. echo '--------------------------------------------------------------------------'
  198. for d in /home/*/ ; do
  199. USRNAME=$(echo "$d" | awk -F '/' '{print $3}')
  200. if [[ $USRNAME != "git" ]]; then
  201. echo -n -e "$(pad_string ${USRNAME})"
  202. # get the SIP extension
  203. SIPEXT=
  204. while read ext; do
  205. if [[ $ext == *"user id"* ]]; then
  206. CURR_UID=$(echo "$ext" | awk -F '"' '{print $2}' | awk -F '"' '{print $1}')
  207. fi
  208. if [[ $ext == *"extension"* ]]; then
  209. if [[ $CURR_UID == $USRNAME ]]; then
  210. SIPEXT=$(echo "$ext" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')
  211. fi
  212. fi
  213. done < $SIP_CONFIG_FILE
  214. if [ $SIPEXT ]; then
  215. echo -n -e "$(pad_string SIP:${SIPEXT})"
  216. else
  217. echo -n -e "$(pad_string '')"
  218. fi
  219. # size of the home directory
  220. echo "$(du -s -h /home/${USRNAME} | awk -F ' ' '{print $1}')"
  221. fi
  222. done
  223. }
  224. function show_about {
  225. clear
  226. show_domains
  227. show_users
  228. any_key
  229. }
  230. function select_user {
  231. SELECTED_USERNAME=
  232. data=$(tempfile 2>/dev/null)
  233. trap "rm -f $data" 0 1 2 5 15
  234. dialog --title "Select a user" \
  235. --backtitle $"Freedombone Control Panel" \
  236. --dselect "/home/" 14 40 2> $data
  237. sel=$?
  238. case $sel in
  239. 0) SELECTED_USERNAME=$(cat $data | awk -F '/' '{print $3}');;
  240. 1) return;;
  241. 255) return;;
  242. esac
  243. if [ ${#SELECTED_USERNAME} -lt 2 ]; then
  244. SELECTED_USERNAME=
  245. fi
  246. if [ ! -d /home/$SELECTED_USERNAME ]; then
  247. dialog --title $"User directory check" \
  248. --msgbox $"This does not look like a user directory" 6 40
  249. SELECTED_USERNAME=
  250. fi
  251. }
  252. function delete_user {
  253. select_user
  254. if [ ! $SELECTED_USERNAME ]; then
  255. return
  256. fi
  257. if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then
  258. dialog --title $"Administrator user" \
  259. --msgbox $"You can't delete the administrator user" 6 40
  260. return
  261. fi
  262. clear
  263. ${PROJECT_NAME}-rmuser $SELECTED_USERNAME
  264. any_key
  265. }
  266. function configure_remote_backups {
  267. if ! grep -Fxq "Admin user:$ADMIN_USER" $COMPLETION_FILE; then
  268. dialog --title $"Administrator user" \
  269. --msgbox $"No Administrator user found. Check $COMPLETION_FILE" 6 40
  270. return
  271. fi
  272. if [ ${#ADMIN_USER} -lt 2 ]; then
  273. dialog --title $"Administrator user" \
  274. --msgbox $"Username not found" 6 40
  275. return
  276. fi
  277. if [ ! -d /home/$ADMIN_USER ]; then
  278. dialog --title $"Administrator user" \
  279. --msgbox $"Home directory not found" 6 40
  280. return
  281. fi
  282. ${PROJECT_NAME}-remote -u $ADMIN_USER
  283. if [ ! "$?" = "0" ]; then
  284. any_key
  285. fi
  286. }
  287. function change_password {
  288. select_user
  289. if [ ! $SELECTED_USERNAME ]; then
  290. return
  291. fi
  292. dialog --title $"Change password" \
  293. --passwordbox $"New password for user $SELECTED_USERNAME" 8 40 2> $data
  294. newpassword=$(<$data)
  295. if [ ${#newpassword} -lt ${MINIMUM_PASSWORD_LENGTH} ]; then
  296. dialog --title $"Change password" \
  297. --msgbox $"The password should be ${MINIMUM_PASSWORD_LENGTH} or more characters" 6 40
  298. return
  299. fi
  300. echo "$SELECTED_USERNAME:$newpassword"|chpasswd
  301. dialog --title $"Change password" \
  302. --msgbox $"Password for $SELECTED_USERNAME was changed" 6 40
  303. }
  304. function irc_set_global_password {
  305. dialog --title $"IRC Password" \
  306. --clear \
  307. --backtitle $"Freedombone Control Panel" \
  308. --passwordbox $"Password for all IRC users, or press Enter for no password" 10 50 2> $data
  309. sel=$?
  310. case $sel in
  311. 0)
  312. NEW_IRC_PASSWORD=$(<$data)
  313. sed -i "0,/RE/s/Password =.*/Password =$NEW_IRC_PASSWORD/" /etc/ngircd/ngircd.conf
  314. dialog --title $"IRC Password" \
  315. --msgbox $"The IRC password was changed" 6 40
  316. ;;
  317. esac
  318. }
  319. function change_ssh_public_key {
  320. select_user
  321. if [ ! $SELECTED_USERNAME ]; then
  322. return
  323. fi
  324. if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then
  325. dialog --title $"Change ssh public key" \
  326. --backtitle $"Freedombone Control Panel" \
  327. --defaultno \
  328. --yesno $"\nThis is the administrator user.\n\nAre you sure you want to change the ssh public key for the administrator?" 10 60
  329. sel=$?
  330. case $sel in
  331. 1) return;;
  332. 255) return;;
  333. esac
  334. fi
  335. data=$(tempfile 2>/dev/null)
  336. trap "rm -f $data" 0 1 2 5 15
  337. dialog --title $"Change ssh public key for $SELECTED_USERNAME" \
  338. --backtitle $"Freedombone Control Panel" \
  339. --inputbox $"Paste the ssh public key below" 8 60 2>$data
  340. sel=$?
  341. case $sel in
  342. 0)
  343. SSH_PUBLIC_KEY=$(<$data)
  344. if [ "$SSH_PUBLIC_KEY" ]; then
  345. if [ ${#SSH_PUBLIC_KEY} -gt 5 ]; then
  346. if [ -f "$SSH_PUBLIC_KEY" ]; then
  347. if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then
  348. mkdir /home/$SELECTED_USERNAME/.ssh
  349. fi
  350. cp $SSH_PUBLIC_KEY \
  351. /home/$SELECTED_USERNAME/.ssh/authorized_keys
  352. chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \
  353. /home/$SELECTED_USERNAME/.ssh
  354. dialog --title $"Change ssh public key" \
  355. --msgbox $"ssh public key was installed" 6 40
  356. else
  357. if [[ "$SSH_PUBLIC_KEY" == "ssh-"* ]]; then
  358. if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then
  359. mkdir /home/$SELECTED_USERNAME/.ssh
  360. fi
  361. echo "$SSH_PUBLIC_KEY" > \
  362. /home/$SELECTED_USERNAME/.ssh/authorized_keys
  363. chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \
  364. /home/$SELECTED_USERNAME/.ssh
  365. dialog --title $"Change ssh public key" \
  366. --msgbox $"ssh public key was installed" 6 40
  367. fi
  368. fi
  369. fi
  370. fi
  371. ;;
  372. esac
  373. }
  374. function add_to_mailing_list {
  375. select_user
  376. if [ ! $SELECTED_USERNAME ]; then
  377. return
  378. fi
  379. data=$(tempfile 2>/dev/null)
  380. trap "rm -f $data" 0 1 2 5 15
  381. dialog --backtitle $"Freedombone Control Panel" \
  382. --title $"Subscribe $SELECTED_USERNAME to a mailing list" \
  383. --form "\n" 8 68 4 \
  384. $"List folder name:" 1 1 "" 1 35 26 25 \
  385. $"Name between [] on subject line:" 2 1 "" 2 35 26 25 \
  386. $"List email address:" 3 1 "" 3 35 26 25 \
  387. 2> $data
  388. sel=$?
  389. case $sel in
  390. 1) return;;
  391. 255) return;;
  392. esac
  393. LIST_NAME=$(cat $data | sed -n 1p)
  394. LIST_SUBJECT=$(cat $data | sed -n 2p)
  395. LIST_EMAIL=$(cat $data | sed -n 3p)
  396. if [ ${#LIST_NAME} -lt 2 ]; then
  397. dialog --title $"Add mailing list" \
  398. --msgbox $"No mailing list name was given" 6 40
  399. return
  400. fi
  401. if [ ${#LIST_SUBJECT} -lt 2 ]; then
  402. dialog --title $"Add mailing list" \
  403. --msgbox $"No mailing list subject was given" 6 40
  404. return
  405. fi
  406. if [ ${#LIST_EMAIL} -lt 2 ]; then
  407. dialog --title $"Add mailing list" \
  408. --msgbox $"No mailing list email address was given" 6 40
  409. return
  410. fi
  411. if [[ "$LIST_EMAIL" != *"@"* || "$LIST_EMAIL" != *"."* ]]; then
  412. dialog --title $"Add mailing list" \
  413. --msgbox $"Unrecognised email address" 6 40
  414. return
  415. fi
  416. ${PROJECT_NAME}-addlist -u $SELECTED_USERNAME -l "$LIST_NAME" \
  417. -s "$LIST_SUBJECT" -e "$LIST_EMAIL"
  418. dialog --title $"Add mailing list" \
  419. --msgbox $"$LIST_NAME list was added" 6 40
  420. }
  421. function email_rule {
  422. select_user
  423. if [ ! $SELECTED_USERNAME ]; then
  424. return
  425. fi
  426. data=$(tempfile 2>/dev/null)
  427. trap "rm -f $data" 0 1 2 5 15
  428. dialog --backtitle $"Freedombone Control Panel" \
  429. --title $"Email rule for user $SELECTED_USERNAME" \
  430. --form "\n" 8 65 3 \
  431. $"When email arrives from address:" 1 1 "" 1 35 24 28 \
  432. $"Move to folder:" 2 1 "" 2 35 24 28 \
  433. 2> $data
  434. sel=$?
  435. case $sel in
  436. 1) return;;
  437. 255) return;;
  438. esac
  439. RULE_EMAIL=$(cat $data | sed -n 1p)
  440. RULE_FOLDER=$(cat $data | sed -n 2p)
  441. if [ ${#RULE_EMAIL} -lt 2 ]; then
  442. dialog --title $"Add email rule" \
  443. --msgbox $"No email address was given" 6 40
  444. return
  445. fi
  446. if [ ${#RULE_FOLDER} -lt 2 ]; then
  447. dialog --title $"Add email rule" \
  448. --msgbox $"No folder name was given" 6 40
  449. return
  450. fi
  451. if [[ "$RULE_EMAIL" != *"@"* || "$RULE_EMAIL" != *"."* ]]; then
  452. dialog --title $"Add email rule" \
  453. --msgbox $"Unrecognised email address" 6 40
  454. return
  455. fi
  456. ${PROJECT_NAME}-addemail -u $SELECTED_USERNAME -e "$RULE_EMAIL" \
  457. -g "$RULE_FOLDER"
  458. dialog --title $"Add email rule" \
  459. --msgbox $"Email rule for $RULE_EMAIL was added" 6 40
  460. }
  461. function block_unblock_email {
  462. select_user
  463. if [ ! $SELECTED_USERNAME ]; then
  464. return
  465. fi
  466. blockstr=$"Block/Unblock email going to"
  467. data=$(tempfile 2>/dev/null)
  468. trap "rm -f $data" 0 1 2 5 15
  469. dialog --backtitle $"Freedombone Control Panel" \
  470. --title "$blockstr $SELECTED_USERNAME" \
  471. --form "\n" 8 65 3 \
  472. $"When email arrives from address:" 1 1 "" 1 35 24 28 \
  473. $"Block it:" 2 1 "yes" 2 35 4 4 \
  474. 2> $data
  475. sel=$?
  476. case $sel in
  477. 1) return;;
  478. 255) return;;
  479. esac
  480. BLOCK_EMAIL=$(cat $data | sed -n 1p)
  481. BLOCK=$(cat $data | sed -n 2p)
  482. if [ ${#BLOCK_EMAIL} -lt 2 ]; then
  483. dialog --title $"Block/Unblock an email" \
  484. --msgbox $"No email address was given" 6 40
  485. return
  486. fi
  487. if [[ "$BLOCK_EMAIL" != *"@"* || "$BLOCK_EMAIL" != *"."* ]]; then
  488. dialog --title $"Block/Unblock an email" \
  489. --msgbox $"Unrecognised email address" 6 40
  490. return
  491. fi
  492. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  493. ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL"
  494. dialog --title $"Block an email" \
  495. --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME blocked" 6 40
  496. else
  497. ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL"
  498. dialog --title $"Unblock an email" \
  499. --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME unblocked" 6 40
  500. fi
  501. }
  502. function block_unblock_subject {
  503. select_user
  504. if [ ! $SELECTED_USERNAME ]; then
  505. return
  506. fi
  507. blockstr=$"Block/Unblock email going to"
  508. data=$(tempfile 2>/dev/null)
  509. trap "rm -f $data" 0 1 2 5 15
  510. dialog --backtitle $"Freedombone Control Panel" \
  511. --title "$blockstr $SELECTED_USERNAME" \
  512. --form "\n" 8 70 3 \
  513. $"When email arrives with subject text:" 1 1 "" 1 40 24 28 \
  514. $"Block it:" 2 1 "yes" 2 40 4 4 \
  515. 2> $data
  516. sel=$?
  517. case $sel in
  518. 1) return;;
  519. 255) return;;
  520. esac
  521. BLOCK_SUBJECT=$(cat $data | sed -n 1p)
  522. BLOCK=$(cat $data | sed -n 2p)
  523. if [ ${#BLOCK_SUBJECT} -lt 2 ]; then
  524. dialog --title $"Block/Unblock an email" \
  525. --msgbox $"No subject was given" 6 40
  526. return
  527. fi
  528. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  529. ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT"
  530. dialog --title $"Block an email" \
  531. --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME blocked" 6 40
  532. else
  533. ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT"
  534. dialog --title $"Unblock an email" \
  535. --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME unblocked" 6 40
  536. fi
  537. }
  538. function create_keydrive_master {
  539. select_user
  540. if [ ! $SELECTED_USERNAME ]; then
  541. return
  542. fi
  543. dialog --title $"USB Master Keydrive" \
  544. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  545. clear
  546. ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME --master 'yes'
  547. any_key
  548. }
  549. function create_keydrive_fragment {
  550. select_user
  551. if [ ! $SELECTED_USERNAME ]; then
  552. return
  553. fi
  554. dialog --title $"USB Fragment Keydrive" \
  555. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  556. clear
  557. ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME
  558. any_key
  559. }
  560. function backup_data {
  561. dialog --title $"Backup data to USB" \
  562. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  563. clear
  564. echo ' '
  565. echo $'Enter the passphrase for your LUKS encrypted backup drive:'
  566. ${PROJECT_NAME}-backup-local
  567. any_key
  568. }
  569. function restore_from_usb {
  570. while true
  571. do
  572. data=$(tempfile 2>/dev/null)
  573. trap "rm -f $data" 0 1 2 5 15
  574. dialog --backtitle $"Freedombone Control Panel" \
  575. --title $"Restore from USB backup" \
  576. --radiolist $"Choose an application to restore:" 30 70 27 \
  577. 1 $"Everything" on \
  578. 2 $"Return to the backup and restore menu" off \
  579. 3 $"Configuration files" off \
  580. 4 $"MariaDB settings" off \
  581. 5 $"Let's Encrypt account" off \
  582. 6 $"Mutt email client settings" off \
  583. 7 $"GPG keys" off \
  584. 8 $"Email processing rules" off \
  585. 9 $"Spam filtering rules" off \
  586. 10 $"Administrator's README file" off \
  587. 11 $"IPFS" off \
  588. 12 $"SSH keys" off \
  589. 13 $"User configuration files" off \
  590. 14 $"SSL/TLS certificates" off \
  591. 15 $"Personal settings" off \
  592. 16 $"Mailing List" off \
  593. 17 $"XMPP chat" off \
  594. 18 $"GNU Social" off \
  595. 19 $"Hubzilla" off \
  596. 20 $"Owncloud" off \
  597. 21 $"Gogs" off \
  598. 22 $"Wiki" off \
  599. 23 $"Blog" off \
  600. 24 $"CJDNS" off \
  601. 25 $"Email" off \
  602. 26 $"DLNA" off \
  603. 27 $"VoIP" off \
  604. 28 $"Tox" off 2> $data
  605. sel=$?
  606. case $sel in
  607. 1) break;;
  608. 255) break;;
  609. esac
  610. case $(cat $data) in
  611. 1) ${PROJECT_NAME}-restore-local $USB_DRIVE;;
  612. 2) return;;
  613. 3) ${PROJECT_NAME}-restore-local $USB_DRIVE configuration;;
  614. 4) ${PROJECT_NAME}-restore-local $USB_DRIVE mariadb;;
  615. 5) ${PROJECT_NAME}-restore-local $USB_DRIVE letsencrypt;;
  616. 6) ${PROJECT_NAME}-restore-local $USB_DRIVE mutt;;
  617. 7) ${PROJECT_NAME}-restore-local $USB_DRIVE gpg;;
  618. 8) ${PROJECT_NAME}-restore-local $USB_DRIVE procmail;;
  619. 9) ${PROJECT_NAME}-restore-local $USB_DRIVE spamassassin;;
  620. 10) ${PROJECT_NAME}-restore-local $USB_DRIVE readme;;
  621. 11) ${PROJECT_NAME}-restore-local $USB_DRIVE ipfs;;
  622. 12) ${PROJECT_NAME}-restore-local $USB_DRIVE ssh;;
  623. 13) ${PROJECT_NAME}-restore-local $USB_DRIVE userconfig;;
  624. 14) ${PROJECT_NAME}-restore-local $USB_DRIVE certs;;
  625. 15) ${PROJECT_NAME}-restore-local $USB_DRIVE personal;;
  626. 16) ${PROJECT_NAME}-restore-local $USB_DRIVE mailinglist;;
  627. 17) ${PROJECT_NAME}-restore-local $USB_DRIVE xmpp;;
  628. 18) ${PROJECT_NAME}-restore-local $USB_DRIVE gnusocial;;
  629. 19) ${PROJECT_NAME}-restore-local $USB_DRIVE hubzilla;;
  630. 20) ${PROJECT_NAME}-restore-local $USB_DRIVE owncloud;;
  631. 21) ${PROJECT_NAME}-restore-local $USB_DRIVE gogs;;
  632. 22) ${PROJECT_NAME}-restore-local $USB_DRIVE wiki;;
  633. 23) ${PROJECT_NAME}-restore-local $USB_DRIVE blog;;
  634. 24) ${PROJECT_NAME}-restore-local $USB_DRIVE cjdns;;
  635. 25) ${PROJECT_NAME}-restore-local $USB_DRIVE email;;
  636. 26) ${PROJECT_NAME}-restore-local $USB_DRIVE dlna;;
  637. 27) ${PROJECT_NAME}-restore-local $USB_DRIVE voip;;
  638. 28) ${PROJECT_NAME}-restore-local $USB_DRIVE tox;;
  639. esac
  640. done
  641. any_key
  642. }
  643. function restore_from_remote {
  644. remote_domain_name=$1
  645. while true
  646. do
  647. data=$(tempfile 2>/dev/null)
  648. trap "rm -f $data" 0 1 2 5 15
  649. dialog --backtitle $"Freedombone Control Panel" \
  650. --title $"Restore from ${remote_domain_name}" \
  651. --radiolist $"Choose an application to restore:" 30 70 27 \
  652. 1 $"Everything" on \
  653. 2 $"Return to the backup and restore menu" off \
  654. 3 $"Configuration files" off \
  655. 4 $"MariaDB settings" off \
  656. 5 $"Let's Encrypt account" off \
  657. 6 $"Mutt email client settings" off \
  658. 7 $"GPG keys" off \
  659. 8 $"Email processing rules" off \
  660. 9 $"Spam filtering rules" off \
  661. 10 $"Administrator's README file" off \
  662. 11 $"IPFS" off \
  663. 12 $"SSH keys" off \
  664. 13 $"User configuration files" off \
  665. 14 $"SSL/TLS certificates" off \
  666. 15 $"Personal settings" off \
  667. 16 $"Mailing List" off \
  668. 17 $"XMPP chat" off \
  669. 18 $"GNU Social" off \
  670. 19 $"Hubzilla" off \
  671. 20 $"Owncloud" off \
  672. 21 $"Gogs" off \
  673. 22 $"Wiki" off \
  674. 23 $"Blog" off \
  675. 24 $"CJDNS" off \
  676. 25 $"Email" off \
  677. 26 $"DLNA" off \
  678. 27 $"VoIP" off \
  679. 28 $"Tox" off 2> $data
  680. sel=$?
  681. case $sel in
  682. 1) break;;
  683. 255) break;;
  684. esac
  685. case $(cat $data) in
  686. 1) ${PROJECT_NAME}-restore-remote $remote_domain_name;;
  687. 2) return;;
  688. 3) ${PROJECT_NAME}-restore-remote $remote_domain_name configuration;;
  689. 4) ${PROJECT_NAME}-restore-remote $remote_domain_name mariadb;;
  690. 5) ${PROJECT_NAME}-restore-remote $remote_domain_name letsencrypt;;
  691. 6) ${PROJECT_NAME}-restore-remote $remote_domain_name mutt;;
  692. 7) ${PROJECT_NAME}-restore-remote $remote_domain_name gpg;;
  693. 8) ${PROJECT_NAME}-restore-remote $remote_domain_name procmail;;
  694. 9) ${PROJECT_NAME}-restore-remote $remote_domain_name spamassassin;;
  695. 10) ${PROJECT_NAME}-restore-remote $remote_domain_name readme;;
  696. 11) ${PROJECT_NAME}-restore-remote $remote_domain_name ipfs;;
  697. 12) ${PROJECT_NAME}-restore-remote $remote_domain_name ssh;;
  698. 13) ${PROJECT_NAME}-restore-remote $remote_domain_name userconfig;;
  699. 14) ${PROJECT_NAME}-restore-remote $remote_domain_name certs;;
  700. 15) ${PROJECT_NAME}-restore-remote $remote_domain_name personal;;
  701. 16) ${PROJECT_NAME}-restore-remote $remote_domain_name mailinglist;;
  702. 17) ${PROJECT_NAME}-restore-remote $remote_domain_name xmpp;;
  703. 18) ${PROJECT_NAME}-restore-remote $remote_domain_name gnusocial;;
  704. 19) ${PROJECT_NAME}-restore-remote $remote_domain_name hubzilla;;
  705. 20) ${PROJECT_NAME}-restore-remote $remote_domain_name owncloud;;
  706. 21) ${PROJECT_NAME}-restore-remote $remote_domain_name gogs;;
  707. 22) ${PROJECT_NAME}-restore-remote $remote_domain_name wiki;;
  708. 23) ${PROJECT_NAME}-restore-remote $remote_domain_name blog;;
  709. 24) ${PROJECT_NAME}-restore-remote $remote_domain_name cjdns;;
  710. 25) ${PROJECT_NAME}-restore-remote $remote_domain_name email;;
  711. 26) ${PROJECT_NAME}-restore-remote $remote_domain_name dlna;;
  712. 27) ${PROJECT_NAME}-restore-remote $remote_domain_name voip;;
  713. 28) ${PROJECT_NAME}-restore-remote $remote_domain_name tox;;
  714. esac
  715. done
  716. any_key
  717. }
  718. function restore_data {
  719. dialog --title $"Restore data from USB" \
  720. --msgbox $"Plug in your backup USB drive" 6 40
  721. clear
  722. echo ' '
  723. echo $'Enter the passphrase for your LUKS encrypted backup drive:'
  724. restore_from_usb
  725. }
  726. function restore_data_remote {
  727. if [ ! $ADMIN_USER ]; then
  728. dialog --title $"Restore data from remote server" \
  729. --msgbox $"Unknown admin user" 6 40
  730. return
  731. fi
  732. data=$(tempfile 2>/dev/null)
  733. trap "rm -f $data" 0 1 2 5 15
  734. dialog --title $"Restore from remote server" \
  735. --backtitle $"Freedombone Control Panel" \
  736. --inputbox $"Enter the domain name of the server from which you wish to restore" 8 60 2>$data
  737. sel=$?
  738. case $sel in
  739. 0)
  740. friend_server_domain_name=$(<$data)
  741. if [ ${#friend_server_domain_name} -lt 2 ]; then
  742. return
  743. fi
  744. if [[ $friend_server_domain_name != *"."* ]]; then
  745. dialog --title $"Remote server domain name" \
  746. --msgbox $"Invalid domain name" 6 40
  747. return
  748. fi
  749. restore_from_remote $friend_server_domain_name
  750. ;;
  751. esac
  752. }
  753. function ping_enable_disable {
  754. ping_str=$"\nDo you want to enable other systems to ping this machine?\n\nPing may be useful for diagnostic purposes, but for added security you may not want to enable it."
  755. enable_ping="no"
  756. dialog --title $"Enable Ping / ICMP" \
  757. --backtitle $"Freedombone Control Panel" \
  758. --defaultno \
  759. --yesno "$ping_str" 10 60
  760. sel=$?
  761. case $sel in
  762. 0) enable_ping="yes";;
  763. 255) return;;
  764. esac
  765. if [[ $enable_ping == "yes" ]]; then
  766. iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
  767. iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
  768. echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all
  769. else
  770. iptables -D INPUT -p icmp --icmp-type echo-request -j ACCEPT
  771. iptables -D OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
  772. echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
  773. fi
  774. }
  775. function logging_on_off {
  776. logging="no"
  777. dialog --title $"Logging" \
  778. --backtitle $"Freedombone Control Panel" \
  779. --yesno $"\nDo you want to turn logging on?" 7 60
  780. sel=$?
  781. case $sel in
  782. 0) logging="yes";;
  783. 255) return;;
  784. esac
  785. clear
  786. echo ''
  787. echo $'This may take a few seconds. Please wait...'
  788. if [[ $logging == "no" ]]; then
  789. ${PROJECT_NAME}-logging off
  790. else
  791. ${PROJECT_NAME}-logging on
  792. fi
  793. }
  794. function restore_gpg_key {
  795. select_user
  796. if [ ! $SELECTED_USERNAME ]; then
  797. return
  798. fi
  799. restorestr=$"Restore GPG key for user"
  800. dialog --title "$restorestr $SELECTED_USERNAME" \
  801. --msgbox $"Plug in your USB keydrive" 6 40
  802. clear
  803. ${PROJECT_NAME}-recoverkey -u $SELECTED_USERNAME
  804. any_key
  805. }
  806. function security_settings {
  807. ${PROJECT_NAME}-sec
  808. any_key
  809. }
  810. function reset_tripwire {
  811. clear
  812. echo $'Resetting the Tripwire...'
  813. echo ' '
  814. echo '
  815. ' | reset-tripwire
  816. any_key
  817. }
  818. function hubzilla_renew_cert {
  819. dialog --title $"Renew SSL certificate" \
  820. --backtitle $"Freedombone Control Panel" \
  821. --yesno $"\nThis will renew a letsencrypt certificate. Select 'yes' to continue" 16 60
  822. sel=$?
  823. case $sel in
  824. 1) return;;
  825. 255) return;;
  826. esac
  827. HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
  828. if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
  829. dialog --title $"Renew SSL certificate" \
  830. --msgbox $"Hubzilla install directory not found" 6 40
  831. return
  832. fi
  833. ${PROJECT_NAME}-renew-cert -h $HUBZILLA_DOMAIN_NAME -p 'letsencrypt'
  834. if [ ! "$?" = "0" ]; then
  835. any_key
  836. else
  837. dialog --title $"Renew SSL certificate" \
  838. --msgbox $"Hubzilla certificate has been renewed" 6 40
  839. fi
  840. }
  841. function hubzilla_channel_directory_server {
  842. if ! grep -q "Hubzilla domain" $COMPLETION_FILE; then
  843. dialog --title $"Hubzilla channel directory server" \
  844. --msgbox $"Hubzilla is not installed on this system" 6 40
  845. return
  846. fi
  847. HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
  848. if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
  849. dialog --title $"Hubzilla channel directory server" \
  850. --msgbox $"Hubzilla install directory not found" 6 40
  851. return
  852. fi
  853. data=$(tempfile 2>/dev/null)
  854. trap "rm -f $data" 0 1 2 5 15
  855. dialog --title $"Hubzilla channel directory server" \
  856. --backtitle $"Freedombone Control Panel" \
  857. --inputbox $"When you click on 'channel directory' this is where Hubzilla will obtain its list from" 8 60 2>$data
  858. sel=$?
  859. case $sel in
  860. 0)
  861. hubzilla_domain_server=$(<$data)
  862. if [[ $hubzilla_domain_server != *"."* ]]; then
  863. return
  864. fi
  865. if [[ $hubzilla_domain_server != "https"* ]]; then
  866. dialog --title $"Hubzilla channel directory server" \
  867. --msgbox $"Invalid domain - include the https://" 6 40
  868. return
  869. fi
  870. ./var/www/$HUBZILLA_DOMAIN_NAME/htdocs/util/config system directory_server $hubzilla_domain_server
  871. dialog --title $"Hubzilla channel directory server" \
  872. --msgbox $"Domain channel directory server changed to $hubzilla_domain_server" 6 40
  873. ;;
  874. esac
  875. }
  876. function format_drive {
  877. drive=
  878. data=$(tempfile 2>/dev/null)
  879. trap "rm -f $data" 0 1 2 5 15
  880. dialog --backtitle $"Freedombone Control Panel" \
  881. --title $"Format a USB drive (LUKS encrypted)" \
  882. --radiolist $"Choose a drive:" 12 70 5 \
  883. 1 $"sda (Beaglebone Black)" off \
  884. 2 $"sdb" off \
  885. 3 $"sdc" off \
  886. 4 $"sdd" off \
  887. 5 $"Back to Backup and Restore menu" on 2> $data
  888. sel=$?
  889. case $sel in
  890. 1) return;;
  891. 255) return;;
  892. esac
  893. case $(cat $data) in
  894. 1) drive='sda';;
  895. 2) drive='sdb';;
  896. 3) drive='sdc';;
  897. 4) drive='sdd';;
  898. 5) return;;
  899. esac
  900. dialog --title $"Format USB drive" \
  901. --backtitle $"Freedombone Control Panel" \
  902. --defaultno \
  903. --yesno $"\nPlease confirm that you wish to format drive\n\n ${drive}\n\nAll current data on the drive will be lost, and you will be prompted to give a password used to encrypt the drive.\n\nDANGER: If you screw up here and format the wrong drive it's your own fault!" 16 60
  904. sel=$?
  905. case $sel in
  906. 1) return;;
  907. 255) return;;
  908. esac
  909. clear
  910. ${PROJECT_NAME}-format $drive
  911. any_key
  912. }
  913. function remove_backups {
  914. drive=
  915. data=$(tempfile 2>/dev/null)
  916. trap "rm -f $data" 0 1 2 5 15
  917. dialog --backtitle $"Freedombone Control Panel" \
  918. --title $"Remove backups from a USB drive" \
  919. --radiolist $"Choose a drive:" 12 70 5 \
  920. 1 $"sda (Beaglebone Black)" off \
  921. 2 $"sdb" off \
  922. 3 $"sdc" off \
  923. 4 $"sdd" off \
  924. 5 $"Back to Backup and Restore menu" on 2> $data
  925. sel=$?
  926. case $sel in
  927. 1) return;;
  928. 255) return;;
  929. esac
  930. case $(cat $data) in
  931. 1) drive='sda';;
  932. 2) drive='sdb';;
  933. 3) drive='sdc';;
  934. 4) drive='sdd';;
  935. 5) return;;
  936. esac
  937. dialog --title $"Remove backups from a USB drive" \
  938. --backtitle $"Freedombone Control Panel" \
  939. --defaultno \
  940. --yesno $"\nPlease confirm that you wish to remove backups from this drive\n\n ${drive}\n\nYou will not be able to recover them afterwards." 12 60
  941. sel=$?
  942. case $sel in
  943. 1) return;;
  944. 255) return;;
  945. esac
  946. clear
  947. ${PROJECT_NAME}-backup-local $drive remove
  948. any_key
  949. }
  950. function shut_down_system {
  951. dialog --title $"Power off the system" \
  952. --backtitle $"Freedombone Control Panel" \
  953. --defaultno \
  954. --yesno $"\nPlease confirm that you wish to power off the system.\n\nWARNING: to power on again you will need to have physical access to the hardware." 10 60
  955. sel=$?
  956. case $sel in
  957. 1) return;;
  958. 255) return;;
  959. esac
  960. shutdown now
  961. }
  962. function restart_system {
  963. dialog --title $"Restart the system" \
  964. --backtitle $"Freedombone Control Panel" \
  965. --defaultno \
  966. --yesno $"\nPlease confirm that you wish to restart the system.\n\nWARNING: If you are using full disk encryption then you will need physical access to the hardware to type in the password" 10 60
  967. sel=$?
  968. case $sel in
  969. 1) return;;
  970. 255) return;;
  971. esac
  972. reboot
  973. }
  974. function change_system_name {
  975. data=$(tempfile 2>/dev/null)
  976. trap "rm -f $data" 0 1 2 5 15
  977. dialog --title $"Change the name of this system" \
  978. --backtitle $"Freedombone Control Panel" \
  979. --inputbox $'Enter a new name for this system on your local network\n\nIt will appear as newname.local' 10 60 2>$data
  980. sel=$?
  981. case $sel in
  982. 0) NEW_SYSTEM_NAME=$(<$data)
  983. if [ "$NEW_SYSTEM_NAME" ]; then
  984. if [ ${#NEW_SYSTEM_NAME} -gt 1 ]; then
  985. sed -i "s|host-name=.*|host-name=$NEW_SYSTEM_NAME|g" /etc/avahi/avahi-daemon.conf
  986. systemctl restart avahi-daemon
  987. if grep -q "host-name=$NEW_SYSTEM_NAME" /etc/avahi/avahi-daemon.conf; then
  988. dialog --title $"New local network name" \
  989. --msgbox $"The name of this system on your local network was changed successfully" 6 70
  990. fi
  991. fi
  992. fi
  993. ;;
  994. esac
  995. }
  996. function set_tls_time_source {
  997. TLS_DATE_SOURCE=$(cat /usr/bin/updatedate | grep "TIMESOURCE='" | awk -F '=' '{print $2}' | awk -F "'" '{print $2}')
  998. data=$(tempfile 2>/dev/null)
  999. trap "rm -f $data" 0 1 2 5 15
  1000. dialog --title $"Set the TLS date/time source" \
  1001. --backtitle $"Freedombone Control Panel" \
  1002. --inputbox $"Enter a domain name to use as a TLS time source.\n\nFactors to consider when choosing a source are whether you wish that site to know that your system is 'alive' and also what might happen if an adversary were to try to mess with the date/time from that domain (i.e. how much blowback would there be)." 14 60 "$TLS_DATE_SOURCE" 2>$data
  1003. sel=$?
  1004. case $sel in
  1005. 0) NEW_TLS_DATE_SOURCE=$(<$data)
  1006. if [[ $NEW_TLS_DATE_SOURCE == *"."* && $NEW_TLS_DATE_SOURCE != *'/'* ]]; then
  1007. if [[ $NEW_TLS_DATE_SOURCE != "http"* ]]; then
  1008. sed -i "s|TIMESOURCE='.*|TIMESOURCE='${NEW_TLS_DATE_SOURCE}'|g" $UPDATE_DATE_SCRIPT
  1009. else
  1010. dialog --title $"Invalid domain name" \
  1011. --msgbox $"Don't include the 'https'" 6 70
  1012. fi
  1013. else
  1014. dialog --title $"Invalid domain name" \
  1015. --msgbox $"That doesn't look like a domain name" 6 70
  1016. fi
  1017. ;;
  1018. esac
  1019. }
  1020. function set_static_IP {
  1021. STATIC_IP='192.168.1.60'
  1022. STATIC_GATEWAY='192.168.1.1'
  1023. NEW_STATIC_IP=
  1024. NEW_STATIC_GATEWAY=
  1025. if grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1026. STATIC_IP=$(cat /etc/network/interfaces | grep "address " | awk -F ' ' '{print $2}' | head -n 1)
  1027. STATIC_GATEWAY=$(cat /etc/network/interfaces | grep "gateway " | awk -F ' ' '{print $2}' | head -n 1)
  1028. fi
  1029. # get the IP for the box
  1030. data=$(tempfile 2>/dev/null)
  1031. trap "rm -f $data" 0 1 2 5 15
  1032. dialog --title $"Set a static local IP address" \
  1033. --backtitle $"Freedombone Control Panel" \
  1034. --inputbox $"In order to forward incoming internet traffic to this system most internet routers need to know a static local IP address to send the data to.\n\n
  1035. Enter a static local IP address for this system.\n\nIt will typically be 192.168.1.x" 15 60 "$STATIC_IP" 2>$data
  1036. sel=$?
  1037. case $sel in
  1038. 0) NEW_STATIC_IP=$(<$data)
  1039. if [[ "$NEW_STATIC_IP" != *"."* ]]; then
  1040. return
  1041. fi
  1042. if grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1043. if [[ "$NEW_STATIC_IP" != "$STATIC_IP" ]]; then
  1044. sed -i "s|${STATIC_IP}|${NEW_STATIC_IP}|g" /etc/network/interfaces
  1045. fi
  1046. fi
  1047. ;;
  1048. esac
  1049. # get the gateway
  1050. data=$(tempfile 2>/dev/null)
  1051. trap "rm -f $data" 0 1 2 5 15
  1052. dialog --title $"Set the IP address of your internet router/modem" \
  1053. --backtitle $"Freedombone Control Panel" \
  1054. --inputbox $"Set the local IP address for your internet router or ADSL modem.\n\nIt will typically be 192.168.1.1, 192.168.1.254, or similar" 12 60 "$STATIC_GATEWAY" 2>$data
  1055. sel=$?
  1056. case $sel in
  1057. 0) NEW_STATIC_GATEWAY=$(<$data)
  1058. if [[ "$NEW_STATIC_GATEWAY" != *"."* ]]; then
  1059. return
  1060. fi
  1061. if grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1062. if [[ "$NEW_STATIC_GATEWAY" != "$STATIC_GATEWAY" ]]; then
  1063. sed -i "s|${STATIC_GATEWAY}|${NEW_STATIC_GATEWAY}|g" /etc/network/interfaces
  1064. fi
  1065. return
  1066. fi
  1067. ;;
  1068. esac
  1069. if ! grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1070. if [ "$NEW_STATIC_GATEWAY" && "$NEW_STATIC_IP" ]; then
  1071. echo '# This file describes the network interfaces available on your system' > /etc/network/interfaces
  1072. echo '# and how to activate them. For more information, see interfaces(5).' >> /etc/network/interfaces
  1073. echo '' >> /etc/network/interfaces
  1074. echo '# The loopback network interface' >> /etc/network/interfaces
  1075. echo 'auto lo' >> /etc/network/interfaces
  1076. echo 'iface lo inet loopback' >> /etc/network/interfaces
  1077. echo '' >> /etc/network/interfaces
  1078. echo '# The primary network interface' >> /etc/network/interfaces
  1079. echo 'auto eth0' >> /etc/network/interfaces
  1080. echo 'iface eth0 inet static' >> /etc/network/interfaces
  1081. echo " address ${NEW_STATIC_IP}" >> /etc/network/interfaces
  1082. echo ' netmask 255.255.255.0' >> /etc/network/interfaces
  1083. echo " gateway ${NEW_STATIC_GATEWAY}" >> /etc/network/interfaces
  1084. echo " dns-nameservers 213.73.91.35 85.214.20.141" >> /etc/network/interfaces
  1085. echo '# Example to keep MAC address between reboots' >> /etc/network/interfaces
  1086. echo '#hwaddress ether DE:AD:BE:EF:CA:FE' >> /etc/network/interfaces
  1087. echo '' >> /etc/network/interfaces
  1088. echo '# The secondary network interface' >> /etc/network/interfaces
  1089. echo '#auto eth1' >> /etc/network/interfaces
  1090. echo '#iface eth1 inet dhcp' >> /etc/network/interfaces
  1091. echo '' >> /etc/network/interfaces
  1092. echo '# WiFi Example' >> /etc/network/interfaces
  1093. echo "#auto $WIFI_INTERFACE" >> /etc/network/interfaces
  1094. echo "#iface $WIFI_INTERFACE inet dhcp" >> /etc/network/interfaces
  1095. echo '# wpa-ssid "essid"' >> /etc/network/interfaces
  1096. echo '# wpa-psk "password"' >> /etc/network/interfaces
  1097. echo '' >> /etc/network/interfaces
  1098. echo '# Ethernet/RNDIS gadget (g_ether)' >> /etc/network/interfaces
  1099. echo '# ... or on host side, usbnet and random hwaddr' >> /etc/network/interfaces
  1100. echo '# Note on some boards, usb0 is automaticly setup with an init script' >> /etc/network/interfaces
  1101. echo '#iface usb0 inet static' >> /etc/network/interfaces
  1102. echo '# address 192.168.7.2' >> /etc/network/interfaces
  1103. echo '# netmask 255.255.255.0' >> /etc/network/interfaces
  1104. echo '# network 192.168.7.0' >> /etc/network/interfaces
  1105. echo '# gateway 192.168.7.1' >> /etc/network/interfaces
  1106. fi
  1107. fi
  1108. }
  1109. function menu_backup_restore {
  1110. while true
  1111. do
  1112. data=$(tempfile 2>/dev/null)
  1113. trap "rm -f $data" 0 1 2 5 15
  1114. dialog --backtitle $"Freedombone Control Panel" \
  1115. --title $"Backup and Restore" \
  1116. --radiolist $"Choose an operation:" 18 70 11 \
  1117. 1 $"Backup data to USB drive" off \
  1118. 2 $"Restore GPG key from USB keydrive" off \
  1119. 3 $"Restore data from USB drive" off \
  1120. 4 $"Configure remote backups" off \
  1121. 5 $"Restore from remote backup" off \
  1122. 6 $"Backup GPG key to USB (master keydrive)" off \
  1123. 7 $"Backup GPG key to USB (fragment keydrive)" off \
  1124. 8 $"Format a USB drive (LUKS encrypted)" off \
  1125. 9 $"Remove backups from a USB drive" off \
  1126. 10 $"Back to main menu" on 2> $data
  1127. sel=$?
  1128. case $sel in
  1129. 1) break;;
  1130. 255) break;;
  1131. esac
  1132. case $(cat $data) in
  1133. 1) backup_data;;
  1134. 2) restore_gpg_key;;
  1135. 3) restore_data;;
  1136. 4) configure_remote_backups;;
  1137. 5) restore_data_remote;;
  1138. 6) create_keydrive_master;;
  1139. 7) create_keydrive_fragment;;
  1140. 8) format_drive;;
  1141. 9) remove_backups;;
  1142. 10) break;;
  1143. esac
  1144. done
  1145. }
  1146. function menu_email {
  1147. while true
  1148. do
  1149. data=$(tempfile 2>/dev/null)
  1150. trap "rm -f $data" 0 1 2 5 15
  1151. dialog --backtitle $"Freedombone Control Panel" \
  1152. --title $"Email Filtering Rules" \
  1153. --radiolist $"Choose an operation:" 12 70 5 \
  1154. 1 $"Add a user to a mailing list" off \
  1155. 2 $"Add an email rule" off \
  1156. 3 $"Block/Unblock an email address" off \
  1157. 4 $"Block/Unblock email with subject text" off \
  1158. 5 $"Back to main menu" on 2> $data
  1159. sel=$?
  1160. case $sel in
  1161. 1) break;;
  1162. 255) break;;
  1163. esac
  1164. case $(cat $data) in
  1165. 1) add_to_mailing_list;;
  1166. 2) email_rule;;
  1167. 3) block_unblock_email;;
  1168. 4) block_unblock_subject;;
  1169. 5) break;;
  1170. esac
  1171. done
  1172. }
  1173. function menu_users {
  1174. while true
  1175. do
  1176. data=$(tempfile 2>/dev/null)
  1177. trap "rm -f $data" 0 1 2 5 15
  1178. dialog --backtitle $"Freedombone Control Panel" \
  1179. --title $"Manage Users" \
  1180. --radiolist $"Choose an operation:" 12 70 5 \
  1181. 1 $"Add a user" off \
  1182. 2 $"Delete a user" off \
  1183. 3 $"Change user password" off \
  1184. 4 $"Change user ssh public key" off \
  1185. 5 $"Back to main menu" on 2> $data
  1186. sel=$?
  1187. case $sel in
  1188. 1) break;;
  1189. 255) break;;
  1190. esac
  1191. case $(cat $data) in
  1192. 1) add_user;;
  1193. 2) delete_user;;
  1194. 3) change_password;;
  1195. 4) change_ssh_public_key;;
  1196. 5) break;;
  1197. esac
  1198. done
  1199. }
  1200. function menu_hubzilla {
  1201. while true
  1202. do
  1203. data=$(tempfile 2>/dev/null)
  1204. trap "rm -f $data" 0 1 2 5 15
  1205. dialog --backtitle $"Freedombone Control Panel" \
  1206. --title $"Hubzilla" \
  1207. --radiolist $"Choose an operation:" 13 70 4 \
  1208. 1 $"Set channel directory server" off \
  1209. 2 $"Renew SSL certificate" off \
  1210. 3 $"Back to main menu" on 2> $data
  1211. sel=$?
  1212. case $sel in
  1213. 1) break;;
  1214. 255) break;;
  1215. esac
  1216. case $(cat $data) in
  1217. 1) hubzilla_channel_directory_server;;
  1218. 2) hubzilla_renew_cert;;
  1219. 3) break;;
  1220. esac
  1221. done
  1222. }
  1223. function menu_media {
  1224. while true
  1225. do
  1226. data=$(tempfile 2>/dev/null)
  1227. trap "rm -f $data" 0 1 2 5 15
  1228. dialog --backtitle $"Freedombone Control Panel" \
  1229. --title $"Media Menu" \
  1230. --radiolist $"Choose an operation:" 13 70 3 \
  1231. 1 $"Attach a drive containing playable media" off \
  1232. 2 $"Remove a drive containing playable media" off \
  1233. 3 $"Exit" on 2> $data
  1234. sel=$?
  1235. case $sel in
  1236. 1) break;;
  1237. 255) break;;
  1238. esac
  1239. case $(cat $data) in
  1240. 1) remove-music
  1241. attach-music;;
  1242. 2) remove-music;;
  1243. 3) break;;
  1244. esac
  1245. done
  1246. }
  1247. function menu_irc {
  1248. while true
  1249. do
  1250. data=$(tempfile 2>/dev/null)
  1251. trap "rm -f $data" 0 1 2 5 15
  1252. dialog --backtitle $"Freedombone Control Panel" \
  1253. --title $"IRC Menu" \
  1254. --radiolist $"Choose an operation:" 13 70 3 \
  1255. 1 $"Set a password for all IRC users" off \
  1256. 2 $"Exit" on 2> $data
  1257. sel=$?
  1258. case $sel in
  1259. 1) break;;
  1260. 255) break;;
  1261. esac
  1262. case $(cat $data) in
  1263. 1) irc_set_global_password;;
  1264. 2) break;;
  1265. esac
  1266. done
  1267. }
  1268. function menu_top_level {
  1269. while true
  1270. do
  1271. data=$(tempfile 2>/dev/null)
  1272. trap "rm -f $data" 0 1 2 5 15
  1273. dialog --backtitle $"Freedombone Control Panel" \
  1274. --title $"Control Panel" \
  1275. --radiolist $"Choose an operation:" 25 70 18 \
  1276. 1 $"About this system" off \
  1277. 2 $"Backup and Restore" off \
  1278. 3 $"Reset Tripwire" off \
  1279. 4 $"Logging on/off" off \
  1280. 5 $"Ping enable/disable" off \
  1281. 6 $"Manage Users" off \
  1282. 7 $"Email Filtering Rules" off \
  1283. 8 $"Security Settings" off \
  1284. 9 $"Hubzilla" off \
  1285. 10 $"Media menu" off \
  1286. 11 $"IRC menu" off \
  1287. 12 $"Change the name of this system" off \
  1288. 13 $"Set the TLS date/time source" off \
  1289. 14 $"Set a static local IP address" off \
  1290. 15 $"Check for updates" off \
  1291. 16 $"Power off the system" off \
  1292. 17 $"Restart the system" off \
  1293. 18 $"Exit" on 2> $data
  1294. sel=$?
  1295. case $sel in
  1296. 1) exit 1;;
  1297. 255) exit 1;;
  1298. esac
  1299. case $(cat $data) in
  1300. 1) show_about;;
  1301. 2) menu_backup_restore;;
  1302. 3) reset_tripwire;;
  1303. 4) logging_on_off;;
  1304. 5) ping_enable_disable;;
  1305. 6) menu_users;;
  1306. 7) menu_email;;
  1307. 8) security_settings;;
  1308. 9) menu_hubzilla;;
  1309. 10) menu_media;;
  1310. 11) menu_irc;;
  1311. 12) change_system_name;;
  1312. 13) set_tls_time_source;;
  1313. 14) set_static_IP;;
  1314. 15) check_for_updates;;
  1315. 16) shut_down_system;;
  1316. 17) restart_system;;
  1317. 18) break;;
  1318. esac
  1319. done
  1320. }
  1321. if [ ! -f $COMPLETION_FILE ]; then
  1322. echo $'This command should only be run on an installed Freedombone system'
  1323. exit 1
  1324. fi
  1325. ADMIN_USER=$(cat $COMPLETION_FILE | grep "Admin user" | awk -F ':' '{print $2}')
  1326. menu_top_level
  1327. clear
  1328. cat /etc/motd
  1329. exit 0