freedombone-controlpanel 66KB

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