oliver@240
|
1 |
# ------------------------------------------------------------
|
oliver@240
|
2 |
# proxy_getter
|
oliver@240
|
3 |
#
|
oliver@240
|
4 |
# Aquire the correct proxy settings of the current machine
|
oliver@240
|
5 |
#
|
oliver@240
|
6 |
# Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
|
oliver@240
|
7 |
#
|
oliver@240
|
8 |
# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology
|
oliver@240
|
9 |
#
|
oliver@240
|
10 |
#
|
oliver@240
|
11 |
# X-Net Services GmbH
|
oliver@240
|
12 |
# Elisabethstrasse 1
|
oliver@240
|
13 |
# 4020 Linz
|
oliver@240
|
14 |
# AUSTRIA
|
oliver@240
|
15 |
# https://www.x-net.at
|
oliver@240
|
16 |
#
|
oliver@240
|
17 |
# AIT Austrian Institute of Technology
|
oliver@240
|
18 |
# Donau City Strasse 1
|
oliver@240
|
19 |
# 1220 Wien
|
oliver@240
|
20 |
# AUSTRIA
|
oliver@240
|
21 |
# http://www.ait.ac.at
|
oliver@240
|
22 |
#
|
oliver@240
|
23 |
#
|
oliver@240
|
24 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
oliver@240
|
25 |
# you may not use this file except in compliance with the License.
|
oliver@240
|
26 |
# You may obtain a copy of the License at
|
oliver@240
|
27 |
#
|
oliver@240
|
28 |
# http://www.apache.org/licenses/LICENSE-2.0
|
oliver@240
|
29 |
#
|
oliver@240
|
30 |
# Unless required by applicable law or agreed to in writing, software
|
oliver@240
|
31 |
# distributed under the License is distributed on an "AS IS" BASIS,
|
oliver@240
|
32 |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
oliver@240
|
33 |
# See the License for the specific language governing permissions and
|
oliver@240
|
34 |
# limitations under the License.
|
oliver@240
|
35 |
# ------------------------------------------------------------
|
oliver@240
|
36 |
|
BarthaM@234
|
37 |
import socket
|
BarthaM@234
|
38 |
import os
|
BarthaM@234
|
39 |
import httplib
|
BarthaM@234
|
40 |
import sys
|
BarthaM@234
|
41 |
import _winreg
|
BarthaM@234
|
42 |
import re
|
BarthaM@234
|
43 |
|
BarthaM@234
|
44 |
DNS_WPAD_FILENAME = "wpad.dat"
|
BarthaM@234
|
45 |
|
BarthaM@234
|
46 |
def check_for_wpad_file(server, path):
|
BarthaM@234
|
47 |
|
BarthaM@234
|
48 |
wpad_url = "http://%s/%s"%(server, path)
|
BarthaM@234
|
49 |
print "checking", wpad_url
|
BarthaM@234
|
50 |
try:
|
BarthaM@234
|
51 |
conn = httplib.HTTPConnection(server)
|
BarthaM@234
|
52 |
conn.request("HEAD", "/%s"%path)
|
BarthaM@234
|
53 |
r = conn.getresponse()
|
BarthaM@234
|
54 |
if r.status == 200:
|
BarthaM@234
|
55 |
return wpad_url
|
BarthaM@234
|
56 |
except Exception, e:
|
BarthaM@234
|
57 |
return None
|
BarthaM@234
|
58 |
|
BarthaM@234
|
59 |
return None
|
BarthaM@234
|
60 |
|
BarthaM@234
|
61 |
def get_wpad_server_searchlist():
|
BarthaM@234
|
62 |
#get fully-qualified hostname
|
BarthaM@234
|
63 |
fqhn = socket.getfqdn().split(" ")[0]
|
BarthaM@234
|
64 |
|
BarthaM@234
|
65 |
#do we really have a fully-qualified name?
|
BarthaM@234
|
66 |
#if not, linux offers a second possibility
|
BarthaM@234
|
67 |
if fqhn.count(".") == 0 and os.name == 'posix':
|
BarthaM@234
|
68 |
#weird method to get own ip address and fqhn
|
BarthaM@234
|
69 |
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
BarthaM@234
|
70 |
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
BarthaM@234
|
71 |
s.connect(('<broadcast>', 0))
|
BarthaM@234
|
72 |
my_ip = s.getsockname()[0]
|
BarthaM@234
|
73 |
s.close()
|
BarthaM@234
|
74 |
fqhn = socket.gethostbyaddr(my_ip)[0]
|
BarthaM@234
|
75 |
|
BarthaM@234
|
76 |
parts = fqhn.split(".")
|
BarthaM@234
|
77 |
if len(parts) < 3:
|
BarthaM@234
|
78 |
return []
|
BarthaM@234
|
79 |
|
BarthaM@234
|
80 |
servers = []
|
BarthaM@234
|
81 |
parts[0] = "wpad"
|
BarthaM@234
|
82 |
servers.append(".".join(parts))
|
BarthaM@234
|
83 |
parts = parts[0:1]+parts[2:]
|
BarthaM@234
|
84 |
#not correct for some suffixes, but everyone does it that way, see wikipedia for details
|
BarthaM@234
|
85 |
while len(parts) >= 3:
|
BarthaM@234
|
86 |
servers.append(".".join(parts))
|
BarthaM@234
|
87 |
parts = parts[0:1]+parts[2:]
|
BarthaM@234
|
88 |
|
BarthaM@234
|
89 |
return servers
|
BarthaM@234
|
90 |
|
BarthaM@234
|
91 |
def search_for_wpad_url():
|
BarthaM@234
|
92 |
#TODO: According to RFC we should check DHCP first, but it isn't used often
|
BarthaM@234
|
93 |
#check most common case first
|
BarthaM@234
|
94 |
wpad_server = "wpad"
|
BarthaM@234
|
95 |
wpad_url = check_for_wpad_file(wpad_server, DNS_WPAD_FILENAME)
|
BarthaM@234
|
96 |
if wpad_url:
|
BarthaM@234
|
97 |
return wpad_url
|
BarthaM@234
|
98 |
|
BarthaM@234
|
99 |
#wpad DNS search procedure
|
BarthaM@234
|
100 |
possible_wpad_servers = get_wpad_server_searchlist()
|
BarthaM@234
|
101 |
for server in possible_wpad_servers:
|
BarthaM@234
|
102 |
wpad_url = check_for_wpad_file(server, DNS_WPAD_FILENAME)
|
BarthaM@234
|
103 |
if wpad_url:
|
BarthaM@234
|
104 |
return wpad_url
|
BarthaM@234
|
105 |
|
BarthaM@234
|
106 |
#no wpad url found
|
BarthaM@234
|
107 |
return None
|
BarthaM@234
|
108 |
|
BarthaM@234
|
109 |
def getProxySettings():
|
BarthaM@234
|
110 |
# try to autodetect domain wpad file
|
BarthaM@234
|
111 |
wpad_url = search_for_wpad_url()
|
BarthaM@234
|
112 |
if wpad_url:
|
BarthaM@234
|
113 |
return {'ProxyAutoConfigURL': wpad_url}
|
BarthaM@234
|
114 |
|
BarthaM@234
|
115 |
# get Proxy settings from registry
|
BarthaM@234
|
116 |
aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_CURRENT_USER)
|
BarthaM@234
|
117 |
aKey = _winreg.OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings")
|
BarthaM@234
|
118 |
_, valueCount, _ = _winreg.QueryInfoKey(aKey)
|
BarthaM@234
|
119 |
reg_entries = dict()
|
BarthaM@234
|
120 |
for i in range(valueCount):
|
BarthaM@234
|
121 |
try:
|
BarthaM@234
|
122 |
n,v,_ = _winreg.EnumValue(aKey,i)
|
BarthaM@234
|
123 |
reg_entries[n] = v
|
BarthaM@234
|
124 |
except EnvironmentError:
|
BarthaM@234
|
125 |
break
|
BarthaM@234
|
126 |
_winreg.CloseKey(aKey)
|
BarthaM@234
|
127 |
|
BarthaM@234
|
128 |
# return configured WPAD url
|
BarthaM@234
|
129 |
if 'AutoConfigURL' in reg_entries.keys():
|
BarthaM@234
|
130 |
return {'ProxyAutoConfigURL': reg_entries['AutoConfigURL']}
|
BarthaM@234
|
131 |
|
BarthaM@234
|
132 |
# return manually configured proxy
|
BarthaM@234
|
133 |
if 'ProxyEnable' in reg_entries.keys() and reg_entries['ProxyEnable'] == 1:
|
BarthaM@234
|
134 |
proxy_search = re.search(r"(?<=http=)(?P<ProxyServer>.*?)(?=;)", reg_entries['ProxyServer'])
|
BarthaM@234
|
135 |
if proxy_search:
|
BarthaM@234
|
136 |
proxies = proxy_search.groupdict()
|
BarthaM@234
|
137 |
if 'ProxyServer' in proxies.keys(): # found http proxy
|
BarthaM@234
|
138 |
return {'ProxyServer': proxies['ProxyServer']}
|
BarthaM@234
|
139 |
return {'ProxyServer': reg_entries['ProxyServer']}
|
BarthaM@234
|
140 |
|
oliver@240
|
141 |
return None
|