freedombone-controlpanel 63KB

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