freedombone-controlpanel 69KB

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