freedombone-controlpanel 62KB

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