freedombone-controlpanel 58KB

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