connect.sh 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/usr/bin/env sh
  2. #
  3. # ~~ Protonator: a ProtonVPN connect script ~~
  4. #
  5. # License:
  6. # - This script: MIT (Expat)
  7. # - update-resolv-conf.sh (downloaded automatically): GNU GPL
  8. # Check if a command exists on system
  9. # - $1: command to check if it exists
  10. command_exists() {
  11. if type "$1" >/dev/null 2>&1; then
  12. return 0
  13. else
  14. return 1
  15. fi
  16. }
  17. # Check requirements
  18. if ! command_exists 'openvpn'; then
  19. echo 'Error: OpenVPN is not installed. Please install it and try again.'
  20. exit 1272
  21. else
  22. if [ "$SHELL" = '/bin/bash' ] || [ "$SHELL" = '/usr/local/bin/bash' ]; then
  23. openvpn_version="$(openvpn --version)"
  24. openvpn_version="${openvpn_version#OpenVPN *}"
  25. openvpn_version="${openvpn_version%%.*}"
  26. else
  27. openvpn_version=$( openvpn --version | head -n 1 | \
  28. awk '{ print $2 }' | awk -F'.' '{ print $1 }' )
  29. fi
  30. if [ "$openvpn_version" != '2' ]; then
  31. echo "Error: Currently only OpenVPN v2 is supported" \
  32. "but v${openvpn_version} is installed."
  33. exit 1247
  34. fi
  35. fi
  36. # Program to use for root priviledges
  37. if command_exists 'sudo'; then
  38. subin='sudo'
  39. elif command_exists 'doas'; then
  40. subin='doas'
  41. else
  42. echo 'Error: sudo or doas not found... exiting...'
  43. exit 1235
  44. fi
  45. # Set selection to none
  46. chosen=''
  47. # Going to start file based operations, so cd into script directory so that
  48. # relative paths can be used safely. This would allow script to be run from
  49. # other directories without messing up things.
  50. cd "$(dirname "$0")"
  51. # If config/config.sh exists, source it to take values from it
  52. [ -f 'config/config.sh' ] && . 'config/config.sh'
  53. # Show CLI based menu (without dmenu, fzf or other GUI tools)
  54. shell_menu () {
  55. file_list=$( cd ovpns; ls *.ovpn )
  56. menu=$( echo "$file_list" | cat -n | column -c 100 | sed 's/\t/ /g' )
  57. echo "$menu"
  58. echo -n 'Enter the number beside the ovpn config filename to connect: '
  59. read selection
  60. chosen=$( echo "$file_list" | sed -n "${selection}p" )
  61. }
  62. # If there's no menu chooser installed, fallback to shell selection.
  63. if [ -z "$DISPLAY" ] || \
  64. ( ! command_exists 'fzf' && ! command_exists 'dmenu' && \
  65. ! command_exists 'rofi' ); then
  66. shell_menu
  67. else
  68. chosen=$( cd ovpns; ls *.ovpn | \
  69. (fzf || dmenu || rofi -dmenu -i) 2>/dev/null )
  70. fi
  71. # If nothing is chosen, exit script, otherwise continue
  72. if [ -z "$chosen" ]; then
  73. echo 'Cancelled menu selection... exiting...'
  74. exit 1
  75. fi
  76. echo "Chosen to connect to $chosen ..."
  77. # Create '/etc/openvpn/update-resolv-conf' if it does not exist
  78. # Source: https://protonvpn.com/support/linux-vpn-setup/
  79. update_resolv_conf_file='/etc/openvpn/update-resolv-conf'
  80. if [ ! -f "$update_resolv_conf_file" ]; then
  81. echo "$update_resolv_conf_file not found ..."
  82. echo 'Downloading update-resolv-conf and installing it to /etc/openvpn ...'
  83. [ ! -d '/etc/openvpn' ] && $subin mkdir -p '/etc/openvpn'
  84. update_resolv_conf_url='https://raw.githubusercontent.com/ProtonVPN/scripts/master/update-resolv-conf.sh'
  85. if command_exists 'wget'; then
  86. $subin wget "$update_resolv_conf_url" -O "$update_resolv_conf_file"
  87. elif command_exists 'curl'; then
  88. $subin curl -L "$update_resolv_conf_url" -o "$update_resolv_conf_file"
  89. else
  90. echo 'Error: curl or wget not found... could not download... exiting...'
  91. exit 1224
  92. fi
  93. if [ "$?" = '0' ]; then
  94. $subin chmod +x "$update_resolv_conf_file"
  95. else
  96. echo 'Download was not successful... exiting...'
  97. exit 1227
  98. fi
  99. fi
  100. # Proceed with connect process
  101. if [ -f 'config/cred.aes' ]; then
  102. # If cred.aes is found, we use it. Requires passphrase, but superior to
  103. # other options.
  104. # To encrypt:
  105. # openssl aes-256-cbc -pbkdf2 -iter 25763 -salt -in config/cred.txt -out config/cred.aes -e -a && rm config/cred.txt
  106. DEC=$(openssl aes-256-cbc -pbkdf2 -iter 25763 -in config/cred.aes -d -a)
  107. # Separate line with variable is to address mess up of sudo/doas password
  108. # prompt with openssl one at the same time.
  109. echo "$DEC" | $subin openvpn --config "ovpns/$chosen" \
  110. --auth-user-pass /dev/stdin $openvpn_cli_arguments_append
  111. # Discard the decrypted data because it's not needed anymore.
  112. unset DEC
  113. elif [ -f 'config/cred.enc' ]; then
  114. # If cred.enc is found, we use it.
  115. # To encrypt:
  116. # openssl enc -pbkdf2 -salt -in config/cred.txt -out config/cred.enc -e -a && rm config/cred.txt
  117. openssl enc -pbkdf2 -in config/cred.enc -d -a | $subin openvpn \
  118. --config "ovpns/$chosen" --auth-user-pass /dev/stdin \
  119. $openvpn_cli_arguments_append
  120. elif [ -f 'config/cred.txt' ]; then
  121. # If pass.txt is found, we use it.
  122. $subin openvpn --config "ovpns/$chosen" --auth-user-pass 'config/cred.txt' \
  123. $openvpn_cli_arguments_append
  124. else
  125. # If saved cred.txt is not found, we just connect to the config and user
  126. # will be asked for username and passphrase.
  127. $subin openvpn --config "ovpns/$chosen" $openvpn_cli_arguments_append
  128. fi