config 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #!/bin/bash
  2. #=================================================
  3. # GENERIC STARTING
  4. #=================================================
  5. # IMPORT GENERIC HELPERS
  6. #=================================================
  7. source _common.sh
  8. source /usr/share/yunohost/helpers
  9. #=================================================
  10. # RETRIEVE ARGUMENTS
  11. #=================================================
  12. app=$YNH_APP_INSTANCE_NAME
  13. final_path=$(ynh_app_setting_get $app final_path)
  14. #=================================================
  15. # SPECIFIC CODE
  16. #=================================================
  17. # DECLARE GENERIC FUNCTION
  18. #=================================================
  19. lowerdot_to_uppersnake() {
  20. local lowerdot
  21. lowerdot=$(echo "$1" | cut -d= -f1 | sed "s/\./_/g")
  22. echo "${lowerdot^^}"
  23. }
  24. _ynh_panel_get() {
  25. # From settings
  26. local params_sources
  27. params_sources=`python << EOL
  28. import toml
  29. from collections import OrderedDict
  30. with open("/etc/yunohost/apps/vpnclient/config_panel.toml", "r") as f:
  31. file_content = f.read()
  32. loaded_toml = toml.loads(file_content, _dict=OrderedDict)
  33. for panel_name,panel in loaded_toml.items():
  34. if isinstance(panel, dict):
  35. for section_name, section in panel.items():
  36. if isinstance(section, dict):
  37. for name, param in section.items():
  38. if isinstance(param, dict) and param.get('source', '') == 'settings':
  39. print("%s.%s.%s=%s" %(panel_name, section_name, name, param.get('source', 'settings')))
  40. EOL
  41. `
  42. for param_source in params_sources
  43. do
  44. local _dot_setting=$(echo "$param_source" | cut -d= -f1)
  45. local _snake_setting="YNH_CONFIG_$(lowerdot_to_uppersnake $dot_setting)"
  46. local short_setting=$(echo "$_dot_setting" | cut -d. -f3)
  47. local _getter="get__${short_setting}"
  48. local source="$(echo $param_source | cut -d= -f2)"
  49. # Get value from getter if exists
  50. if type $getter | grep -q '^function$' 2>/dev/null; then
  51. old[$short_setting]="$($getter)"
  52. #
  53. elif [[ "$source" != "settings" ]]
  54. then
  55. old[$short_setting]="$source"
  56. # By default, get value from settings.yml
  57. else
  58. old[$short_setting]="$(ynh_app_setting_get $app $short_setting)"
  59. fi
  60. done
  61. }
  62. _ynh_panel_apply() {
  63. for short_setting in "${!dot_settings[@]}"
  64. do
  65. local setter="set__${short_setting}"
  66. local source="$sources[$short_setting]"
  67. # Apply setter if exists
  68. if type $setter | grep -q '^function$' 2>/dev/null; then
  69. $setter
  70. # Copy file in right place
  71. elif [[ "$source" != "settings" ]]
  72. then
  73. cp "$new[$short_setting]" "$source"
  74. # By default, set value into settings.yml
  75. else
  76. ynh_app_setting_get $app $short_setting "$new[$short_setting]"
  77. fi
  78. done
  79. }
  80. _ynh_panel_show() {
  81. for short_setting in "${!old[@]}"
  82. do
  83. local key="YNH_CONFIG_$(lowerdot_to_uppersnake $dot_settings[$short_setting])"
  84. ynh_return "$key=${old[$short_setting]}"
  85. done
  86. }
  87. _ynh_panel_validate() {
  88. # Change detection
  89. local is_error=true
  90. #for changed_status in "${!changed[@]}"
  91. for short_setting in "${!dot_settings[@]}"
  92. do
  93. #TODO file hash
  94. file_hash[$setting]=$(sha256sum "$_source" | cut -d' ' -f1)
  95. file_hash[$form_setting]=$(sha256sum "${!form_setting}" | cut -d' ' -f1)
  96. if [[ "${file_hash[$setting]}" != "${file_hash[$form_setting]}" ]]
  97. then
  98. changed[$setting]=true
  99. fi
  100. if [[ "$new[$short_setting]" == "$old[$short_setting]" ]]
  101. then
  102. changed[$short_setting]=false
  103. else
  104. changed[$short_setting]=true
  105. is_error=false
  106. fi
  107. done
  108. # Run validation if something is changed
  109. if [[ "$is_error" == "false" ]]
  110. then
  111. for short_setting in "${!dot_settings[@]}"
  112. do
  113. local result="$(validate__$short_setting)"
  114. local key="YNH_ERROR_$(lowerdot_to_uppersnake $dot_settings[$short_setting])"
  115. if [ -n "$result" ]
  116. then
  117. ynh_return "$key=$result"
  118. is_error=true
  119. fi
  120. done
  121. fi
  122. if [[ "$is_error" == "true" ]]
  123. then
  124. ynh_die
  125. fi
  126. }
  127. ynh_panel_init() {
  128. declare -A old=()
  129. declare -A changed=()
  130. declare -A file_hash=()
  131. ynh_panel_get
  132. }
  133. ynh_panel_show() {
  134. _ynh_panel_show
  135. }
  136. ynh_panel_validate() {
  137. _ynh_panel_validate
  138. }
  139. ynh_panel_apply() {
  140. _ynh_panel_apply
  141. }
  142. #=================================================
  143. # SPECIFIC GETTERS FOR TOML SHORT KEY
  144. #=================================================
  145. get__status() {
  146. if [ -f "/sys/class/net/tun0/operstate" ] && [ "$(cat /sys/class/net/tun0/operstate)" == "up" ]
  147. then
  148. echo "running"
  149. else
  150. echo "not running"
  151. fi
  152. }
  153. get__login_user() {
  154. if [ -s /etc/openvpn/keys/credentials ]
  155. then
  156. sed -n 1p /etc/openvpn/keys/credentials
  157. fi
  158. }
  159. get__login_passphrase() {
  160. if [ -s /etc/openvpn/keys/credentials ]
  161. then
  162. sed -n 2p /etc/openvpn/keys/credentials
  163. fi
  164. }
  165. #=================================================
  166. # SPECIFIC VALIDATORS FOR TOML SHORT KEYS
  167. #=================================================
  168. validate__login_user() {
  169. [[ -n "$login_passphrase" && -z "$login_user" ]] &&
  170. echo 'A Username is needed when you suggest a Password'
  171. }
  172. validate__login_passphrase() {
  173. [[ -n "$login_user" && -z "$login_passphrase" ]] &&
  174. echo 'A Password is needed when you suggest a Username'
  175. }
  176. validate__crt() {
  177. [[ -n "$key" && -z "$crt" ]] &&
  178. echo "A Client Certificate is needed when you suggest a Key"
  179. }
  180. validate__key() {
  181. [[ -n "$crt" && -z "$key" ]] &&
  182. echo "A Key is needed when you suggest a Client Certificate"
  183. }
  184. # TODO
  185. validate__server_ip6() {
  186. $ipv6_expanded=$(ipv6_expanded "$server_ip6")
  187. if [[ -z "$ipv6_expanded" ]]
  188. then
  189. echo 'The IPv6 Delegated Prefix format looks bad'
  190. fi
  191. # $ip6_blocs = explode(':', $ip6_net);
  192. # $ip6_addr = "${ip6_blocs[0]}:${ip6_blocs[1]}:${ip6_blocs[2]}:${ip6_blocs[3]}:${ip6_blocs[4]}:${ip6_blocs[5]}:${ip6_blocs[6]}:42";
  193. # $ip6_net = ipv6_compressed($ip6_net);
  194. # $ip6_addr = ipv6_compressed($ip6_addr);
  195. }
  196. #=================================================
  197. # SPECIFIC SETTERS FOR TOML SHORT KEYS
  198. #=================================================
  199. set__login_user() {
  200. if [ -z "$login_user" ]
  201. then
  202. echo "$login_user\n$login_passphrase" > /etc/openvpn/keys/credentials
  203. else
  204. echo "" > /etc/openvpn/keys/credentials
  205. fi
  206. }
  207. set__login_passphrase() {
  208. :
  209. }
  210. # TODO
  211. set__cube_file() {
  212. if [ -f "$cube_file" ]
  213. then
  214. cp -f $tmp_dir/client.conf.tpl /etc/openvpn/client.conf.tpl
  215. fi
  216. }
  217. #=================================================
  218. # OVERWRITING VALIDATE STEP
  219. #=================================================
  220. ynh_panel_validate() {
  221. # Overwrite form response with cube files data before validation process
  222. if [[ "$cube_file" ]]
  223. then
  224. # TODO
  225. declare -A settings
  226. settings[server_name]=""
  227. settings[server_port]=""
  228. settings[server_proto]=""
  229. settings[login_user]=""
  230. settings[login_passphrase]=""
  231. settings[dns0]=""
  232. settings[dns1]=""
  233. settings[crt_server_ca]="file"
  234. settings[crt_client]="file"
  235. settings[crt_client_key]="file"
  236. settings[crt_client_ta]="file"
  237. tmp_dir=$(dirname "$cube_file")
  238. for setting_name in "${!settings[@]}"
  239. do
  240. setting_value="$(jq --raw-output '.$setting_name' '$cube_file')"
  241. if [[ "$setting_value" == "null" ]]
  242. then
  243. setting_value=''
  244. # Save file in tmp dir
  245. elif [[ "${settings[$setting_name]}" == "file" ]]
  246. then
  247. echo "${settings[$setting_name]}" | sed s/|/\n/g > $tmp_dir/$setting_name
  248. setting_value="$tmp_dir/$setting_name"
  249. fi
  250. # Change settings value and changed status if needed
  251. if [[ "$setting_value" != "${!setting}" ]]
  252. then
  253. declare "$setting='$setting_value'"
  254. changed[$setting]=false
  255. if [[ "$setting_value" != "${old[$setting]}" ]]
  256. then
  257. changed[$setting]=true
  258. fi
  259. fi
  260. done
  261. # Build specific OVPN template
  262. cp -f /etc/openvpn/client.conf.tpl.restore $tmp_dir/client.conf.tpl
  263. # Remove some lines
  264. for rm_regex in "$(jq --raw-output '.openvpn_rm[]' '$cube_file')"
  265. do
  266. sed -i "/$rm_regex/di" $tmp_dir/client.conf.tpl
  267. done
  268. # Add some other lines
  269. echo "# Custom" >> $tmp_dir/client.conf.tpl
  270. jq --raw-output ".openvpn_add[]" "$cube_file" >> $tmp_dir/client.conf.tpl
  271. fi
  272. _ynh_panel_validate
  273. }
  274. #=================================================
  275. # OVERWRITING APPLY STEP
  276. #=================================================
  277. ynh_panel_apply() {
  278. # Stop vpn client
  279. touch /tmp/.ynh-vpnclient-stopped
  280. systemctl stop ynh-vpnclient
  281. _ynh_panel_apply
  282. # Start vpn client
  283. systemctl start ynh-vpnclient
  284. rm -f /tmp/.ynh-vpnclient-stopped
  285. }
  286. #=================================================
  287. # GENERIC FINALIZATION
  288. #=================================================
  289. # Please don't change that code.
  290. # You can overwrite these functions if you need it
  291. #=================================================
  292. ynh_panel_init
  293. case $1 in
  294. show) ynh_panel_show;;
  295. apply) ynh_panel_validate && ynh_panel_apply;;
  296. esac