1 | #!/bin/bash -e |
---|
2 | |
---|
3 | trap "" TSTP |
---|
4 | trap "" HUP |
---|
5 | trap "" INT |
---|
6 | |
---|
7 | export PATH="/bin:/sbin:/usr/sbin:/usr/bin" |
---|
8 | |
---|
9 | readonly OSX_VERSION="$(sw_vers | grep 'ProductVersion:' | grep -o '10\.[0-9]*')" |
---|
10 | readonly DEFAULT_DOMAIN_NAME="openvpn" |
---|
11 | |
---|
12 | SCRIPT_LOG_FILE="/opt/local/var/log/openvpn2/client.log" |
---|
13 | WATCHER_PLIST="/Library/LaunchDaemons/net.openvpn.watcher.plist" |
---|
14 | |
---|
15 | # TODO Run some tests to make these dynamic |
---|
16 | MONITOR_NETWORK="true" |
---|
17 | RESTORE_ON_RESET="true" |
---|
18 | IS_TAP="false" |
---|
19 | bRouteGatewayIsDhcp="false" |
---|
20 | |
---|
21 | # @param String message - The message to log |
---|
22 | readonly LOG_MESSAGE_COMMAND=$(basename "${0}") |
---|
23 | logMessage() |
---|
24 | { |
---|
25 | echo "$(date '+%a %b %e %T %Y') *OpenVPN $LOG_MESSAGE_COMMAND: "${@} >> "${SCRIPT_LOG_FILE}" |
---|
26 | } |
---|
27 | |
---|
28 | # @param String string - Content to trim |
---|
29 | trim() |
---|
30 | { |
---|
31 | echo ${@} |
---|
32 | } |
---|
33 | |
---|
34 | # @param String[] dnsServers - The name servers to use |
---|
35 | # @param String domainName - The domain name to use |
---|
36 | # @param \optional String[] winsServers - The WINS servers to use |
---|
37 | setDnsServersAndDomainName() |
---|
38 | { |
---|
39 | OPENVPN_SERVER_ADDRESSES=("${!1}") |
---|
40 | OPENVPN_SEARCH_DOMAIN=$2 |
---|
41 | OPENVPN_WINS=("${!3}") |
---|
42 | |
---|
43 | set +e # "grep" will return error status (1) if no matches are found, so don't fail on individual errors |
---|
44 | |
---|
45 | PRIMARY_SERVICE_ID=$( (scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<<- EOF |
---|
46 | open |
---|
47 | show State:/Network/Global/IPv4 |
---|
48 | quit |
---|
49 | EOF ) |
---|
50 | |
---|
51 | PRIMARY_SERVICE_STATIC_DNS="$( (scutil | sed -e 's/^[[:space:]]*[[:digit:]]* : //g' | tr '\n' ' ')<<- EOF |
---|
52 | open |
---|
53 | show Setup:/Network/Service/${PRIMARY_SERVICE_ID}/DNS |
---|
54 | quit |
---|
55 | EOF )" |
---|
56 | if echo "${PRIMARY_SERVICE_STATIC_DNS}" | grep -q "ServerAddresses" ; then |
---|
57 | readonly PRIMARY_SERVICE_STATIC_SERVER_ADDRESSES="$(trim "$( echo "${PRIMARY_SERVICE_STATIC_DNS}" | sed -e 's/^.*ServerAddresses[^{]*{[[:space:]]*\([^}]*\)[[:space:]]*}.*$/\1/g' )")" |
---|
58 | fi |
---|
59 | if echo "${PRIMARY_SERVICE_STATIC_DNS}" | grep -q "SearchDomains" ; then |
---|
60 | readonly PRIMARY_SERVICE_STATIC_SEARCH_DOMAINS="$(trim "$( echo "${PRIMARY_SERVICE_STATIC_DNS}" | sed -e 's/^.*SearchDomains[^{]*{[[:space:]]*\([^}]*\)[[:space:]]*}.*$/\1/g' )")" |
---|
61 | fi |
---|
62 | |
---|
63 | PRIMARY_SERVICE_STATIC_SMB="$( (scutil | sed -e 's/^[[:space:]]*[[:digit:]]* : //g' | tr '\n' ' ')<<- EOF |
---|
64 | open |
---|
65 | show Setup:/Network/Service/${PRIMARY_SERVICE_ID}/SMB |
---|
66 | quit |
---|
67 | EOF )" |
---|
68 | if echo "${PRIMARY_SERVICE_STATIC_SMB}" | grep -q "WINSAddresses" ; then |
---|
69 | readonly PRIMARY_SERVICE_STATIC_WINS_ADDRESSES="$(trim "$( echo "${PRIMARY_SERVICE_STATIC_SMB}" | sed -e 's/^.*WINSAddresses[^{]*{[[:space:]]*\([^}]*\)[[:space:]]*}.*$/\1/g' )")" |
---|
70 | fi |
---|
71 | if [ -n "${PRIMARY_SERVICE_STATIC_SMB}" ] ; then |
---|
72 | readonly PRIMARY_SERVICE_STATIC_WORKGROUP="$(trim "$( echo "${PRIMARY_SERVICE_STATIC_SMB}" | sed -e 's/^.*Workgroup : \([^[:space:]]*\).*$/\1/g' )")" |
---|
73 | fi |
---|
74 | if echo "${PRIMARY_SERVICE_STATIC_SMB}" | grep -q "NetBIOSName" ; then |
---|
75 | readonly PRIMARY_SERVICE_STATIC_NETBIOS_NAME="$(trim "$( echo "${PRIMARY_SERVICE_STATIC_SMB}" | sed -e 's/^.*NetBIOSName : \([^[:space:]]*\).*$/\1/g' )")" |
---|
76 | fi |
---|
77 | |
---|
78 | if [ ${#OPENVPN_SERVER_ADDRESSES[*]} -eq 0 ] ; then |
---|
79 | DYNAMIC_SERVER_ADDRESSES="false" |
---|
80 | ALL_SERVER_ADDRESSES="${PRIMARY_SERVICE_STATIC_SERVER_ADDRESSES}" |
---|
81 | elif [ -n "${PRIMARY_SERVICE_STATIC_SERVER_ADDRESSES}" ] ; then |
---|
82 | case "${OSX_VERSION}" in |
---|
83 | 10.6 | 10.7 ) |
---|
84 | # Do nothing - in 10.6 we don't aggregate our configurations, apparently |
---|
85 | DYNAMIC_SERVER_ADDRESSES="false" |
---|
86 | ALL_SERVER_ADDRESSES="${PRIMARY_SERVICE_STATIC_SERVER_ADDRESSES}" |
---|
87 | ;; |
---|
88 | 10.4 | 10.5 ) |
---|
89 | DYNAMIC_SERVER_ADDRESSES="true" |
---|
90 | # We need to remove duplicate DNS entries, so that our reference list matches MacOSX's |
---|
91 | SDNS="$(echo "${PRIMARY_SERVICE_STATIC_SERVER_ADDRESSES}" | tr ' ' '\n')" |
---|
92 | (( i=0 )) |
---|
93 | for n in "${OPENVPN_SERVER_ADDRESSES[@]}" ; do |
---|
94 | if echo "${SDNS}" | grep -q "${n}" ; then |
---|
95 | unset OPENVPN_SERVER_ADDRESSES[${i}] |
---|
96 | fi |
---|
97 | (( i++ )) |
---|
98 | done |
---|
99 | if [ ${#OPENVPN_SERVER_ADDRESSES[*]} -gt 0 ] ; then |
---|
100 | ALL_SERVER_ADDRESSES="$(trim "${PRIMARY_SERVICE_STATIC_SERVER_ADDRESSES}" "${OPENVPN_SERVER_ADDRESSES[*]}")" |
---|
101 | else |
---|
102 | DYNAMIC_SERVER_ADDRESSES="false" |
---|
103 | ALL_SERVER_ADDRESSES="${PRIMARY_SERVICE_STATIC_SERVER_ADDRESSES}" |
---|
104 | fi |
---|
105 | ;; |
---|
106 | esac |
---|
107 | else |
---|
108 | DYNAMIC_SERVER_ADDRESSES="true" |
---|
109 | ALL_SERVER_ADDRESSES="$(trim "${OPENVPN_SERVER_ADDRESSES[*]}")" |
---|
110 | fi |
---|
111 | readonly DYNAMIC_SERVER_ADDRESSES ALL_SERVER_ADDRESSES |
---|
112 | |
---|
113 | if [ ${#OPENVPN_WINS[*]} -eq 0 ] ; then |
---|
114 | DYNAMIC_WINS_ADDRESSES="false" |
---|
115 | ALL_WINS_ADDRESSES="${PRIMARY_SERVICE_STATIC_WINS_ADDRESSES}" |
---|
116 | elif [ -n "${PRIMARY_SERVICE_STATIC_WINS_ADDRESSES}" ] ; then |
---|
117 | case "${OSX_VERSION}" in |
---|
118 | 10.6 | 10.7 ) |
---|
119 | # Do nothing - in 10.6 we don't aggregate our configurations, apparently |
---|
120 | DYNAMIC_WINS_ADDRESSES="false" |
---|
121 | ALL_WINS_ADDRESSES="${PRIMARY_SERVICE_STATIC_WINS_ADDRESSES}" |
---|
122 | ;; |
---|
123 | 10.4 | 10.5 ) |
---|
124 | DYNAMIC_WINS_ADDRESSES="true" |
---|
125 | # We need to remove duplicate WINS entries, so that our reference list matches MacOSX's |
---|
126 | SWINS="$(echo "${PRIMARY_SERVICE_STATIC_WINS_ADDRESSES}" | tr ' ' '\n')" |
---|
127 | (( i=0 )) |
---|
128 | for n in "${OPENVPN_WINS[@]}" ; do |
---|
129 | if echo "${SWINS}" | grep -q "${n}" ; then |
---|
130 | unset OPENVPN_WINS[${i}] |
---|
131 | fi |
---|
132 | (( i++ )) |
---|
133 | done |
---|
134 | if [ ${#OPENVPN_WINS[*]} -gt 0 ] ; then |
---|
135 | ALL_WINS_ADDRESSES="$(trim "${PRIMARY_SERVICE_STATIC_WINS_ADDRESSES}" "${OPENVPN_WINS[*]}")" |
---|
136 | else |
---|
137 | DYNAMIC_WINS_ADDRESSES="false" |
---|
138 | ALL_WINS_ADDRESSES="${PRIMARY_SERVICE_STATIC_WINS_ADDRESSES}" |
---|
139 | fi |
---|
140 | ;; |
---|
141 | esac |
---|
142 | else |
---|
143 | DYNAMIC_WINS_ADDRESSES="true" |
---|
144 | ALL_WINS_ADDRESSES="$(trim "${OPENVPN_WINS[*]}")" |
---|
145 | fi |
---|
146 | readonly DYNAMIC_WINS_ADDRESSES ALL_WINS_ADDRESSES |
---|
147 | |
---|
148 | # We double-check that our search domain isn't already on the list |
---|
149 | SEARCH_DOMAIN=${OPENVPN_SEARCH_DOMAIN} |
---|
150 | case "${OSX_VERSION}" in |
---|
151 | 10.6 | 10.7 ) |
---|
152 | # Do nothing - in 10.6 we don't aggregate our configurations, apparently |
---|
153 | if [ -n "${PRIMARY_SERVICE_STATIC_SEARCH_DOMAINS}" ] ; then |
---|
154 | ALL_SEARCH_DOMAINS="${PRIMARY_SERVICE_STATIC_SEARCH_DOMAINS}" |
---|
155 | SEARCH_DOMAIN="" |
---|
156 | else |
---|
157 | ALL_SEARCH_DOMAINS="${SEARCH_DOMAIN}" |
---|
158 | fi |
---|
159 | ;; |
---|
160 | 10.4 | 10.5 ) |
---|
161 | if echo "${PRIMARY_SERVICE_STATIC_SEARCH_DOMAINS}" | tr ' ' '\n' | grep -q "${OPENVPN_SEARCH_DOMAIN}" ; then |
---|
162 | SEARCH_DOMAIN="" |
---|
163 | fi |
---|
164 | if [ -z "${SEARCH_DOMAIN}" ] ; then |
---|
165 | ALL_SEARCH_DOMAINS="${PRIMARY_SERVICE_STATIC_SEARCH_DOMAINS}" |
---|
166 | else |
---|
167 | ALL_SEARCH_DOMAINS="$(trim "${PRIMARY_SERVICE_STATIC_SEARCH_DOMAINS}" "${SEARCH_DOMAIN}")" |
---|
168 | fi |
---|
169 | ;; |
---|
170 | esac |
---|
171 | readonly SEARCH_DOMAIN ALL_SEARCH_DOMAINS |
---|
172 | |
---|
173 | # DEBUG |
---|
174 | #logMessage "DYNAMIC_SERVER_ADDRESSES: ${DYNAMIC_SERVER_ADDRESSES}" |
---|
175 | #logMessage "DYNAMIC_WINS_ADDRESSES: ${DYNAMIC_WINS_ADDRESSES}" |
---|
176 | #logMessage "OPENVPN_SEARCH_DOMAIN: ${OPENVPN_SEARCH_DOMAIN}" |
---|
177 | #logMessage "SEARCH_DOMAIN: ${SEARCH_DOMAIN}" |
---|
178 | #logMessage "PRIMARY_SERVICE_STATIC_WORKGROUP: ${PRIMARY_SERVICE_STATIC_WORKGROUP}" |
---|
179 | #logMessage "PRIMARY_SERVICE_STATIC_NETBIOS_NAME: ${PRIMARY_SERVICE_STATIC_NETBIOS_NAME}" |
---|
180 | #logMessage "ALL_SERVER_ADDRESSES: ${ALL_SERVER_ADDRESSES}" |
---|
181 | #logMessage "ALL_SEARCH_DOMAINS: ${ALL_SEARCH_DOMAINS}" |
---|
182 | #logMessage "ALL_WINS_ADDRESSES: ${ALL_WINS_ADDRESSES}" |
---|
183 | |
---|
184 | if ! ${DYNAMIC_SERVER_ADDRESSES} ; then |
---|
185 | NO_SERVER_ADDRESSES="#" |
---|
186 | fi |
---|
187 | if ! ${DYNAMIC_WINS_ADDRESSES} ; then |
---|
188 | NO_WINS_ADDRESSES="#" |
---|
189 | fi |
---|
190 | if [ -z "${SEARCH_DOMAIN}" ] ; then |
---|
191 | NO_SEARCH_DOMAIN="#" |
---|
192 | fi |
---|
193 | if [ -z "${PRIMARY_SERVICE_STATIC_WORKGROUP}" ] ; then |
---|
194 | NO_WORKGROUP="#" |
---|
195 | fi |
---|
196 | if [ -z "${PRIMARY_SERVICE_STATIC_NETBIOS_NAME}" ] ; then |
---|
197 | NO_NETBIOS_NAME="#" |
---|
198 | fi |
---|
199 | if [ -z "${ALL_SERVER_ADDRESSES}" ] ; then |
---|
200 | NO_AGGREGATE_SERVER_ADDRESSES="#" |
---|
201 | fi |
---|
202 | if [ -z "${ALL_SEARCH_DOMAINS}" ] ; then |
---|
203 | NO_AGGREGATE_SEARCH_DOMAINS="#" |
---|
204 | fi |
---|
205 | if [ -z "${ALL_WINS_ADDRESSES}" ] ; then |
---|
206 | NO_AGGREGATE_WINS_ADDRESSES="#" |
---|
207 | fi |
---|
208 | |
---|
209 | # Now, do the aggregation: |
---|
210 | # - Save the openvpn process ID and the Network Primary Service ID, and logfile path |
---|
211 | # - Then save old and new DNS and WINS settings |
---|
212 | # - PPID is a bash-script variable that contains the process ID of the parent of the process running the script (i.e., OpenVPN's process ID) |
---|
213 | # - config is an environmental variable set to the configuration path by OpenVPN prior to running this up script |
---|
214 | logMessage "Up to two 'No such key' warnings are normal and may be ignored" |
---|
215 | |
---|
216 | # If DNS is manually set, it overrides the DHCP setting, which isn't reflected in 'State:/Network/Service/${PRIMARY_SERVICE_ID}/DNS' |
---|
217 | if echo "${PRIMARY_SERVICE_STATIC_DNS}" | grep -q "ServerAddresses" ; then |
---|
218 | CORRECT_OLD_DNS_KEY="Setup:" |
---|
219 | else |
---|
220 | CORRECT_OLD_DNS_KEY="State:" |
---|
221 | fi |
---|
222 | |
---|
223 | # If WINS is manually set, it overrides the DHCP setting, which isn't reflected in 'State:/Network/Service/${PRIMARY_SERVICE_ID}/DNS' |
---|
224 | if echo "${PRIMARY_SERVICE_STATIC_SMB}" | grep -q "WINSAddresses" ; then |
---|
225 | CORRECT_OLD_WINS_KEY="Setup:" |
---|
226 | else |
---|
227 | CORRECT_OLD_WINS_KEY="State:" |
---|
228 | fi |
---|
229 | |
---|
230 | set -e # We instruct bash that it CAN again fail on errors |
---|
231 | |
---|
232 | scutil <<- EOF |
---|
233 | open |
---|
234 | d.init |
---|
235 | |
---|
236 | d.add PID # ${PPID} |
---|
237 | d.add Service ${PRIMARY_SERVICE_ID} |
---|
238 | d.add WatcherPlist "${WATCHER_PLIST}" |
---|
239 | d.add ScriptLogFile "${SCRIPT_LOG_FILE}" |
---|
240 | d.add MonitorNetwork "${MONITOR_NETWORK}" |
---|
241 | d.add RestoreOnReset "${RESTORE_ON_RESET}" |
---|
242 | d.add IsTapInterface "${IS_TAP}" |
---|
243 | d.add RouteGatewayIsDhcp "${bRouteGatewayIsDhcp}" |
---|
244 | set State:/Network/OpenVPN |
---|
245 | |
---|
246 | # First, back up the device's current DNS and WINS configurations |
---|
247 | # Indicate 'no such key' by a dictionary with a single entry: "NoSuchKey : true" |
---|
248 | d.init |
---|
249 | d.add NoSuchKey true |
---|
250 | get ${CORRECT_OLD_DNS_KEY}/Network/Service/${PRIMARY_SERVICE_ID}/DNS |
---|
251 | set State:/Network/OpenVPN/OldDNS |
---|
252 | |
---|
253 | d.init |
---|
254 | d.add NoSuchKey true |
---|
255 | get ${CORRECT_OLD_WINS_KEY}/Network/Service/${PRIMARY_SERVICE_ID}/SMB |
---|
256 | set State:/Network/OpenVPN/OldSMB |
---|
257 | |
---|
258 | # Second, initialize the new DNS map |
---|
259 | d.init |
---|
260 | ${NO_SERVER_ADDRESSES}d.add ServerAddresses * ${OPENVPN_SERVER_ADDRESSES[*]} |
---|
261 | ${NO_SEARCH_DOMAIN}d.add SearchDomains * ${SEARCH_DOMAIN} |
---|
262 | d.add DomainName ${OPENVPN_SEARCH_DOMAIN} |
---|
263 | set State:/Network/Service/${PRIMARY_SERVICE_ID}/DNS |
---|
264 | |
---|
265 | # Third, initialize the WINS map |
---|
266 | d.init |
---|
267 | ${NO_NETBIOS_NAME}d.add NetBIOSName ${PRIMARY_SERVICE_STATIC_NETBIOS_NAME} |
---|
268 | ${NO_WINS_ADDRESSES}d.add WINSAddresses * ${OPENVPN_WINS[*]} |
---|
269 | ${NO_WORKGROUP}d.add Workgroup ${PRIMARY_SERVICE_STATIC_WORKGROUP} |
---|
270 | set State:/Network/Service/${PRIMARY_SERVICE_ID}/SMB |
---|
271 | |
---|
272 | # Now, initialize the maps that will be compared against the system-generated map |
---|
273 | # which means that we will have to aggregate configurations of statically-configured |
---|
274 | # nameservers, and statically-configured search domains |
---|
275 | d.init |
---|
276 | ${NO_AGGREGATE_SERVER_ADDRESSES}d.add ServerAddresses * ${ALL_SERVER_ADDRESSES} |
---|
277 | ${NO_AGGREGATE_SEARCH_DOMAINS}d.add SearchDomains * ${ALL_SEARCH_DOMAINS} |
---|
278 | d.add DomainName ${OPENVPN_SEARCH_DOMAIN} |
---|
279 | set State:/Network/OpenVPN/DNS |
---|
280 | |
---|
281 | d.init |
---|
282 | ${NO_NETBIOS_NAME}d.add NetBIOSName ${PRIMARY_SERVICE_STATIC_NETBIOS_NAME} |
---|
283 | ${NO_AGGREGATE_WINS_ADDRESSES}d.add WINSAddresses * ${ALL_WINS_ADDRESSES} |
---|
284 | ${NO_WORKGROUP}d.add Workgroup ${PRIMARY_SERVICE_STATIC_WORKGROUP} |
---|
285 | set State:/Network/OpenVPN/SMB |
---|
286 | |
---|
287 | # We're done |
---|
288 | quit |
---|
289 | EOF |
---|
290 | |
---|
291 | logMessage "Saved the DNS and WINS configurations for later use" |
---|
292 | |
---|
293 | if ${MONITOR_NETWORK} ; then |
---|
294 | sleep 2 |
---|
295 | launchctl load "${WATCHER_PLIST}" |
---|
296 | logMessage "Set up to monitor system configuration with leasewatch" |
---|
297 | fi |
---|
298 | } |
---|
299 | |
---|
300 | configureDhcpDns() |
---|
301 | { |
---|
302 | # whilst ipconfig will have created the neccessary Network Service keys, the DNS |
---|
303 | # settings won't actually be used by OS X unless the SupplementalMatchDomains key |
---|
304 | # is added |
---|
305 | # ref. <http://lists.apple.com/archives/Macnetworkprog/2005/Jun/msg00011.html> |
---|
306 | # - is there a way to extract the domains from the SC dictionary and re-insert |
---|
307 | # as SupplementalMatchDomains? i.e. not requiring the ipconfig domain_name call? |
---|
308 | |
---|
309 | # - wait until we get a lease before extracting the DNS domain name and merging into SC |
---|
310 | # - despite it's name, ipconfig waitall doesn't (but maybe one day it will :-) |
---|
311 | ipconfig waitall |
---|
312 | |
---|
313 | unset test_domain_name |
---|
314 | unset test_name_server |
---|
315 | |
---|
316 | set +e # We instruct bash NOT to exit on individual command errors, because if we need to wait longer these commands will fail |
---|
317 | |
---|
318 | # usually takes at least a few seconds to get a DHCP lease |
---|
319 | sleep 3 |
---|
320 | n=0 |
---|
321 | while [ -z "$test_domain_name" -a -z "$test_name_server" -a $n -lt 5 ] |
---|
322 | do |
---|
323 | logMessage "Sleeping for $n seconds to wait for DHCP to finish setup." |
---|
324 | sleep $n |
---|
325 | n=`expr $n + 1` |
---|
326 | |
---|
327 | if [ -z "$test_domain_name" ]; then |
---|
328 | test_domain_name=`ipconfig getoption $dev domain_name 2>/dev/null` |
---|
329 | fi |
---|
330 | |
---|
331 | if [ -z "$test_name_server" ]; then |
---|
332 | test_name_server=`ipconfig getoption $dev domain_name_server 2>/dev/null` |
---|
333 | fi |
---|
334 | done |
---|
335 | |
---|
336 | sGetPacketOutput=`ipconfig getpacket $dev` |
---|
337 | |
---|
338 | set -e # We instruct bash that it CAN again fail on individual errors |
---|
339 | |
---|
340 | #echo "`date` test_domain_name = $test_domain_name, test_name_server = $test_name_server, sGetPacketOutput = $sGetPacketOutput" |
---|
341 | |
---|
342 | unset aNameServers |
---|
343 | unset aWinsServers |
---|
344 | |
---|
345 | nNameServerIndex=1 |
---|
346 | nWinsServerIndex=1 |
---|
347 | |
---|
348 | if [ "$sGetPacketOutput" ]; then |
---|
349 | sGetPacketOutput_FirstLine=`echo "$sGetPacketOutput"|head -n 1` |
---|
350 | #echo $sGetPacketOutput_FirstLine |
---|
351 | |
---|
352 | if [ "$sGetPacketOutput_FirstLine" == "op = BOOTREPLY" ]; then |
---|
353 | set +e # "grep" will return error status (1) if no matches are found, so don't fail on individual errors |
---|
354 | |
---|
355 | for tNameServer in `echo "$sGetPacketOutput"|grep "domain_name_server"|grep -Eo "\{([0-9\.]+)(, [0-9\.]+)*\}"|grep -Eo "([0-9\.]+)"`; do |
---|
356 | aNameServers[nNameServerIndex-1]="$(trim "$tNameServer")" |
---|
357 | let nNameServerIndex++ |
---|
358 | done |
---|
359 | |
---|
360 | for tWINSServer in `echo "$sGetPacketOutput"|grep "nb_over_tcpip_name_server"|grep -Eo "\{([0-9\.]+)(, [0-9\.]+)*\}"|grep -Eo "([0-9\.]+)"`; do |
---|
361 | aWinsServers[nWinsServerIndex-1]="$(trim "$tWINSServer")" |
---|
362 | let nWinsServerIndex++ |
---|
363 | done |
---|
364 | |
---|
365 | sDomainName=`echo "$sGetPacketOutput"|grep "domain_name "|grep -Eo ": [-A-Za-z0-9\-\.]+"|grep -Eo "[-A-Za-z0-9\-\.]+"` |
---|
366 | sDomainName="$(trim "$sDomainName")" |
---|
367 | |
---|
368 | if [ ${#aNameServers[*]} -gt 0 -a "$sDomainName" ]; then |
---|
369 | logMessage "Retrieved name server(s) [ ${aNameServers[@]} ], domain name [ $sDomainName ], and WINS server(s) [ ${aWinsServers[@]} ]" |
---|
370 | setDnsServersAndDomainName aNameServers[@] "$sDomainName" aWinsServers[@] |
---|
371 | return 0 |
---|
372 | elif [ ${#aNameServers[*]} -gt 0 ]; then |
---|
373 | logMessage "Retrieved name server(s) [ ${aNameServers[@]} ] and WINS server(s) [ ${aWinsServers[@]} ] and using default domain name [ $DEFAULT_DOMAIN_NAME ]" |
---|
374 | setDnsServersAndDomainName aNameServers[@] "$DEFAULT_DOMAIN_NAME" aWinsServers[@] |
---|
375 | return 0 |
---|
376 | else |
---|
377 | # Should we return 1 here and indicate an error, or attempt the old method? |
---|
378 | logMessage "No useful information extracted from DHCP/BOOTP packet. Attempting legacy configuration." |
---|
379 | fi |
---|
380 | |
---|
381 | set -e # We instruct bash that it CAN again fail on errors |
---|
382 | else |
---|
383 | # Should we return 1 here and indicate an error, or attempt the old method? |
---|
384 | logMessage "No DHCP/BOOTP packet found on interface. Attempting legacy configuration." |
---|
385 | fi |
---|
386 | fi |
---|
387 | |
---|
388 | unset sDomainName |
---|
389 | unset sNameServer |
---|
390 | unset aNameServers |
---|
391 | |
---|
392 | sDomainName=`ipconfig getoption $dev domain_name 2>/dev/null` |
---|
393 | sNameServer=`ipconfig getoption $dev domain_name_server 2>/dev/null` |
---|
394 | |
---|
395 | sDomainName="$(trim "$sDomainName")" |
---|
396 | sNameServer="$(trim "$sNameServer")" |
---|
397 | |
---|
398 | declare -a aWinsServers=( ) # Declare empty WINS array to avoid any useless error messages |
---|
399 | |
---|
400 | if [ "$sDomainName" -a "$sNameServer" ]; then |
---|
401 | aNameServers[0]=$sNameServer |
---|
402 | logMessage "Retrieved name server [ $sNameServer ], domain name [ $sDomainName ], and no WINS servers" |
---|
403 | setDnsServersAndDomainName aNameServers[@] "$sDomainName" aWinsServers[@] |
---|
404 | elif [ "$sNameServer" ]; then |
---|
405 | aNameServers[0]=$sNameServer |
---|
406 | logMessage "Retrieved name server [ $sNameServer ] and no WINS servers, and using default domain name [ $DEFAULT_DOMAIN_NAME ]" |
---|
407 | setDnsServersAndDomainName aNameServers[@] "$DEFAULT_DOMAIN_NAME" aWinsServers[@] |
---|
408 | elif [ "$sDomainName" ]; then |
---|
409 | logMessage "WARNING: Retrieved domain name [ $sDomainName ] but no name servers from OpenVPN (DHCP), which is not sufficient to make network/DNS configuration changes." |
---|
410 | else |
---|
411 | logMessage "WARNING: No DNS information recieved from OpenVPN (DHCP), so no network/DNS configuration changes need to be made." |
---|
412 | fi |
---|
413 | |
---|
414 | return 0 |
---|
415 | } |
---|
416 | |
---|
417 | configureOpenVpnDns() |
---|
418 | { |
---|
419 | unset vForOptions |
---|
420 | unset vOptions |
---|
421 | unset aNameServers |
---|
422 | unset aWinsServers |
---|
423 | |
---|
424 | nOptionIndex=1 |
---|
425 | nNameServerIndex=1 |
---|
426 | nWinsServerIndex=1 |
---|
427 | |
---|
428 | while vForOptions=foreign_option_$nOptionIndex; [ -n "${!vForOptions}" ]; do |
---|
429 | vOptions[nOptionIndex-1]=${!vForOptions} |
---|
430 | case ${vOptions[nOptionIndex-1]} in |
---|
431 | *DOMAIN* ) |
---|
432 | sDomainName="$(trim "${vOptions[nOptionIndex-1]//dhcp-option DOMAIN /}")" |
---|
433 | ;; |
---|
434 | *DNS* ) |
---|
435 | aNameServers[nNameServerIndex-1]="$(trim "${vOptions[nOptionIndex-1]//dhcp-option DNS /}")" |
---|
436 | let nNameServerIndex++ |
---|
437 | ;; |
---|
438 | *WINS* ) |
---|
439 | aWinsServers[nWinsServerIndex-1]="$(trim "${vOptions[nOptionIndex-1]//dhcp-option WINS /}")" |
---|
440 | let nWinsServerIndex++ |
---|
441 | ;; |
---|
442 | esac |
---|
443 | let nOptionIndex++ |
---|
444 | done |
---|
445 | |
---|
446 | if [ ${#aNameServers[*]} -gt 0 -a "$sDomainName" ]; then |
---|
447 | logMessage "Retrieved name server(s) [ ${aNameServers[@]} ], domain name [ $sDomainName ], and WINS server(s) [ ${aWinsServers[@]} ]" |
---|
448 | setDnsServersAndDomainName aNameServers[@] "$sDomainName" aWinsServers[@] |
---|
449 | elif [ ${#aNameServers[*]} -gt 0 ]; then |
---|
450 | logMessage "Retrieved name server(s) [ ${aNameServers[@]} ] and WINS server(s) [ ${aWinsServers[@]} ] and using default domain name [ $DEFAULT_DOMAIN_NAME ]" |
---|
451 | setDnsServersAndDomainName aNameServers[@] "$DEFAULT_DOMAIN_NAME" aWinsServers[@] |
---|
452 | else |
---|
453 | # Should we maybe just return 1 here to indicate an error? Does this mean that something bad has happened? |
---|
454 | logMessage "No DNS information recieved from OpenVPN, so no network configuration changes need to be made." |
---|
455 | fi |
---|
456 | |
---|
457 | return 0 |
---|
458 | } |
---|
459 | |
---|
460 | # We sleep here to allow time for OS X to process network settings |
---|
461 | sleep 2 |
---|
462 | |
---|
463 | EXIT_CODE=0 |
---|
464 | |
---|
465 | if ${IS_TAP} ; then |
---|
466 | # Still need to do: Look for route-gateway dhcp (TAP isn't always DHCP) |
---|
467 | bRouteGatewayIsDhcp="false" |
---|
468 | if [ -z "${route_vpn_gateway}" -o "$route_vpn_gateway" == "dhcp" -o "$route_vpn_gateway" == "DHCP" ]; then |
---|
469 | bRouteGatewayIsDhcp="true" |
---|
470 | fi |
---|
471 | |
---|
472 | if [ "$bRouteGatewayIsDhcp" == "true" ]; then |
---|
473 | if [ -z "$dev" ]; then |
---|
474 | logMessage "Cannot configure TAP interface for DHCP without \$dev being defined. Exiting." |
---|
475 | exit 1 |
---|
476 | fi |
---|
477 | |
---|
478 | ipconfig set "$dev" DHCP |
---|
479 | |
---|
480 | configureDhcpDns & |
---|
481 | elif [ "$foreign_option_1" == "" ]; then |
---|
482 | logMessage "No network configuration changes need to be made." |
---|
483 | else |
---|
484 | configureOpenVpnDns |
---|
485 | EXIT_CODE=$? |
---|
486 | fi |
---|
487 | else |
---|
488 | if [ "$foreign_option_1" == "" ]; then |
---|
489 | logMessage "No network configuration changes need to be made." |
---|
490 | else |
---|
491 | configureOpenVpnDns |
---|
492 | EXIT_CODE=$? |
---|
493 | fi |
---|
494 | fi |
---|
495 | |
---|
496 | exit $EXIT_CODE |
---|