freedombone-controlpanel 51KB

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