win32-sspi 0.0.1.rc1-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,441 @@
1
+ ########################################################################
2
+ # Tests for the Win32::SSPI::Negotiate::Server class.
3
+ ########################################################################
4
+ require 'test-unit'
5
+ require 'win32/sspi/negotiate/server'
6
+
7
+ class TC_Win32_SSPI_Negotiate_Server < Test::Unit::TestCase
8
+ MockSpnegoToken = Random.new.bytes(128)
9
+ MockCredentialHandle = [777,888]
10
+ MockTimeStamp = [0x000000FF,0xFF000000]
11
+ MockContextHandle = [123,987]
12
+ MockSecBufferContent = Random.new.bytes(128)
13
+ ContextAttr = Windows::Constants::ISC_REQ_CONFIDENTIALITY |
14
+ Windows::Constants::ISC_REQ_REPLAY_DETECT |
15
+ Windows::Constants::ISC_REQ_CONNECTION
16
+
17
+ def setup
18
+ @server = Win32::SSPI::Negotiate::Server.new
19
+ end
20
+
21
+ # assert helper to help remove test duplication
22
+ def assert_server_call_state(server)
23
+ ach_args = server.retrieve_state(:ach)
24
+ refute_nil ach_args
25
+ assert_equal 9, ach_args.length
26
+
27
+ asc_args = server.retrieve_state(:asc)
28
+ refute_nil asc_args
29
+ assert_equal 9, asc_args.length
30
+
31
+ cat_args = server.retrieve_state(:cat)
32
+ refute_nil cat_args
33
+ assert_equal 2, cat_args.length
34
+
35
+ dsc_args = server.retrieve_state(:dsc)
36
+ refute_nil dsc_args
37
+ assert_equal 1, dsc_args.length
38
+
39
+ fch_args = server.retrieve_state(:fch)
40
+ refute_nil fch_args
41
+ assert_equal 1, fch_args.length
42
+
43
+ fcb_args = server.retrieve_state(:fcb)
44
+ refute_nil fcb_args
45
+ assert_equal 1, fcb_args.length
46
+
47
+ assert_nil server.instance_variable_get(:@credentials_handle)
48
+ assert_nil server.instance_variable_get(:@context_handle)
49
+ end
50
+
51
+ def assert_base64_http_header(header,auth_type)
52
+ if Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE == auth_type
53
+ assert_match( /\ANegotiate \p{Print}+={,2}\z/,header)
54
+ end
55
+ if Win32::SSPI::API::Common::AUTH_TYPE_NTLM == auth_type
56
+ assert_match( /\ANTLM \p{Print}+={,2}\z/,header)
57
+ end
58
+ end
59
+
60
+ def test_auth_type_basic_functionality
61
+ assert_respond_to(@server, :auth_type)
62
+ assert_respond_to(@server, :auth_type=)
63
+ assert_nothing_raised{ @server.auth_type }
64
+ assert_kind_of(String, @server.auth_type)
65
+ assert_equal Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE, @server.auth_type
66
+
67
+ server = Win32::SSPI::Negotiate::Server.new(auth_type: "Kerberos")
68
+ assert_equal "Kerberos", server.auth_type
69
+ end
70
+
71
+ def test_token_basic_functionality
72
+ assert_respond_to(@server, :token)
73
+ assert_nothing_raised{ @server.token }
74
+ assert_kind_of(String, @server.token)
75
+ assert_equal "", @server.token
76
+ end
77
+
78
+ def test_username_and_domain_basic_functionality
79
+ assert_respond_to(@server, :username)
80
+ assert_nothing_raised{ @server.username }
81
+ assert_kind_of(String, @server.username)
82
+ assert_equal "", @server.username
83
+ assert_respond_to(@server, :domain)
84
+ assert_nothing_raised{ @server.domain }
85
+ assert_kind_of(String, @server.domain)
86
+ assert_equal "", @server.domain
87
+ end
88
+
89
+ def test_acquire_handle_basic_functionality
90
+ assert_respond_to(@server, :acquire_handle)
91
+ assert_equal 0, @server.method(:acquire_handle).arity
92
+ assert_respond_to(@server, :acquire_credentials_handle)
93
+ assert_equal 9, @server.method(:acquire_credentials_handle).arity
94
+ end
95
+
96
+ def test_accept_context_basic_functionality
97
+ assert_respond_to(@server, :accept_context)
98
+ assert_equal( -1, @server.method(:accept_context).arity)
99
+ assert_respond_to(@server, :accept_security_context)
100
+ assert_equal 9, @server.method(:accept_security_context).arity
101
+ assert_respond_to(@server, :complete_auth_token)
102
+ assert_equal 2, @server.method(:complete_auth_token).arity
103
+ end
104
+
105
+ def test_query_attributes_basic_functionality
106
+ assert_respond_to(@server, :query_attributes)
107
+ assert_equal 0, @server.method(:query_attributes).arity
108
+ assert_respond_to(@server, :query_context_attributes)
109
+ assert_equal 3, @server.method(:query_context_attributes).arity
110
+ assert_respond_to(@server, :free_credentials_handle)
111
+ assert_equal 1, @server.method(:free_credentials_handle).arity
112
+ end
113
+
114
+ def test_acquire_handle_invokes_windows_api_as_expected
115
+ server = Class.new(MockNegotiateServer).new
116
+ assert_nothing_raised{ @status = server.acquire_handle }
117
+ assert_equal Windows::Constants::SEC_E_OK, @status
118
+
119
+ # test acquire_credentials_handle
120
+ args = server.retrieve_state(:ach)
121
+ assert_equal 9, args.length, "unexpected args"
122
+ assert_nil args[0], "unexpected psz_principal"
123
+ assert_equal Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE, args[1], "unexpected psz_package"
124
+ assert_equal Windows::Constants::SECPKG_CRED_INBOUND, args[2], "unexpected f_credentialuse"
125
+ assert_nil args[3], "unexpected pv_logonid"
126
+ assert_nil args[4], "unexpected p_authdata"
127
+ assert_nil args[5], "unexpected p_getkeyfn"
128
+ assert_nil args[6], "unexpected p_getkeyarg"
129
+ assert_kind_of Windows::Structs::CredHandle, args[7], "unexpected ph_newcredentials"
130
+ assert_equal MockCredentialHandle, args[7].marshal_dump
131
+ assert_kind_of Windows::Structs::TimeStamp, args[8], "unexpected pts_expiry"
132
+ assert_equal MockTimeStamp, args[8].marshal_dump
133
+ end
134
+
135
+ def test_acquire_handle_memoizes_handle
136
+ server = Class.new(MockNegotiateServer).new
137
+ assert_nothing_raised{ server.acquire_handle }
138
+ assert_nothing_raised{ @status = server.acquire_handle }
139
+ assert_equal Windows::Constants::SEC_E_OK, @status
140
+ assert_equal 9, server.retrieve_state(:ach).length
141
+ end
142
+
143
+ def test_acquire_handle_raises_when_windows_api_returns_failed_status
144
+ server = Class.new(MockNegotiateServer) do
145
+ def acquire_credentials_handle(*args)
146
+ capture_state(:ach, args)
147
+ return Windows::Constants::SEC_E_SECPKG_NOT_FOUND
148
+ end
149
+ end.new
150
+ assert_raises(SecurityStatusError){ server.acquire_handle }
151
+ end
152
+
153
+ def test_accept_context_invokes_windows_api_as_expected
154
+ server = Class.new(MockNegotiateServer).new
155
+ assert_nothing_raised{ server.acquire_handle }
156
+ assert_nothing_raised{ @status = server.accept_context(MockSpnegoToken) }
157
+ assert_equal Windows::Constants::SEC_E_OK, @status
158
+
159
+ args = server.retrieve_state(:asc)
160
+ assert_equal 9, args.length, "unexpected args"
161
+ assert_kind_of Windows::Structs::CredHandle, args[0], "unexpected ph_credentials"
162
+ assert_equal MockCredentialHandle, args[0].marshal_dump
163
+ assert_nil args[1], "unexpected ph_context"
164
+ assert_kind_of Windows::Structs::SecBufferDesc, args[2], "unexpected p_input"
165
+ assert_equal ContextAttr, args[3], "unexpected f_contextreq"
166
+ assert_equal Windows::Constants::SECURITY_NATIVE_DREP, args[4], "unexpected targetdatarep"
167
+ assert_kind_of Windows::Structs::CtxtHandle, args[5], "unexpected ph_newcontext"
168
+ assert_equal MockContextHandle, args[5].marshal_dump
169
+ assert_kind_of Windows::Structs::SecBufferDesc, args[6], "unexpected p_output"
170
+ assert_equal MockSecBufferContent, server.token
171
+ assert_kind_of FFI::MemoryPointer, args[7], "unexpected pf_contextattr"
172
+ assert_equal ContextAttr, args[7].read_ulong
173
+ assert_kind_of Windows::Structs::TimeStamp, args[8], "unexpected pts_expiry"
174
+ assert_equal MockTimeStamp, args[8].marshal_dump
175
+ end
176
+
177
+ def test_accept_context_raises_when_windows_api_returns_failed_status
178
+ server = Class.new(MockNegotiateServer) do
179
+ def accept_security_context(*args)
180
+ capture_state(:asc, args)
181
+ return Windows::Constants::SEC_E_SECPKG_NOT_FOUND
182
+ end
183
+ end.new
184
+ assert_raises(SecurityStatusError){ server.accept_context }
185
+ end
186
+
187
+ def test_complet_auth_invokes_windows_api_as_expected
188
+ server = Class.new(MockNegotiateServer) do
189
+ def accept_security_context(*args)
190
+ super
191
+ return Windows::Constants::SEC_I_COMPLETE_NEEDED
192
+ end
193
+ end.new
194
+
195
+ assert_nothing_raised{ server.acquire_handle }
196
+ assert_nothing_raised{ server.accept_context(MockSpnegoToken) }
197
+ assert_nothing_raised{ @status=server.complete_authentication }
198
+ assert_equal Windows::Constants::SEC_E_OK, @status
199
+
200
+ args = server.retrieve_state(:cat)
201
+ assert_equal 2, args.length
202
+ assert_kind_of Windows::Structs::CtxtHandle, args[0], "unexpected ph_context"
203
+ assert_equal MockContextHandle, args[0].marshal_dump
204
+ assert_kind_of Windows::Structs::SecBufferDesc, args[1], "unexpected p_output"
205
+ assert_equal MockSecBufferContent, args[1].marshal_dump
206
+ end
207
+
208
+ def test_complet_auth_raises_when_windows_api_returns_failed_status
209
+ server = Class.new(MockNegotiateServer) do
210
+ def accept_security_context(*args)
211
+ super
212
+ return Windows::Constants::SEC_I_COMPLETE_NEEDED
213
+ end
214
+ def complete_auth_token(*args)
215
+ capture_state(:cat,args)
216
+ return Windows::Constants::SEC_E_INVALID_HANDLE
217
+ end
218
+ end.new
219
+
220
+ assert_nothing_raised{ server.acquire_handle }
221
+ assert_nothing_raised{ server.accept_context(MockSpnegoToken) }
222
+ assert_raises(SecurityStatusError){ server.complete_authentication }
223
+ end
224
+
225
+ def test_query_attributes_invokes_windows_api_as_expected
226
+ server = Class.new(MockNegotiateServer).new
227
+ assert_nothing_raised{ server.acquire_handle }
228
+ assert_nothing_raised{ server.accept_context(MockSpnegoToken) }
229
+ assert_nothing_raised{ @status = server.query_attributes }
230
+ assert_equal Windows::Constants::SEC_E_OK, @status
231
+
232
+ args = server.retrieve_state(:qca)
233
+ assert_equal 3, args.length
234
+ assert_kind_of Windows::Structs::CtxtHandle, args[0], "unexpected ph_context"
235
+ assert_equal MockContextHandle, args[0].marshal_dump
236
+ assert_equal Windows::Constants::SECPKG_ATTR_NAMES, args[1], "unexpected ul_attribute"
237
+ assert_kind_of Windows::Structs::SecPkgContext_Names, args[2], "unexpected p_buffer"
238
+
239
+ assert_equal "jimmy", server.username
240
+ assert_equal "jes.local", server.domain
241
+
242
+ # Need to grap this address for test below
243
+ expected_fcb_ptr = args[2].to_username_ptr
244
+
245
+ args = server.retrieve_state(:fcb)
246
+ assert_equal 1, args.length
247
+ assert_equal expected_fcb_ptr, args[0], "unexpected pv_contextbuffer"
248
+ end
249
+
250
+ def test_query_attributes_without_domain_in_user_string
251
+ server = Class.new(MockNegotiateServer) do
252
+ def query_context_attributes(*args)
253
+ super
254
+ args[2].marshal_load("jimmy")
255
+ return Windows::Constants::SEC_E_OK
256
+ end
257
+ end.new
258
+ assert_nothing_raised{ server.acquire_handle }
259
+ assert_nothing_raised{ server.accept_context(MockSpnegoToken) }
260
+ assert_nothing_raised{ @status = server.query_attributes }
261
+ assert_equal Windows::Constants::SEC_E_OK, @status
262
+ assert_equal "jimmy", server.username
263
+ assert_equal "", server.domain
264
+ end
265
+
266
+ def test_query_attributes_raises_when_windows_api_returns_failed_status
267
+ server = Class.new(MockNegotiateServer) do
268
+ def query_context_attributes(*args)
269
+ capture_state(:asc, args)
270
+ return Windows::Constants::SEC_E_INVALID_HANDLE
271
+ end
272
+ end.new
273
+ assert_raises(SecurityStatusError){ server.query_attributes }
274
+ end
275
+
276
+ def test_free_handles_raises_when_free_handle_returns_failed_status
277
+ server = Class.new(MockNegotiateServer) do
278
+ def free_credentials_handle(*args)
279
+ capture_state(:fch,args)
280
+ return Windows::Constants::SEC_E_INVALID_HANDLE
281
+ end
282
+ end.new
283
+
284
+ assert_nothing_raised{ server.acquire_handle }
285
+ assert_nothing_raised{ server.accept_context(MockSpnegoToken) }
286
+ assert_nothing_raised{ server.query_attributes }
287
+ assert_raises(SecurityStatusError){ server.free_handles }
288
+ end
289
+
290
+ def test_both_handles_freed_when_free_handles_raises
291
+ server = Class.new(MockNegotiateServer) do
292
+ def delete_security_context(*args)
293
+ capture_state(:dsc, args)
294
+ return Windows::Constants::SEC_E_INVALID_TOKEN
295
+ end
296
+ end.new
297
+
298
+ assert_nothing_raised{ server.acquire_handle }
299
+ assert_nothing_raised{ server.accept_context(MockSpnegoToken) }
300
+
301
+ refute_nil server.instance_variable_get(:@context_handle)
302
+ refute_nil server.instance_variable_get(:@credentials_handle)
303
+
304
+ assert_raises{ server.free_handles }
305
+
306
+ assert_nil server.instance_variable_get(:@context_handle)
307
+ assert_nil server.instance_variable_get(:@credentials_handle)
308
+ end
309
+
310
+ def test_http_authenticate
311
+ server = Class.new(MockNegotiateServer) do
312
+ def accept_security_context(*args)
313
+ status = self.retrieve_state(:asc) ?
314
+ Windows::Constants::SEC_I_COMPLETE_NEEDED :
315
+ Windows::Constants::SEC_I_CONTINUE_NEEDED
316
+ super
317
+ return status
318
+ end
319
+ end.new
320
+
321
+ counter = 0
322
+ authenticated = false
323
+ until( authenticated )
324
+ header = "#{Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE} #{Base64.strict_encode64(MockSpnegoToken)}"
325
+ authenticated = server.http_authenticate(header) do |hdr|
326
+ counter += 1
327
+ fail "loop failed to complete in a reasonable iteration count" if counter > 3
328
+ assert_base64_http_header(hdr,Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE)
329
+ hdr
330
+ end
331
+ end
332
+
333
+ assert_equal 2, counter
334
+
335
+ assert_server_call_state(server)
336
+ end
337
+
338
+ def test_authenticate
339
+ server = Class.new(MockNegotiateServer) do
340
+ def accept_security_context(*args)
341
+ status = self.retrieve_state(:asc) ?
342
+ Windows::Constants::SEC_I_COMPLETE_NEEDED :
343
+ Windows::Constants::SEC_I_CONTINUE_NEEDED
344
+ super
345
+ return status
346
+ end
347
+ end.new
348
+
349
+ counter = 0
350
+ authenticated = false
351
+ until( authenticated )
352
+ client_msg = MockSpnegoToken
353
+ authenticated = server.authenticate(client_msg) do |msg|
354
+ counter += 1
355
+ fail "loop failed to complete in a reasonable iteration count" if counter > 3
356
+ assert_equal MockSecBufferContent,msg
357
+ msg
358
+ end
359
+ end
360
+
361
+ assert_equal 2, counter
362
+
363
+ assert_server_call_state(server)
364
+ end
365
+
366
+ def teardown
367
+ @server = nil
368
+ end
369
+ end
370
+
371
+ class MockNegotiateServer < Win32::SSPI::Negotiate::Server
372
+ def acquire_credentials_handle(*args)
373
+ s_args = retrieve_state(:ach) || Array.new
374
+ s_args << args
375
+ capture_state(:ach,s_args.flatten)
376
+ # this api should return a credential handle in arg[7] and a timestamp in arg[8]
377
+ args[7].marshal_load(TC_Win32_SSPI_Negotiate_Server::MockCredentialHandle)
378
+ args[8].marshal_load(TC_Win32_SSPI_Negotiate_Server::MockTimeStamp)
379
+ return Windows::Constants::SEC_E_OK
380
+ end
381
+
382
+ def accept_security_context(*args)
383
+ capture_state(:asc, args)
384
+ # this api should return a new context, p_output, context attr and timestamp
385
+ args[5].marshal_load(TC_Win32_SSPI_Negotiate_Server::MockContextHandle)
386
+ args[6].marshal_load(TC_Win32_SSPI_Negotiate_Server::MockSecBufferContent)
387
+ args[7].write_ulong(TC_Win32_SSPI_Negotiate_Server::ContextAttr)
388
+ args[8].marshal_load(TC_Win32_SSPI_Negotiate_Server::MockTimeStamp)
389
+ return Windows::Constants::SEC_E_OK
390
+ end
391
+
392
+ def complete_auth_token(*args)
393
+ capture_state(:cat,args)
394
+ return Windows::Constants::SEC_E_OK
395
+ end
396
+
397
+ def query_context_attributes(*args)
398
+ capture_state(:qca,args)
399
+ args[2].marshal_load("jes.local\\jimmy")
400
+ return Windows::Constants::SEC_E_OK
401
+ end
402
+
403
+ def delete_security_context(*args)
404
+ capture_state(:dsc,args)
405
+ return Windows::Constants::SEC_E_OK
406
+ end
407
+
408
+ def free_credentials_handle(*args)
409
+ capture_state(:fch,args)
410
+ return Windows::Constants::SEC_E_OK
411
+ end
412
+
413
+ def free_context_buffer(*args)
414
+ capture_state(:fcb,args)
415
+ return Windows::Constants::SEC_E_OK
416
+ end
417
+
418
+ def capture_state(key,value)
419
+ self.class.capture_state(key,value)
420
+ end
421
+
422
+ def retrieve_state(key)
423
+ self.class.retrieve_state(key)
424
+ end
425
+
426
+ def self.state
427
+ @state ||= Hash.new
428
+ end
429
+
430
+ def self.capture_state(key,value)
431
+ state[key] = value
432
+ end
433
+
434
+ def self.retrieve_state(key)
435
+ state[key]
436
+ end
437
+
438
+ def self.clear_state
439
+ state.clear
440
+ end
441
+ end
@@ -0,0 +1,100 @@
1
+ ########################################################################
2
+ # Tests for the Windows::API::create_xxx methods
3
+ ########################################################################
4
+ require 'test-unit'
5
+ require 'win32/sspi/api/common'
6
+
7
+ class TC_Win32_SSPI_Negotiate_Client < Test::Unit::TestCase
8
+ include Win32::SSPI::API::Common
9
+
10
+ def test_create_sec_winnt_auth_identity
11
+ user,domain,password = %w[tom gas yadayadayada]
12
+ identity = create_sec_winnt_auth_identity(user,domain,password)
13
+ assert_equal user, identity[:User].read_string
14
+ assert_equal user.length, identity[:UserLength]
15
+ assert_equal user, identity.user_to_ruby_s
16
+ assert_equal domain, identity[:Domain].read_string
17
+ assert_equal domain.length, identity[:DomainLength]
18
+ assert_equal domain, identity.domain_to_ruby_s
19
+ assert_equal password, identity[:Password].read_string
20
+ assert_equal password.length, identity[:PasswordLength]
21
+ assert_equal SEC_WINNT_AUTH_IDENTITY_ANSI, identity[:Flags]
22
+ end
23
+
24
+ def test_create_credhandle
25
+ h_credential = create_credhandle(777,888)
26
+ assert_equal 777, h_credential[:dwLower].read_ulong
27
+ assert_equal 888, h_credential[:dwUpper].read_ulong
28
+ assert_equal [777,888], h_credential.marshal_dump
29
+ end
30
+
31
+ def test_create_ctxhandle
32
+ h_ctx = create_ctxhandle(777,888)
33
+ assert_equal 777, h_ctx[:dwLower].read_ulong
34
+ assert_equal 888, h_ctx[:dwUpper].read_ulong
35
+ assert_equal [777,888], h_ctx.marshal_dump
36
+ end
37
+
38
+ def test_create_timestamp
39
+ ts = create_timestamp(0xFFAA8811,0x00000044)
40
+ assert_equal 0xFFAA8811, ts[:dwLowDateTime]
41
+ assert_equal 0x00000044, ts[:dwHighDateTime]
42
+ end
43
+
44
+ def test_create_secbuffer
45
+ content = "test content"
46
+ buffer = create_secbuffer(content)
47
+ assert_equal content, buffer[:pvBuffer].read_string
48
+ assert_equal content.length, buffer[:cbBuffer]
49
+ assert_equal SECBUFFER_TOKEN, buffer[:BufferType]
50
+
51
+ buffer = create_secbuffer
52
+ assert_not_nil buffer[:pvBuffer]
53
+ assert_equal TOKENBUFSIZE, buffer[:cbBuffer]
54
+ assert_equal SECBUFFER_TOKEN, buffer[:BufferType]
55
+ end
56
+
57
+ def test_create_secbufferdesc
58
+ content = "test content"
59
+ buffer = create_secbuffer(content)
60
+ bufdesc = create_secbufferdesc(buffer)
61
+ assert_equal FFI::Pointer.new(buffer.pointer), bufdesc[:pBuffers]
62
+ assert_equal 1, bufdesc[:cBuffers]
63
+ assert_equal SECBUFFER_VERSION, bufdesc[:ulVersion]
64
+ end
65
+
66
+ def test_create_secpkg_context_names
67
+ name ="test"
68
+ spkg_names = create_secpkg_context_names(name)
69
+ assert_equal name, spkg_names[:sUserName].read_string
70
+ end
71
+
72
+ def test_to_ruby_s_accessors
73
+ content = "test content"
74
+ buffer = create_secbuffer(content)
75
+ assert_equal content, buffer.to_ruby_s
76
+
77
+ # FIXME: something un-intuitive about this ...
78
+ buffer = create_secbuffer
79
+ assert_equal TOKENBUFSIZE, buffer.to_ruby_s.length
80
+
81
+ name ="test"
82
+ spkg_names = create_secpkg_context_names(name)
83
+ assert_equal name, spkg_names.to_ruby_s
84
+
85
+ spkg_names = create_secpkg_context_names
86
+ assert_nil spkg_names.to_ruby_s
87
+ end
88
+
89
+ def test_construct_de_construct_http_header
90
+ srand(Time.now.to_i)
91
+ tokenA = (1..40).inject([]) {|m,r| m << rand(255)}.join('')
92
+ header = construct_http_header(Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE, tokenA)
93
+ assert_equal Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE, header[0,9]
94
+ assert_match( /\A\p{Print}+\Z/, header)
95
+
96
+ auth_type, tokenB = de_construct_http_header(header)
97
+ assert_equal Win32::SSPI::API::Common::AUTH_TYPE_NEGOTIATE, auth_type
98
+ assert_equal tokenA, tokenB
99
+ end
100
+ end