diff options
author | Flamus Diu | 2015-07-01 12:12:08 -0400 |
---|---|---|
committer | Flamus Diu | 2015-07-01 12:12:08 -0400 |
commit | 0b372a65f2d54d330d6147271e944e1813ae69e8 (patch) | |
tree | 1e86c0cd0f64f07dae11ca9b9efa4952ac1a868d | |
parent | 3735cd6cb7cbc29e520c527c80521cb19190de97 (diff) | |
download | aur-0b372a65f2d54d330d6147271e944e1813ae69e8.tar.gz |
Renamed pia-auto-login.py to pia. Reworked script and updated man page. Added Connman support
-rw-r--r-- | .SRCINFO | 15 | ||||
-rw-r--r-- | PKGBUILD | 20 | ||||
-rwxr-xr-x | pia | 284 | ||||
-rwxr-xr-x | pia-auto-login.py | 223 | ||||
-rw-r--r-- | pia-auto-login.py.8.gz | bin | 698 -> 0 bytes | |||
-rw-r--r-- | pia.8.gz | bin | 0 -> 985 bytes |
6 files changed, 302 insertions, 240 deletions
@@ -1,24 +1,25 @@ pkgbase = private-internet-access-vpn pkgdesc = Installs VPN profiles for Private Internet Access Service - pkgver = 1.4 + pkgver = 1.5 pkgrel = 1 url = https://www.privateinternetaccess.com/ arch = any license = GPL depends = python optdepends = networkmanager: Enables PIA for Network Manager + optdepends = connman: Enables PIA for Connman optdepends = openvpn: Allows running configurations from command-line noextract = openvpn.zip source = https://www.privateinternetaccess.com/openvpn/openvpn.zip source = https://raw.githubusercontent.com/masterkorp/openvpn-update-resolv-conf/master/update-resolv-conf.sh source = source.tar.gz - source = pia-auto-login.py - source = pia-auto-login.py.8.gz - sha256sums = 88aff6f0fdd2c87523eb1044787287883a0692e94574644260065823ea5a5dfc + source = pia + source = pia.8.gz + sha256sums = c2f9af251ae63395896366e0be03ff4eea7748dcc6333fbe777a8f09317bba92 sha256sums = 6d3bdc9531f16cc1ad199913a71554a0b50aea87e140b28d079c4ab4c0b8c51b - sha256sums = c09bf706dd14b6c89441e204c05656562066029e97a44f9176a9ed29408c40c0 - sha256sums = f7062497a64d27aed797c088c7250028d0754963ccd3e8c8c1aff6898092045a - sha256sums = 445eaad874754485741fa717842a479c57d9725e81f023f8f6f970349cd2a3b5 + sha256sums = 0ee7b31d6a36379adbe402b3db565ce95111443d6d2fd0e6a3ccd4d8a39681c7 + sha256sums = 9dc895351f55f744329a12a43a300b76dd9cabfa45f9fd0450a4329a09c6930d + sha256sums = 55c0935a10a4d036a20fdbe7c690fd1e454802418d4a3d88c4454b99a3260693 pkgname = private-internet-access-vpn @@ -1,7 +1,7 @@ # Maintainer: Jesse Spangenberger <azulephoenix@gmail.com> pkgname=private-internet-access-vpn -pkgver=1.4 -pkgrel=2 +pkgver=1.5 +pkgrel=1 pkgdesc="Installs VPN profiles for Private Internet Access Service" arch=('any') url="https://www.privateinternetaccess.com/" @@ -10,17 +10,17 @@ depends=('python') optdepends=('networkmanager: Enables PIA for Network Manager' 'connman: Enables PIA for Connman' 'openvpn: Allows running configurations from command-line') -sha256sums=('88aff6f0fdd2c87523eb1044787287883a0692e94574644260065823ea5a5dfc' +sha256sums=('c2f9af251ae63395896366e0be03ff4eea7748dcc6333fbe777a8f09317bba92' '6d3bdc9531f16cc1ad199913a71554a0b50aea87e140b28d079c4ab4c0b8c51b' - 'c09bf706dd14b6c89441e204c05656562066029e97a44f9176a9ed29408c40c0' - 'f7062497a64d27aed797c088c7250028d0754963ccd3e8c8c1aff6898092045a' - '445eaad874754485741fa717842a479c57d9725e81f023f8f6f970349cd2a3b5') + '0ee7b31d6a36379adbe402b3db565ce95111443d6d2fd0e6a3ccd4d8a39681c7' + '9dc895351f55f744329a12a43a300b76dd9cabfa45f9fd0450a4329a09c6930d' + '55c0935a10a4d036a20fdbe7c690fd1e454802418d4a3d88c4454b99a3260693') source=("https://www.privateinternetaccess.com/openvpn/openvpn.zip" "https://raw.githubusercontent.com/masterkorp/openvpn-update-resolv-conf/master/update-resolv-conf.sh" "source.tar.gz" - "pia-auto-login.py" - "pia-auto-login.py.8.gz") + "pia" + "pia.8.gz") noextract=("openvpn.zip") @@ -71,6 +71,6 @@ package() { install -Dm 600 vpn-configs/*.* "${pkgdir}/etc/openvpn/" install -m 755 update-resolv-conf.sh "${pkgdir}/etc/openvpn" - install -m 755 pia-auto-login.py "${pkgdir}/usr/bin" - install -m 644 pia-auto-login.py.8.gz "${pkgdir}/usr/share/man/man8" + install -m 755 pia "${pkgdir}/usr/bin" + install -m 644 pia.8.gz "${pkgdir}/usr/share/man/man8" } @@ -0,0 +1,284 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +__VERSION__ = (1,5) + +import os, stat +import argparse, glob +import pathlib, re, uuid + +# Class holds all static variables +class Props(object): + _openvpn_conf_dir = '/etc/openvpn' + _login_config = '/etc/private-internet-access/login.conf' + _system_connection_conf = '/etc/private-internet-access/system-connection-example' + _connman_connection_conf = '/etc/private-internet-access/connman-config-example.config' + _nm_conf_dir = '/etc/NetworkManager/system-connections' + _cm_conf_dir = '/var/lib/connman-vpn' + _progs = {'cm':False,'nm':False, 'openvpn':False} + _openvpn_configs = {} + + @property + def openvpn_conf_dir(self): + return self._openvpn_conf_dir + + @property + def login_config(self): + return self._login_config + + @property + def system_connection_conf(self): + return self._system_connection_conf + + @property + def nm_conf_dir (self): + return self._nm_conf_dir + + @property + def cm_conf_dir (self): + return self._cm_conf_dir + + @property + def connman_connection_conf (self): + return self._connman_connection_conf + + @property + def progs (self): + return self._progs + + @progs.setter + def progs (self, prog, installed): + self._progs[prog] = installed + + @property + def openvpn_configs(self): + return self._openvpn_configs + + @openvpn_configs.setter + def openvpn_configs(self, configs): + self._openvpn_configs = configs + + def __init__(self): + self.get_openvpn_configs() + + def get_openvpn_configs(self): + openvpn_configs = {} + for filename in glob.glob(self.openvpn_conf_dir + '/*.conf') : + id = re.sub('_',' ', re.match(r"^/(.*/)*(.+)\.conf$", filename).group(2)) + openvpn_configs[id] = [re.sub(' ', '_', id), filename] + + self.openvpn_configs = openvpn_configs + + def remove_configurations(self): + for config in self.openvpn_configs: + id,filename = self.openvpn_configs[config] + + if (self.progs['nm']): + try: + os.remove(self.nm_conf_dir + "/" + id) + except IOError: + print('Cannot remove configuration for ' + id) + pass + + if (self.progs['cm']): + try: + os.remove(self.cm_conf_dir + "/" + id + ".config") + except IOError: + print('Cannot delete configuration for ' + id + '. Skipping...') + pass + +props = Props() + +# Checks if script has root permissions only. +def has_proper_permissions(filepath): + st = os.stat(filepath) + + return bool(st.st_uid == 0 & st.st_gid == 0 & int(oct(stat.S_IMODE(os.stat(filepath).st_mode)) == "0o600")) + +# Modifies OpenVPN configurations in /etc/openvpn +def openvpn_autologin (id, filename, enable=True): + try: + p = pathlib.Path(filename) + with p.open() as f: + content = f.read() + + if (enable): + content = re.sub("(auth-user-pass)(?:.*)","auth-user-pass " + props.login_config, content) + else: + content = re.sub("(auth-user-pass)(?:.*)","auth-user-pass", content) + + with open(filename, "w") as f: + f.write(content) + except IOError: + print ('Cannot access ' + filename + '.') + exit (1) + +def check_installed(): + global props + + if os.path.isfile('/usr/bin/nmcli'): + if os.path.isfile('/usr/lib/networkmanager/nm-openvpn-service'): + props.progs['nm'] = True + + if os.path.isfile('/usr/bin/connmanctl'): + props.progs['cm'] = True + + if os.path.isfile('/usr/bin/openvpn'): + props.progs['openvpn'] = True + +# Modifies Network Connection configurations +def nm_autologin(id, filename): + # Creates dictionary to hold replacement values + re_dict = {} + + try: + #Opens login.conf and reads login and passwords from file + p = pathlib.Path(props.login_config) + with p.open() as f: + content = f.read().splitlines() + + except IOError: + print ('Cannot access ' + props.login_config + '. Please make sure the file is created and readable by root.') + + else: + re_dict["##username##"] = content[0] + re_dict["##password##"] = content[1] + + re_dict["##id##"] = id + + # Creates uuid for configuration file + re_dict["##uuid##"] = str(uuid.uuid4()) + + # Retrieves remote address from OpenVPN configuration + re_dict["##remote##"] = get_remote_address(filename) + + try: + p = pathlib.Path(props.system_connection_conf) + with p.open() as f: + content = f.read() + + except IOError: + print('Network Manager template missing from ' + props.system_connection_conf) + + else: + nm_conf = props.nm_conf_dir + "/" + id + + try: + #Opens Network Configurations and replaces options from the "re_dict" dictionary + with open(nm_conf,"w") as f: + f.write(multiple_replace(re_dict,content)) + + os.chmod(nm_conf,0o600) + os.chown(nm_conf,0,0) + except IOError: + #No Network Manager installed? + pass + +def cm_autologin(id, filename): + # Creates dictionary to hold replacement values + re_dict = {} + + re_dict["##id##"] = id + re_dict["##filename##"] = filename + # Retrieves remote address from OpenVPN configuration + re_dict["##remote##"] = get_remote_address(filename) + + try: + p = pathlib.Path(props.connman_connection_conf) + with p.open() as f: + content = f.read() + + except IOError: + print('Connman template missing from ' + props.connman_connection_conf) + + else: + cm_conf = props.cm_conf_dir + "/" + re.sub(' ','_',id) + ".config" + + try: + #Opens Connman Configurations and replaces options from the "re_dict" dictionary + with open(cm_conf,"w") as f: + f.write(multiple_replace(re_dict,content)) + + os.chmod(cm_conf,0o600) + os.chown(cm_conf,0,0) + except IOError: + print('Cannot modify configuration for ' + id + '. Skipping...') + pass + +# Gets remote address from OpenVPn files +def get_remote_address(filename): + p = pathlib.Path(filename) + + with p.open() as f: + contents = f.read() + + return ''.join(re.findall("(?:remote.)(.*)(?:.\d{4})",contents)) + +def multiple_replace(dict, text): + # Create a regular expression from the dictionary keys + regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys()))) + + # For each match, look-up corresponding value in dictionary + return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text) + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description='Configures PIA VPN Services for Connman, Network Manager, and OpenVPN') + + group = parser.add_mutually_exclusive_group(required=False) + group.add_argument('-a','--auto-configure', dest='configure', action='store_true',help='Automatically generates configurations') + group.add_argument('-r','--remove-configurations', dest='configure', action='store_false',help='Removes auto-generated configurations') + + parser.add_argument('-e','--exclude', dest='exclude', choices=props.progs, action='append', + help='Excludes modifying the configurations of the listed program. Maybe used more then once.') + + parser.add_argument('host',nargs='*', help='Lists of host names to configure') + + parser.add_argument('-v','--verbose', dest='verbose', action='store_true',help='Enables more verbose logging') + parser.add_argument('--version', action='version', version='%(prog)s 1.5') + parser.parse_args(namespace=props) + + if os.getuid() > 0: + print ('ERROR: You must run this script with administrative privilages!') + exit(1) + + + if not has_proper_permissions(props.login_config): + print ('ERROR: ' + props.login_config + ' must be owned by root and not world readable!') + exit(1) + + check_installed() + + if props.exclude: + for prog in props.exclude: + props.progs[prog] = False + + custom_configs = {} + + if props.host: + for id in props.host: + custom_configs[id] = props.openvpn_configs[id] + + if custom_configs: + props.openvpn_configs = custom_configs + + if props.configure: + for config in props.openvpn_configs: + id, filename = props.openvpn_configs[config] + + if (props.verbose): + if (props.auto_login): + print ("Enabling auto-logins for " + config + " remote server...") + else: + print ("Disablig auto-logins for " + config + " remote server...") + + if (props.configure): + if (props.progs['openvpn']): + openvpn_autologin(id, filename) + + if (props.progs['nm']): + nm_autologin(id, filename) + + if (props.progs['cm']): + cm_autologin(id, filename) + else: + props.remove_configurations() diff --git a/pia-auto-login.py b/pia-auto-login.py deleted file mode 100755 index 18b4ca7f2016..000000000000 --- a/pia-auto-login.py +++ /dev/null @@ -1,223 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import os, stat -import argparse, glob -import pathlib, re, uuid - -# Class holds all static variables -class Props(object): - _openvpn_conf_dir='/etc/openvpn' - _login_config='/etc/private-internet-access/login.conf' - _system_connection_conf='/etc/private-internet-access/system-connection-example' - _connman_connection_conf='/etc/private-internet-access/connman-config-example.config' - _nm_conf_dir='/etc/NetworkManager/system-connections' - _cm_conf_dir='/var/lib/connman-vpn' - - @property - def openvpn_conf_dir(self): - return self._openvpn_conf_dir - - @property - def login_config(self): - return self._login_config - - @property - def system_connection_conf(self): - return self._system_connection_conf - - @property - def nm_conf_dir (self): - return self._nm_conf_dir - - @property - def cm_conf_dir (self): - return self._cm_conf_dir - - @property - def connman_connection_conf (self): - return self._connman_connection_conf - -# Checks if script has root permissions only. -def hasproperpermissions(filepath): - st = os.stat(filepath) - - return bool(st.st_uid == 0 & st.st_gid == 0 & int(oct(stat.S_IMODE(os.stat(filepath).st_mode)) == "0o600")) - -# Modifies OpenVPN configurations in /etc/openvpn -def openvpn_autologin (id, filename, enable): - try: - p = pathlib.Path(filename) - with p.open() as f: - content = f.read() - - if (enable): - content = re.sub("(auth-user-pass)(?:.*)","auth-user-pass " + props.login_config, content) - else: - content = re.sub("(auth-user-pass)(?:.*)","auth-user-pass", content) - - with open(filename, "w") as f: - f.write(content) - except IOError: - print ('Cannot access ' + filename + '.') - exit (1) - -# Modifies Network Connection configurations -def nm_autologin(id, filename, enable): - if (enable): - # Creates dictionary to hold replacement values - re_dict = {} - - try: - #Opens login.conf and reads login and passwords from file - p = pathlib.Path(props.login_config) - with p.open() as f: - content = f.read().splitlines() - - except IOError: - print ('Cannot access ' + props.login_config + '. Please make sure the file is created and readable by root.') - - else: - re_dict["##username##"] = content[0] - re_dict["##password##"] = content[1] - - re_dict["##id##"] = id - - # Creates uuid for configuration file - re_dict["##uuid##"] = str(uuid.uuid4()) - - # Retrieves remote address from OpenVPN configuration - re_dict["##remote##"] = get_remote_address(filename) - - try: - p = pathlib.Path(props.system_connection_conf) - with p.open() as f: - content = f.read() - - except IOError: - print('Network Manager template missing from ' + props.system_connection_conf) - - else: - nm_conf = props.nm_conf_dir + "/" + id - - try: - #Opens Network Configurations and replaces options from the "re_dict" dictionary - with open(nm_conf,"w") as f: - f.write(multiple_replace(re_dict,content)) - - os.chmod(nm_conf,0o600) - os.chown(nm_conf,0,0) - except IOError: - #No Network Manager installed? - pass - else: - nm_conf = props.nm_conf_dir + "/" + id - content = None - - try: - p=pathlib.Path(nm_conf) - with p.open() as f: - content = f.read() - - except IOError: - print (id + " connection does not exist as a Network Manager connection ... skipping") - pass - - else: - # Removes password from configuration file - if (content): - content = re.sub("\[vpn-secrets\]","",content) - content = re.sub("password=.*","",content) - - try: - with open(nm_conf, "w") as f: - f.write(content) - except IOError: - print ("Failed to write config file for " + id) - pass - -def cm_autologin(id, filename, enable): - if (enable): - # Creates dictionary to hold replacement values - re_dict = {} - - re_dict["##id##"] = id - re_dict["##filename##"] = filename - # Retrieves remote address from OpenVPN configuration - re_dict["##remote##"] = get_remote_address(filename) - - try: - p = pathlib.Path(props.connman_connection_conf) - with p.open() as f: - content = f.read() - - except IOError: - print('Connman template missing from ' + props.connman_connection_conf) - - else: - cm_conf = props.cm_conf_dir + "/" + re.sub(' ','_',id) + ".config" - - try: - #Opens Connman Configurations and replaces options from the "re_dict" dictionary - with open(cm_conf,"w") as f: - f.write(multiple_replace(re_dict,content)) - - os.chmod(cm_conf,0o600) - os.chown(cm_conf,0,0) - except IOError: - #No Connman Manager installed? - pass - -# Gets remote address from OpenVPn files -def get_remote_address(filename): - p = pathlib.Path(filename) - - with p.open() as f: - contents = f.read() - - return ''.join(re.findall("(?:remote.)(.*)(?:.\d{4})",contents)) - -def multiple_replace(dict, text): - # Create a regular expression from the dictionary keys - regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys()))) - - # For each match, look-up corresponding value in dictionary - return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text) - -# Creates help menu -def menu(): - parser = argparse.ArgumentParser(description='Configures auto login for OpenVPN and NetworkMananger for PIA VPN Service') - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('-l','--auto-login',dest='auto_login',action='store_true',help='Enables auto-login') - group.add_argument('-n','--no-auto-login',dest='auto_login',action='store_false',help='Disable auto-login') - parser.add_argument('-v','--verbose',dest='verbose', action='store_true',help='Enables more verbose logging') - parser.add_argument('--version',action='version', version='%(prog)s 1.2') - - return parser.parse_args(); - -if __name__ == "__main__": - props = Props() - args = menu() - - - if os.getuid() > 0: - print ('ERROR: You must run this script with administrative privilages!') - exit(1) - - - if not hasproperpermissions(props.login_config): - print ('ERROR: ' + props.login_config + ' must be owned by root and not world readable!') - exit(1) - - for filename in glob.glob(props.openvpn_conf_dir + '/*.conf') : - id = re.sub('_',' ', re.match(r"^/(.*/)*(.+)\.conf$",filename).group(2)) - - if (args.verbose): - if (args.auto_login): - print ("Enabling auto-logins for " + id + " remote server...") - else: - print ("Disablig auto-logins for " + id + " remote server...") - - openvpn_autologin(id, filename, args.auto_login) - nm_autologin(id, filename, args.auto_login) - cm_autologin(id, filename, args.auto_login)
\ No newline at end of file diff --git a/pia-auto-login.py.8.gz b/pia-auto-login.py.8.gz Binary files differdeleted file mode 100644 index 5279c12d1f09..000000000000 --- a/pia-auto-login.py.8.gz +++ /dev/null diff --git a/pia.8.gz b/pia.8.gz Binary files differnew file mode 100644 index 000000000000..d79cce07bdc7 --- /dev/null +++ b/pia.8.gz |