forked from googlearchive/gsa-admin-toolkit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgsa_win_utility.hta
797 lines (699 loc) · 38.3 KB
/
gsa_win_utility.hta
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
<html>
<!--
Copyright 2010 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This code is not supported by Google
-->
<!--
Google Search Appliance Kerberos Setup Validation
=================================================
Description:
Diagnostics utility to help identify kerberos-related configuration/setup and serving issues for the Google Search Appliance (GSA). It is assumed
the GSA Admin ran through the kerberos IWA setup for the GSA (i.e, created an account, created a DNS name, ran ktpass)
System Requirements:
32-bit Windows XP, Vista, Windows 7
MIT Kerberos Client (http://web.mit.edu/Kerberos/dist/index.html)
installed at (c:\program files\ such that klist exists at: c:\program files\mit\kerberos\bin\klist.exe
Usage:
1. Download the gsa_win_toolkit.hta and save it to the desktop with the extension .hta. The users account running the script
does not have to be an admin.
2. Right click on the file, select 'Properties'. If the security setting blocks execution, select "Unblock"
3. On launch, enter the following
a. Fully qualified DNS A-Name of the GSA (eg gsa.yourdomain.com)
b. User account for the GSA in active directory associated with the keytab.
(omit the domain information. eg: just gsauser not DOMAIN\gsauser or gsauser@DOMAIN)
c. Select the latest keytab
4. The utility will run through about 20+ individual tests comparing the keytab/DNS/AD entry, etc.
Output in green is a pass, in red is an error that the tool detected in the confiuration.
References:
http://mirror2.activexperts.com/activmonitor/windowsmanagement/scripts/desktop/internet/#LSIESZ.htm
http://web.mit.edu/Kerberos/dist/index.html
http://technet.microsoft.com/en-us/library/ee156506.aspx
-->
<head>
<!-- register the .hta file -->
<HTA:APPLICATION
APPLICATIONNAME="Google Search Appliance Kerberos Setup Validation"
SCROLL="yes"
SINGLEINSTANCE="yes"
WINDOWSTATE="normal"
ICON="http://www.google.com/favicon.ico"
>
<title>Google Search Appliance Kerberos Setup Validation</title>
</head>
<link href="http://www.google.com/enterprise/css/styles.css" rel="stylesheet" type="text/css" media="screen" />
<STYLE type="text/css">
pre
{
background-color: #FAFAFA;
border-bottom-color: #BBB;
border-bottom-style: solid;
border-bottom-width: 1px;
border-left-color: #BBB;
border-left-style: solid;
border-left-width: 1px;
border-right-color: #BBB;
border-right-style: solid;
border-right-width: 1px;
border-top-color: #BBB;
border-top-style: solid;
border-top-width: 1px;
color: #007000;
display: block;
font-family: monospace;
font-size: 12px;
padding-bottom: 11px;
padding-left: 11px;
padding-right: 11px;
padding-top: 11px;
white-space: pre;
xwidth: 100px;
word-wrap: break-word;
}
</STYLE>
<script language="VBScript">
'some global variables to get set/read in the subroutines.
' The variables prefixed by AD_ are read from active directory
' The variables prefixed by KT_ are read from the keytab
Dim UPN, AD_SPN, AD_KVNO, KT_KVNO, KT_SPN, DNS_ANAME, exception
'write some data to the bottom pane
Sub writeOutput(msg)
Set doutput = document.getElementById("dout")
doutput.innerHTML = doutput.innerHTML & "<br/>" & msg
End Sub
'write some output to the right hand info pane
Sub writeInfo(msg)
Set dinfo = document.getElementById("info")
dinfo.innerHTML = dinfo.innerHTML & "<br/>" & msg
End Sub
'reset all the data between each test
Sub ClearOutput()
Set doutput = document.getElementById("dout")
doutput.innerHTML = ""
username = ""
UPN = ""
AD_SPN = ""
AD_KVNO = ""
KT_KVNO = ""
KT_SPN = ""
DNS_ANAME = ""
exception = false
End Sub
'check to see if the MIT kerberos client is installed.
'the default location to for install is c:\program files and it must be installed there
Sub CheckMITKerberos()
Set WshShell = CreateObject("WScript.Shell")
Architecture = WshShell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")
namePos = InStr(Architecture ,"64")
If namePos > 0 Then
writeOutput "<font color='red' size=2>---> MIT Kerberos for Windows is not supported on 64bit OS</font><br>"
Else
writeOutput "<font color='green' size=2>---> This is a 32-bit OS</font><br>"
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists ("c:\program files\mit\kerberos\bin\klist.exe") then
writeOutput "<font color='green'>---> Found MIT Kerberos Client</font>"
ELSE
writeOutput "<font color='red' size=2>---> Cant find klist.exe in c:\program files\mit\kerberos\bin\klist.exe<br/>Please Install the MIT Kerberos Client for windows <a href='http://web.mit.edu/Kerberos/dist/index.html#kfw-3.2'>MIT Kerberos</a></font>"
exception = true
END IF
End Sub
'main script invoked when the user clicks 'Run Diagnostics'
Sub RunDiag()
writeoutput "<font color=black>Starting Diagnostics</font>"
Set objdns = document.getElementById("dnsname")
'first see if the dns entry is CNAME
CheckforCNAME objdns.value
Set objkt = document.getElementById("keytab")
'then parse out the keytab and display results
ParseKeytab objkt.value
Set objuname = document.getElementById("uname")
'connecto to AD and verify the kvno, SPN, etc
CheckUserEntry objuname.value
'use kinit to verify the password
VerifyPasswordInKeytab objkt.value
'is the SPN unique
CheckSPNUniqueness AD_SPN
'see if the GSA is in the correct intranet zone
VerifyIESettings objdns.value
'TODO: run a secure search if all tests pass
'compare the klist before/after
'check for valid results
'RunSecureSearch objdns.value
End Sub
'Invoked with the .hta is initially loaded (runs only once)
'First connecto to AD and display the Domain/Forest version
Sub ShowDSEInfo()
'http://msdn.microsoft.com/en-us/library/ms684291(VS.85).aspx
Set objSysInfo = CreateObject("ADSystemInfo")
on error resume next
if exception = true Then
exit sub
end if
username = objSysInfo.UserName + "<br/>"
'that error is a general connection error
if err.number = -2147023541 Then
writeOutput "<font color='red'>---> Unable to find DomainController. Aborting</font>"
'set exception to true so we don't continue
exception = true
Exit Sub
End if
writeoutput "<font color='green'>---> Contacted DomainController</font>"
forestdns = "Forest DNS Name: " & objSysInfo.ForestDNSName + "<br/>"
Set objRootDSE = GetObject("LDAP://RootDSE")
rootdse = "Root Domain: " & objRootDSE.Get("RootDomainNamingContext")
dnsserver = "DNSServer: " & objRootDSE.Get("dnsHostName")
dcfunctional_level = objRootDSE.Get("domainControllerFunctionality")
forest_level = objRootDSE.Get("forestFunctionality")
sdcfunctional_level = "Domain Controller Functionality Level: "
Select Case dcfunctional_level
Case 0 sdcfunctional_level = sdcfunctional_level + " WIN 2000"
Case 2 sdcfunctional_level = sdcfunctional_level + " WIN 2003"
Case 3 sdcfunctional_level = sdcfunctional_level + " WIN 2008"
Case 4 sdcfunctional_level = sdcfunctional_level + " WIN 2008R2"
End Select
sforest_level = "Forest Functionality Level: "
Select Case forest_level
Case 0 sforest_level = sforest_level + " WIN 2000"
Case 1 sforest_level = sforest_level + " WIN 2003Mixed"
Case 2 sforest_level = sforest_level + " WIN 2003"
Case 3 sforest_level = sforest_level + " WIN 2008"
Case 4 sforest_level = sforest_level + " WIN 2008R2"
End Select
strout = "<b>Running Diagnostics for: </b><br/>" & username & forestdns & dnsserver & "<br/>" & rootdse & "<br/>" & sdcfunctional_level & _
"<br/>" + sforest_level + "<br/>"
writeInfo "<br/>" + strout
End Sub
'check to see if the name provided is a CNAME or ANAME
Sub CheckforCNAME(lookForCNAME)
if exception = true Then
Exit Sub
End If
writeoutput "<font color='green'>1 Attempting verify DNS ANAME</font></br>"
'get the output for 'nslookup
strResult = getcommandOutput("%comspec% /c nslookup " & lookForCNAME )
Set doutput = document.getElementById("dout")
namePos = InStr(strResult ,"Aliases:")
If namePos > 0 Then
writeoutput "<font color=red> --->DNS Entry provided is a CNAME</font>"
writeoutput "<font color=red> --->Please specify the DNS A-NAME for the GSA.</font>"
Else
namePos = InStr(strResult ,"Name:")
If namePos > 0 Then
writeoutput "<font color=green> --->DNS Entry for the GSA is an A-Name</font>"
DNS_ANAME = lookForCNAME
Else
writeoutput "<font color=red> --->DNS Entry not found</font>"
End If
End If
End Sub
'run kinit against the keytab to verifiy the password there matches the one in Active directory.
Sub VerifyPasswordInKeytab(keytab)
if exception = true Then
Exit Sub
End If
writeoutput "<font color='green'>4 Attempting to verify password in keytab</font></br>"
strResult = getktout("%comspec% /c c:\progra~1\mit\kerberos\bin\kinit.exe -V -v -k -t " & chr(34) & keytab & chr(34) & " " & KT_SPN)
if (strResult = "Authenticated to Kerberos v5") Then
writeoutput "<font color='green'> ---> Password in Keytab Verified in AD</font></br>"
Else
writeoutput "<font color='red'> ---> Password in Keytab Could not be verified in AD</font></br>"
writeoutput "<font color='red'> ---> Reset the password in AD and rerun ktpass with that password</font></br>"
End If
End Sub
'Connect to AD and see if the SPN provided/derived from AD/keytab/DNS is unique.
Sub CheckSPNUniqueness(strAD_KVNO)
if exception = true Then
Exit Sub
End If
writeoutput "<font color='green'>5 Attempting to verify SPN uniqueness in AD</font></br>"
'search the AD for servicePrincipalName=
str_mode = "(servicePrincipalName=" & strAD_KVNO & ");"
Set oNSP = GetObject("GC:")
For Each oGC in oNSP
strGCPath = oGC.ADsPath
Next
Set oConnection = CreateObject("ADODB.Connection")
Set oCmd = CReateObject("ADODB.Command")
oConnection.Provider = "ADsDSOObject"
oConnection.Open "ADs Provider"
Set oCmd.ActiveConnection = oConnection
oCmd.Properties("Page Size") = 1000
strADOQuery = "<" + strGCPath + ">;" & str_mode & "dnsHostName,distinguishedName,servicePrincipalName,objectClass,userprincipalName,msDS-KeyVersionNumber,userAccountControl, samAccountName;subtree"
oCmd.CommandText = strADOQuery
dn = ""
hit_counter = 0
Set oRecordSet = oCmd.Execute
If oRecordSet.EOF and oRecordSet.Bof Then
'if the SPN wasn't even found...
strout = "No users found!" & "</br>"
Else
While Not oRecordset.Eof
Dim dn
dn = dn & "[" & oRecordset.Fields("distinguishedName") & "]"
hit_counter = hit_counter +1
oRecordset.MoveNext
Wend
End If
'if we found more than one result
if (hit_counter> 1) Then
writeoutput "<font color=red> ---> SPN is not unique: " & strAD_KVNO & "--->" & dn
writeoutput "<font color=red> ---> Delete the duplicate SPNs associated with the non-GSA accounts"
Else
writeoutput "<font color=green> ---> SPN is unique: " & strAD_KVNO & "--->" & dn
End If
oRecordset.Close
oConnection.Close
End Sub
'connecto to AD and validate some flags for the GSA's user in AD.
Sub CheckUserEntry(username)
if exception = true Then
Exit Sub
End If
Dim objHash
writeoutput "<font color='green'>3 Attempting to contact Active Directory</font></br>"
'uses the useraccountcontrol http://support.microsoft.com/kb/305144
Set objHash = CreateObject("Scripting.Dictionary")
objHash.Add "LOCKOUT", &h0010
objHash.Add "ACCOUNTDISABLED", &h0002
objHash.Add "NORMAL_ACCOUNT", &h0200
objHash.Add "TRUSTED_FOR_DELEGATION", &h80000
objHash.Add "USE_DES_KEY_ONLY", &h200000
objHash.Add "DONT_REQ_PREAUTH", &h400000
objHash.Add "PASSWORD_EXPIRED", &h800000
str_mode = "(samAccountName=" & username & ");"
Set oNSP = GetObject("GC:")
For Each oGC in oNSP
strGCPath = oGC.ADsPath
Next
Set oConnection = CreateObject("ADODB.Connection")
Set oCmd = CReateObject("ADODB.Command")
oConnection.Provider = "ADsDSOObject"
oConnection.Open "ADs Provider"
Set oCmd.ActiveConnection = oConnection
oCmd.Properties("Page Size") = 1000
strADOQuery = "<" + strGCPath + ">;" & str_mode & "dnsHostName,distinguishedName,servicePrincipalName,objectClass,userprincipalName,msDS-KeyVersionNumber,userAccountControl, samAccountName;subtree"
oCmd.CommandText = strADOQuery
Set oRecordSet = oCmd.Execute
If oRecordSet.EOF and oRecordSet.Bof Then
writeoutput "<font color='red'> --->Username/samAccountName [" & username & "] not found: </font></br>"
writeoutput "<font color='red'> --->Please verify the username registered to the GSA</font></br>"
writeoutput "<font color='red'> --->(enter the username without the domain eg: user1 and not YOURDOMAIN\user1 or user1@DOMAIN)</font></br>"
Else
'for each user found
While Not oRecordset.Eof
Dim dn
dn = oRecordset.Fields("distinguishedName")
strout = strout & "<li>DN: " & dn & "</br>"
vObjClass = oRecordset.Fields("objectClass")
strClass = vObjClass( UBound(vObjClass) )
strout = strout & " Class: " & strClass & "</br>"
'if the account is fo type computer, we can't proceed.
If UCase(strClass) = "COMPUTER" Then
writeoutput "<font color='red'> ---> Account is not a User account: " & oRecordset.Fields("dnsHostName") & "; it is a COMPUTER account</font></br>"
writeoutput "<font color='red'> ---> Please delete this account in AD and recreate as a User account (not computer account)</font></br>"
Else
writeoutput "<font color='green'> ---> Found User account [" & username & "]</font></br>"
username = oRecordset.Fields("samAccountName")
AD_UPN = oRecordset.Fields("userprincipalName")
AD_KVNO = oRecordset.Fields("msDS-KeyVersionNumber")
userAccountControl = oRecordset.Fields("userAccountControl")
writeoutput "<font color='green'> ---> AD UserPrincipalName: " & AD_UPN & "</font><br/>"
writeoutput "<font color='green'> ---> AD KVNO: " & AD_KVNO & "</font><br/>"
'do the KVNO numbers match?
If clng(AD_KVNO) = clng(KT_KVNO) Then
writeoutput "<font color='green'> ---> KVNOs in AD and keytab matched</font><br/>"
Else
writeoutput "<font color='red'> ---> KVNO in AD and keytab do not match</font><br/>"
End If
Dim objUser, intUAC,Key
Set objUser = GetObject("LDAP://" + dn)
intUAC = objUser.Get("userAccountControl")
'now compare the flags in the userAccountcontrol
'eg: http://gallery.technet.microsoft.com/ScriptCenter/en-us/67244a3c-3615-46d5-9c6f-92df8823b7bf
For Each Key In objHash.Keys
If objHash(Key) And intUAC Then
Select Case Key
Case "ACCOUNTDISABLED"
writeoutput "<font color='red'> ---> AD Useraccount is locked" & "</font></br>"
writeoutput "<font color='red'> ---> Please unlock this account in AD" & "</font></br>"
Case "LOCKOUT"
writeoutput "<font color='red'> ---> AD Useraccount is locked" & "</font></br>"
writeoutput "<font color='red'> ---> Please unlock this account in AD" & "</font></br>"
Case "TRUSTED_FOR_DELEGATION"
writeoutput "<font color='green'> ---> AD Account Trusted for Delegation" & "</font></br>"
Case "USE_DES_KEY_ONLY"
writeoutput "<font color='green'> ---> AD DES Encryption Enabled" & "</font></br>"
Case "PASSWORD_EXPIRED"
writeoutput "<font color='red'> ---> AD Password Expired" & "</font></br>"
writeoutput "<font color='red'> ---> Please reset the password and rerun ktpass. If possible set the AD flag to never expire this account." & "</font></br>"
End Select
Else
Select Case Key
Case "ACCOUNTDISABLED"
writeoutput "<font color='green'> ---> AD Useraccount is unlocked" & "</font></br>"
Case "TRUSTED_FOR_DELEGATION"
writeoutput "<font color='red'> ---> ADAccount is NOT Trusted for Delegation" & "</font></br>"
writeoutput "<font color='red'> ---> Please enable 'Trust this user for delegation to any service'</font></br>"
Case "USE_DES_KEY_ONLY"
writeoutput "<font color='green'> ---> AD DES Encryption is Disabled" & "</font></br>"
Case "PASSWORD_EXPIRED"
writeoutput "<font color='green'> ---> AD Password has not Expired" & "</font></br>"
End Select
End If
Next
End If
'now compare the serviceprincipal name in AD
On Error Resume Next
vSPNs = oRecordset.Fields("servicePrincipalName")
ad_kt_spn_matched = false
'the Principal in the keytab has the REALM HTTP/[email protected]
'and the SPN in AD is just HTTP/gsa.yourdomain.com...so we strip off everything after the @
kt_spn_without_realm = Mid(KT_SPN,1,Instr(KT_SPN,"@")-1)
For Each vName in vSPNs
writeoutput "<font color='green'> ---> AD SPN Found: " & vName & "</font></br>"
writeoutput "<font color='green'> ---> Comparing SPN from AD against keytab...</font></br>"
'compare the spn in AD and the principal in the keytab...
'there can be multiple SPN for the account...we just need it to match the keytab...
If vName = kt_spn_without_realm Then
AD_SPN = vName
ad_kt_spn_matched = true
End If
Next
if (ad_kt_spn_matched = true) Then
writeoutput "<font color='green'> ---> SPN/Principal in Keytab and AD Matched: " & kt_spn_without_realm & "</font></br>"
'now does the SPN match the DNS A-name
if kt_spn_without_realm = ("HTTP/" & Lcase(DNS_ANAME)) Then
writeoutput "<font color='green'> ---> DNS ANAME matches the host portion of the SPN</font></br>"
Else
writeoutput "<font color='red'> ---> DNS ANAME does not match the host portion of the SPN</font></br>"
writeoutput "<font color='red'> ---> DNS ANAME [" & DNS_ANAME & "] does not match the host portion of the SPN [" & kt_spn_without_realm &"]</font></br>"
writeoutput "<font color='red'> ---> Verify the correct useraccount for the GSA has a host portion of that matches the DNS ANAME</font></br>"
exception = true
exit sub
End If
Else
writeoutput "<font color='red'> ---> SPN/Principal in Keytab does not match any AD SPNs for user: " & username & "</font></br>"
writeoutput "<font color='red'> ---> Check if [" & username & "] is actually the user entered as the -mapuser parameter wil running ktpass</font></br>"
End If
' We also know that the UPN in AD must match the Principal in the keytab (this time the @ symbol is needed.)
'eg a UPN after keytab generation looks like: HTTP/[email protected]
if (AD_UPN = KT_SPN) Then
writeoutput "<font color='green'> ---> Principal in Keytab matches UPN in AD: " & AD_UPN & "</font></br>"
Else
writeoutput "<font color='red'> ---> Principal in Keytab [" & KT_SPN & "] does not match UPN in AD: " & AD_UPN & "</font></br>"
writeoutput "<font color='red'> ---> The UPN for the GSA's user must match the principal name specified in the keytab</font></br>"
writeoutput "<font color='red'> ---> Delete the user account in AD, regenerate it and rerun ktpass</font></br>"
End If
oRecordset.MoveNext
Wend
End If
oRecordset.Close
oConnection.Close
End Sub
'parse out the keytab
Sub ParseKeytab(keytabfile)
if exception = true Then
Exit Sub
End If
writeoutput "<font color='green'>2 Attempting to parse keytab</font></br>"
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists (keytabfile) then
Else
writeoutput "<font color=red>2 Keytab file specified does not exist</font>"
exception = true
Exit Sub
End If
strResult = getcommandOutput("%comspec% /c c:\progra~1\mit\kerberos\bin\klist.exe -k -t -e " & chr(34) & keytabfile & chr(34))
arrlines= split(strResult,vbcrlf)
' check to see if we have more than 1 key in this keytab:
if ubound(arrlines) > 4 Then
writeoutput "<font color=red>2 Keytab file has more than one entry</font>"
writeoutput "<font color=red> ---> The GSA can only process keytabs with one Principal</font>"
exception = true
Exit Sub
End If
'now scrape out the info we need from the klist output (yeah, i know)
arrlines(3) = Trim(arrlines(3))
arrentries = split(arrlines(3)," ")
KT_KVNO = ""
KT_KVNO = arrentries(0)
KT_SPN = arrentries(3)
raw_out = Trim(arrlines(3))
KT_ENC = Mid(raw_out,Instr(raw_out,"("),30)
if KT_KVNO = "" Then
writeoutput "<font color='red'>2 Unable to parse Keytab: "& strResult & "</font><br/>"
writeoutput "<font color='red'> ---> Please verify the file specified is a keytab</font>"
'Exit Sub
End If
writeoutput "<font color='green'> --->Found KVNO: "& KT_KVNO & "</font></br>"
writeoutput "<font color='green'> --->Found Principal: "& KT_SPN & "</font></br>"
if (KT_ENC = "(DES cbc mode with RSA-MD5)") Then
writeoutput "<font color='green'> --->Found Encryption is DES: "& KT_ENC & "</font></br>"
elseif (KT_ENC = "(ArcFour with HMAC/md5)") Then
writeoutput "<font color='green'> --->Found Encryption is RC4: "& KT_ENC & "</font></br>"
else
writeoutput "<font color='red'> --->Please run ktpass again and specify the encryption type</font></br>"
end if
'now parse out the KT_SPN to see if its in correct case: HTTP/[email protected]
'the parsing logic below is so-so
prefix = Mid(KT_SPN,1,5)
SPN_less_prefix = MID(KT_SPN,6,60)
host = Mid(SPN_less_prefix,1,instr(SPN_less_prefix,"@")-1)
realm = MID(SPN_less_prefix,instr(SPN_less_prefix,"@")+1,80)
'compare the prefix/service, the host and realm.
If (prefix = "" OR host = "" OR realm = "") Then
writeoutput "<font color='red'> --->Principal in keytab is not in correct format: Needs match case/format HTTP/[email protected] found: " & KT_SPN & "</font></br>"
exception = true
Exit Sub
End IF
if (prefix <> UCASE(prefix) OR UCASE(prefix) <> "HTTP/") Then
writeoutput "<font color='red'> --->Principal-prefix in keytab is not in correct case format</font></br>"
writeoutput "<font color='red'> ---> correct format: <b>HTTP</b>/[email protected] found: " & KT_SPN & "</font></br>"
writeoutput "<font color='red'> ---> Please rerun ktpass using the <i>exact</i> case-sensitive format shown above</font></br>"
exception = true
Exit Sub
elseif host <> LCASE(host) Then
writeoutput "<font color='red'> --->Principal-host in keytab is not in correct case format (Needs match case/format): HTTP/[email protected]</font></br>"
writeoutput "<font color='red'> ---> correct format: HTTP/<b>gsa.yourdomain.com</b>@YOURDOMAIN.COM found: " & KT_SPN & "</font></br>"
writeoutput "<font color='red'> ---> Please rerun ktpass using the <i>exact</i> case-sensitive format shown above</font></br>"
exception = true
Exit Sub
elseif realm <> UCASE(realm) Then
writeoutput "<font color='red'> --->Principal-realm in keytab is not in correct case format (Needs match case/format): HTTP/[email protected]:</font></br>"
writeoutput "<font color='red'> ---> correct format: HTTP/gsa.yourdomain.com@<b>YOURDOMAIN.COM</b> found: " & KT_SPN & "</font></br>"
writeoutput "<font color='red'> ---> Please rerun ktpass using the <i>exact</i> case-sensitive format shown above</font></br>"
exception = true
Exit Sub
else
writeoutput "<font color='green'> --->Principal in keytab is in correct case format: HTTP/[email protected]</font></br>"
End If
End Sub
'connect to the local registry, find ou the IE version and see if the GSA is registered in the 'local intranet zone'
Sub VerifyIESettings(dnsentry)
if exception = true Then
Exit Sub
End If
writeoutput "<font color='green'>6 Attempting to verify IE Zone settings</font></br>"
is_in_zone = false
strComputer = "."
on error resume next
'Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2\Applications\MicrosoftIE")
'if err.number = -2147217394 Then
' writeoutput "<font color=red>Unable to determine IE Version via registry (non admin user)</font>"
'End if
'Set colIESettings = objWMIService.ExecQuery ("Select * from MicrosoftIE_Summary")
'For Each strIESetting in colIESettings
' writeoutput "Client IEVersion: " & strIESetting.Version
'Next
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strValue = objShell.RegRead("HKLM\Software\Microsoft\Internet Explorer\Version")
writeoutput " ---> Internet Explorer Version: " & strValue
Const HKEY_CURRENT_USER = &H80000001
Set objReg = GetObject("winmgmts:" & "{impersonationLevel=impersonate}\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains"
objReg.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubKeys
if isNull(arrSubKeys) then
writeoutput "<font color=red> ---> GSA ANAME not found in IE Zone settings</font>"
writeoutput "<font color=red> ---> The DNS ANAME for the GSA must be set in a Local & Trusted IE zone for IWA.</font>"
exception = true
exit sub
end if
'parse out the registry keys.
For Each subkey In arrSubKeys
strDomains = strKeyPath & "\" & subkey
objReg.EnumKey HKEY_CURRENT_USER, strDomains, arrDomainKeys
For Each domainKey in arrDomainKeys
fqdn = domainKey & "." & subkey
if (lcase(fqdn) = lcase(DNS_ANAME)) THen
gsazone = strKeyPath & "\" & subkey & "\" & domainKey
objReg.EnumValues HKEY_CURRENT_USER, gsazone, gsazonevalues, gsatypes
For i = 0 to Ubound(gsazonevalues)
objReg.GetDWORDValue HKEY_CURRENT_USER, gsazone, gsazonevalues(i),dwValue
Next
Select Case dwValue
Case 0 strZone = "My Computer"
Case 1 strZone = "Local Intranet zone"
Case 2 strZone = "Trusted Sites Zone"
Case 3 strZone = "Internet Zone"
Case 4 strZone = "Restricted Sites Zone"
End Select
if (strZone = "Local Intranet zone") Then
writeoutput "<font color=green> ---> GSA ANAME Found in IE Local Intranet Zone</font>"
Else
writeoutput "<font color=red> ---> GSA ANAME Found in IE [" & strZone & "] zone</font>"
writeoutput "<font color=red> ---> The DNS ANAME for the GSA must be set in a Local & Trusted IE zone for IWA.</font>"
exception = true
End If
is_in_zone = true
End If
Next
Next
if (is_in_zone = false) Then
writeoutput "<font color=red> ---> GSA ANAME not found in IE Zone settings</font>"
writeoutput "<font color=red> ---> The DNS ANAME for the GSA must be set in a Local & Trusted IE zone for IWA.</font>"
exception = true
End If
End Sub
'these two scripts invokes a shell using two different mechanisms: shell.exec and shell.run.
'for some reason, the keytab/klist commands don't complete fully using the shell.run so until i figure why...
Function getktout(strCommand)
dim objShell, objExecObject, strOutput
Set objShell = CreateObject("WScript.Shell")
Set objExecObject = objShell.Exec(strCommand)
Do Until objExecObject.StdErr.AtEndOfStream
strOutput = objExecObject.StdErr.ReadLine()
getktout = strOutput
loop
End Function
'launches a shell, pipes the output to a file, reads that file then deletes it.
Function getcommandOutput(cmd)
Const OpenAsDefault = -2
Const FailIfNotExist = 0
Const ForReading = 1
Set oShell = CreateObject("WScript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")
sTemp = oShell.ExpandEnvironmentStrings("%TEMP%")
sTempFile = sTemp & "\" & oFSO.GetTempName
oShell.Run cmd & " >" & sTempFile, 0, True
Set fFile = oFSO.OpenTextFile(sTempFile, ForReading, FailIfNotExist, OpenAsDefault)
strResult= fFile.ReadAll
fFile.Close
oFSO.DeleteFile (sTempFile)
getcommandOutput = strResult
End Function
</script>
<script language="javascript">
function none() { }
function init() { }
//not implemented yet:
//in a later release, this routine will:
//1.get a list of the existing kerberos ticket on the system
//2.run a secure search using the dns aname
//3.parse out the returning XML results (if any)
//4.compare the tickets before/after the search and display the results.
function RunSecureSearch(dns) {
url = "https://" + dns + "/search?q=*&access=s&client=default_frontend&output=xml_no_dtd&filter=0&xproxystylesheet=default_frontend&sort=date%3AD%3AL%3Ad1&entqr=0&oe=UTF-8&ie=UTF-8&ud=1&site=default_collection";
writeoutput("<font color=green>7 Running Secure Search with URL: " + url + "</font>");
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
objxmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
objxmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
objxmlhttp.onreadystatechange = function() {
if (objxmlhttp.readyState == 4 && objxmlhttp.status == 200) {
//xmldoc = new ActiveXObject("Microsoft.XMLDOM");
xmldoc.async = false
if (xmldoc.load(objxmlhttp.responsexml)) {
var doc = xmldoc.documentElement;
var m = doc.getElementsByTagName("M")[0];
writeoutput("<font color=red> ---> Secure Search Succeeded: Number of search results [" + m + "</font>");
}
}
else {
writeoutput("<font color=red> ---> Secure Search Failed: Response Code: [" + objxmlhttp.status + "]</font>");
}
}
objxmlhttp.open("GET", url, true);
objxmlhttp.send();
}
</script>
<body onLoad="javascript:init(); ClearOutput(); CheckMITKerberos(); ShowDSEInfo();">
<table id="header" style="" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td valign="bottom" width="5px"><img src="http://www.google.com/images/cleardot.gif" height="1" width="5" /></td>
<td width="1%"><a href="http://www.google.com"><img src="http://www.google.com/enterprise/images/150x55.gif" alt="Google" border="0" height="55" width="150" /></a></td>
<td valign="bottom" width="5px"><img src="http://www.google.com/images/cleardot.gif" height="1" width="3" /></td>
<td align="left" valign="top" width="98%">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td colspan="2"><img src="http://www.google.com/images/cleardot.gif" height="18" width="2" /></td>
</tr>
<tr>
<td class="header1">Google Search Appliance Kerberos Setup Validation</td>
<td align="right"></td>
</tr>
<tr>
<td colspan="2"><img src="http://www.google.com/images/cleardot.gif" height="2" width="2" /></td>
</tr>
<tr>
<td bgcolor="#999999" colspan="2"><img src="http://www.google.com/images/cleardot.gif" height="1" width="2" /></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<div width="100%">
<hr />
<table width="100%">
<tr>
<td VALIGN="top">
<font class="header1">Validate GSA Kerberos Configuraton</font>
<br/>
<table>
<tr>
<td><li><font size=2>FullyQualified DNS AName for GSA </font></td><td><input size=35 name="dnsname" id="dnsname" type=text value="gsa1.esodomain.com"/></td>
</tr>
<tr>
<td><li><font size=2>GSA username (not DOMAIN\username)</font></td><td> <input size=35 name="uname" id="uname" type=text value="gsa1"/></td>
</tr>
<tr>
<td><li><font size=2>Keytab file</font> </td><td> <input size=35 type="file" name="keytab" id="keytab" type=text value="c:\gsa1.keytab"/></td>
</tr>
</table>
<center>
<input type="submit" onclick="javascript:ClearOutput(); RunDiag();" class="lsb" value="Run Diagnostics" name="btnG"/>
</center>
<br />
<font size="1" >
This utility validates various GSA-related kerberos infrastructure and configuration options for Secure Serving. Please run this script on any windows system that has the
<a href="http://web.mit.edu/kerberos/dist/index.html#kfw-3.2">MIT Kerberos client</a> installed. It is assumed the user
ran through the <a href="http://www.google.com/support/enterprise/static/gsa/docs/admin/72/gsa_doc_set/secure_search/secure_search_crwlsrv.html#1072773">GSA Kerberos Setup</a>. This script
also tests the IE version and Zone settings for the current user.
<br/>
Additional Kerberos Troubleshooting <a href="https://support.google.com/gsa/answer/6055171?hl=en">link</a> on the GSA:
<br/>
</font>
</td>
<td width="40%" >
<pre style="height=150px; width=100%;" id="info" name="info" />
</td>
</tr>
</table>
<pre style="width=100%; height=350px; " id="dout" name="dout" />
</body>
</html>