freedombone-controlpanel 76KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129
  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. # voip
  52. VOIP_PORT=64738
  53. VOIP_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. DEFAULT_DOMAIN_NAME=$(cat $CONFIGURATION_FILE | grep "DEFAULT_DOMAIN_NAME=" | awk -F '=' '{print $2}')
  273. echo 'Domains'
  274. echo '======='
  275. echo ''
  276. echo -n -e "$(pad_string 'Name')"
  277. echo -n -e "$(pad_string 'ICANN')"
  278. echo -n -e "$(pad_string 'Tor')"
  279. echo ''
  280. echo '--------------------------------------------------------------------------'
  281. if grep -q "ssh onion domain" $COMPLETION_FILE; then
  282. echo -n -e "$(pad_string 'ssh')"
  283. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  284. echo "$(cat ${COMPLETION_FILE} | grep 'ssh onion domain' | awk -F ':' '{print $2}')"
  285. fi
  286. if grep -q "Email onion domain" $COMPLETION_FILE; then
  287. echo -n -e "$(pad_string 'Email')"
  288. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  289. echo "$(cat ${COMPLETION_FILE} | grep 'Email onion domain' | awk -F ':' '{print $2}')"
  290. fi
  291. if grep -q "XMPP onion domain" $COMPLETION_FILE; then
  292. echo -n -e "$(pad_string 'XMPP')"
  293. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  294. echo "$(cat ${COMPLETION_FILE} | grep 'XMPP onion domain' | awk -F ':' '{print $2}')"
  295. fi
  296. if grep -q "VoIP onion domain" $COMPLETION_FILE; then
  297. echo -n -e "$(pad_string 'VoIP/Mumble')"
  298. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  299. echo "$(cat ${COMPLETION_FILE} | grep 'VoIP onion domain' | awk -F ':' '{print $2}')"
  300. fi
  301. if grep -q "SIP onion domain" $COMPLETION_FILE; then
  302. echo -n -e "$(pad_string 'SIP')"
  303. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  304. echo "$(cat ${COMPLETION_FILE} | grep 'SIP onion domain' | awk -F ':' '{print $2}')"
  305. fi
  306. if grep -q "IRC onion domain" $COMPLETION_FILE; then
  307. echo -n -e "$(pad_string 'IRC')"
  308. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  309. echo "$(cat ${COMPLETION_FILE} | grep 'IRC onion domain' | awk -F ':' '{print $2}')"
  310. fi
  311. if grep -q "tox onion domain" $COMPLETION_FILE; then
  312. echo -n -e "$(pad_string 'Tox Bootstrap')"
  313. echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})"
  314. echo "$(cat ${COMPLETION_FILE} | grep 'tox onion domain' | awk -F ':' '{print $2}')"
  315. fi
  316. if grep -q "Wiki domain" $COMPLETION_FILE; then
  317. echo -n -e "$(pad_string 'Wiki')"
  318. WIKIDOM=$(cat ${COMPLETION_FILE} | grep 'Wiki domain' | awk -F ':' '{print $2}')
  319. echo -n -e "$(pad_string ${WIKIDOM})"
  320. if [ -d /var/lib/tor/hidden_service_wiki ]; then
  321. echo -n "$(cat /var/lib/tor/hidden_service_wiki/hostname)"
  322. fi
  323. echo ''
  324. fi
  325. if grep -q "Hubzilla domain" $COMPLETION_FILE; then
  326. echo -n -e "$(pad_string 'Hubzilla')"
  327. HUBZILLADOM=$(cat ${COMPLETION_FILE} | grep 'Hubzilla domain' | awk -F ':' '{print $2}')
  328. echo -n -e "$(pad_string ${HUBZILLADOM})"
  329. if [ -d /var/lib/tor/hidden_service_hubzilla ]; then
  330. echo -n "$(cat /var/lib/tor/hidden_service_hubzilla/hostname)"
  331. fi
  332. echo ''
  333. fi
  334. if grep -q "Blog domain" $COMPLETION_FILE; then
  335. echo -n -e "$(pad_string 'Blog')"
  336. BLOGDOM=$(cat ${COMPLETION_FILE} | grep 'Blog domain' | awk -F ':' '{print $2}')
  337. echo -n -e "$(pad_string ${BLOGDOM})"
  338. if [ -d /var/lib/tor/hidden_service_blog ]; then
  339. echo -n "$(cat /var/lib/tor/hidden_service_blog/hostname)"
  340. fi
  341. echo ''
  342. fi
  343. if grep -q "GNU Social domain" $COMPLETION_FILE; then
  344. echo -n -e "$(pad_string 'GNU Social')"
  345. GNUSOCIALDOM=$(cat ${COMPLETION_FILE} | grep 'GNU Social domain' | awk -F ':' '{print $2}')
  346. echo -n -e "$(pad_string ${GNUSOCIALDOM})"
  347. if [ -d /var/lib/tor/hidden_service_microblog ]; then
  348. echo -n "$(cat /var/lib/tor/hidden_service_microblog/hostname)"
  349. fi
  350. echo ''
  351. fi
  352. if grep -q "Gogs domain" $COMPLETION_FILE; then
  353. echo -n -e "$(pad_string 'Gogs')"
  354. GOGSDOM=$(cat ${COMPLETION_FILE} | grep 'Gogs domain' | awk -F ':' '{print $2}')
  355. echo -n -e "$(pad_string ${GOGSDOM})"
  356. if [ -d /var/lib/tor/hidden_service_gogs ]; then
  357. echo -n "$(cat /var/lib/tor/hidden_service_gogs/hostname)"
  358. fi
  359. echo ''
  360. fi
  361. if grep -q "RSS reader domain" $COMPLETION_FILE; then
  362. if [ -d /var/lib/tor/hidden_service_ttrss ]; then
  363. echo -n -e "$(pad_string 'RSS reader')"
  364. RSSDOM='-'
  365. echo -n -e "$(pad_string ${RSSDOM})"
  366. echo -n "$(cat /var/lib/tor/hidden_service_ttrss/hostname)"
  367. echo ''
  368. fi
  369. if [ -d /var/lib/tor/hidden_service_ttrss_mobile ]; then
  370. echo -n -e "$(pad_string 'RSS mobile')"
  371. RSSMOBILEDOM='-'
  372. echo -n -e "$(pad_string ${RSSMOBILEDOM})"
  373. echo -n "$(cat /var/lib/tor/hidden_service_ttrss_mobile/hostname)"
  374. echo ''
  375. fi
  376. fi
  377. if grep -q "Webmail onion domain" $COMPLETION_FILE; then
  378. echo -n -e "$(pad_string 'Webmail')"
  379. WEBMAILDOM='-'
  380. echo -n -e "$(pad_string ${WEBMAILDOM})"
  381. if [ -d /var/lib/tor/hidden_service_webmail ]; then
  382. echo -n "$(cat /var/lib/tor/hidden_service_webmail/hostname)"
  383. fi
  384. echo ''
  385. fi
  386. if grep -q "Search engine onion domain" $COMPLETION_FILE; then
  387. echo -n -e "$(pad_string 'Search engine')"
  388. SEARCHDOM='-'
  389. echo -n -e "$(pad_string ${SEARCHDOM})"
  390. if [ -d /var/lib/tor/hidden_service_searx ]; then
  391. echo -n "$(cat /var/lib/tor/hidden_service_searx/hostname)"
  392. fi
  393. echo ''
  394. fi
  395. if grep -q "Mediagoblin domain" $COMPLETION_FILE; then
  396. echo -n -e "$(pad_string 'Mediagoblin')"
  397. MEDIADOM=$(cat ${COMPLETION_FILE} | grep 'Mediagoblin domain' | awk -F ':' '{print $2}')
  398. echo -n -e "$(pad_string ${MEDIADOM})"
  399. if [ -d /var/lib/tor/hidden_service_mediagoblin ]; then
  400. echo -n "$(cat /var/lib/tor/hidden_service_mediagoblin/hostname)"
  401. fi
  402. echo ''
  403. fi
  404. if grep -q "Media server domain" $COMPLETION_FILE; then
  405. echo -n -e "$(pad_string 'Media server')"
  406. MEDIADOM=$(cat ${COMPLETION_FILE} | grep 'Media server domain' | awk -F ':' '{print $2}')
  407. echo -n -e "$(pad_string ${MEDIADOM})"
  408. if [ -d /var/lib/tor/hidden_service_mediadrop ]; then
  409. echo -n "$(cat /var/lib/tor/hidden_service_mediadrop/hostname)"
  410. fi
  411. echo ''
  412. fi
  413. echo ''
  414. }
  415. function show_users {
  416. echo 'Users'
  417. echo '====='
  418. echo ''
  419. echo -n -e "$(pad_string 'Name')"
  420. echo -n -e "$(pad_string 'SIP ext')"
  421. echo -n -e "$(pad_string 'Data')"
  422. echo ''
  423. echo '--------------------------------------------------------------------------'
  424. for d in /home/*/ ; do
  425. USRNAME=$(echo "$d" | awk -F '/' '{print $3}')
  426. if [[ $USRNAME != "git" && $USRNAME != "mirrors" && $USRNAME != "sync" && $USERNAME != "tahoelafs" ]]; then
  427. echo -n -e "$(pad_string ${USRNAME})"
  428. # get the SIP extension
  429. SIPEXT=
  430. while read ext; do
  431. if [[ $ext == *"user id"* ]]; then
  432. CURR_UID=$(echo "$ext" | awk -F '"' '{print $2}' | awk -F '"' '{print $1}')
  433. fi
  434. if [[ $ext == *"extension"* ]]; then
  435. if [[ $CURR_UID == $USRNAME ]]; then
  436. SIPEXT=$(echo "$ext" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')
  437. fi
  438. fi
  439. done < $SIP_CONFIGURATION_FILE
  440. if [ $SIPEXT ]; then
  441. echo -n -e "$(pad_string SIP:${SIPEXT})"
  442. else
  443. echo -n -e "$(pad_string '')"
  444. fi
  445. # size of the home directory
  446. echo "$(du -s -h /home/${USRNAME} | awk -F ' ' '{print $1}')"
  447. fi
  448. done
  449. echo ''
  450. }
  451. function show_mirrors_password {
  452. if [ ! /home/mirrors ]; then
  453. return
  454. fi
  455. if grep -q "MY_MIRRORS_PASSWORD" $CONFIGURATION_FILE; then
  456. MY_MIRRORS_PASSWORD=$(grep "MY_MIRRORS_PASSWORD" $CONFIGURATION_FILE | awk -F '=' '{print $2}')
  457. fi
  458. echo 'Local Mirrors'
  459. echo '============='
  460. echo ''
  461. echo -n "URL: "
  462. echo "$(cat ${COMPLETION_FILE} | grep 'ssh onion domain' | awk -F ':' '{print $2}')"
  463. echo "SSH Port: $SSH_PORT"
  464. echo "Password: $MY_MIRRORS_PASSWORD"
  465. echo ''
  466. }
  467. function show_tahoe_introducer {
  468. if [ ! -f /home/tahoelafs/.tahoe-introducer/private/introducer.furl ]; then
  469. return
  470. fi
  471. echo 'Tahoe-LAFS'
  472. echo '=========='
  473. echo ''
  474. cat /home/tahoelafs/.tahoe-introducer/private/introducer.furl
  475. echo ''
  476. }
  477. function show_about {
  478. clear
  479. show_domains
  480. show_mirrors_password
  481. show_tahoe_introducer
  482. show_users
  483. any_key
  484. }
  485. function select_user {
  486. SELECTED_USERNAME=
  487. users_array=($(ls /home))
  488. delete=(mirrors git)
  489. for del in ${delete[@]}
  490. do
  491. users_array=(${users_array[@]/$del})
  492. done
  493. i=0
  494. W=()
  495. name=()
  496. for u in ${users_array[@]}
  497. do
  498. i=$((i+1))
  499. W+=($i "$u")
  500. name+=("$u")
  501. done
  502. 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)
  503. if [ $? -eq 0 ]; then
  504. SELECTED_USERNAME="${name[$((user_index-1))]}"
  505. fi
  506. }
  507. function smtp_proxy {
  508. MUTTRC_FILE=/home/$ADMIN_USER/.muttrc
  509. if [ ! -f $MUTTRC_FILE ]; then
  510. return
  511. fi
  512. data=$(tempfile 2>/dev/null)
  513. trap "rm -f $data" 0 1 2 5 15
  514. dialog --backtitle $"Freedombone Control Panel" \
  515. --title $"SMTP Proxy for $ADMIN_USER" \
  516. --form $"You may need to proxy outgoing email via your ISP's mail server. If so enter the details below." 14 75 6 \
  517. $"Enable proxy:" 1 1 "$SMTP_PROXY_ENABLE" 1 24 5 5 \
  518. $"Protocol (smtp/smtps):" 2 1 "$SMTP_PROXY_PROTOCOL" 2 24 5 5 \
  519. $"ISP mail server:" 3 1 "$SMTP_PROXY_SERVER" 3 24 40 10000 \
  520. $"Port:" 4 1 "$SMTP_PROXY_PORT" 4 24 5 5 \
  521. $"Username:" 5 1 "$SMTP_PROXY_USERNAME" 5 24 40 10000 \
  522. $"Password:" 6 1 "$SMTP_PROXY_PASSWORD" 6 24 40 10000 \
  523. 2> $data
  524. sel=$?
  525. case $sel in
  526. 1) return;;
  527. 255) return;;
  528. esac
  529. SMTP_PROXY_ENABLE=$(cat $data | sed -n 1p)
  530. SMTP_PROXY_PROTOCOL=$(cat $data | sed -n 2p)
  531. SMTP_PROXY_SERVER=$(cat $data | sed -n 3p)
  532. SMTP_PROXY_PORT=$(cat $data | sed -n 4p)
  533. SMTP_PROXY_USERNAME=$(cat $data | sed -n 5p)
  534. SMTP_PROXY_PASSWORD=$(cat $data | sed -n 6p)
  535. # change muttrc
  536. if [ $SMTP_PROXY_ENABLE != $'no' ]; then
  537. if ! grep "set smtp_url" $MUTTRC_FILE; then
  538. echo "set smtp_url=\"${SMTP_PROXY_PROTOCOL}://${SMTP_PROXY_USERNAME}:${SMTP_PROXY_PASSWORD}@${SMTP_PROXY_SERVER}:${SMTP_PROXY_PORT}/\"" >> $MUTTRC_FILE
  539. else
  540. 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
  541. fi
  542. sed -i 's|#set smtp_url|set smtp_url|g' $MUTTRC_FILE
  543. else
  544. if grep "set smtp_url" $MUTTRC_FILE; then
  545. sed -i 's|set smtp_url|#set smtp_url|g' $MUTTRC_FILE
  546. fi
  547. fi
  548. # save settings within the main configuration file
  549. if ! grep -q "SMTP_PROXY_ENABLE=" $CONFIGURATION_FILE; then
  550. echo "SMTP_PROXY_ENABLE=$SMTP_PROXY_ENABLE" >> $CONFIGURATION_FILE
  551. else
  552. sed -i "s|SMTP_PROXY_ENABLE=.*|SMTP_PROXY_ENABLE=$SMTP_PROXY_ENABLE|g" $CONFIGURATION_FILE
  553. fi
  554. if ! grep -q "SMTP_PROXY_PROTOCOL=" $CONFIGURATION_FILE; then
  555. echo "SMTP_PROXY_PROTOCOL=$SMTP_PROXY_PROTOCOL" >> $CONFIGURATION_FILE
  556. else
  557. sed -i "s|SMTP_PROXY_PROTOCOL=.*|SMTP_PROXY_PROTOCOL=$SMTP_PROXY_PROTOCOL|g" $CONFIGURATION_FILE
  558. fi
  559. if ! grep -q "SMTP_PROXY_SERVER=" $CONFIGURATION_FILE; then
  560. echo "SMTP_PROXY_SERVER=$SMTP_PROXY_SERVER" >> $CONFIGURATION_FILE
  561. else
  562. sed -i "s|SMTP_PROXY_SERVER=.*|SMTP_PROXY_SERVER=$SMTP_PROXY_SERVER|g" $CONFIGURATION_FILE
  563. fi
  564. if ! grep -q "SMTP_PROXY_PORT=" $CONFIGURATION_FILE; then
  565. echo "SMTP_PROXY_PORT=$SMTP_PROXY_PORT" >> $CONFIGURATION_FILE
  566. else
  567. sed -i "s|SMTP_PROXY_PORT=.*|SMTP_PROXY_PORT=$SMTP_PROXY_PORT|g" $CONFIGURATION_FILE
  568. fi
  569. if ! grep -q "SMTP_PROXY_USERNAME=" $CONFIGURATION_FILE; then
  570. echo "SMTP_PROXY_USERNAME=$SMTP_PROXY_USERNAME" >> $CONFIGURATION_FILE
  571. else
  572. sed -i "s|SMTP_PROXY_USERNAME=.*|SMTP_PROXY_USERNAME=$SMTP_PROXY_USERNAME|g" $CONFIGURATION_FILE
  573. fi
  574. if ! grep -q "SMTP_PROXY_PASSWORD=" $CONFIGURATION_FILE; then
  575. echo "SMTP_PROXY_PASSWORD=$SMTP_PROXY_PASSWORD" >> $CONFIGURATION_FILE
  576. else
  577. sed -i "s|SMTP_PROXY_PASSWORD=.*|SMTP_PROXY_PASSWORD=$SMTP_PROXY_PASSWORD|g" $CONFIGURATION_FILE
  578. fi
  579. }
  580. function delete_user {
  581. select_user
  582. if [ ! $SELECTED_USERNAME ]; then
  583. return
  584. fi
  585. if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then
  586. dialog --title $"Administrator user" \
  587. --msgbox $"You can't delete the administrator user" 6 40
  588. return
  589. fi
  590. clear
  591. ${PROJECT_NAME}-rmuser $SELECTED_USERNAME
  592. any_key
  593. }
  594. function configure_remote_backups {
  595. if ! grep -Fxq "Admin user:$ADMIN_USER" $COMPLETION_FILE; then
  596. dialog --title $"Administrator user" \
  597. --msgbox $"No Administrator user found. Check $COMPLETION_FILE" 6 40
  598. return
  599. fi
  600. if [ ${#ADMIN_USER} -lt 2 ]; then
  601. dialog --title $"Administrator user" \
  602. --msgbox $"Username not found" 6 40
  603. return
  604. fi
  605. if [ ! -d /home/$ADMIN_USER ]; then
  606. dialog --title $"Administrator user" \
  607. --msgbox $"Home directory not found" 6 40
  608. return
  609. fi
  610. ${PROJECT_NAME}-remote -u $ADMIN_USER
  611. if [ ! "$?" = "0" ]; then
  612. any_key
  613. fi
  614. }
  615. function change_password {
  616. select_user
  617. if [ ! $SELECTED_USERNAME ]; then
  618. return
  619. fi
  620. dialog --title $"Change password" \
  621. --passwordbox $"New password for user $SELECTED_USERNAME" 8 40 2> $data
  622. newpassword=$(<$data)
  623. if [ ${#newpassword} -lt ${MINIMUM_PASSWORD_LENGTH} ]; then
  624. dialog --title $"Change password" \
  625. --msgbox $"The password should be ${MINIMUM_PASSWORD_LENGTH} or more characters" 6 40
  626. return
  627. fi
  628. echo "$SELECTED_USERNAME:$newpassword"|chpasswd
  629. dialog --title $"Change password" \
  630. --msgbox $"Password for $SELECTED_USERNAME was changed" 6 40
  631. }
  632. function irc_show_password {
  633. IRC_PASSWORD=$(cat /etc/ngircd/ngircd.conf | grep "Password =" | head -n 1 | awk -F '=' '{print $2}')
  634. dialog --title $"IRC Password" \
  635. --msgbox "$IRC_PASSWORD" 6 40
  636. }
  637. function irc_set_global_password {
  638. dialog --title $"IRC Password" \
  639. --clear \
  640. --backtitle $"Freedombone Control Panel" \
  641. --passwordbox $"Password for all IRC users, or press Enter for no password" 10 50 2> $data
  642. sel=$?
  643. case $sel in
  644. 0)
  645. EXISTING_IRC_PASSWORD=$(cat /etc/ngircd/ngircd.conf | grep "Password =" | head -n 1 | awk -F '=' '{print $2}')
  646. NEW_IRC_PASSWORD=$(<$data)
  647. sed -i "0,/RE/s/Password =.*/Password =$NEW_IRC_PASSWORD/" /etc/ngircd/ngircd.conf
  648. # replace the password for all users
  649. for d in /home/*/ ; do
  650. IRC_USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
  651. if [[ $IRC_USERNAME != "git" && $IRC_USERNAME != "mirrors" && $IRC_USERNAME != "sync" && $IRC_USERNAME != "tahoelafs" ]]; then
  652. if [ -f /home/$IRC_USERNAME/.irssi/config ]; then
  653. sed -i "s|$EXISTING_IRC_PASSWORD|$NEW_IRC_PASSWORD|g" /home/$IRC_USERNAME/.irssi/config
  654. chown -R $IRC_USERNAME:$IRC_USERNAME /home/$IRC_USERNAME/.irssi
  655. fi
  656. fi
  657. done
  658. # restart the daemon for the new password to take effect
  659. systemctl restart ngircd
  660. dialog --title $"IRC Password" \
  661. --msgbox $"The IRC password was changed" 6 40
  662. ;;
  663. esac
  664. }
  665. function change_blog_avatar {
  666. data=$(tempfile 2>/dev/null)
  667. trap "rm -f $data" 0 1 2 5 15
  668. dialog --title $"Change blog avatar" \
  669. --backtitle $"Freedombone Control Panel" \
  670. --inputbox $"Enter a URL for an image. It should be approximately a square image." 8 75 2>$data
  671. sel=$?
  672. case $sel in
  673. 0)
  674. IMAGE_URL=$(<$data)
  675. if [ ${#IMAGE_URL} -gt 5 ]; then
  676. clear
  677. ${PROJECT_NAME}-blog -a $IMAGE_URL
  678. if [ "$?" = "0" ]; then
  679. dialog --title $"Change blog avatar" \
  680. --msgbox $"Your blog avatar has been changed" 6 40
  681. fi
  682. fi
  683. ;;
  684. esac
  685. }
  686. function change_ssh_public_key {
  687. select_user
  688. if [ ! $SELECTED_USERNAME ]; then
  689. return
  690. fi
  691. if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then
  692. dialog --title $"Change ssh public key" \
  693. --backtitle $"Freedombone Control Panel" \
  694. --defaultno \
  695. --yesno $"\nThis is the administrator user.\n\nAre you sure you want to change the ssh public key for the administrator?" 10 60
  696. sel=$?
  697. case $sel in
  698. 1) return;;
  699. 255) return;;
  700. esac
  701. fi
  702. data=$(tempfile 2>/dev/null)
  703. trap "rm -f $data" 0 1 2 5 15
  704. dialog --title $"Change ssh public key for $SELECTED_USERNAME" \
  705. --backtitle $"Freedombone Control Panel" \
  706. --inputbox $"Paste the ssh public key below" 8 60 2>$data
  707. sel=$?
  708. case $sel in
  709. 0)
  710. SSH_PUBLIC_KEY=$(<$data)
  711. if [ "$SSH_PUBLIC_KEY" ]; then
  712. if [ ${#SSH_PUBLIC_KEY} -gt 5 ]; then
  713. if [ -f "$SSH_PUBLIC_KEY" ]; then
  714. if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then
  715. mkdir /home/$SELECTED_USERNAME/.ssh
  716. fi
  717. cp $SSH_PUBLIC_KEY \
  718. /home/$SELECTED_USERNAME/.ssh/authorized_keys
  719. chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \
  720. /home/$SELECTED_USERNAME/.ssh
  721. dialog --title $"Change ssh public key" \
  722. --msgbox $"ssh public key was installed" 6 40
  723. else
  724. if [[ "$SSH_PUBLIC_KEY" == "ssh-"* ]]; then
  725. if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then
  726. mkdir /home/$SELECTED_USERNAME/.ssh
  727. fi
  728. echo "$SSH_PUBLIC_KEY" > \
  729. /home/$SELECTED_USERNAME/.ssh/authorized_keys
  730. chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \
  731. /home/$SELECTED_USERNAME/.ssh
  732. dialog --title $"Change ssh public key" \
  733. --msgbox $"ssh public key was installed" 6 40
  734. fi
  735. fi
  736. fi
  737. fi
  738. ;;
  739. esac
  740. }
  741. function remove_user_from_mailing_list {
  742. select_user
  743. if [ ! $SELECTED_USERNAME ]; then
  744. return
  745. fi
  746. USER_MAILING_LISTS=$(cat "/home/$SELECTED_USERNAME/.procmailrc" | grep '\[' | grep '\]' | awk -F '\[' '{print $2}' | awk -F '\\' '{print $1}')
  747. i=0
  748. W=()
  749. list_name=()
  750. while read -r listname; do
  751. i=$((i+1))
  752. W+=($i "$listname")
  753. list_name+=("$listname")
  754. echo $listname
  755. done <<< "$USER_MAILING_LISTS"
  756. i=$((i+1))
  757. W+=($i $"Exit back to user mainenance")
  758. 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)
  759. if [ $? -eq 0 ]; then # Exit with OK
  760. if [ ${list_selected} -ne ${i} ]; then
  761. remove_list_name="${list_name[$((list_selected-1))]}"
  762. # find the line number where the list is defined
  763. line_number=0
  764. i=0
  765. while read -r line
  766. do
  767. if [[ "$line" == *"\[${remove_list_name}\\]"* ]]; then
  768. line_number=${i}
  769. fi
  770. i=$((i+1))
  771. done < "/home/$SELECTED_USERNAME/.procmailrc"
  772. if [ ${line_number} -eq 0 ]; then
  773. # no match was found
  774. return
  775. fi
  776. # recreate the file
  777. if [ -f /home/${SELECTED_USERNAME}/.procmailrc_new ]; then
  778. rm /home/${SELECTED_USERNAME}/.procmailrc_new
  779. fi
  780. i=0
  781. clip=0
  782. while read -r line
  783. do
  784. i=$((i+1))
  785. if [ ${i} -gt $((line_number-1)) ]; then
  786. if [ ${clip} -eq 0 ]; then
  787. clip=1
  788. fi
  789. if [ ${clip} -eq 1 ]; then
  790. if [ ${i} -lt $((line_number+2)) ]; then
  791. continue
  792. else
  793. if [ ${#line} -lt 1 ]; then
  794. clip=2
  795. continue
  796. fi
  797. if [[ "$line" == ":"* || "$line" == "#"* ]]; then
  798. clip=2
  799. else
  800. continue
  801. fi
  802. fi
  803. fi
  804. fi
  805. echo "$line" >> /home/${SELECTED_USERNAME}/.procmailrc_new
  806. if [[ "$line" == *"\[${remove_list_name}\\]"* ]]; then
  807. line_number=${i}
  808. fi
  809. done < "/home/$SELECTED_USERNAME/.procmailrc"
  810. cp /home/${SELECTED_USERNAME}/.procmailrc_new /home/${SELECTED_USERNAME}/.procmailrc
  811. rm /home/${SELECTED_USERNAME}/.procmailrc_new
  812. chown ${SELECTED_USERNAME}:${SELECTED_USERNAME} /home/${SELECTED_USERNAME}/.procmailrc
  813. dialog --title $"Remove user from mailing list" \
  814. --msgbox $"${SELECTED_USERNAME} has been removed from ${remove_list_name}" 6 50
  815. fi
  816. fi
  817. }
  818. function add_to_mailing_list {
  819. select_user
  820. if [ ! $SELECTED_USERNAME ]; then
  821. return
  822. fi
  823. data=$(tempfile 2>/dev/null)
  824. trap "rm -f $data" 0 1 2 5 15
  825. dialog --backtitle $"Freedombone Control Panel" \
  826. --title $"Subscribe $SELECTED_USERNAME to a mailing list" \
  827. --form $"You can either enter a subject or an email address\n" 11 68 4 \
  828. $"List folder name:" 1 1 "" 1 35 26 25 \
  829. $"Name between [] on subject line:" 2 1 "" 2 35 26 25 \
  830. $"List email address:" 3 1 "" 3 35 26 25 \
  831. $"Public:" 4 1 $"yes" 4 35 4 25 \
  832. 2> $data
  833. sel=$?
  834. case $sel in
  835. 1) return;;
  836. 255) return;;
  837. esac
  838. LIST_NAME=$(cat $data | sed -n 1p)
  839. LIST_SUBJECT=$(cat $data | sed -n 2p)
  840. LIST_EMAIL=$(cat $data | sed -n 3p)
  841. LIST_PUBLIC=$(cat $data | sed -n 4p)
  842. if [ ${#LIST_PUBLIC} -lt 1 ]; then
  843. LIST_PUBLIC='no'
  844. fi
  845. if [[ $LIST_PUBLIC == $'y' || $LIST_PUBLIC == $'Y' || $LIST_PUBLIC == $'true' || $LIST_PUBLIC == $'True' || $LIST_PUBLIC == $'yes' || $LIST_PUBLIC == $'Yes' || $LIST_PUBLIC == $'YES' ]]; then
  846. LIST_PUBLIC='yes'
  847. else
  848. LIST_PUBLIC='no'
  849. fi
  850. if [ ${#LIST_NAME} -lt 2 ]; then
  851. dialog --title $"Add mailing list" \
  852. --msgbox $"No mailing list name was given" 6 40
  853. return
  854. fi
  855. if [ ${#LIST_SUBJECT} -lt 2 ]; then
  856. if [ ${#LIST_EMAIL} -lt 2 ]; then
  857. dialog --title $"Add mailing list" \
  858. --msgbox $"No mailing list subject or address was given" 6 40
  859. return
  860. fi
  861. fi
  862. if [ ${#LIST_SUBJECT} -gt 1 ]; then
  863. ${PROJECT_NAME}-addlist -u $SELECTED_USERNAME -l "$LIST_NAME" \
  864. -s "$LIST_SUBJECT" --public $LIST_PUBLIC
  865. else
  866. if [[ "$LIST_EMAIL" != *"@"* || "$LIST_EMAIL" != *"."* ]]; then
  867. dialog --title $"Add mailing list" \
  868. --msgbox $"Unrecognised email address" 6 40
  869. return
  870. else
  871. ${PROJECT_NAME}-addlist -u $SELECTED_USERNAME -l "$LIST_NAME" \
  872. -e "$LIST_EMAIL" --public $LIST_PUBLIC
  873. fi
  874. fi
  875. dialog --title $"Add mailing list" \
  876. --msgbox $"$LIST_NAME list was added" 6 40
  877. }
  878. function email_rule {
  879. select_user
  880. if [ ! $SELECTED_USERNAME ]; then
  881. return
  882. fi
  883. data=$(tempfile 2>/dev/null)
  884. trap "rm -f $data" 0 1 2 5 15
  885. dialog --backtitle $"Freedombone Control Panel" \
  886. --title $"Email rule for user $SELECTED_USERNAME" \
  887. --form "\n" 9 65 4 \
  888. $"When email arrives from address:" 1 1 "" 1 35 24 28 \
  889. $"Move to folder:" 2 1 "" 2 35 24 28 \
  890. $"Public:" 3 1 $"no" 3 35 4 25 \
  891. 2> $data
  892. sel=$?
  893. case $sel in
  894. 1) return;;
  895. 255) return;;
  896. esac
  897. RULE_EMAIL=$(cat $data | sed -n 1p)
  898. RULE_FOLDER=$(cat $data | sed -n 2p)
  899. RULE_PUBLIC=$(cat $data | sed -n 3p)
  900. if [ ${#RULE_PUBLIC} -lt 1 ]; then
  901. RULE_PUBLIC='no'
  902. fi
  903. if [[ $RULE_PUBLIC == $'y' || $RULE_PUBLIC == $'Y' || $RULE_PUBLIC == $'true' || $RULE_PUBLIC == $'True' || $RULE_PUBLIC == $'yes' || $RULE_PUBLIC == $'Yes' || $RULE_PUBLIC == $'YES' ]]; then
  904. RULE_PUBLIC='yes'
  905. else
  906. RULE_PUBLIC='no'
  907. fi
  908. if [ ${#RULE_EMAIL} -lt 2 ]; then
  909. dialog --title $"Add email rule" \
  910. --msgbox $"No email address was given" 6 40
  911. return
  912. fi
  913. if [ ${#RULE_FOLDER} -lt 2 ]; then
  914. dialog --title $"Add email rule" \
  915. --msgbox $"No folder name was given" 6 40
  916. return
  917. fi
  918. if [[ "$RULE_EMAIL" != *"@"* || "$RULE_EMAIL" != *"."* ]]; then
  919. dialog --title $"Add email rule" \
  920. --msgbox $"Unrecognised email address" 6 40
  921. return
  922. fi
  923. ${PROJECT_NAME}-addemail -u $SELECTED_USERNAME -e "$RULE_EMAIL" \
  924. -g "$RULE_FOLDER" --public $RULE_PUBLIC
  925. dialog --title $"Add email rule" \
  926. --msgbox $"Email rule for $RULE_EMAIL was added" 6 40
  927. }
  928. function block_unblock_email {
  929. select_user
  930. if [ ! $SELECTED_USERNAME ]; then
  931. return
  932. fi
  933. blockstr=$"Block/Unblock email going to"
  934. data=$(tempfile 2>/dev/null)
  935. trap "rm -f $data" 0 1 2 5 15
  936. dialog --backtitle $"Freedombone Control Panel" \
  937. --title "$blockstr $SELECTED_USERNAME" \
  938. --form "\n" 8 65 3 \
  939. $"When email arrives from address:" 1 1 "" 1 35 24 100 \
  940. $"Block it:" 2 1 "yes" 2 35 4 4 \
  941. 2> $data
  942. sel=$?
  943. case $sel in
  944. 1) return;;
  945. 255) return;;
  946. esac
  947. BLOCK_EMAIL=$(cat $data | sed -n 1p)
  948. BLOCK=$(cat $data | sed -n 2p)
  949. if [ ${#BLOCK_EMAIL} -lt 2 ]; then
  950. dialog --title $"Block/Unblock an email" \
  951. --msgbox $"No email address was given" 6 40
  952. return
  953. fi
  954. if [[ "$BLOCK_EMAIL" != *"@"* || "$BLOCK_EMAIL" != *"."* ]]; then
  955. dialog --title $"Block/Unblock an email" \
  956. --msgbox $"Unrecognised email address" 6 40
  957. return
  958. fi
  959. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  960. ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL"
  961. dialog --title $"Block an email" \
  962. --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME blocked" 6 75
  963. else
  964. ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL"
  965. dialog --title $"Unblock an email" \
  966. --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME unblocked" 6 75
  967. fi
  968. }
  969. function block_unblock_subject {
  970. select_user
  971. if [ ! $SELECTED_USERNAME ]; then
  972. return
  973. fi
  974. blockstr=$"Block/Unblock email going to"
  975. data=$(tempfile 2>/dev/null)
  976. trap "rm -f $data" 0 1 2 5 15
  977. dialog --backtitle $"Freedombone Control Panel" \
  978. --title "$blockstr $SELECTED_USERNAME" \
  979. --form "\n" 8 70 3 \
  980. $"When email arrives with subject text:" 1 1 "" 1 40 24 28 \
  981. $"Block it:" 2 1 "yes" 2 40 4 4 \
  982. 2> $data
  983. sel=$?
  984. case $sel in
  985. 1) return;;
  986. 255) return;;
  987. esac
  988. BLOCK_SUBJECT=$(cat $data | sed -n 1p)
  989. BLOCK=$(cat $data | sed -n 2p)
  990. if [ ${#BLOCK_SUBJECT} -lt 2 ]; then
  991. dialog --title $"Block/Unblock an email" \
  992. --msgbox $"No subject was given" 6 40
  993. return
  994. fi
  995. if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then
  996. ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT"
  997. dialog --title $"Block an email" \
  998. --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME blocked" 6 40
  999. else
  1000. ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT"
  1001. dialog --title $"Unblock an email" \
  1002. --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME unblocked" 6 40
  1003. fi
  1004. }
  1005. function create_keydrive_master {
  1006. select_user
  1007. if [ ! $SELECTED_USERNAME ]; then
  1008. return
  1009. fi
  1010. dialog --title $"USB Master Keydrive" \
  1011. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  1012. clear
  1013. ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME --master 'yes'
  1014. any_key
  1015. }
  1016. function create_keydrive_fragment {
  1017. select_user
  1018. if [ ! $SELECTED_USERNAME ]; then
  1019. return
  1020. fi
  1021. dialog --title $"USB Fragment Keydrive" \
  1022. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  1023. clear
  1024. ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME
  1025. any_key
  1026. }
  1027. function backup_data {
  1028. dialog --title $"Backup data to USB" \
  1029. --msgbox $"Plug in a LUKS encrypted USB drive" 6 40
  1030. clear
  1031. echo ' '
  1032. echo $'Enter the passphrase for your LUKS encrypted backup drive:'
  1033. ${PROJECT_NAME}-backup-local
  1034. any_key
  1035. }
  1036. function restore_from_usb {
  1037. detect_apps
  1038. applist="all"
  1039. n=1
  1040. app_index=0
  1041. for a in "${APPS_INSTALLED_NAMES[@]}"
  1042. do
  1043. applist="$applist $n $a off"
  1044. n=$[n+1]
  1045. app_index=$[app_index+1]
  1046. done
  1047. choices=$(dialog --stdout --backtitle $"Freedombone" \
  1048. --title $"Restore apps" \
  1049. --checklist $'Choose:' \
  1050. 80 40 20 $applist)
  1051. if [ $? -eq 0 ]; then
  1052. clear
  1053. ctr=0
  1054. for choice in $choices
  1055. do
  1056. app_index = $[choice-1]
  1057. app_name=${APPS_INSTALLED_NAMES[app_index]}
  1058. if [[ "${app_name}" == 'all' ]]; then
  1059. ${PROJECT_NAME}-restore-local $USB_DRIVE
  1060. else
  1061. ${PROJECT_NAME}-restore-local $USB_DRIVE "${app_name}"
  1062. fi
  1063. if [ ! "$?" = "0" ]; then
  1064. dialog --title $"Restore apps from USB" \
  1065. --msgbox $"Restore of ${app_name} failed with code $?" 6 40
  1066. return
  1067. fi
  1068. ctr=$((ctr + 1))
  1069. done
  1070. if [ $ctr -gt 0 ]; then
  1071. dialog --title $"Restore apps from USB" \
  1072. --msgbox $"Restore complete" 6 40
  1073. fi
  1074. fi
  1075. }
  1076. function restore_from_remote {
  1077. remote_domain_name=$1
  1078. while true
  1079. do
  1080. data=$(tempfile 2>/dev/null)
  1081. trap "rm -f $data" 0 1 2 5 15
  1082. dialog --backtitle $"Freedombone Control Panel" \
  1083. --title $"Restore from ${remote_domain_name}" \
  1084. --radiolist $"Choose an application to restore:" 31 70 28 \
  1085. 1 $"Everything" off \
  1086. 2 $"Return to the backup and restore menu" on \
  1087. 3 $"Configuration files" off \
  1088. 4 $"MariaDB settings" off \
  1089. 5 $"Let's Encrypt account" off \
  1090. 6 $"Mutt email client settings" off \
  1091. 7 $"GPG keys" off \
  1092. 8 $"Email processing rules" off \
  1093. 9 $"Spam filtering rules" off \
  1094. 10 $"Administrator's README file" off \
  1095. 11 $"IPFS" off \
  1096. 12 $"SSH keys" off \
  1097. 13 $"User configuration files" off \
  1098. 14 $"User local files" off \
  1099. 15 $"User fin files" off \
  1100. 16 $"SSL/TLS certificates" off \
  1101. 17 $"Personal settings" off \
  1102. 18 $"Mailing List" off \
  1103. 19 $"XMPP chat" off \
  1104. 20 $"GNU Social" off \
  1105. 21 $"Hubzilla" off \
  1106. 22 $"Syncthing" off \
  1107. 23 $"Gogs" off \
  1108. 24 $"Wiki" off \
  1109. 25 $"Blog" off \
  1110. 26 $"CJDNS" off \
  1111. 27 $"Email" off \
  1112. 28 $"DLNA" off \
  1113. 29 $"VoIP" off \
  1114. 30 $"RSS reader" off \
  1115. 31 $"Tox" off 2> $data
  1116. sel=$?
  1117. case $sel in
  1118. 1) break;;
  1119. 255) break;;
  1120. esac
  1121. if [ $(cat $data) -ne 2 ]; then
  1122. clear
  1123. fi
  1124. case $(cat $data) in
  1125. 1) ${PROJECT_NAME}-restore-remote $remote_domain_name;;
  1126. 2) return;;
  1127. 3) ${PROJECT_NAME}-restore-remote $remote_domain_name configuration;;
  1128. 4) ${PROJECT_NAME}-restore-remote $remote_domain_name mariadb;;
  1129. 5) ${PROJECT_NAME}-restore-remote $remote_domain_name letsencrypt;;
  1130. 6) ${PROJECT_NAME}-restore-remote $remote_domain_name mutt;;
  1131. 7) ${PROJECT_NAME}-restore-remote $remote_domain_name gpg;;
  1132. 8) ${PROJECT_NAME}-restore-remote $remote_domain_name procmail;;
  1133. 9) ${PROJECT_NAME}-restore-remote $remote_domain_name spamassassin;;
  1134. 10) ${PROJECT_NAME}-restore-remote $remote_domain_name readme;;
  1135. 11) ${PROJECT_NAME}-restore-remote $remote_domain_name ipfs;;
  1136. 12) ${PROJECT_NAME}-restore-remote $remote_domain_name ssh;;
  1137. 13) ${PROJECT_NAME}-restore-remote $remote_domain_name userconfig;;
  1138. 14) ${PROJECT_NAME}-restore-remote $remote_domain_name userlocal;;
  1139. 15) ${PROJECT_NAME}-restore-remote $remote_domain_name userfin;;
  1140. 16) ${PROJECT_NAME}-restore-remote $remote_domain_name certs;;
  1141. 17) ${PROJECT_NAME}-restore-remote $remote_domain_name personal;;
  1142. 18) ${PROJECT_NAME}-restore-remote $remote_domain_name mailinglist;;
  1143. 19) ${PROJECT_NAME}-restore-remote $remote_domain_name xmpp;;
  1144. 20) ${PROJECT_NAME}-restore-remote $remote_domain_name gnusocial;;
  1145. 21) ${PROJECT_NAME}-restore-remote $remote_domain_name hubzilla;;
  1146. 22) ${PROJECT_NAME}-restore-remote $remote_domain_name syncthing;;
  1147. 23) ${PROJECT_NAME}-restore-remote $remote_domain_name gogs;;
  1148. 24) ${PROJECT_NAME}-restore-remote $remote_domain_name wiki;;
  1149. 25) ${PROJECT_NAME}-restore-remote $remote_domain_name blog;;
  1150. 26) ${PROJECT_NAME}-restore-remote $remote_domain_name cjdns;;
  1151. 27) ${PROJECT_NAME}-restore-remote $remote_domain_name email;;
  1152. 28) ${PROJECT_NAME}-restore-remote $remote_domain_name dlna;;
  1153. 29) ${PROJECT_NAME}-restore-remote $remote_domain_name voip;;
  1154. 30) ${PROJECT_NAME}-restore-remote $remote_domain_name ttrss;;
  1155. 31) ${PROJECT_NAME}-restore-remote $remote_domain_name tox;;
  1156. esac
  1157. done
  1158. any_key
  1159. }
  1160. function restore_data {
  1161. dialog --title $"Restore data from USB" \
  1162. --msgbox $"Plug in your backup USB drive" 6 40
  1163. clear
  1164. echo ' '
  1165. echo $'Enter the passphrase for your LUKS encrypted backup drive:'
  1166. restore_from_usb
  1167. }
  1168. function restore_data_remote {
  1169. if [ ! $ADMIN_USER ]; then
  1170. dialog --title $"Restore data from remote server" \
  1171. --msgbox $"Unknown admin user" 6 40
  1172. return
  1173. fi
  1174. data=$(tempfile 2>/dev/null)
  1175. trap "rm -f $data" 0 1 2 5 15
  1176. dialog --title $"Restore from remote server" \
  1177. --backtitle $"Freedombone Control Panel" \
  1178. --inputbox $"Enter the domain name of the server from which you wish to restore" 8 60 2>$data
  1179. sel=$?
  1180. case $sel in
  1181. 0)
  1182. friend_server_domain_name=$(<$data)
  1183. if [ ${#friend_server_domain_name} -lt 2 ]; then
  1184. return
  1185. fi
  1186. if [[ $friend_server_domain_name != *"."* ]]; then
  1187. dialog --title $"Remote server domain name" \
  1188. --msgbox $"Invalid domain name" 6 40
  1189. return
  1190. fi
  1191. restore_from_remote $friend_server_domain_name
  1192. ;;
  1193. esac
  1194. }
  1195. function ping_enable_disable {
  1196. 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."
  1197. enable_ping="no"
  1198. dialog --title $"Enable Ping / ICMP" \
  1199. --backtitle $"Freedombone Control Panel" \
  1200. --defaultno \
  1201. --yesno "$ping_str" 10 60
  1202. sel=$?
  1203. case $sel in
  1204. 0) enable_ping="yes";;
  1205. 255) return;;
  1206. esac
  1207. if [[ $enable_ping == "yes" ]]; then
  1208. iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
  1209. iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
  1210. echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all
  1211. else
  1212. iptables -D INPUT -p icmp --icmp-type echo-request -j ACCEPT
  1213. iptables -D OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
  1214. echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
  1215. fi
  1216. }
  1217. function logging_on_off {
  1218. logging="no"
  1219. dialog --title $"Logging" \
  1220. --backtitle $"Freedombone Control Panel" \
  1221. --yesno $"\nDo you want to turn logging on?" 7 60
  1222. sel=$?
  1223. case $sel in
  1224. 0) logging="yes";;
  1225. 255) return;;
  1226. esac
  1227. clear
  1228. echo ''
  1229. echo $'This may take a few seconds. Please wait...'
  1230. if [[ $logging == "no" ]]; then
  1231. ${PROJECT_NAME}-logging off
  1232. else
  1233. ${PROJECT_NAME}-logging on
  1234. fi
  1235. }
  1236. function restore_gpg_key {
  1237. select_user
  1238. if [ ! $SELECTED_USERNAME ]; then
  1239. return
  1240. fi
  1241. restorestr=$"Restore GPG key for user"
  1242. dialog --title "$restorestr $SELECTED_USERNAME" \
  1243. --msgbox $"Plug in your USB keydrive" 6 40
  1244. clear
  1245. ${PROJECT_NAME}-recoverkey -u $SELECTED_USERNAME
  1246. any_key
  1247. }
  1248. function security_settings {
  1249. ${PROJECT_NAME}-sec
  1250. any_key
  1251. }
  1252. function reset_tripwire {
  1253. if [ ! -f /usr/bin/reset-tripwire ]; then
  1254. return
  1255. fi
  1256. clear
  1257. echo $'Resetting the Tripwire...'
  1258. echo ' '
  1259. echo '
  1260. ' | reset-tripwire
  1261. any_key
  1262. }
  1263. function hubzilla_renew_cert {
  1264. dialog --title $"Renew SSL certificate" \
  1265. --backtitle $"Freedombone Control Panel" \
  1266. --yesno $"\nThis will renew a letsencrypt certificate. Select 'yes' to continue" 16 60
  1267. sel=$?
  1268. case $sel in
  1269. 1) return;;
  1270. 255) return;;
  1271. esac
  1272. HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
  1273. if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
  1274. dialog --title $"Renew SSL certificate" \
  1275. --msgbox $"Hubzilla install directory not found" 6 40
  1276. return
  1277. fi
  1278. ${PROJECT_NAME}-renew-cert -h $HUBZILLA_DOMAIN_NAME -p 'letsencrypt'
  1279. if [ ! "$?" = "0" ]; then
  1280. any_key
  1281. else
  1282. dialog --title $"Renew SSL certificate" \
  1283. --msgbox $"Hubzilla certificate has been renewed" 6 40
  1284. fi
  1285. }
  1286. function hubzilla_channel_directory_server {
  1287. if ! grep -q "Hubzilla domain" $COMPLETION_FILE; then
  1288. dialog --title $"Hubzilla channel directory server" \
  1289. --msgbox $"Hubzilla is not installed on this system" 6 40
  1290. return
  1291. fi
  1292. HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
  1293. if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
  1294. dialog --title $"Hubzilla channel directory server" \
  1295. --msgbox $"Hubzilla install directory not found" 6 40
  1296. return
  1297. fi
  1298. data=$(tempfile 2>/dev/null)
  1299. trap "rm -f $data" 0 1 2 5 15
  1300. dialog --title $"Hubzilla channel directory server" \
  1301. --backtitle $"Freedombone Control Panel" \
  1302. --inputbox $"When you click on 'channel directory' this is where Hubzilla will obtain its list from" 8 60 2>$data
  1303. sel=$?
  1304. case $sel in
  1305. 0)
  1306. hubzilla_domain_server=$(<$data)
  1307. if [[ $hubzilla_domain_server != *"."* ]]; then
  1308. return
  1309. fi
  1310. if [[ $hubzilla_domain_server != "https"* ]]; then
  1311. dialog --title $"Hubzilla channel directory server" \
  1312. --msgbox $"Invalid domain - include the https://" 6 40
  1313. return
  1314. fi
  1315. ./var/www/$HUBZILLA_DOMAIN_NAME/htdocs/util/config system directory_server $hubzilla_domain_server
  1316. dialog --title $"Hubzilla channel directory server" \
  1317. --msgbox $"Domain channel directory server changed to $hubzilla_domain_server" 6 40
  1318. ;;
  1319. esac
  1320. }
  1321. function format_drive {
  1322. drive=
  1323. data=$(tempfile 2>/dev/null)
  1324. trap "rm -f $data" 0 1 2 5 15
  1325. dialog --backtitle $"Freedombone Control Panel" \
  1326. --title $"Format a USB drive (LUKS encrypted)" \
  1327. --radiolist $"Choose a drive:" 12 70 5 \
  1328. 1 $"sda (Beaglebone Black)" off \
  1329. 2 $"sdb" off \
  1330. 3 $"sdc" off \
  1331. 4 $"sdd" off \
  1332. 5 $"Back to Backup and Restore menu" on 2> $data
  1333. sel=$?
  1334. case $sel in
  1335. 1) return;;
  1336. 255) return;;
  1337. esac
  1338. case $(cat $data) in
  1339. 1) drive='sda';;
  1340. 2) drive='sdb';;
  1341. 3) drive='sdc';;
  1342. 4) drive='sdd';;
  1343. 5) return;;
  1344. esac
  1345. dialog --title $"Format USB drive" \
  1346. --backtitle $"Freedombone Control Panel" \
  1347. --defaultno \
  1348. --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
  1349. sel=$?
  1350. case $sel in
  1351. 1) return;;
  1352. 255) return;;
  1353. esac
  1354. clear
  1355. ${PROJECT_NAME}-format $drive
  1356. any_key
  1357. }
  1358. function remove_backups {
  1359. drive=
  1360. data=$(tempfile 2>/dev/null)
  1361. trap "rm -f $data" 0 1 2 5 15
  1362. dialog --backtitle $"Freedombone Control Panel" \
  1363. --title $"Remove backups from a USB drive" \
  1364. --radiolist $"Choose a drive:" 12 70 5 \
  1365. 1 $"sda (Beaglebone Black)" off \
  1366. 2 $"sdb" off \
  1367. 3 $"sdc" off \
  1368. 4 $"sdd" off \
  1369. 5 $"Back to Backup and Restore menu" on 2> $data
  1370. sel=$?
  1371. case $sel in
  1372. 1) return;;
  1373. 255) return;;
  1374. esac
  1375. case $(cat $data) in
  1376. 1) drive='sda';;
  1377. 2) drive='sdb';;
  1378. 3) drive='sdc';;
  1379. 4) drive='sdd';;
  1380. 5) return;;
  1381. esac
  1382. dialog --title $"Remove backups from a USB drive" \
  1383. --backtitle $"Freedombone Control Panel" \
  1384. --defaultno \
  1385. --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
  1386. sel=$?
  1387. case $sel in
  1388. 1) return;;
  1389. 255) return;;
  1390. esac
  1391. clear
  1392. ${PROJECT_NAME}-backup-local $drive remove
  1393. any_key
  1394. }
  1395. function shut_down_system {
  1396. dialog --title $"Power off the system" \
  1397. --backtitle $"Freedombone Control Panel" \
  1398. --defaultno \
  1399. --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
  1400. sel=$?
  1401. case $sel in
  1402. 1) return;;
  1403. 255) return;;
  1404. esac
  1405. shutdown now
  1406. }
  1407. function restart_system {
  1408. dialog --title $"Restart the system" \
  1409. --backtitle $"Freedombone Control Panel" \
  1410. --defaultno \
  1411. --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
  1412. sel=$?
  1413. case $sel in
  1414. 1) return;;
  1415. 255) return;;
  1416. esac
  1417. reboot
  1418. }
  1419. function change_system_name {
  1420. data=$(tempfile 2>/dev/null)
  1421. trap "rm -f $data" 0 1 2 5 15
  1422. dialog --title $"Change the name of this system" \
  1423. --backtitle $"Freedombone Control Panel" \
  1424. --inputbox $'Enter a new name for this system on your local network\n\nIt will appear as newname.local' 10 60 2>$data
  1425. sel=$?
  1426. case $sel in
  1427. 0) NEW_SYSTEM_NAME=$(<$data)
  1428. if [ "$NEW_SYSTEM_NAME" ]; then
  1429. if [ ${#NEW_SYSTEM_NAME} -gt 1 ]; then
  1430. sed -i "s|host-name=.*|host-name=$NEW_SYSTEM_NAME|g" /etc/avahi/avahi-daemon.conf
  1431. systemctl restart avahi-daemon
  1432. if grep -q "host-name=$NEW_SYSTEM_NAME" /etc/avahi/avahi-daemon.conf; then
  1433. dialog --title $"New local network name" \
  1434. --msgbox $"The name of this system on your local network was changed successfully" 6 70
  1435. fi
  1436. fi
  1437. fi
  1438. ;;
  1439. esac
  1440. }
  1441. function set_tls_time_source {
  1442. TLS_DATE_SOURCE=$(cat /usr/bin/updatedate | grep "TIMESOURCE='" | awk -F '=' '{print $2}' | awk -F "'" '{print $2}')
  1443. data=$(tempfile 2>/dev/null)
  1444. trap "rm -f $data" 0 1 2 5 15
  1445. dialog --title $"Set the TLS date/time source" \
  1446. --backtitle $"Freedombone Control Panel" \
  1447. --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
  1448. sel=$?
  1449. case $sel in
  1450. 0) NEW_TLS_DATE_SOURCE=$(<$data)
  1451. if [[ $NEW_TLS_DATE_SOURCE == *"."* && $NEW_TLS_DATE_SOURCE != *'/'* ]]; then
  1452. if [[ $NEW_TLS_DATE_SOURCE != "http"* ]]; then
  1453. sed -i "s|TIMESOURCE='.*|TIMESOURCE='${NEW_TLS_DATE_SOURCE}'|g" $UPDATE_DATE_SCRIPT
  1454. else
  1455. dialog --title $"Invalid domain name" \
  1456. --msgbox $"Don't include the 'https'" 6 70
  1457. fi
  1458. else
  1459. dialog --title $"Invalid domain name" \
  1460. --msgbox $"That doesn't look like a domain name" 6 70
  1461. fi
  1462. ;;
  1463. esac
  1464. }
  1465. function set_static_IP {
  1466. STATIC_IP='192.168.1.60'
  1467. STATIC_GATEWAY='192.168.1.1'
  1468. NEW_STATIC_IP=
  1469. NEW_STATIC_GATEWAY=
  1470. if grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1471. STATIC_IP=$(cat /etc/network/interfaces | grep "address " | awk -F ' ' '{print $2}' | head -n 1)
  1472. STATIC_GATEWAY=$(cat /etc/network/interfaces | grep "gateway " | awk -F ' ' '{print $2}' | head -n 1)
  1473. fi
  1474. # get the IP for the box
  1475. data=$(tempfile 2>/dev/null)
  1476. trap "rm -f $data" 0 1 2 5 15
  1477. dialog --title $"Set a static local IP address" \
  1478. --backtitle $"Freedombone Control Panel" \
  1479. --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
  1480. Enter a static local IP address for this system.\n\nIt will typically be 192.168.1.x" 15 60 "$STATIC_IP" 2>$data
  1481. sel=$?
  1482. case $sel in
  1483. 0) NEW_STATIC_IP=$(<$data)
  1484. if [[ "$NEW_STATIC_IP" != *"."* ]]; then
  1485. return
  1486. fi
  1487. if grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1488. if [[ "$NEW_STATIC_IP" != "$STATIC_IP" ]]; then
  1489. sed -i "s|${STATIC_IP}|${NEW_STATIC_IP}|g" /etc/network/interfaces
  1490. fi
  1491. fi
  1492. ;;
  1493. esac
  1494. # get the gateway
  1495. data=$(tempfile 2>/dev/null)
  1496. trap "rm -f $data" 0 1 2 5 15
  1497. dialog --title $"Set the IP address of your internet router/modem" \
  1498. --backtitle $"Freedombone Control Panel" \
  1499. --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
  1500. sel=$?
  1501. case $sel in
  1502. 0) NEW_STATIC_GATEWAY=$(<$data)
  1503. if [[ "$NEW_STATIC_GATEWAY" != *"."* ]]; then
  1504. return
  1505. fi
  1506. if grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1507. if [[ "$NEW_STATIC_GATEWAY" != "$STATIC_GATEWAY" ]]; then
  1508. sed -i "s|${STATIC_GATEWAY}|${NEW_STATIC_GATEWAY}|g" /etc/network/interfaces
  1509. fi
  1510. return
  1511. fi
  1512. ;;
  1513. esac
  1514. if ! grep -q 'iface eth0 inet static' /etc/network/interfaces; then
  1515. if [ "$NEW_STATIC_GATEWAY" && "$NEW_STATIC_IP" ]; then
  1516. echo '# This file describes the network interfaces available on your system' > /etc/network/interfaces
  1517. echo '# and how to activate them. For more information, see interfaces(5).' >> /etc/network/interfaces
  1518. echo '' >> /etc/network/interfaces
  1519. echo '# The loopback network interface' >> /etc/network/interfaces
  1520. echo 'auto lo' >> /etc/network/interfaces
  1521. echo 'iface lo inet loopback' >> /etc/network/interfaces
  1522. echo '' >> /etc/network/interfaces
  1523. echo '# The primary network interface' >> /etc/network/interfaces
  1524. echo 'auto eth0' >> /etc/network/interfaces
  1525. echo 'iface eth0 inet static' >> /etc/network/interfaces
  1526. echo " address ${NEW_STATIC_IP}" >> /etc/network/interfaces
  1527. echo ' netmask 255.255.255.0' >> /etc/network/interfaces
  1528. echo " gateway ${NEW_STATIC_GATEWAY}" >> /etc/network/interfaces
  1529. echo " dns-nameservers 213.73.91.35 85.214.20.141" >> /etc/network/interfaces
  1530. echo '# Example to keep MAC address between reboots' >> /etc/network/interfaces
  1531. echo '#hwaddress ether DE:AD:BE:EF:CA:FE' >> /etc/network/interfaces
  1532. echo '' >> /etc/network/interfaces
  1533. echo '# The secondary network interface' >> /etc/network/interfaces
  1534. echo '#auto eth1' >> /etc/network/interfaces
  1535. echo '#iface eth1 inet dhcp' >> /etc/network/interfaces
  1536. echo '' >> /etc/network/interfaces
  1537. echo '# WiFi Example' >> /etc/network/interfaces
  1538. echo "#auto $WIFI_INTERFACE" >> /etc/network/interfaces
  1539. echo "#iface $WIFI_INTERFACE inet dhcp" >> /etc/network/interfaces
  1540. echo '# wpa-ssid "essid"' >> /etc/network/interfaces
  1541. echo '# wpa-psk "password"' >> /etc/network/interfaces
  1542. echo '' >> /etc/network/interfaces
  1543. echo '# Ethernet/RNDIS gadget (g_ether)' >> /etc/network/interfaces
  1544. echo '# ... or on host side, usbnet and random hwaddr' >> /etc/network/interfaces
  1545. echo '# Note on some boards, usb0 is automaticly setup with an init script' >> /etc/network/interfaces
  1546. echo '#iface usb0 inet static' >> /etc/network/interfaces
  1547. echo '# address 192.168.7.2' >> /etc/network/interfaces
  1548. echo '# netmask 255.255.255.0' >> /etc/network/interfaces
  1549. echo '# network 192.168.7.0' >> /etc/network/interfaces
  1550. echo '# gateway 192.168.7.1' >> /etc/network/interfaces
  1551. fi
  1552. fi
  1553. }
  1554. function wifi_settings {
  1555. if [ -f /etc/hostapd/hostapd.conf ]; then
  1556. return
  1557. fi
  1558. TEMP_WIFI_NETWORKS_FILE=~/.temp-${PROJECT_NAME}-wifi.cfg
  1559. ${PROJECT_NAME}-wifi --networksinteractive $TEMP_WIFI_NETWORKS_FILE
  1560. if [ -f $TEMP_WIFI_NETWORKS_FILE ]; then
  1561. cp $TEMP_WIFI_NETWORKS_FILE $WIFI_NETWORKS_FILE
  1562. rm $TEMP_WIFI_NETWORKS_FILE
  1563. ${PROJECT_NAME}-wifi --networks $WIFI_NETWORKS_FILE
  1564. dialog --title $"Wifi Settings" \
  1565. --msgbox $"Wifi settings were changed" 6 40
  1566. fi
  1567. }
  1568. function wifi_edit_networks {
  1569. if [ -f /etc/hostapd/hostapd.conf ]; then
  1570. return
  1571. fi
  1572. if [ ! -f $WIFI_NETWORKS_FILE ]; then
  1573. echo $'# Add wifi networks as follows:' > $WIFI_NETWORKS_FILE
  1574. echo '#' >> $WIFI_NETWORKS_FILE
  1575. echo $'# MySSID' >> $WIFI_NETWORKS_FILE
  1576. echo $'# wpa2-psk' >> $WIFI_NETWORKS_FILE
  1577. echo $'# myWifiPassphrase' >> $WIFI_NETWORKS_FILE
  1578. echo '#' >> $WIFI_NETWORKS_FILE
  1579. echo $'# AnotherSSID' >> $WIFI_NETWORKS_FILE
  1580. echo $'# none' >> $WIFI_NETWORKS_FILE
  1581. echo '#' >> $WIFI_NETWORKS_FILE
  1582. fi
  1583. editor $WIFI_NETWORKS_FILE
  1584. ${PROJECT_NAME}-wifi --networks $WIFI_NETWORKS_FILE
  1585. }
  1586. function hotspot_settings {
  1587. data=$(tempfile 2>/dev/null)
  1588. trap "rm -f $data" 0 1 2 5 15
  1589. dialog --backtitle $"Freedombone Control Panel" \
  1590. --title $"Hotspot Settings" \
  1591. --form $"" 10 60 4 \
  1592. $"Enabled (yes/no):" 1 1 "$WIFI_HOTSPOT" 1 24 5 5 \
  1593. $"SSID:" 2 1 "$WIFI_SSID" 2 24 256 256 \
  1594. $"Type (wpa2-psk/none):" 3 1 "$WIFI_TYPE" 3 24 10 10 \
  1595. $"Passphrase:" 4 1 "$WIFI_PASSPHRASE" 4 24 256 256 \
  1596. 2> $data
  1597. sel=$?
  1598. case $sel in
  1599. 1) return;;
  1600. 255) return;;
  1601. esac
  1602. TEMP_WIFI_HOTSPOT=$(cat $data | sed -n 1p)
  1603. TEMP_WIFI_SSID=$(cat $data | sed -n 2p)
  1604. TEMP_WIFI_TYPE=$(cat $data | sed -n 3p)
  1605. TEMP_WIFI_PASSPHRASE=$(cat $data | sed -n 4p)
  1606. if [ ${#TEMP_WIFI_SSID} -lt 2 ]; then
  1607. return
  1608. fi
  1609. if [ ${#TEMP_WIFI_TYPE} -lt 2 ]; then
  1610. return
  1611. fi
  1612. WIFI_EXTRA=''
  1613. if [[ $TEMP_WIFI_HOTSPOT == $'yes' || $TEMP_WIFI_HOTSPOT == $'y' || $TEMP_WIFI_HOTSPOT == $'on' ]]; then
  1614. TEMP_WIFI_HOTSPOT='yes'
  1615. else
  1616. TEMP_WIFI_HOTSPOT='no'
  1617. if [ -f $WIFI_NETWORKS_FILE ]; then
  1618. WIFI_EXTRA='--networks $WIFI_NETWORKS_FILE'
  1619. fi
  1620. fi
  1621. if [[ $TEMP_WIFI_TYPE != $'none' ]]; then
  1622. if [ ! $TEMP_WIFI_PASSPHRASE ]; then
  1623. dialog --title $"Wifi Settings" \
  1624. --msgbox $"No wifi hotspot passphrase was given" 6 40
  1625. return
  1626. fi
  1627. if [ ${#TEMP_WIFI_PASSPHRASE} -lt 2 ]; then
  1628. dialog --title $"Wifi Settings" \
  1629. --msgbox $"Wifi hotspot passphrase was too short" 6 40
  1630. return
  1631. fi
  1632. WIFI_HOTSPOT=$TEMP_WIFI_HOTSPOT
  1633. WIFI_SSID=$TEMP_WIFI_SSID
  1634. WIFI_TYPE=$TEMP_WIFI_TYPE
  1635. WIFI_PASSPHRASE=$TEMP_WIFI_PASSPHRASE
  1636. ${PROJECT_NAME}-wifi -i $WIFI_INTERFACE -s $WIFI_SSID -t $WIFI_TYPE -p $WIFI_PASSPHRASE --hotspot $WIFI_HOTSPOT $WIFI_EXTRA
  1637. else
  1638. WIFI_HOTSPOT=$TEMP_WIFI_HOTSPOT
  1639. WIFI_SSID=$TEMP_WIFI_SSID
  1640. WIFI_TYPE=$TEMP_WIFI_TYPE
  1641. WIFI_PASSPHRASE=$TEMP_WIFI_PASSPHRASE
  1642. ${PROJECT_NAME}-wifi -i $WIFI_INTERFACE -s $WIFI_SSID -t $WIFI_TYPE --hotspot $WIFI_HOTSPOT $WIFI_EXTRA
  1643. fi
  1644. # store any changes
  1645. if ! grep -q "WIFI_HOTSPOT" $CONFIGURATION_FILE; then
  1646. echo "WIFI_HOTSPOT=$WIFI_HOTSPOT" >> $CONFIGURATION_FILE
  1647. else
  1648. sed -i "s|WIFI_HOTSPOT=.*|WIFI_HOTSPOT=$WIFI_HOTSPOT|g" $CONFIGURATION_FILE
  1649. fi
  1650. if ! grep -q "WIFI_SSID" $CONFIGURATION_FILE; then
  1651. echo "WIFI_SSID=$WIFI_SSID" >> $CONFIGURATION_FILE
  1652. else
  1653. sed -i "s|WIFI_SSID=.*|WIFI_SSID=$WIFI_SSID|g" $CONFIGURATION_FILE
  1654. fi
  1655. if ! grep -q "WIFI_TYPE" $CONFIGURATION_FILE; then
  1656. echo "WIFI_TYPE=$WIFI_TYPE" >> $CONFIGURATION_FILE
  1657. else
  1658. sed -i "s|WIFI_TYPE=.*|WIFI_SSID=$WIFI_TYPE|g" $CONFIGURATION_FILE
  1659. fi
  1660. if ! grep -q "WIFI_PASSPHRASE" $CONFIGURATION_FILE; then
  1661. echo "WIFI_PASSPHRASE=$WIFI_PASSPHRASE" >> $CONFIGURATION_FILE
  1662. else
  1663. sed -i "s|WIFI_PASSPHRASE=.*|WIFI_PASSPHRASE=$WIFI_PASSPHRASE|g" $CONFIGURATION_FILE
  1664. fi
  1665. dialog --title $"Wifi Settings" \
  1666. --msgbox $"Hotspot settings were changed" 6 40
  1667. }
  1668. function reinstall_mariadb {
  1669. dialog --title $"Reinstall MariaDB" \
  1670. --backtitle $"Freedombone Control Panel" \
  1671. --defaultno \
  1672. --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
  1673. sel=$?
  1674. case $sel in
  1675. 1) return;;
  1676. 255) return;;
  1677. esac
  1678. clear
  1679. database_reinstall
  1680. dialog --title $"Reinstall MariaDB" \
  1681. --msgbox $"MariaDB has been reinstalled" 6 40
  1682. }
  1683. function menu_backup_restore {
  1684. while true
  1685. do
  1686. data=$(tempfile 2>/dev/null)
  1687. trap "rm -f $data" 0 1 2 5 15
  1688. dialog --backtitle $"Freedombone Control Panel" \
  1689. --title $"Backup and Restore" \
  1690. --radiolist $"Choose an operation:" 19 70 12 \
  1691. 1 $"Backup data to USB drive" off \
  1692. 2 $"Restore GPG key from USB keydrive" off \
  1693. 3 $"Restore data from USB drive" off \
  1694. 4 $"Reinstall mariadb" off \
  1695. 5 $"Configure remote backups" off \
  1696. 6 $"Restore from remote backup" off \
  1697. 7 $"Backup GPG key to USB (master keydrive)" off \
  1698. 8 $"Backup GPG key to USB (fragment keydrive)" off \
  1699. 9 $"Format a USB drive (LUKS encrypted)" off \
  1700. 10 $"Remove backups from a USB drive" off \
  1701. 11 $"Back to main menu" on 2> $data
  1702. sel=$?
  1703. case $sel in
  1704. 1) break;;
  1705. 255) break;;
  1706. esac
  1707. case $(cat $data) in
  1708. 1) backup_data;;
  1709. 2) restore_gpg_key;;
  1710. 3) restore_data;;
  1711. 4) reinstall_mariadb;;
  1712. 5) configure_remote_backups;;
  1713. 6) restore_data_remote;;
  1714. 7) create_keydrive_master;;
  1715. 8) create_keydrive_fragment;;
  1716. 9) format_drive;;
  1717. 10) remove_backups;;
  1718. 11) break;;
  1719. esac
  1720. done
  1721. }
  1722. function menu_email {
  1723. while true
  1724. do
  1725. data=$(tempfile 2>/dev/null)
  1726. trap "rm -f $data" 0 1 2 5 15
  1727. dialog --backtitle $"Freedombone Control Panel" \
  1728. --title $"Email Filtering Rules" \
  1729. --radiolist $"Choose an operation:" 13 70 6 \
  1730. 1 $"Add a user to a mailing list" off \
  1731. 2 $"Remove a user from a mailing list" off \
  1732. 3 $"Add an email rule" off \
  1733. 4 $"Block/Unblock an email address" off \
  1734. 5 $"Block/Unblock email with subject text" off \
  1735. 6 $"Back to main menu" on 2> $data
  1736. sel=$?
  1737. case $sel in
  1738. 1) break;;
  1739. 255) break;;
  1740. esac
  1741. case $(cat $data) in
  1742. 1) add_to_mailing_list;;
  1743. 2) remove_user_from_mailing_list;;
  1744. 3) email_rule;;
  1745. 4) block_unblock_email;;
  1746. 5) block_unblock_subject;;
  1747. 6) break;;
  1748. esac
  1749. done
  1750. }
  1751. function menu_users {
  1752. while true
  1753. do
  1754. data=$(tempfile 2>/dev/null)
  1755. trap "rm -f $data" 0 1 2 5 15
  1756. dialog --backtitle $"Freedombone Control Panel" \
  1757. --title $"Manage Users" \
  1758. --radiolist $"Choose an operation:" 12 70 5 \
  1759. 1 $"Add a user" off \
  1760. 2 $"Delete a user" off \
  1761. 3 $"Change user password" off \
  1762. 4 $"Change user ssh public key" off \
  1763. 5 $"Back to main menu" on 2> $data
  1764. sel=$?
  1765. case $sel in
  1766. 1) break;;
  1767. 255) break;;
  1768. esac
  1769. case $(cat $data) in
  1770. 1) add_user;;
  1771. 2) delete_user;;
  1772. 3) change_password;;
  1773. 4) change_ssh_public_key;;
  1774. 5) break;;
  1775. esac
  1776. done
  1777. }
  1778. function menu_hubzilla {
  1779. while true
  1780. do
  1781. data=$(tempfile 2>/dev/null)
  1782. trap "rm -f $data" 0 1 2 5 15
  1783. dialog --backtitle $"Freedombone Control Panel" \
  1784. --title $"Hubzilla" \
  1785. --radiolist $"Choose an operation:" 13 70 4 \
  1786. 1 $"Set channel directory server" off \
  1787. 2 $"Renew SSL certificate" off \
  1788. 3 $"Back to main menu" on 2> $data
  1789. sel=$?
  1790. case $sel in
  1791. 1) break;;
  1792. 255) break;;
  1793. esac
  1794. case $(cat $data) in
  1795. 1) hubzilla_channel_directory_server;;
  1796. 2) hubzilla_renew_cert;;
  1797. 3) break;;
  1798. esac
  1799. done
  1800. }
  1801. function menu_media {
  1802. while true
  1803. do
  1804. data=$(tempfile 2>/dev/null)
  1805. trap "rm -f $data" 0 1 2 5 15
  1806. dialog --backtitle $"Freedombone Control Panel" \
  1807. --title $"Media Menu" \
  1808. --radiolist $"Choose an operation:" 13 70 3 \
  1809. 1 $"Attach a drive containing playable media" off \
  1810. 2 $"Remove a drive containing playable media" off \
  1811. 3 $"Exit" on 2> $data
  1812. sel=$?
  1813. case $sel in
  1814. 1) break;;
  1815. 255) break;;
  1816. esac
  1817. case $(cat $data) in
  1818. 1) remove-music
  1819. attach-music;;
  1820. 2) remove-music;;
  1821. 3) break;;
  1822. esac
  1823. done
  1824. }
  1825. function wifi_enable {
  1826. disable_wifi='yes'
  1827. dialog --title $"Enable Wifi" \
  1828. --backtitle $"Freedombone Control Panel" \
  1829. --defaultno \
  1830. --yesno $"\nDo you wish to enable wifi?" 10 50
  1831. sel=$?
  1832. case $sel in
  1833. 0) disable_wifi='no';;
  1834. 1) disable_wifi='yes';;
  1835. 255) return;;
  1836. esac
  1837. ${PROJECT_NAME}-wifi --disable $disable_wifi
  1838. }
  1839. function menu_wifi {
  1840. while true
  1841. do
  1842. status_str=$'Wifi OFF'
  1843. if [ -f /etc/hostapd/hostapd.conf ]; then
  1844. status_str=$'Hotspot ON'
  1845. else
  1846. if grep -q "# wifi enabled" /etc/network/interfaces; then
  1847. status_str=$'Wifi ON'
  1848. fi
  1849. fi
  1850. data=$(tempfile 2>/dev/null)
  1851. trap "rm -f $data" 0 1 2 5 15
  1852. dialog --backtitle $"Freedombone Control Panel" \
  1853. --title $"Wifi Menu" \
  1854. --radiolist $"${status_str}\n\nChoose an operation:" 14 70 6 \
  1855. 1 $"Enable or disable Wifi" off \
  1856. 2 $"Configure wifi networks" off \
  1857. 3 $"Manually edit wifi networks file" off \
  1858. 4 $"Hotspot settings" off \
  1859. 5 $"Exit" on 2> $data
  1860. sel=$?
  1861. case $sel in
  1862. 1) break;;
  1863. 255) break;;
  1864. esac
  1865. case $(cat $data) in
  1866. 1) wifi_enable;;
  1867. 2) wifi_settings;;
  1868. 3) wifi_edit_networks;;
  1869. 4) hotspot_settings;;
  1870. 5) break;;
  1871. esac
  1872. done
  1873. }
  1874. function menu_irc {
  1875. if [ ! -d /etc/ngircd ]; then
  1876. dialog --title $"IRC Menu" \
  1877. --msgbox $"No IRC server is installed" 6 70
  1878. return
  1879. fi
  1880. while true
  1881. do
  1882. data=$(tempfile 2>/dev/null)
  1883. trap "rm -f $data" 0 1 2 5 15
  1884. dialog --backtitle $"Freedombone Control Panel" \
  1885. --title $"IRC Menu" \
  1886. --radiolist $"Choose an operation:" 14 70 4 \
  1887. 1 $"Set a password for all IRC users" off \
  1888. 2 $"Show current IRC login password" off \
  1889. 3 $"Exit" on 2> $data
  1890. sel=$?
  1891. case $sel in
  1892. 1) break;;
  1893. 255) break;;
  1894. esac
  1895. case $(cat $data) in
  1896. 1) irc_set_global_password;;
  1897. 2) irc_show_password;;
  1898. 3) break;;
  1899. esac
  1900. done
  1901. }
  1902. function menu_top_level {
  1903. while true
  1904. do
  1905. data=$(tempfile 2>/dev/null)
  1906. trap "rm -f $data" 0 1 2 5 15
  1907. dialog --backtitle $"Freedombone Control Panel" \
  1908. --title $"Control Panel" \
  1909. --radiolist $"Choose an operation:" 29 70 22 \
  1910. 1 $"About this system" off \
  1911. 2 $"Backup and Restore" off \
  1912. 3 $"Reset Tripwire" off \
  1913. 4 $"Logging on/off" off \
  1914. 5 $"Ping enable/disable" off \
  1915. 6 $"Manage Users" off \
  1916. 7 $"Email Filtering Rules" off \
  1917. 8 $"Outgoing Email Proxy" off \
  1918. 9 $"Security Settings" off \
  1919. 10 $"Set the main repository (repo mirrors)" off \
  1920. 11 $"Hubzilla" off \
  1921. 12 $"Media menu" off \
  1922. 13 $"IRC menu" off \
  1923. 14 $"Change your blog avatar" off \
  1924. 15 $"Change the name of this system" off \
  1925. 16 $"Set the TLS date/time source" off \
  1926. 17 $"Set a static local IP address" off \
  1927. 18 $"Wifi menu" off \
  1928. 19 $"Check for updates" off \
  1929. 20 $"Power off the system" off \
  1930. 21 $"Restart the system" off \
  1931. 22 $"Exit" on 2> $data
  1932. sel=$?
  1933. case $sel in
  1934. 1) exit 1;;
  1935. 255) exit 1;;
  1936. esac
  1937. case $(cat $data) in
  1938. 1) show_about;;
  1939. 2) menu_backup_restore;;
  1940. 3) reset_tripwire;;
  1941. 4) logging_on_off;;
  1942. 5) ping_enable_disable;;
  1943. 6) menu_users;;
  1944. 7) menu_email;;
  1945. 8) smtp_proxy;;
  1946. 9) security_settings;;
  1947. 10) set_main_repo;;
  1948. 11) menu_hubzilla;;
  1949. 12) menu_media;;
  1950. 13) menu_irc;;
  1951. 14) change_blog_avatar;;
  1952. 15) change_system_name;;
  1953. 16) set_tls_time_source;;
  1954. 17) set_static_IP;;
  1955. 18) menu_wifi;;
  1956. 19) check_for_updates;;
  1957. 20) shut_down_system;;
  1958. 21) restart_system;;
  1959. 22) break;;
  1960. esac
  1961. done
  1962. }
  1963. if [[ $USER != 'root' ]]; then
  1964. # show the user version of the control panel
  1965. ${PROJECT_NAME}-controlpanel-user
  1966. exit 0
  1967. fi
  1968. if [ ! -f $COMPLETION_FILE ]; then
  1969. echo $'This command should only be run on an installed Freedombone system'
  1970. exit 1
  1971. fi
  1972. ADMIN_USER=$(cat $COMPLETION_FILE | grep "Admin user" | awk -F ':' '{print $2}')
  1973. read_repo_servers
  1974. menu_top_level
  1975. clear
  1976. cat /etc/motd
  1977. exit 0