tncc-wrapper.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/python3
  2. # Lifted from Russ Dill's juniper-vpn-wrap.py, thus:
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. import subprocess
  18. import sys
  19. import os
  20. import zipfile
  21. import urllib.request
  22. import ssl
  23. # In order to run this, you will need to build tncc_preload.so (from
  24. # https://github.com/russdill/ncsvc-socks-wrapper) and place it in this
  25. # directory.
  26. #
  27. # Very old versions of the TNCC Java binary expect to find files in
  28. # ~/.juniper_networks instead of ~/.pulse_secure
  29. TNCC_DIRECTORY = "~/.pulse_secure"
  30. ssl._create_default_https_context = ssl._create_unverified_context
  31. class Tncc:
  32. def __init__(self, vpn_host):
  33. self.vpn_host = vpn_host
  34. self.plugin_jar = '/usr/share/icedtea-web/plugin.jar'
  35. if not os.path.isfile(self.plugin_jar):
  36. print('WARNING: no IcedTea Java web plugin JAR found at %s' % self.plugin_jar, file=sys.stderr)
  37. self.plugin_jar = None
  38. self.user_agent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1'
  39. def tncc_init(self):
  40. class_names = ('net.juniper.tnc.NARPlatform.linux.LinuxHttpNAR',
  41. 'net.juniper.tnc.HttpNAR.HttpNAR')
  42. self.class_name = None
  43. self.tncc_jar = os.path.expanduser(os.path.join(TNCC_DIRECTORY, 'tncc.jar'))
  44. try:
  45. if zipfile.ZipFile(self.tncc_jar, 'r').testzip() is not None:
  46. raise Exception()
  47. except Exception:
  48. print('Downloading tncc.jar...')
  49. os.makedirs(os.path.expanduser(TNCC_DIRECTORY), exist_ok=True)
  50. urllib.request.urlretrieve('https://' + self.vpn_host
  51. + '/dana-cached/hc/tncc.jar', self.tncc_jar)
  52. with zipfile.ZipFile(self.tncc_jar, 'r') as jar:
  53. for name in class_names:
  54. try:
  55. jar.getinfo(name.replace('.', '/') + '.class')
  56. self.class_name = name
  57. break
  58. except Exception:
  59. pass
  60. else:
  61. raise Exception('Could not find class name for', self.tncc_jar)
  62. self.tncc_preload = \
  63. os.path.expanduser(os.path.join(TNCC_DIRECTORY, 'tncc_preload.so'))
  64. if not os.path.isfile(self.tncc_preload):
  65. print('WARNING: no tncc_preload found at %s' % self.tncc_preload, file=sys.stderr)
  66. self.tncc_preload = None
  67. def tncc_start(self):
  68. # tncc is the host checker app. It can check different
  69. # security policies of the host and report back. We have
  70. # to send it a preauth key (from the DSPREAUTH cookie)
  71. # and it sends back a new cookie value we submit.
  72. # After logging in, we send back another cookie to tncc.
  73. # Subsequently, it contacts https://<vpn_host:443 every
  74. # 10 minutes.
  75. if not self.tncc_jar:
  76. self.tncc_init()
  77. self.tncc_process = subprocess.Popen(['java',
  78. '-classpath', self.tncc_jar + (':' + self.plugin_jar if self.plugin_jar else ''),
  79. self.class_name,
  80. 'log_level', '100',
  81. 'postRetries', '6',
  82. 'ivehost', self.vpn_host,
  83. 'home_dir', os.path.expanduser('~'),
  84. 'Parameter0', '',
  85. 'user_agent', self.user_agent,
  86. ], env={'LD_PRELOAD': self.tncc_preload} if self.tncc_preload else {})
  87. if __name__ == "__main__":
  88. if len(sys.argv) <= 1:
  89. print("Usage: %s [vpn-host]" % sys.argv[0])
  90. raise SystemExit(1)
  91. tncc = Tncc(sys.argv[1])
  92. tncc.tncc_init()
  93. tncc.tncc_start()