Remote Call Framework 3.1
SspiFilter.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2019, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 3.1
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_SSPIFILTER_HPP
20 #define INCLUDE_RCF_SSPIFILTER_HPP
21 
22 #include <functional>
23 #include <memory>
24 
25 #include <RCF/ByteBuffer.hpp>
26 #include <RCF/Filter.hpp>
27 #include <RCF/RcfFwd.hpp>
28 #include <RCF/RecursionLimiter.hpp>
29 #include <RCF/Export.hpp>
30 
31 #include <RCF/Tchar.hpp>
32 
33 #ifndef SECURITY_WIN32
34 #define SECURITY_WIN32
35 #endif
36 
37 #include <windows.h>
38 #include <security.h>
39 #include <WinCrypt.h>
40 #include <tchar.h>
41 
42 namespace RCF {
43 
44  static const bool BoolClient = false;
45  static const bool BoolServer = true;
46 
47  static const bool BoolSchannel = true;
48 
49  typedef RCF::tstring tstring;
50 
51  class SspiFilter;
52  class RcfSession;
53  class ClientStub;
54 
55  typedef std::shared_ptr<SspiFilter> SspiFilterPtr;
56 
58  class RCF_EXPORT SspiImpersonator
59  {
60  public:
61  SspiImpersonator(SspiFilterPtr sspiFilterPtr);
62 
64  SspiImpersonator(RcfSession & session);
65 
68 
69  bool impersonate();
70 
72  void revertToSelf() const;
73 
74  private:
75  SspiFilterPtr mSspiFilterPtr;
76  };
77 
78  static const ULONG DefaultSspiContextRequirements =
79  ISC_REQ_REPLAY_DETECT |
80  ISC_REQ_SEQUENCE_DETECT |
81  ISC_REQ_CONFIDENTIALITY |
82  ISC_REQ_INTEGRITY |
83  ISC_REQ_DELEGATE |
84  ISC_REQ_MUTUAL_AUTH;
85 
86  class SchannelClientFilter;
87  typedef SchannelClientFilter SchannelFilter;
88 
89  class SchannelFilterFactory;
90 
91  class Certificate;
92  class Win32Certificate;
93 
94  class RCF_EXPORT SspiFilter : public Filter
95  {
96  public:
97 
98  ~SspiFilter();
99 
100  SspiMessageProtection getQop();
101 
102  typedef SspiImpersonator Impersonator;
103 
104  Win32CertificatePtr getPeerCertificate();
105 
106  PCtxtHandle getSecurityContext() const;
107 
108  protected:
109 
110  friend class SspiImpersonator;
111 
112  SspiFilter(
113  ClientStub * pClientStub,
114  const tstring & packageName,
115  const tstring & packageList,
116  bool server,
117  bool schannel);
118 
119  SspiFilter(
120  ClientStub * pClientStub,
122  ULONG contextRequirements,
123  const tstring & packageName,
124  const tstring & packageList,
125  bool server,
126  bool schannel);
127 
128  SspiFilter(
129  ClientStub * pClientStub,
131  ULONG contextRequirements,
132  const tstring & packageName,
133  const tstring & packageList,
134  bool server);
135 
136  enum Event
137  {
138  ReadIssued,
139  WriteIssued,
140  ReadCompleted,
141  WriteCompleted
142  };
143 
144  enum ContextState
145  {
146  AuthContinue,
147  AuthOk,
148  AuthOkAck,
149  AuthFailed
150  };
151 
152  enum State
153  {
154  Ready,
155  Reading,
156  Writing
157  };
158 
159  void setupCredentials(
160  const tstring &userName,
161  const tstring &password,
162  const tstring &domain);
163 
164  void setupCredentialsSchannel();
165 
166  void acquireCredentials(
167  const tstring &userName = RCF_T(""),
168  const tstring &password = RCF_T(""),
169  const tstring &domain = RCF_T(""));
170 
171  void freeCredentials();
172  void freeContext();
173  void freePackageInfo();
174 
175  void init();
176  void deinit();
177  void resetState();
178 
179  void read(
180  const ByteBuffer &byteBuffer,
181  std::size_t bytesRequested);
182 
183  void write(const std::vector<ByteBuffer> &byteBuffers);
184 
185  void onReadCompleted(const ByteBuffer &byteBuffer);
186  void onWriteCompleted(std::size_t bytesTransferred);
187 
188  void handleEvent(Event event);
189  void readBuffer();
190  void writeBuffer();
191 
192  void encryptWriteBuffer();
193  bool decryptReadBuffer();
194 
195  void encryptWriteBufferSchannel();
196  bool decryptReadBufferSchannel();
197 
198  bool completeReadBlock();
199  bool completeWriteBlock();
200  bool completeBlock();
201  void resumeUserIo();
202  void resizeReadBuffer(std::size_t newSize);
203  void resizeWriteBuffer(std::size_t newSize);
204 
205  void shiftReadBuffer();
206  void trimReadBuffer();
207 
208  virtual void handleHandshakeEvent() = 0;
209 
210  protected:
211 
212  ClientStub * mpClientStub;
213 
214  const tstring mPackageName;
215  const tstring mPackageList;
217  ULONG mContextRequirements;
218 
219  bool mHaveContext;
220  bool mHaveCredentials;
221  bool mImplicitCredentials;
222  SecPkgInfo mPkgInfo;
223  CtxtHandle mContext;
224  CredHandle mCredentials;
225  tstring mUserName;
226 
227  ContextState mContextState;
228  State mPreState;
229  State mPostState;
230  Event mEvent;
231  const bool mServer;
232 
233  ByteBuffer mReadByteBufferOrig;
234  ByteBuffer mWriteByteBufferOrig;
235  std::size_t mBytesRequestedOrig;
236 
237  ByteBuffer mReadByteBuffer;
238  ReallocBufferPtr mReadBufferVectorPtr;
239  char * mReadBuffer;
240  std::size_t mReadBufferPos;
241  std::size_t mReadBufferLen;
242 
243  ByteBuffer mWriteByteBuffer;
244  ReallocBufferPtr mWriteBufferVectorPtr;
245  char * mWriteBuffer;
246  std::size_t mWriteBufferPos;
247  std::size_t mWriteBufferLen;
248 
249  std::vector<ByteBuffer> mByteBuffers;
250  ByteBuffer mTempByteBuffer;
251 
252  const bool mSchannel;
253 
254  std::size_t mMaxMessageLength;
255 
256  // Schannel-specific members.
257  Win32CertificatePtr mLocalCertPtr;
258  Win32CertificatePtr mRemoteCertPtr;
259  CertificateValidationCallback mCertValidationCallback;
260  DWORD mEnabledProtocols;
261  tstring mAutoCertValidation;
262  const std::size_t mReadAheadChunkSize;
263  std::size_t mRemainingDataPos;
264 
265  std::vector<RCF::ByteBuffer> mMergeBufferList;
266  std::vector<char> mMergeBuffer;
267 
268  bool mProtocolChecked;
269 
270  private:
271  bool mLimitRecursion;
272  RecursionState<ByteBuffer, int> mRecursionStateRead;
273  RecursionState<std::size_t, int> mRecursionStateWrite;
274 
275  void onReadCompleted_(const ByteBuffer &byteBuffer);
276  void onWriteCompleted_(std::size_t bytesTransferred);
277 
278  friend class SchannelFilterFactory;
279  };
280 
281  // server filters
282 
283  class RCF_EXPORT SspiServerFilter : public SspiFilter
284  {
285  public:
286  SspiServerFilter(
287  const tstring &packageName,
288  const tstring &packageList,
289  bool schannel = false);
290 
291  private:
292  bool doHandshakeSchannel();
293  bool doHandshake();
294  void handleHandshakeEvent();
295  };
296 
297  class NtlmServerFilter : public SspiServerFilter
298  {
299  public:
300  NtlmServerFilter();
301  int getFilterId() const;
302  };
303 
304  class KerberosServerFilter : public SspiServerFilter
305  {
306  public:
307  KerberosServerFilter();
308  int getFilterId() const;
309  };
310 
311  class NegotiateServerFilter : public SspiServerFilter
312  {
313  public:
314  NegotiateServerFilter(const tstring &packageList);
315  int getFilterId() const;
316  };
317 
318  // filter factories
319 
320  class RCF_EXPORT NtlmFilterFactory : public FilterFactory
321  {
322  public:
323  FilterPtr createFilter(RcfServer & server);
324  int getFilterId();
325  };
326 
327  class KerberosFilterFactory : public FilterFactory
328  {
329  public:
330  FilterPtr createFilter(RcfServer & server);
331  int getFilterId();
332  };
333 
334  class NegotiateFilterFactory : public FilterFactory
335  {
336  public:
337  NegotiateFilterFactory(const tstring &packageList = RCF_T("Kerberos, NTLM"));
338  FilterPtr createFilter(RcfServer & server);
339  int getFilterId();
340  private:
341  tstring mPackageList;
342  };
343 
344  // client filters
345 
346  class SspiClientFilter : public SspiFilter
347  {
348  public:
349  SspiClientFilter(
350  ClientStub * pClientStub,
352  ULONG contextRequirements,
353  const tstring & packageName,
354  const tstring & packageList) :
355  SspiFilter(
356  pClientStub,
357  qop,
358  contextRequirements,
359  packageName,
360  packageList,
361  BoolClient)
362  {}
363 
364  SspiClientFilter(
365  ClientStub * pClientStub,
367  ULONG contextRequirements,
368  const tstring & packageName,
369  const tstring & packageList,
370  bool schannel) :
371  SspiFilter(
372  pClientStub,
373  qop,
374  contextRequirements,
375  packageName,
376  packageList,
377  BoolClient,
378  schannel)
379  {}
380 
381  private:
382  bool doHandshakeSchannel();
383  bool doHandshake();
384  void handleHandshakeEvent();
385  };
386 
387  class NtlmClientFilter : public SspiClientFilter
388  {
389  public:
390  NtlmClientFilter(
391  ClientStub * pClientStub,
392  SspiMessageProtection qop = Smp_Encryption,
393  ULONG contextRequirements
394  = DefaultSspiContextRequirements);
395 
396  int getFilterId() const;
397  };
398 
399  class KerberosClientFilter : public SspiClientFilter
400  {
401  public:
402  KerberosClientFilter(
403  ClientStub * pClientStub,
404  SspiMessageProtection qop = Smp_Encryption,
405  ULONG contextRequirements
406  = DefaultSspiContextRequirements);
407 
408  int getFilterId() const;
409  };
410 
411  class NegotiateClientFilter : public SspiClientFilter
412  {
413  public:
414  NegotiateClientFilter(
415  ClientStub * pClientStub,
417  ULONG contextRequirements
418  = DefaultSspiContextRequirements);
419 
420 
421  int getFilterId() const;
422  };
423 
424  typedef NtlmClientFilter NtlmFilter;
425  typedef KerberosClientFilter KerberosFilter;
426  typedef NegotiateClientFilter NegotiateFilter;
427 
428 
429  // These SSPI-prefixed typedefs make us compatible with code written for RCF 1.0.
430  typedef NtlmFilter SspiNtlmFilter;
431  typedef KerberosFilter SspiKerberosFilter;
432  typedef NegotiateFilter SspiNegotiateFilter;
433 
434  typedef NtlmServerFilter SspiNtlmServerFilter;
435  typedef KerberosServerFilter SspiKerberosServerFilter;
436  typedef NegotiateServerFilter SspiNegotiateServerFilter;
437  typedef NtlmFilterFactory SspiNtlmFilterFactory;
438  typedef KerberosFilterFactory SspiKerberosFilterFactory;
439  typedef NegotiateFilterFactory SspiNegotiateFilterFactory;
440  typedef NtlmClientFilter SspiNtlmClientFilter;
441  typedef KerberosClientFilter SspiKerberosClientFilter;
442  typedef NegotiateClientFilter SspiNegotiateClientFilter;
443 
444  typedef SspiFilter SspiFilterBase;
445  typedef SspiFilterPtr SspiFilterBasePtr;
446 
447 } // namespace RCF
448 
449 #endif // ! INCLUDE_RCF_SSPIFILTER_HPP
SspiMessageProtection
Definition: Enums.hpp:207
Allows the server side of a SSPI-based connection to impersonate the client. Only applicable to conne...
Definition: SspiFilter.hpp:58
Represents a server side session, associated with a client connection.
Definition: RcfSession.hpp:67
Controls the client side of a RCF connection.
Definition: ClientStub.hpp:82
std::shared_ptr< Win32Certificate > Win32CertificatePtr
Reference counted wrapper for RCF::Win32Certificate.
Definition: RcfFwd.hpp:257
std::function< bool(Certificate *)> CertificateValidationCallback
Describes user-provided callback functions for validating a certificate.
Definition: RcfFwd.hpp:114
RCF_EXPORT bool deinit()
Reference-counted deinitialization of RCF library. For actual deinitialization to take place...
Represents an in-memory certificate, either from a remote peer or loaded from a local certificate sto...
Definition: Win32Certificate.hpp:38
Provides RCF server-side functionality.
Definition: RcfServer.hpp:54
Definition: ByteBuffer.hpp:40
Definition: AmiIoHandler.hpp:24
Base class for all RCF certificate classes.
Definition: Certificate.hpp:30
RCF_EXPORT bool init(RcfConfigT *=nullptr)
Reference-counted initialization of RCF library. May be called multiple times (see deinit())...
Messages are sent in clear text.
Definition: Enums.hpp:210