freedombone-controlpanel 60KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818
  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 Affero General Public License as published by
  20. # the Free Software Foundation, either version 3 of the License, or
  21. # (at your option) any later version.
  22. #
  23. # This program is distributed in the hope that it will be useful,
  24. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. # GNU Affero General Public License for more details.
  27. #
  28. # You should have received a copy of the GNU Affero General Public License
  29. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  30. PROJECT_NAME='freedombone'
  31. export TEXTDOMAIN=${PROJECT_NAME}-controlpanel
  32. export TEXTDOMAINDIR="/usr/share/locale"
  33. UTILS_FILES=/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-*
  34. for f in $UTILS_FILES
  35. do
  36. source $f
  37. done
  38. APP_FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*
  39. for f in $APP_FILES
  40. do
  41. source $f
  42. done
  43. COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt
  44. SELECTED_USERNAME=
  45. SIP_CONFIGURATION_FILE=/etc/sipwitch.conf
  46. ADMIN_USER=
  47. UPGRADE_SCRIPT_NAME="${PROJECT_NAME}-upgrade"
  48. UPDATE_DATE_SCRIPT=/usr/bin/updatedate
  49. # Minimum number of characters in a password
  50. MINIMUM_PASSWORD_LENGTH=$(cat /usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-passwords | grep 'MINIMUM_PASSWORD_LENGTH=' | head -n 1 | awk -F '=' '{print $2}')
  51. # Mumble
  52. MUMBLE_PORT=64738
  53. MUMBLE_ONION_PORT=8095
  54. SSH_PORT=2222
  55. # outgoing SMTP proxy
  56. SMTP_PROXY_ENABLE=$'no'
  57. SMTP_PROXY_PROTOCOL='smtps'
  58. SMTP_PROXY_SERVER='mail.myispdomain'
  59. SMTP_PROXY_PORT=465
  60. SMTP_PROXY_USERNAME=''
  61. SMTP_PROXY_PASSWORD=''
  62. WIFI_INTERFACE=wlan0
  63. WIFI_SSID=
  64. WIFI_TYPE='wpa2-psk'
  65. WIFI_PASSPHRASE=
  66. WIFI_HOTSPOT='no'
  67. WIFI_NETWORKS_FILE=~/${PROJECT_NAME}-wifi.cfg
  68. USB_DRIVE=sdb
  69. # get default USB from config file
  70. CONFIGURATION_FILE=$HOME/${PROJECT_NAME}.cfg
  71. read_config_param WIFI_HOTSPOT
  72. read_config_param WIFI_INTERFACE
  73. read_config_param WIFI_TYPE
  74. read_config_param WIFI_SSID
  75. read_config_param WIFI_PASSPHRASE
  76. read_config_param SSH_PORT
  77. read_config_param SMTP_PROXY_ENABLE
  78. read_config_param SMTP_PROXY_PROTOCOL
  79. read_config_param SMTP_PROXY_SERVER
  80. read_config_param SMTP_PROXY_PORT
  81. read_config_param SMTP_PROXY_USERNAME
  82. read_config_param SMTP_PROXY_PASSWORD
  83. read_config_param USB_DRIVE
  84. if [[ $USB_DRIVE == *"dev"* ]]; then
  85. USB_DRIVE=$(echo ${USB_DRIVE} | awk -F '/' '{print $3}' | sed 's|1||g' | sed 's|2||g')
  86. fi
  87. # Mirrors settings
  88. FRIENDS_MIRRORS_SERVER=
  89. FRIENDS_MIRRORS_SSH_PORT=2222
  90. FRIENDS_MIRRORS_PASSWORD=
  91. MY_MIRRORS_PASSWORD=
  92. function any_key {
  93. echo ' '
  94. read -n1 -r -p $"Press any key to continue..." key
  95. }
  96. function check_for_updates {
  97. if [ ! -f /etc/cron.weekly/$UPGRADE_SCRIPT_NAME ]; then
  98. dialog --title $"Check for updates" \
  99. --msgbox $"Upgrade script was not found" 6 40
  100. return
  101. fi
  102. clear
  103. . /etc/cron.weekly/$UPGRADE_SCRIPT_NAME
  104. any_key
  105. }
  106. function set_main_repo {
  107. data=$(tempfile 2>/dev/null)
  108. trap "rm -f $data" 0 1 2 5 15
  109. dialog --backtitle $"Freedombone Control Panel" \
  110. --title $"Main Repository (Mirrors)" \
  111. --form $"If you do not wish to use the default repositories they can be obtained from mirrors on another ${PROJECT_NAME} server." 14 60 3 \
  112. $"URL:" 1 1 "$FRIENDS_MIRRORS_SERVER" 1 14 40 15 \
  113. $"SSH Port:" 2 1 "$FRIENDS_MIRRORS_SSH_PORT" 2 14 40 10000 \
  114. $"Password:" 3 1 "$FRIENDS_MIRRORS_PASSWORD" 3 14 40 10000 \
  115. 2> $data
  116. sel=$?
  117. case $sel in
  118. 1) return;;
  119. 255) return;;
  120. esac
  121. new_mirrors_url=$(cat $data | sed -n 1p)
  122. new_mirrors_ssh_port=$(cat $data | sed -n 2p)
  123. new_mirrors_password=$(cat $data | sed -n 3p)
  124. if [ ${#new_mirrors_url} -lt 2 ]; then
  125. return
  126. fi
  127. if [ ${#new_mirrors_ssh_port} -lt 1 ]; then
  128. return
  129. fi
  130. if [ ${#new_mirrors_password} -lt 10 ]; then
  131. dialog --title $"Main Repository" \
  132. --msgbox $'Mirrors password was too short. Should be at least 10 characters.' 6 40
  133. return
  134. fi
  135. if [[ $new_mirrors_url == *"."* ]]; then
  136. FRIENDS_MIRRORS_SERVER=$new_mirrors_url
  137. FRIENDS_MIRRORS_SSH_PORT=$new_mirrors_ssh_port
  138. FRIENDS_MIRRORS_PASSWORD=$new_mirrors_password
  139. write_config_param "FRIENDS_MIRRORS_SERVER" "$FRIENDS_MIRRORS_SERVER"
  140. write_config_param "FRIENDS_MIRRORS_SSH_PORT" "$FRIENDS_MIRRORS_SSH_PORT"
  141. write_config_param "FRIENDS_MIRRORS_PASSWORD" "$FRIENDS_MIRRORS_PASSWORD"
  142. # re-read the repos
  143. read_repo_servers
  144. dialog --title $"Main Repository" \
  145. --msgbox $"Main repository set to $FRIENDS_MIRRORS_SERVER" 6 60
  146. fi
  147. }
  148. function add_user {
  149. data=$(tempfile 2>/dev/null)
  150. trap "rm -f $data" 0 1 2 5 15
  151. dialog --backtitle $"Freedombone Control Panel" \
  152. --title $"Add new user" \
  153. --form "\n" 8 60 3 \
  154. $"Username:" 1 1 "" 1 28 16 15 \
  155. $"ssh public key (optional):" 2 1 "" 2 28 40 10000 \
  156. 2> $data
  157. sel=$?
  158. case $sel in
  159. 1) return;;
  160. 255) return;;
  161. esac
  162. new_user_username=$(cat $data | sed -n 1p)
  163. new_user_ssh_public_key=$(cat $data | sed -n 2p)
  164. if [ ${#new_user_username} -lt 2 ]; then
  165. dialog --title $"New username" \
  166. --msgbox $"No username was given" 6 40
  167. return
  168. fi
  169. if [[ "$new_user_username" == *" "* ]]; then
  170. dialog --title $"Invalid username" \
  171. --msgbox $"The username should not contain any spaces" 6 40
  172. return
  173. fi
  174. if [ ${#new_user_ssh_public_key} -lt 20 ]; then
  175. clear
  176. ${PROJECT_NAME}-adduser "$new_user_username"
  177. any_key
  178. else
  179. if [[ "$new_user_ssh_public_key" == "ssh-"* ]]; then
  180. clear
  181. ${PROJECT_NAME}-adduser "$new_user_username" "$new_user_ssh_public_key"
  182. any_key
  183. else
  184. dialog --title $"ssh public key" \
  185. --msgbox $"This does not look like an ssh public key" 6 40
  186. fi
  187. fi
  188. }
  189. function pad_string {
  190. echo -n -e "$1" | sed -e :a -e 's/^.\{1,25\}$/& /;ta'
  191. }
  192. function show_domains {
  193. read_config_param "DEFAULT_DOMAIN_NAME"
  194. echo 'Domains'
  195. echo '======='
  196. echo ''
  197. echo -n -e "$(pad_string 'Name')"
  198. echo -n -e "$(pad_string 'ICANN')"
  199. echo -n -e "$(pad_string 'Tor')"
  200. echo ''
  201. echo '--------------------------------------------------------------------------'
  202. if grep -q "ssh onion domain" $COMPLETION_FILE; then
  203. echo -n -e "$(pad_string 'ssh')"
  204. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  205. echo "$(cat ${COMPLETION_FILE} | grep 'ssh onion domain' | awk -F ':' '{print $2}')"
  206. fi
  207. if grep -q "email onion domain" $COMPLETION_FILE; then
  208. echo -n -e "$(pad_string 'Email')"
  209. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  210. echo "$(cat ${COMPLETION_FILE} | grep 'email onion domain' | awk -F ':' '{print $2}')"
  211. fi
  212. for app_name in "${APPS_INSTALLED_NAMES[@]}"
  213. do
  214. if ! grep -q "SHOW_ON_ABOUT=1" /usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}; then
  215. continue
  216. fi
  217. icann_address=${DEFAULT_DOMAIN_NAME}
  218. onion_address="-"
  219. # handle the foibles of capitalisation
  220. if ! grep -q "${app_name} domain" $COMPLETION_FILE; then
  221. app_name_upper=$(echo ${app_name} | awk '{print toupper($0)}')
  222. if grep -q "${app_name_upper} domain" $COMPLETION_FILE; then
  223. app_name=${app_name_upper}
  224. else
  225. app_name_first_upper="$(tr '[:lower:]' '[:upper:]' <<< ${app_name:0:1})${app_name:1}"
  226. if grep -q "${app_name_first_upper} domain" $COMPLETION_FILE; then
  227. app_name=${app_name_first_upper}
  228. fi
  229. fi
  230. fi
  231. if [ ${#app_name} -gt 0 ]; then
  232. if grep -q "${app_name} domain" $COMPLETION_FILE; then
  233. icann_address=$(cat ${COMPLETION_FILE} | grep "${app_name} domain" | head -n 1 | awk -F ':' '{print $2}')
  234. fi
  235. if grep -q "${app_name} onion domain" $COMPLETION_FILE; then
  236. onion_address=$(cat ${COMPLETION_FILE} | grep "${app_name} onion domain" | head -n 1 | awk -F ':' '{print $2}')
  237. fi
  238. echo -n -e "$(pad_string "${app_name}")"
  239. echo -n -e "$(pad_string "${icann_address}")"
  240. echo "${onion_address}"
  241. if grep -q "${app_name}_mobile onion domain" $COMPLETION_FILE; then
  242. if grep -q "${app_name}_mobile onion domain" $COMPLETION_FILE; then
  243. onion_address=$(cat ${COMPLETION_FILE} | grep "${app_name}_mobile onion domain" | head -n 1 | awk -F ':' '{print $2}')
  244. fi
  245. echo -n -e "$(pad_string "${app_name} (mobile)")"
  246. echo -n -e "$(pad_string "${icann_address}")"
  247. echo "${onion_address}"
  248. fi
  249. fi
  250. done
  251. if grep -q "rss reader domain" $COMPLETION_FILE; then
  252. if [ -d /var/lib/tor/hidden_service_ttrss ]; then
  253. echo -n -e "$(pad_string 'RSS reader')"
  254. RSSDOM='-'
  255. echo -n -e "$(pad_string ${RSSDOM})"
  256. echo -n "$(cat /var/lib/tor/hidden_service_ttrss/hostname)"
  257. echo ''
  258. fi
  259. if [ -d /var/lib/tor/hidden_service_ttrss_mobile ]; then
  260. echo -n -e "$(pad_string 'RSS mobile')"
  261. RSSMOBILEDOM='-'
  262. echo -n -e "$(pad_string ${RSSMOBILEDOM})"
  263. echo -n "$(cat /var/lib/tor/hidden_service_ttrss_mobile/hostname)"
  264. echo ''
  265. fi
  266. fi
  267. echo ''
  268. }
  269. function show_users {
  270. echo 'Users'
  271. echo '====='
  272. echo ''
  273. echo -n -e "$(pad_string 'Name')"
  274. echo -n -e "$(pad_string 'SIP ext')"
  275. echo -n -e "$(pad_string 'Data')"
  276. echo ''
  277. echo '--------------------------------------------------------------------------'
  278. for d in /home/*/ ; do
  279. USRNAME=$(echo "$d" | awk -F '/' '{print $3}')
  280. if [[ $(is_valid_user "$USRNAME") == "1" ]]; then
  281. echo -n -e "$(pad_string ${USRNAME})"
  282. # get the SIP extension
  283. SIPEXT=
  284. if [ -f $SIP_CONFIGURATION_FILE ]; then
  285. while read ext; do
  286. if [[ $ext == *"user id"* ]]; then
  287. CURR_UID=$(echo "$ext" | awk -F '"' '{print $2}' | awk -F '"' '{print $1}')
  288. fi
  289. if [[ $ext == *"extension"* ]]; then
  290. if [[ $CURR_UID == $USRNAME ]]; then
  291. SIPEXT=$(echo "$ext" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')
  292. fi
  293. fi
  294. done < $SIP_CONFIGURATION_FILE
  295. fi
  296. if [ $SIPEXT ]; then
  297. echo -n -e "$(pad_string SIP:${SIPEXT})"
  298. else
  299. echo -n -e "$(pad_string '')"
  300. fi
  301. # size of the home directory
  302. echo "$(du -s -h /home/${USRNAME} | awk -F ' ' '{print $1}')"
  303. fi
  304. done
  305. echo ''
  306. }
  307. function show_mirrors_password {
  308. if [ ! /home/mirrors ]; then
  309. return
  310. fi
  311. read_config_param "MY_MIRRORS_PASSWORD"
  312. echo 'Local Mirrors'
  313. echo '============='
  314. echo ''
  315. echo -n "URL: "
  316. echo "$(cat ${COMPLETION_FILE} | grep 'ssh onion domain' | awk -F ':' '{print $2}')"
  317. echo "SSH Port: $SSH_PORT"
  318. echo "Password: $MY_MIRRORS_PASSWORD"
  319. echo ''
  320. }
  321. function show_tahoe_introducer {
  322. if [ ! -f /home/tahoelafs/.tahoe-introducer/private/introducer.furl ]; then
  323. return
  324. fi
  325. echo 'Tahoe-LAFS'
  326. echo '=========='
  327. echo ''
  328. cat /home/tahoelafs/.tahoe-introducer/private/introducer.furl
  329. echo ''
  330. }
  331. function show_ip_addresses {
  332. echo 'IP/DNS addresses'
  333. echo '================'
  334. echo ''
  335. echo -n "IPv4: $(get_ipv4_address)"
  336. ipv6_address="$(get_ipv6_address)"
  337. if [ ${#ipv6_address} -gt 0 ]; then
  338. echo " IPv6: ${ipv6_address}"
  339. fi
  340. echo ''
  341. echo ''
  342. }
  343. function show_about {
  344. clear
  345. echo ''
  346. echo $' Detecting installed apps...'
  347. detect_apps
  348. get_apps_installed_names
  349. clear
  350. show_ip_addresses
  351. show_domains
  352. show_mirrors_password
  353. show_tahoe_introducer
  354. show_users
  355. any_key
  356. }
  357. function select_user {
  358. SELECTED_USERNAME=
  359. users_array=($(ls /home))
  360. delete=(mirrors git)
  361. for del in ${delete[@]}
  362. do
  363. users_array=(${users_array[@]/$del})
  364. done
  365. i=0
  366. W=()
  367. name=()
  368. for u in ${users_array[@]}
  369. do
  370. if [[ $(is_valid_user "$u") == "1" ]]; then
  371. i=$((i+1))
  372. W+=($i "$u")
  373. name+=("$u")
  374. fi
  375. done
  376. if [ $i -eq 1 ]; then
  377. SELECTED_USERNAME="${name[0]}"
  378. else
  379. user_index=$(dialog --backtitle $"Freedombone Control Panel" --title $"Select User" --menu $"Select one of the following:" 24 40 17 "${W[@]}" 3>&2 2>&1 1>&3)
  380. if [ $? -eq 0 ]; then
  381. SELECTED_USERNAME="${name[$((user_index-1))]}"
  382. fi
  383. fi
  384. }
  385. function smtp_proxy {
  386. MUTTRC_FILE=/home/$ADMIN_USER/.muttrc
  387. if [ ! -f $MUTTRC_FILE ]; then
  388. return
  389. fi
  390. data=$(tempfile 2>/dev/null)
  391. trap "rm -f $data" 0 1 2 5 15
  392. dialog --backtitle $"Freedombone Control Panel" \
  393. --title $"SMTP Proxy for $ADMIN_USER" \
  394. --form $"You may need to proxy outgoing email via your ISP's mail server. If so enter the details below." 14 75 6 \
  395. $"Enable proxy:" 1 1 "$SMTP_PROXY_ENABLE" 1 24 5 5 \
  396. $"Protocol (smtp/smtps):" 2 1 "$SMTP_PROXY_PROTOCOL" 2 24 5 5 \
  397. $"ISP mail server:" 3 1 "$SMTP_PROXY_SERVER" 3 24 40 10000 \
  398. $"Port:" 4 1 "$SMTP_PROXY_PORT" 4 24 5 5 \
  399. $"Username:" 5 1 "$SMTP_PROXY_USERNAME" 5 24 40 10000 \
  400. $"Password:" 6 1 "$SMTP_PROXY_PASSWORD" 6 24 40 10000 \
  401. 2> $data
  402. sel=$?
  403. case $sel in
  404. 1) return;;
  405. 255) return;;
  406. esac
  407. SMTP_PROXY_ENABLE=$(cat $data | sed -n 1p)
  408. SMTP_PROXY_PROTOCOL=$(cat $data | sed -n 2p)
  409. SMTP_PROXY_SERVER=$(cat $data | sed -n 3p)
  410. SMTP_PROXY_PORT=$(cat $data | sed -n 4p)
  411. SMTP_PROXY_USERNAME=$(cat $data | sed -n 5p)
  412. SMTP_PROXY_PASSWORD=$(cat $data | sed -n 6p)
  413. # change muttrc
  414. if [ $SMTP_PROXY_ENABLE != $'no' ]; then
  415. if ! grep "set smtp_url" $MUTTRC_FILE; then
  416. echo "set smtp_url=\"${SMTP_PROXY_PROTOCOL}://${SMTP_PROXY_USERNAME}:${SMTP_PROXY_PASSWORD}@${SMTP_PROXY_SERVER}:${SMTP_PROXY_PORT}/\"" >> $MUTTRC_FILE
  417. else
  418. sed -i "s|set smtp_url=.*|set smtp_url=\"${SMTP_PROXY_PROTOCOL}://${SMTP_PROXY_USERNAME}:${SMTP_PROXY_PASSWORD}@${SMTP_PROXY_SERVER}:${SMTP_PROXY_PORT}/\"|g" $MUTTRC_FILE
  419. fi
  420. sed -i 's|#set smtp_url|set smtp_url|g' $MUTTRC_FILE
  421. else
  422. if grep "set smtp_url" $MUTTRC_FILE; then
  423. sed -i 's|set smtp_url|#set smtp_url|g' $MUTTRC_FILE
  424. fi
  425. fi
  426. # save settings within the main configuration file
  427. write_config_param "SMTP_PROXY_ENABLE" "$SMTP_PROXY_ENABLE"
  428. write_config_param "SMTP_PROXY_PROTOCOL" "$SMTP_PROXY_PROTOCOL"
  429. write_config_param "SMTP_PROXY_SERVER" "$SMTP_PROXY_SERVER"
  430. write_config_param "SMTP_PROXY_PORT" "$SMTP_PROXY_PORT"
  431. write_config_param "SMTP_PROXY_USERNAME" "$SMTP_PROXY_USERNAME"
  432. write_config_param "SMTP_PROXY_PASSWORD" "$SMTP_PROXY_PASSWORD"
  433. }
  434. function delete_user {
  435. select_user
  436. if [ ! $SELECTED_USERNAME ]; then
  437. return
  438. fi
  439. if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then
  440. dialog --title $"Administrator user" \
  441. --msgbox $"You can't delete the administrator user" 6 40
  442. return
  443. fi
  444. clear
  445. ${PROJECT_NAME}-rmuser $SELECTED_USERNAME
  446. any_key
  447. }
  448. function configure_remote_backups {
  449. if ! grep -Fxq "Admin user:$ADMIN_USER" $COMPLETION_FILE; then
  450. dialog --title $"Administrator user" \
  451. --msgbox $"No Administrator user found. Check $COMPLETION_FILE" 6 40
  452. return
  453. fi
  454. if [ ${#ADMIN_USER} -lt 2 ]; then
  455. dialog --title $"Administrator user" \
  456. --msgbox $"Username not found" 6 40
  457. return
  458. fi
  459. if [ ! -d /home/$ADMIN_USER ]; then
  460. dialog --title $"Administrator user" \
  461. --msgbox $"Home directory not found" 6 40
  462. return
  463. fi
  464. ${PROJECT_NAME}-remote -u $ADMIN_USER
  465. if [ ! "$?" = "0" ]; then
  466. any_key
  467. fi
  468. }
  469. function change_password {
  470. select_user
  471. if [ ! $SELECTED_USERNAME ]; then
  472. return
  473. fi
  474. dialog --title $"Change password" \
  475. --passwordbox $"New password for user $SELECTED_USERNAME" 8 40 2> $data
  476. newpassword=$(<$data)
  477. if [ ${#newpassword} -lt ${MINIMUM_PASSWORD_LENGTH} ]; then
  478. dialog --title $"Change password" \
  479. --msgbox $"The password should be ${MINIMUM_PASSWORD_LENGTH} or more characters" 6 40
  480. return
  481. fi
  482. echo "$SELECTED_USERNAME:$newpassword"|chpasswd
  483. dialog --title $"Change password" \
  484. --msgbox $"Password for $SELECTED_USERNAME was changed" 6 40
  485. }
  486. function change_ssh_public_key {
  487. select_user
  488. if [ ! $SELECTED_USERNAME ]; then
  489. return
  490. fi
  491. if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then
  492. dialog --title $"Change ssh public key" \
  493. --backtitle $"Freedombone Control Panel" \
  494. --defaultno \
  495. --yesno $"\nThis is the administrator user.\n\nAre you sure you want to change the ssh public key for the administrator?" 10 60
  496. sel=$?
  497. case $sel in
  498. 1) return;;
  499. 255) return;;
  500. esac
  501. fi
  502. data=$(tempfile 2>/dev/null)
  503. trap "rm -f $data" 0 1 2 5 15
  504. dialog --title $"Change ssh public key for $SELECTED_USERNAME" \
  505. --backtitle $"Freedombone Control Panel" \
  506. --inputbox $"Paste the ssh public key below" 8 60 2>$data
  507. sel=$?
  508. case $sel in
  509. 0)
  510. SSH_PUBLIC_KEY=$(<$data)
  511. if [ "$SSH_PUBLIC_KEY" ]; then
  512. if [ ${#SSH_PUBLIC_KEY} -gt 5 ]; then
  513. if [ -f "$SSH_PUBLIC_KEY" ]; then
  514. if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then
  515. mkdir /home/$SELECTED_USERNAME/.ssh
  516. fi
  517. cp $SSH_PUBLIC_KEY \
  518. /home/$SELECTED_USERNAME/.ssh/authorized_keys
  519. chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \
  520. /home/$SELECTED_USERNAME/.ssh
  521. dialog --title $"Change ssh public key" \
  522. --msgbox $"ssh public key was installed" 6 40
  523. else
  524. if [[ "$SSH_PUBLIC_KEY" == "ssh-"* ]]; then
  525. if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then
  526. mkdir /home/$SELECTED_USERNAME/.ssh
  527. fi
  528. echo "$SSH_PUBLIC_KEY" > \
  529. /home/$SELECTED_USERNAME/.ssh/authorized_keys
  530. chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \
  531. /home/$SELECTED_USERNAME/.ssh
  532. dialog --title $"Change ssh public key" \
  533. --msgbox $"ssh public key was installed" 6 40
  534. fi
  535. fi
  536. fi
  537. fi
  538. ;;
  539. esac
  540. }
  541. function remove_user_from_mailing_list {
  542. select_user
  543. if [ ! $SELECTED_USERNAME ]; then
  544. return
  545. fi
  546. USER_MAILING_LISTS=$(cat "/home/$SELECTED_USERNAME/.procmailrc" | grep '\[' | grep '\]' | awk -F '\[' '{print $2}' | awk -F '\\' '{print $1}')
  547. i=0
  548. W=()
  549. list_name=()
  550. while read -r listname; do
  551. i=$((i+1))
  552. W+=($i "$listname")
  553. list_name+=("$listname")
  554. echo $listname
  555. done <<< "$USER_MAILING_LISTS"
  556. i=$((i+1))
  557. W+=($i $"Exit back to user mainenance")
  558. list_selected=$(dialog --default-item "$i" --backtitle $"Freedombone Control Panel" --title $"Remove a mailing list for $SELECTED_USERNAME" --menu $"Select one of the following:" 24 50 17 "${W[@]}" 3>&2 2>&1 1>&3)
  559. if [ $? -eq 0 ]; then # Exit with OK
  560. if [ ${list_selected} -ne ${i} ]; then
  561. remove_list_name="${list_name[$((list_selected-1))]}"
  562. # find the line number where the list is defined
  563. line_number=0
  564. i=0
  565. while read -r line
  566. do
  567. if [[ "$line" == *"\[${remove_list_name}\\]"* ]]; then
  568. line_number=${i}
  569. fi
  570. i=$((i+1))
  571. done < "/home/$SELECTED_USERNAME/.procmailrc"
  572. if [ ${line_number} -eq 0 ]; then
  573. # no match was found
  574. return
  575. fi
  576. # recreate the file
  577. if [ -f /home/${SELECTED_USERNAME}/.procmailrc_new ]; then
  578. rm /home/${SELECTED_USERNAME}/.procmailrc_new
  579. fi
  580. i=0
  581. clip=0
  582. while read -r line
  583. do
  584. i=$((i+1))
  585. if [ ${i} -gt $((line_number-1)) ]; then
  586. if [ ${clip} -eq 0 ]; then
  587. clip=1
  588. fi
  589. if [ ${clip} -eq 1 ]; then
  590. if [ ${i} -lt $((line_number+2)) ]; then
  591. continue
  592. else
  593. if [ ${#line} -lt 1 ]; then
  594. clip=2
  595. continue
  596. fi
  597. if [[ "$line" == ":"* || "$line" == "#"* ]]; then
  598. clip=2
  599. else
  600. continue
  601. fi
  602. fi
  603. fi
  604. fi
  605. echo "$line" >> /home/${SELECTED_USERNAME}/.procmailrc_new
  606. if [[ "$line" == *"\[${remove_list_name}\\]"* ]]; then
  607. line_number=${i}
  608. fi
  609. done < "/home/$SELECTED_USERNAME/.procmailrc"
  610. cp /home/${SELECTED_USERNAME}/.procmailrc_new /home/${SELECTED_USERNAME}/.procmailrc
  611. rm /home/${SELECTED_USERNAME}/.procmailrc_new
  612. chown ${SELECTED_USERNAME}:${SELECTED_USERNAME} /home/${SELECTED_USERNAME}/.procmailrc
  613. dialog --title $"Remove user from mailing list" \
  614. --msgbox $"${SELECTED_USERNAME} has been removed from ${remove_list_name}" 6 50
  615. fi
  616. fi
  617. }
  618. function add_to_mailing_list {
  619. select_user
  620. if [ ! $SELECTED_USERNAME ]; then
  621. return
  622. fi
  623. data=$(tempfile 2>/dev/null)
  624. trap "rm -f $data" 0 1 2 5 15
  625. dialog --backtitle $"Freedombone Control Panel" \
  626. --title $"Subscribe $SELECTED_USERNAME to a mailing list" \
  627. --form $"You can either enter a subject or an email address\n" 11 68 4 \
  628. $"List folder name:" 1 1 "" 1 35 26 25 \
  629. $"Name between [] on subject line:" 2 1 "" 2 35 26 25 \
  630. $"List email address:" 3 1 "" 3 35 26 25 \
  631. $"Public:" 4 1 $"yes" 4 35 4 25 \
  632. 2> $data
  633. sel=$?
  634. case $sel in
  635. 1) return;;
  636. 255) return;;
  637. esac
  638. LIST_NAME=$(cat $data | sed -n 1p)
  639. LIST_SUBJECT=$(cat $data | sed -n 2p)
  640. LIST_EMAIL=$(cat $data | sed -n 3p)
  641. LIST_PUBLIC=$(cat $data | sed -n 4p)
  642. if [ ${#LIST_PUBLIC} -lt 1 ]; then
  643. LIST_PUBLIC='no'
  644. fi
  645. if [[ $LIST_PUBLIC == $'y' || $LIST_PUBLIC == $'Y' || $LIST_PUBLIC == $'true' || $LIST_PUBLIC == $'True' || $LIST_PUBLIC == $'yes' || $LIST_PUBLIC == $'Yes' || $LIST_PUBLIC == $'YES' ]]; then
  646. LIST_PUBLIC='yes'
  647. else
  648. LIST_PUBLIC='no'
  649. fi
  650. if [ ${#LIST_NAME} -lt 2 ]; then
  651. dialog --title $"Add mailing list" \
  652. --msgbox $"No mailing list name was given" 6 40
  653. return
  654. fi
  655. if [ ${#LIST_SUBJECT} -lt 2 ]; then
  656. if [ ${#LIST_EMAIL} -lt 2 ]; then
  657. dialog --title $"Add mailing list" \
  658. --msgbox $"No mailing list subject or address was given" 6 40
  659. return
  660. fi
  661. fi
  662. if [ ${#LIST_SUBJECT} -gt 1 ]; then
  663. ${PROJECT_NAME}-addlist -u $SELECTED_USERNAME -l "$LIST_NAME" \
  664. -s "$LIST_SUBJECT" --public $LIST_PUBLIC
  665. else
  666. if [[ "$LIST_EMAIL" != *"@"* || "$LIST_EMAIL" != *"."* ]]; then
  667. dialog --title $"Add mailing list" \
  668. --msgbox $"Unrecognised email address" 6 40
  669. return
  670. else
  671. ${PROJECT_NAME}-addlist -u $SELECTED_USERNAME -l "$LIST_NAME" \
  672. -e "$LIST_EMAIL" --public $LIST_PUBLIC
  673. fi
  674. fi
  675. dialog --title $"Add mailing list" \
  676. --msgbox $"$LIST_NAME list was added" 6 40
  677. }
  678. function email_rule {
  679. select_user
  680. if [ ! $SELECTED_USERNAME ]; then
  681. return
  682. fi
  683. data=$(tempfile 2>/dev/null)
  684. trap "rm -f $data" 0 1 2 5 15
  685. dialog --backtitle $"Freedombone Control Panel" \
  686. --title $"Email rule for user $SELECTED_USERNAME" \
  687. --form "\n" 9 65 4 \
  688. $"When email arrives from address:" 1 1 "" 1 35 24 28 \
  689. $"Move to folder:" 2 1 "" 2 35 24 28 \
  690. $"Public:" 3 1 $"no" 3 35 4 25 \
  691. 2> $data
  692. sel=$?
  693. case $sel in
  694. 1) return;;
  695. 255) return;;
  696. esac
  697. RULE_EMAIL=$(cat $data | sed -n 1p)
  698. RULE_FOLDER=$(cat $data | sed -n 2p)
  699. RULE_PUBLIC=$(cat $data | sed -n 3p)
  700. if [ ${#RULE_PUBLIC} -lt 1 ]; then
  701. RULE_PUBLIC='no'
  702. fi
  703. if [[ $RULE_PUBLIC == $'y' || $RULE_PUBLIC == $'Y' || $RULE_PUBLIC == $'true' || $RULE_PUBLIC == $'True' || $RULE_PUBLIC == $'yes' || $RULE_PUBLIC == $'Yes' || $RULE_PUBLIC == $'YES' ]]; then
  704. RULE_PUBLIC='yes'
  705. else
  706. RULE_PUBLIC='no'
  707. fi
  708. if [ ${#RULE_EMAIL} -lt 2 ]; then
  709. dialog --title $"Add email rule" \
  710. --msgbox $"No email address was given" 6 40
  711. return
  712. fi
  713. if [ ${#RULE_FOLDER} -lt 2 ]; then
  714. dialog --title $"Add email rule" \
  715. --msgbox $"No folder name was given" 6 40
  716. return
  717. fi
  718. if [[ "$RULE_EMAIL" != *"@"* || "$RULE_EMAIL" != *"."* ]]; then
  719. dialog --title $"Add email rule" \
  720. --msgbox $"Unrecognised email address" 6 40
  721. return
  722. fi
  723. ${PROJECT_NAME}-addemail -u $SELECTED_USERNAME -e "$RULE_EMAIL" \
  724. -g "$RULE_FOLDER" --public $RULE_PUBLIC
  725. dialog --title $"Add email rule" \
  726. --msgbox $"Email rule for $RULE_EMAIL was added" 6 40
  727. }
  728. function block_unblock_email {
  729. select_user
  730. if [ ! $SELECTED_USERNAME ]; then
  731. return
  732. fi
  733. blockstr=$"Block/Unblock email going to"
  734. data=$(tempfile 2>/dev/null)
  735. trap "rm -f $data" 0 1 2 5 15
  736. dialog --backtitle $"Freedombone Control Panel" \
  737. --title "$blockstr $SELECTED_USERNAME" \
  738. --form "\n" 8 65 3 \
  739. $"When email arrives from address:" 1 1 "" 1 35 24 100 \
  740. $"Block it:" 2 1 "yes" 2 35 4 4 \
  741. 2> $data
  742. sel=$?
  743. case $sel in
  744. 1) return;;
  745. 255) return;;
  746. esac
  747. BLOCK_EMAIL=$(cat $data | sed -n 1p)
  748. BLOCK=$(cat $data | sed -n 2p)
  749. if [ ${#BLOCK_EMAIL} -lt 2 ]; then
  750. dialog --title $"Block/Unblock an email" \
  751. --msgbox $"No email address was given" 6 40
  752. return
  753. fi
  754. if [[ "$BLOCK_EMAIL" != *"@"* || "$BLOCK_EMAIL" != *"."* ]]; then
  755. dialog --title $"Block/Unblock an email" \
  756. --msgbox $"Unrecognised email address" 6 40
  757. return
  758. fi
  759. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  760. ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL"
  761. dialog --title $"Block an email" \
  762. --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME blocked" 6 75
  763. else
  764. ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL"
  765. dialog --title $"Unblock an email" \
  766. --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME unblocked" 6 75
  767. fi
  768. }
  769. function block_unblock_subject {
  770. select_user
  771. if [ ! $SELECTED_USERNAME ]; then
  772. return
  773. fi
  774. blockstr=$"Block/Unblock email going to"
  775. data=$(tempfile 2>/dev/null)
  776. trap "rm -f $data" 0 1 2 5 15
  777. dialog --backtitle $"Freedombone Control Panel" \
  778. --title "$blockstr $SELECTED_USERNAME" \
  779. --form "\n" 8 70 3 \
  780. $"When email arrives with subject text:" 1 1 "" 1 40 24 28 \
  781. $"Block it:" 2 1 "yes" 2 40 4 4 \
  782. 2> $data
  783. sel=$?
  784. case $sel in
  785. 1) return;;
  786. 255) return;;
  787. esac
  788. BLOCK_SUBJECT=$(cat $data | sed -n 1p)
  789. BLOCK=$(cat $data | sed -n 2p)
  790. if [ ${#BLOCK_SUBJECT} -lt 2 ]; then
  791. dialog --title $"Block/Unblock an email" \
  792. --msgbox $"No subject was given" 6 40
  793. return
  794. fi
  795. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  796. ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT"
  797. dialog --title $"Block an email" \
  798. --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME blocked" 6 40
  799. else
  800. ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT"
  801. dialog --title $"Unblock an email" \
  802. --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME unblocked" 6 40
  803. fi
  804. }
  805. function create_keydrive_master {
  806. select_user
  807. if [ ! $SELECTED_USERNAME ]; then
  808. return
  809. fi
  810. dialog --title $"USB Master Keydrive" \
  811. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  812. clear
  813. ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME --master 'yes'
  814. any_key
  815. }
  816. function create_keydrive_fragment {
  817. select_user
  818. if [ ! $SELECTED_USERNAME ]; then
  819. return
  820. fi
  821. dialog --title $"USB Fragment Keydrive" \
  822. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  823. clear
  824. ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME
  825. any_key
  826. }
  827. function backup_data {
  828. dialog --title $"Backup data to USB" \
  829. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  830. clear
  831. echo ' '
  832. echo $'Enter the passphrase for your LUKS encrypted backup drive:'
  833. ${PROJECT_NAME}-backup-local
  834. any_key
  835. }
  836. function restore_data_from_storage {
  837. restore_type="$1"
  838. if [[ $restore_type != "local" ]]; then
  839. restore_command="${PROJECT_NAME}-restore-remote $remote_domain_name configuration;;"
  840. else
  841. remote_domain_name="$1"
  842. if [ ! -b $USB_DRIVE ]; then
  843. if [ -b /dev/sdb1 ]; then
  844. USB_DRIVE=/dev/sdb1
  845. fi
  846. if [ -b /dev/sdc1 ]; then
  847. USB_DRIVE=/dev/sdc1
  848. fi
  849. if [ -b /dev/sdd1 ]; then
  850. USB_DRIVE=/dev/sdd1
  851. fi
  852. if [ -b /dev/sde1 ]; then
  853. USB_DRIVE=/dev/sde1
  854. fi
  855. write_config_param USB_DRIVE "$USB_DRIVE"
  856. fi
  857. restore_command="${PROJECT_NAME}-restore-local $USB_DRIVE"
  858. fi
  859. utils_installed=(config
  860. mariadb
  861. letsencrypt
  862. mutt
  863. gpg
  864. procmail
  865. spamassassin
  866. readme
  867. ssh
  868. userconfig
  869. userlocal
  870. userfin
  871. certs
  872. personal)
  873. detect_apps
  874. app_list=()
  875. AllStr=$"all"
  876. n=1
  877. applist="$n $AllStr off"
  878. n=$[n+1]
  879. util_index=0
  880. for a in "${utils_installed[@]}"
  881. do
  882. applist="$applist $n $a off"
  883. app_name=${utils_installed[util_index]}
  884. n=$[n+1]
  885. util_index=$[util_index+1]
  886. app_list+=("$app_name")
  887. done
  888. app_index=0
  889. for a in "${APPS_INSTALLED_NAMES[@]}"
  890. do
  891. applist="$applist $n $a off"
  892. n=$[n+1]
  893. app_name=${APPS_INSTALLED_NAMES[app_index]}
  894. app_index=$[app_index+1]
  895. app_list+=("$app_name")
  896. done
  897. ExitStr=$"Exit"
  898. applist="$applist $n $ExitStr on"
  899. n=$[n+1]
  900. choices=$(dialog --stdout --backtitle $"Freedombone" \
  901. --title $"Restore apps" \
  902. --checklist $'Choose:' \
  903. 30 40 20 $applist)
  904. if [ $? -eq 0 ]; then
  905. clear
  906. # Test for exit
  907. for choice in $choices
  908. do
  909. app_index=$[choice-1]
  910. app_name=${app_list[app_index]}
  911. if [[ $app_name == "$ExitStr" ]]; then
  912. return
  913. fi
  914. done
  915. # Test for restoring all apps
  916. for choice in $choices
  917. do
  918. app_index=$[choice-2]
  919. app_name=${app_list[app_index]}
  920. if [[ $app_name == "$AllStr" ]]; then
  921. $restore_command
  922. if [ ! "$?" = "0" ]; then
  923. if [[ "$1" == "local" ]]; then
  924. dialog --title $"Restore all apps from USB" \
  925. --msgbox $"Restore failed with code $?" 6 40
  926. else
  927. dialog --title $"Restore all apps from $1" \
  928. --msgbox $"Restore failed with code $?" 6 40
  929. fi
  930. return
  931. fi
  932. if [[ "$1" == "local" ]]; then
  933. dialog --title $"Restore all apps from USB" \
  934. --msgbox $"Restore complete" 6 40
  935. else
  936. dialog --title $"Restore all apps from $1" \
  937. --msgbox $"Restore complete" 6 40
  938. fi
  939. return
  940. fi
  941. done
  942. ctr=0
  943. for choice in $choices
  944. do
  945. app_index=$[choice-2]
  946. app_name=${app_list[app_index]}
  947. if [ ${#app_name} -gt 0 ]; then
  948. $restore_command "${app_name}"
  949. if [ ! "$?" = "0" ]; then
  950. dialog --title $"Restore apps from USB" \
  951. --msgbox $"Restore of ${app_name} failed with code $?" 6 40
  952. return
  953. fi
  954. fi
  955. ctr=$((ctr + 1))
  956. done
  957. if [ $ctr -gt 0 ]; then
  958. if [[ "$1" == "local" ]]; then
  959. dialog --title $"Restore apps from USB" \
  960. --msgbox $"Restore complete" 6 40
  961. else
  962. dialog --title $"Restore apps from $1" \
  963. --msgbox $"Restore complete" 6 40
  964. fi
  965. return
  966. fi
  967. fi
  968. any_key
  969. }
  970. function restore_data {
  971. dialog --title $"Restore data from USB" \
  972. --msgbox $"Plug in your backup USB drive" 6 40
  973. clear
  974. echo ' '
  975. echo $'Enter the passphrase for your LUKS encrypted backup drive:'
  976. restore_data_from_storage local
  977. }
  978. function restore_data_remote {
  979. if [ ! $ADMIN_USER ]; then
  980. dialog --title $"Restore data from remote server" \
  981. --msgbox $"Unknown admin user" 6 40
  982. return
  983. fi
  984. data=$(tempfile 2>/dev/null)
  985. trap "rm -f $data" 0 1 2 5 15
  986. dialog --title $"Restore from remote server" \
  987. --backtitle $"Freedombone Control Panel" \
  988. --inputbox $"Enter the domain name of the server from which you wish to restore" 8 60 2>$data
  989. sel=$?
  990. case $sel in
  991. 0)
  992. friend_server_domain_name=$(<$data)
  993. if [ ${#friend_server_domain_name} -lt 2 ]; then
  994. return
  995. fi
  996. if [[ $friend_server_domain_name != *"."* ]]; then
  997. dialog --title $"Remote server domain name" \
  998. --msgbox $"Invalid domain name" 6 40
  999. return
  1000. fi
  1001. restore_data_from_storage $friend_server_domain_name
  1002. ;;
  1003. esac
  1004. }
  1005. function ping_enable_disable {
  1006. 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."
  1007. enable_ping="no"
  1008. dialog --title $"Enable Ping / ICMP" \
  1009. --backtitle $"Freedombone Control Panel" \
  1010. --defaultno \
  1011. --yesno "$ping_str" 10 60
  1012. sel=$?
  1013. case $sel in
  1014. 0) enable_ping="yes";;
  1015. 255) return;;
  1016. esac
  1017. if [[ $enable_ping == "yes" ]]; then
  1018. iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
  1019. iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
  1020. echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all
  1021. else
  1022. iptables -D INPUT -p icmp --icmp-type echo-request -j ACCEPT
  1023. iptables -D OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
  1024. echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
  1025. fi
  1026. }
  1027. function logging_on_off {
  1028. logging="no"
  1029. dialog --title $"Logging" \
  1030. --backtitle $"Freedombone Control Panel" \
  1031. --yesno $"\nDo you want to turn logging on?" 7 60
  1032. sel=$?
  1033. case $sel in
  1034. 0) logging="yes";;
  1035. 255) return;;
  1036. esac
  1037. clear
  1038. echo ''
  1039. echo $'This may take a few seconds. Please wait...'
  1040. if [[ $logging == "no" ]]; then
  1041. ${PROJECT_NAME}-logging off
  1042. else
  1043. ${PROJECT_NAME}-logging on
  1044. fi
  1045. }
  1046. function restore_gpg_key {
  1047. select_user
  1048. if [ ! $SELECTED_USERNAME ]; then
  1049. return
  1050. fi
  1051. restorestr=$"Restore GPG key for user"
  1052. dialog --title "$restorestr $SELECTED_USERNAME" \
  1053. --msgbox $"Plug in your USB keydrive" 6 40
  1054. clear
  1055. ${PROJECT_NAME}-recoverkey -u $SELECTED_USERNAME
  1056. any_key
  1057. }
  1058. function security_settings {
  1059. ${PROJECT_NAME}-sec
  1060. any_key
  1061. }
  1062. function reset_tripwire {
  1063. if [ ! -f /usr/bin/reset-tripwire ]; then
  1064. return
  1065. fi
  1066. clear
  1067. echo $'Resetting the Tripwire...'
  1068. echo ' '
  1069. echo '
  1070. ' | reset-tripwire
  1071. any_key
  1072. }
  1073. function format_drive {
  1074. drive=
  1075. data=$(tempfile 2>/dev/null)
  1076. trap "rm -f $data" 0 1 2 5 15
  1077. dialog --backtitle $"Freedombone Control Panel" \
  1078. --title $"Format a USB drive (LUKS encrypted)" \
  1079. --radiolist $"Choose a drive:" 12 70 5 \
  1080. 1 $"sda (Beaglebone Black)" off \
  1081. 2 $"sdb" off \
  1082. 3 $"sdc" off \
  1083. 4 $"sdd" off \
  1084. 5 $"Back to Backup and Restore menu" on 2> $data
  1085. sel=$?
  1086. case $sel in
  1087. 1) return;;
  1088. 255) return;;
  1089. esac
  1090. case $(cat $data) in
  1091. 1) drive='sda';;
  1092. 2) drive='sdb';;
  1093. 3) drive='sdc';;
  1094. 4) drive='sdd';;
  1095. 5) return;;
  1096. esac
  1097. dialog --title $"Format USB drive" \
  1098. --backtitle $"Freedombone Control Panel" \
  1099. --defaultno \
  1100. --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
  1101. sel=$?
  1102. case $sel in
  1103. 1) return;;
  1104. 255) return;;
  1105. esac
  1106. clear
  1107. ${PROJECT_NAME}-format $drive
  1108. any_key
  1109. }
  1110. function remove_backups {
  1111. drive=
  1112. data=$(tempfile 2>/dev/null)
  1113. trap "rm -f $data" 0 1 2 5 15
  1114. dialog --backtitle $"Freedombone Control Panel" \
  1115. --title $"Remove backups from a USB drive" \
  1116. --radiolist $"Choose a drive:" 12 70 5 \
  1117. 1 $"sda (Beaglebone Black)" off \
  1118. 2 $"sdb" off \
  1119. 3 $"sdc" off \
  1120. 4 $"sdd" off \
  1121. 5 $"Back to Backup and Restore menu" on 2> $data
  1122. sel=$?
  1123. case $sel in
  1124. 1) return;;
  1125. 255) return;;
  1126. esac
  1127. case $(cat $data) in
  1128. 1) drive='sda';;
  1129. 2) drive='sdb';;
  1130. 3) drive='sdc';;
  1131. 4) drive='sdd';;
  1132. 5) return;;
  1133. esac
  1134. dialog --title $"Remove backups from a USB drive" \
  1135. --backtitle $"Freedombone Control Panel" \
  1136. --defaultno \
  1137. --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
  1138. sel=$?
  1139. case $sel in
  1140. 1) return;;
  1141. 255) return;;
  1142. esac
  1143. clear
  1144. ${PROJECT_NAME}-backup-local $drive remove
  1145. any_key
  1146. }
  1147. function shut_down_system {
  1148. dialog --title $"Power off the system" \
  1149. --backtitle $"Freedombone Control Panel" \
  1150. --defaultno \
  1151. --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
  1152. sel=$?
  1153. case $sel in
  1154. 1) return;;
  1155. 255) return;;
  1156. esac
  1157. shutdown now
  1158. }
  1159. function restart_system {
  1160. dialog --title $"Restart the system" \
  1161. --backtitle $"Freedombone Control Panel" \
  1162. --defaultno \
  1163. --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
  1164. sel=$?
  1165. case $sel in
  1166. 1) return;;
  1167. 255) return;;
  1168. esac
  1169. reboot
  1170. }
  1171. function change_system_name {
  1172. data=$(tempfile 2>/dev/null)
  1173. trap "rm -f $data" 0 1 2 5 15
  1174. dialog --title $"Change the name of this system" \
  1175. --backtitle $"Freedombone Control Panel" \
  1176. --inputbox $'Enter a new name for this system on your local network\n\nIt will appear as newname.local' 10 60 2>$data
  1177. sel=$?
  1178. case $sel in
  1179. 0) NEW_SYSTEM_NAME=$(<$data)
  1180. if [ "$NEW_SYSTEM_NAME" ]; then
  1181. if [ ${#NEW_SYSTEM_NAME} -gt 1 ]; then
  1182. sed -i "s|host-name=.*|host-name=$NEW_SYSTEM_NAME|g" /etc/avahi/avahi-daemon.conf
  1183. systemctl restart avahi-daemon
  1184. if grep -q "host-name=$NEW_SYSTEM_NAME" /etc/avahi/avahi-daemon.conf; then
  1185. dialog --title $"New local network name" \
  1186. --msgbox $"The name of this system on your local network was changed successfully" 6 70
  1187. fi
  1188. fi
  1189. fi
  1190. ;;
  1191. esac
  1192. }
  1193. function set_static_IP {
  1194. STATIC_IP='192.168.1.60'
  1195. STATIC_GATEWAY='192.168.1.1'
  1196. NEW_STATIC_IP=
  1197. NEW_STATIC_GATEWAY=
  1198. if grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1199. STATIC_IP=$(cat /etc/network/interfaces | grep "address " | awk -F ' ' '{print $2}' | head -n 1)
  1200. STATIC_GATEWAY=$(cat /etc/network/interfaces | grep "gateway " | awk -F ' ' '{print $2}' | head -n 1)
  1201. fi
  1202. # get the IP for the box
  1203. data=$(tempfile 2>/dev/null)
  1204. trap "rm -f $data" 0 1 2 5 15
  1205. dialog --title $"Set a static local IP address" \
  1206. --backtitle $"Freedombone Control Panel" \
  1207. --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
  1208. Enter a static local IP address for this system.\n\nIt will typically be 192.168.1.x" 15 60 "$STATIC_IP" 2>$data
  1209. sel=$?
  1210. case $sel in
  1211. 0) NEW_STATIC_IP=$(<$data)
  1212. if [[ "$NEW_STATIC_IP" != *"."* ]]; then
  1213. return
  1214. fi
  1215. ;;
  1216. esac
  1217. # get the gateway
  1218. data=$(tempfile 2>/dev/null)
  1219. trap "rm -f $data" 0 1 2 5 15
  1220. dialog --title $"Set the IP address of your internet router/modem" \
  1221. --backtitle $"Freedombone Control Panel" \
  1222. --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
  1223. sel=$?
  1224. case $sel in
  1225. 0) NEW_STATIC_GATEWAY=$(<$data)
  1226. if [[ "$NEW_STATIC_GATEWAY" != *"."* ]]; then
  1227. return
  1228. fi
  1229. ;;
  1230. esac
  1231. if [[ "$NEW_STATIC_GATEWAY" == *"."* && "$NEW_STATIC_IP" == *"."* ]]; then
  1232. ip_addresses_have_changed=
  1233. if ! grep -q "address ${NEW_STATIC_IP}" /etc/network/interfaces; then
  1234. ip_addresses_have_changed=1
  1235. fi
  1236. if ! grep -q "gateway ${NEW_STATIC_GATEWAY}" /etc/network/interfaces; then
  1237. ip_addresses_have_changed=1
  1238. fi
  1239. if [ $ip_addresses_have_changed ]; then
  1240. echo '# This file describes the network interfaces available on your system' > /etc/network/interfaces
  1241. echo '# and how to activate them. For more information, see interfaces(5).' >> /etc/network/interfaces
  1242. echo '' >> /etc/network/interfaces
  1243. echo '# The loopback network interface' >> /etc/network/interfaces
  1244. echo 'auto lo' >> /etc/network/interfaces
  1245. echo 'iface lo inet loopback' >> /etc/network/interfaces
  1246. echo '' >> /etc/network/interfaces
  1247. echo '# The primary network interface' >> /etc/network/interfaces
  1248. echo 'auto eth0' >> /etc/network/interfaces
  1249. echo 'iface eth0 inet static' >> /etc/network/interfaces
  1250. echo " address ${NEW_STATIC_IP}" >> /etc/network/interfaces
  1251. echo ' netmask 255.255.255.0' >> /etc/network/interfaces
  1252. echo " gateway ${NEW_STATIC_GATEWAY}" >> /etc/network/interfaces
  1253. echo " dns-nameservers 213.73.91.35 85.214.20.141" >> /etc/network/interfaces
  1254. echo '# Example to keep MAC address between reboots' >> /etc/network/interfaces
  1255. echo '#hwaddress ether DE:AD:BE:EF:CA:FE' >> /etc/network/interfaces
  1256. echo '' >> /etc/network/interfaces
  1257. echo '# The secondary network interface' >> /etc/network/interfaces
  1258. echo '#auto eth1' >> /etc/network/interfaces
  1259. echo '#iface eth1 inet dhcp' >> /etc/network/interfaces
  1260. echo '' >> /etc/network/interfaces
  1261. echo '# WiFi Example' >> /etc/network/interfaces
  1262. echo "#auto $WIFI_INTERFACE" >> /etc/network/interfaces
  1263. echo "#iface $WIFI_INTERFACE inet dhcp" >> /etc/network/interfaces
  1264. echo '# wpa-ssid "essid"' >> /etc/network/interfaces
  1265. echo '# wpa-psk "password"' >> /etc/network/interfaces
  1266. echo '' >> /etc/network/interfaces
  1267. echo '# Ethernet/RNDIS gadget (g_ether)' >> /etc/network/interfaces
  1268. echo '# ... or on host side, usbnet and random hwaddr' >> /etc/network/interfaces
  1269. echo '# Note on some boards, usb0 is automaticly setup with an init script' >> /etc/network/interfaces
  1270. echo '#iface usb0 inet static' >> /etc/network/interfaces
  1271. echo '# address 192.168.7.2' >> /etc/network/interfaces
  1272. echo '# netmask 255.255.255.0' >> /etc/network/interfaces
  1273. echo '# network 192.168.7.0' >> /etc/network/interfaces
  1274. echo '# gateway 192.168.7.1' >> /etc/network/interfaces
  1275. clear
  1276. echo ''
  1277. echo $'Restarting the network daemon.'
  1278. echo ''
  1279. echo $'If you logged in using the previous IP address then you may need to close this terminal and log in again on the new one.'
  1280. function_check pihole_change_ipv4
  1281. pihole_change_ipv4 ${NEW_STATIC_IP}
  1282. systemctl restart networking
  1283. # see if the IP address has changed
  1284. IPv4_address=$(get_ipv4_address)
  1285. if [[ "$IPv4_address" == "${NEW_STATIC_IP}"* ]]; then
  1286. pihole_update
  1287. dialog --title $"Static local IP address" \
  1288. --msgbox $"The IP address of this system is now set to ${NEW_STATIC_IP}" 6 50
  1289. else
  1290. dialog --title $"Static local IP address" \
  1291. --backtitle $"Freedombone Control Panel" \
  1292. --defaultno \
  1293. --yesno $"\nFor the change to take effect your system will now need to reboot. Do this now?" 8 60
  1294. sel=$?
  1295. case $sel in
  1296. 0) reboot;;
  1297. esac
  1298. fi
  1299. fi
  1300. fi
  1301. }
  1302. function wifi_settings {
  1303. if [ -f /etc/hostapd/hostapd.conf ]; then
  1304. return
  1305. fi
  1306. TEMP_WIFI_NETWORKS_FILE=~/.temp-${PROJECT_NAME}-wifi.cfg
  1307. ${PROJECT_NAME}-wifi --networksinteractive $TEMP_WIFI_NETWORKS_FILE
  1308. if [ -f $TEMP_WIFI_NETWORKS_FILE ]; then
  1309. cp $TEMP_WIFI_NETWORKS_FILE $WIFI_NETWORKS_FILE
  1310. rm $TEMP_WIFI_NETWORKS_FILE
  1311. ${PROJECT_NAME}-wifi --networks $WIFI_NETWORKS_FILE
  1312. dialog --title $"Wifi Settings" \
  1313. --msgbox $"Wifi settings were changed" 6 40
  1314. fi
  1315. }
  1316. function wifi_edit_networks {
  1317. if [ -f /etc/hostapd/hostapd.conf ]; then
  1318. return
  1319. fi
  1320. if [ ! -f $WIFI_NETWORKS_FILE ]; then
  1321. echo $'# Add wifi networks as follows:' > $WIFI_NETWORKS_FILE
  1322. echo '#' >> $WIFI_NETWORKS_FILE
  1323. echo $'# MySSID' >> $WIFI_NETWORKS_FILE
  1324. echo $'# wpa2-psk' >> $WIFI_NETWORKS_FILE
  1325. echo $'# myWifiPassphrase' >> $WIFI_NETWORKS_FILE
  1326. echo '#' >> $WIFI_NETWORKS_FILE
  1327. echo $'# AnotherSSID' >> $WIFI_NETWORKS_FILE
  1328. echo $'# none' >> $WIFI_NETWORKS_FILE
  1329. echo '#' >> $WIFI_NETWORKS_FILE
  1330. fi
  1331. editor $WIFI_NETWORKS_FILE
  1332. ${PROJECT_NAME}-wifi --networks $WIFI_NETWORKS_FILE
  1333. }
  1334. function hotspot_settings {
  1335. data=$(tempfile 2>/dev/null)
  1336. trap "rm -f $data" 0 1 2 5 15
  1337. dialog --backtitle $"Freedombone Control Panel" \
  1338. --title $"Hotspot Settings" \
  1339. --form $"" 10 60 4 \
  1340. $"Enabled (yes/no):" 1 1 "$WIFI_HOTSPOT" 1 24 5 5 \
  1341. $"SSID:" 2 1 "$WIFI_SSID" 2 24 256 256 \
  1342. $"Type (wpa2-psk/none):" 3 1 "$WIFI_TYPE" 3 24 10 10 \
  1343. $"Passphrase:" 4 1 "$WIFI_PASSPHRASE" 4 24 256 256 \
  1344. 2> $data
  1345. sel=$?
  1346. case $sel in
  1347. 1) return;;
  1348. 255) return;;
  1349. esac
  1350. TEMP_WIFI_HOTSPOT=$(cat $data | sed -n 1p)
  1351. TEMP_WIFI_SSID=$(cat $data | sed -n 2p)
  1352. TEMP_WIFI_TYPE=$(cat $data | sed -n 3p)
  1353. TEMP_WIFI_PASSPHRASE=$(cat $data | sed -n 4p)
  1354. if [ ${#TEMP_WIFI_SSID} -lt 2 ]; then
  1355. return
  1356. fi
  1357. if [ ${#TEMP_WIFI_TYPE} -lt 2 ]; then
  1358. return
  1359. fi
  1360. WIFI_EXTRA=''
  1361. if [[ $TEMP_WIFI_HOTSPOT == $'yes' || $TEMP_WIFI_HOTSPOT == $'y' || $TEMP_WIFI_HOTSPOT == $'on' ]]; then
  1362. TEMP_WIFI_HOTSPOT='yes'
  1363. else
  1364. TEMP_WIFI_HOTSPOT='no'
  1365. if [ -f $WIFI_NETWORKS_FILE ]; then
  1366. WIFI_EXTRA='--networks $WIFI_NETWORKS_FILE'
  1367. fi
  1368. fi
  1369. if [[ $TEMP_WIFI_TYPE != $'none' ]]; then
  1370. if [ ! $TEMP_WIFI_PASSPHRASE ]; then
  1371. dialog --title $"Wifi Settings" \
  1372. --msgbox $"No wifi hotspot passphrase was given" 6 40
  1373. return
  1374. fi
  1375. if [ ${#TEMP_WIFI_PASSPHRASE} -lt 2 ]; then
  1376. dialog --title $"Wifi Settings" \
  1377. --msgbox $"Wifi hotspot passphrase was too short" 6 40
  1378. return
  1379. fi
  1380. WIFI_HOTSPOT=$TEMP_WIFI_HOTSPOT
  1381. WIFI_SSID=$TEMP_WIFI_SSID
  1382. WIFI_TYPE=$TEMP_WIFI_TYPE
  1383. WIFI_PASSPHRASE=$TEMP_WIFI_PASSPHRASE
  1384. ${PROJECT_NAME}-wifi -i $WIFI_INTERFACE -s $WIFI_SSID -t $WIFI_TYPE -p $WIFI_PASSPHRASE --hotspot $WIFI_HOTSPOT $WIFI_EXTRA
  1385. else
  1386. WIFI_HOTSPOT=$TEMP_WIFI_HOTSPOT
  1387. WIFI_SSID=$TEMP_WIFI_SSID
  1388. WIFI_TYPE=$TEMP_WIFI_TYPE
  1389. WIFI_PASSPHRASE=$TEMP_WIFI_PASSPHRASE
  1390. ${PROJECT_NAME}-wifi -i $WIFI_INTERFACE -s $WIFI_SSID -t $WIFI_TYPE --hotspot $WIFI_HOTSPOT $WIFI_EXTRA
  1391. fi
  1392. # store any changes
  1393. write_config_param "WIFI_HOTSPOT" "$WIFI_HOTSPOT"
  1394. write_config_param "WIFI_SSID" "$WIFI_SSID"
  1395. write_config_param "WIFI_TYPE" "$WIFI_TYPE"
  1396. write_config_param "WIFI_PASSPHRASE" "$WIFI_PASSPHRASE"
  1397. dialog --title $"Wifi Settings" \
  1398. --msgbox $"Hotspot settings were changed" 6 40
  1399. }
  1400. function reinstall_mariadb {
  1401. dialog --title $"Reinstall MariaDB" \
  1402. --backtitle $"Freedombone Control Panel" \
  1403. --defaultno \
  1404. --yesno $"\nThis should be a LAST RESORT, if the mysql daemon won't start. You will lose ALL databases and will then need to restore them from backup.\n\nAre you sure that you wish to continue?" 12 60
  1405. sel=$?
  1406. case $sel in
  1407. 1) return;;
  1408. 255) return;;
  1409. esac
  1410. clear
  1411. database_reinstall
  1412. dialog --title $"Reinstall MariaDB" \
  1413. --msgbox $"MariaDB has been reinstalled" 6 40
  1414. }
  1415. function menu_backup_restore {
  1416. while true
  1417. do
  1418. data=$(tempfile 2>/dev/null)
  1419. trap "rm -f $data" 0 1 2 5 15
  1420. dialog --backtitle $"Freedombone Control Panel" \
  1421. --title $"Backup and Restore" \
  1422. --radiolist $"Choose an operation:" 19 70 12 \
  1423. 1 $"Backup data to USB drive" off \
  1424. 2 $"Restore GPG key from USB keydrive" off \
  1425. 3 $"Restore data from USB drive" off \
  1426. 4 $"Reinstall mariadb" off \
  1427. 5 $"Configure remote backups" off \
  1428. 6 $"Restore from remote backup" off \
  1429. 7 $"Backup GPG key to USB (master keydrive)" off \
  1430. 8 $"Backup GPG key to USB (fragment keydrive)" off \
  1431. 9 $"Format a USB drive (LUKS encrypted)" off \
  1432. 10 $"Remove backups from a USB drive" off \
  1433. 11 $"Back to main menu" on 2> $data
  1434. sel=$?
  1435. case $sel in
  1436. 1) break;;
  1437. 255) break;;
  1438. esac
  1439. case $(cat $data) in
  1440. 1) backup_data;;
  1441. 2) restore_gpg_key;;
  1442. 3) restore_data;;
  1443. 4) reinstall_mariadb;;
  1444. 5) configure_remote_backups;;
  1445. 6) restore_data_remote;;
  1446. 7) create_keydrive_master;;
  1447. 8) create_keydrive_fragment;;
  1448. 9) format_drive;;
  1449. 10) remove_backups;;
  1450. 11) break;;
  1451. esac
  1452. done
  1453. }
  1454. function menu_email {
  1455. while true
  1456. do
  1457. data=$(tempfile 2>/dev/null)
  1458. trap "rm -f $data" 0 1 2 5 15
  1459. dialog --backtitle $"Freedombone Control Panel" \
  1460. --title $"Email Filtering Rules" \
  1461. --radiolist $"Choose an operation:" 13 70 6 \
  1462. 1 $"Add a user to a mailing list" off \
  1463. 2 $"Remove a user from a mailing list" off \
  1464. 3 $"Add an email rule" off \
  1465. 4 $"Block/Unblock an email address" off \
  1466. 5 $"Block/Unblock email with subject text" off \
  1467. 6 $"Back to main menu" on 2> $data
  1468. sel=$?
  1469. case $sel in
  1470. 1) break;;
  1471. 255) break;;
  1472. esac
  1473. case $(cat $data) in
  1474. 1) add_to_mailing_list;;
  1475. 2) remove_user_from_mailing_list;;
  1476. 3) email_rule;;
  1477. 4) block_unblock_email;;
  1478. 5) block_unblock_subject;;
  1479. 6) break;;
  1480. esac
  1481. done
  1482. }
  1483. function menu_users {
  1484. while true
  1485. do
  1486. data=$(tempfile 2>/dev/null)
  1487. trap "rm -f $data" 0 1 2 5 15
  1488. dialog --backtitle $"Freedombone Control Panel" \
  1489. --title $"Manage Users" \
  1490. --radiolist $"Choose an operation:" 12 70 5 \
  1491. 1 $"Add a user" off \
  1492. 2 $"Delete a user" off \
  1493. 3 $"Change user password" off \
  1494. 4 $"Change user ssh public key" off \
  1495. 5 $"Back to main menu" on 2> $data
  1496. sel=$?
  1497. case $sel in
  1498. 1) break;;
  1499. 255) break;;
  1500. esac
  1501. case $(cat $data) in
  1502. 1) add_user;;
  1503. 2) delete_user;;
  1504. 3) change_password;;
  1505. 4) change_ssh_public_key;;
  1506. 5) break;;
  1507. esac
  1508. done
  1509. }
  1510. function wifi_enable {
  1511. disable_wifi='yes'
  1512. dialog --title $"Enable Wifi" \
  1513. --backtitle $"Freedombone Control Panel" \
  1514. --defaultno \
  1515. --yesno $"\nDo you wish to enable wifi?" 10 50
  1516. sel=$?
  1517. case $sel in
  1518. 0) disable_wifi='no';;
  1519. 1) disable_wifi='yes';;
  1520. 255) return;;
  1521. esac
  1522. ${PROJECT_NAME}-wifi --disable $disable_wifi
  1523. }
  1524. function menu_wifi {
  1525. while true
  1526. do
  1527. status_str=$'Wifi OFF'
  1528. if [ -f /etc/hostapd/hostapd.conf ]; then
  1529. status_str=$'Hotspot ON'
  1530. else
  1531. if grep -q "# wifi enabled" /etc/network/interfaces; then
  1532. status_str=$'Wifi ON'
  1533. fi
  1534. fi
  1535. data=$(tempfile 2>/dev/null)
  1536. trap "rm -f $data" 0 1 2 5 15
  1537. dialog --backtitle $"Freedombone Control Panel" \
  1538. --title $"Wifi Menu" \
  1539. --radiolist $"${status_str}\n\nChoose an operation:" 14 70 6 \
  1540. 1 $"Enable or disable Wifi" off \
  1541. 2 $"Configure wifi networks" off \
  1542. 3 $"Manually edit wifi networks file" off \
  1543. 4 $"Hotspot settings" off \
  1544. 5 $"Exit" on 2> $data
  1545. sel=$?
  1546. case $sel in
  1547. 1) break;;
  1548. 255) break;;
  1549. esac
  1550. case $(cat $data) in
  1551. 1) wifi_enable;;
  1552. 2) wifi_settings;;
  1553. 3) wifi_edit_networks;;
  1554. 4) hotspot_settings;;
  1555. 5) break;;
  1556. esac
  1557. done
  1558. }
  1559. function menu_app_settings {
  1560. detect_installable_apps
  1561. applist=""
  1562. appnames=()
  1563. n=1
  1564. app_index=0
  1565. for a in "${APPS_AVAILABLE[@]}"
  1566. do
  1567. if [[ ${APPS_INSTALLED[$app_index]} != "0" ]]; then
  1568. if [[ $(function_exists configure_interactive_${a}) == "1" ]]; then
  1569. applist="$applist $n $a off"
  1570. n=$[n+1]
  1571. appnames+=("$a")
  1572. fi
  1573. fi
  1574. app_index=$[app_index+1]
  1575. done
  1576. if [ $n -le 1 ]; then
  1577. return
  1578. fi
  1579. backstr=$'Exit'
  1580. applist="$applist $n $backstr on"
  1581. appnames+=("Exit")
  1582. choice=$(dialog --stdout --backtitle $"Freedombone" \
  1583. --title $"Change Settings for an App" \
  1584. --radiolist $'Choose:' \
  1585. 16 40 20 $applist)
  1586. if [ $? -eq 0 ]; then
  1587. app_index=$[choice-1]
  1588. chosen_app=${appnames[$app_index]}
  1589. if [[ $chosen_app != "Exit" ]]; then
  1590. configure_interactive_${chosen_app}
  1591. fi
  1592. fi
  1593. }
  1594. function menu_top_level {
  1595. while true
  1596. do
  1597. data=$(tempfile 2>/dev/null)
  1598. trap "rm -f $data" 0 1 2 5 15
  1599. dialog --backtitle $"Freedombone Control Panel" \
  1600. --title $"Control Panel" \
  1601. --radiolist $"Choose an operation:" 29 70 22 \
  1602. 1 $"About this system" off \
  1603. 2 $"Backup and Restore" off \
  1604. 3 $"Reset Tripwire" off \
  1605. 4 $"App Settings" off \
  1606. 5 $"Add/Remove Apps" off \
  1607. 6 $"Logging on/off" off \
  1608. 7 $"Ping enable/disable" off \
  1609. 8 $"Manage Users" off \
  1610. 9 $"Email Filtering Rules" off \
  1611. 10 $"Outgoing Email Proxy" off \
  1612. 11 $"Security Settings" off \
  1613. 12 $"Set the main repository (repo mirrors)" off \
  1614. 13 $"Change the name of this system" off \
  1615. 14 $"Set a static local IP address" off \
  1616. 15 $"Wifi menu" off \
  1617. 16 $"Check for updates" off \
  1618. 17 $"Power off the system" off \
  1619. 18 $"Restart the system" off \
  1620. 19 $"Exit" on 2> $data
  1621. sel=$?
  1622. case $sel in
  1623. 1) exit 1;;
  1624. 255) exit 1;;
  1625. esac
  1626. case $(cat $data) in
  1627. 1) show_about;;
  1628. 2) menu_backup_restore;;
  1629. 3) reset_tripwire;;
  1630. 4) menu_app_settings;;
  1631. 5) ${PROJECT_NAME}-addremove;;
  1632. 6) logging_on_off;;
  1633. 7) ping_enable_disable;;
  1634. 8) menu_users;;
  1635. 9) menu_email;;
  1636. 10) smtp_proxy;;
  1637. 11) security_settings;;
  1638. 12) set_main_repo;;
  1639. 13) change_system_name;;
  1640. 14) set_static_IP;;
  1641. 15) menu_wifi;;
  1642. 16) check_for_updates;;
  1643. 17) shut_down_system;;
  1644. 18) restart_system;;
  1645. 19) break;;
  1646. esac
  1647. done
  1648. }
  1649. if [[ $USER != 'root' ]]; then
  1650. # show the user version of the control panel
  1651. ${PROJECT_NAME}-controlpanel-user
  1652. exit 0
  1653. fi
  1654. if [ ! -f $COMPLETION_FILE ]; then
  1655. echo $'This command should only be run on an installed Freedombone system'
  1656. exit 1
  1657. fi
  1658. ADMIN_USER=$(get_completion_param "Admin user")
  1659. read_repo_servers
  1660. menu_top_level
  1661. clear
  1662. cat /etc/motd
  1663. exit 0