1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_HTTP_MOCK_SSPI_LIBRARY_WIN_H_
6#define NET_HTTP_MOCK_SSPI_LIBRARY_WIN_H_
7#pragma once
8
9#include <list>
10#include <set>
11
12#include "net/http/http_auth_sspi_win.h"
13
14namespace net {
15
16// The MockSSPILibrary class is intended for unit tests which want to bypass
17// the system SSPI library calls.
18class MockSSPILibrary : public SSPILibrary {
19 public:
20  MockSSPILibrary();
21  virtual ~MockSSPILibrary();
22
23  // TODO(cbentzel): Only QuerySecurityPackageInfo and FreeContextBuffer
24  //                 are properly handled currently.
25  // SSPILibrary methods:
26  virtual SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal,
27                                                   LPWSTR pszPackage,
28                                                   unsigned long fCredentialUse,
29                                                   void* pvLogonId,
30                                                   void* pvAuthData,
31                                                   SEC_GET_KEY_FN pGetKeyFn,
32                                                   void* pvGetKeyArgument,
33                                                   PCredHandle phCredential,
34                                                   PTimeStamp ptsExpiry);
35  virtual SECURITY_STATUS InitializeSecurityContext(PCredHandle phCredential,
36                                                    PCtxtHandle phContext,
37                                                    SEC_WCHAR* pszTargetName,
38                                                    unsigned long fContextReq,
39                                                    unsigned long Reserved1,
40                                                    unsigned long TargetDataRep,
41                                                    PSecBufferDesc pInput,
42                                                    unsigned long Reserved2,
43                                                    PCtxtHandle phNewContext,
44                                                    PSecBufferDesc pOutput,
45                                                    unsigned long* contextAttr,
46                                                    PTimeStamp ptsExpiry);
47  virtual SECURITY_STATUS QuerySecurityPackageInfo(LPWSTR pszPackageName,
48                                                   PSecPkgInfoW *pkgInfo);
49  virtual SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential);
50  virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext);
51  virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer);
52
53  // Establishes an expectation for a |QuerySecurityPackageInfo()| call.
54  //
55  // Each expectation established by |ExpectSecurityQueryPackageInfo()| must be
56  // matched by a call to |QuerySecurityPackageInfo()| during the lifetime of
57  // the MockSSPILibrary. The |expected_package| argument must equal the
58  // |*pszPackageName| argument to |QuerySecurityPackageInfo()| for there to be
59  // a match. The expectations also establish an explicit ordering.
60  //
61  // For example, this sequence will be successful.
62  //   MockSSPILibrary lib;
63  //   lib.ExpectQuerySecurityPackageInfo(L"NTLM", ...)
64  //   lib.ExpectQuerySecurityPackageInfo(L"Negotiate", ...)
65  //   lib.QuerySecurityPackageInfo(L"NTLM", ...)
66  //   lib.QuerySecurityPackageInfo(L"Negotiate", ...)
67  //
68  // This sequence will fail since the queries do not occur in the order
69  // established by the expectations.
70  //   MockSSPILibrary lib;
71  //   lib.ExpectQuerySecurityPackageInfo(L"NTLM", ...)
72  //   lib.ExpectQuerySecurityPackageInfo(L"Negotiate", ...)
73  //   lib.QuerySecurityPackageInfo(L"Negotiate", ...)
74  //   lib.QuerySecurityPackageInfo(L"NTLM", ...)
75  //
76  // This sequence will fail because there were not enough queries.
77  //   MockSSPILibrary lib;
78  //   lib.ExpectQuerySecurityPackageInfo(L"NTLM", ...)
79  //   lib.ExpectQuerySecurityPackageInfo(L"Negotiate", ...)
80  //   lib.QuerySecurityPackageInfo(L"NTLM", ...)
81  //
82  // |response_code| is used as the return value for
83  // |QuerySecurityPackageInfo()|. If |response_code| is SEC_E_OK,
84  // an expectation is also set for a call to |FreeContextBuffer()| after
85  // the matching |QuerySecurityPackageInfo()| is called.
86  //
87  // |package_info| is assigned to |*pkgInfo| in |QuerySecurityPackageInfo|.
88  // The lifetime of |*package_info| should last at least until the matching
89  // |QuerySecurityPackageInfo()| is called.
90  void ExpectQuerySecurityPackageInfo(const std::wstring& expected_package,
91                                      SECURITY_STATUS response_code,
92                                      PSecPkgInfoW package_info);
93
94 private:
95  struct PackageQuery {
96    std::wstring expected_package;
97    SECURITY_STATUS response_code;
98    PSecPkgInfoW package_info;
99  };
100
101  // expected_package_queries contains an ordered list of expected
102  // |QuerySecurityPackageInfo()| calls and the return values for those
103  // calls.
104  std::list<PackageQuery> expected_package_queries_;
105
106  // Set of packages which should be freed.
107  std::set<PSecPkgInfoW> expected_freed_packages_;
108};
109
110}  // namespace net
111
112#endif  // NET_HTTP_MOCK_SSPI_LIBRARY_WIN_H_
113