Remote Call Framework 3.0
SspiFilter.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2018, 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.0
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  enum QualityOfProtection
101  {
102  None,
103  Encryption,
104  Integrity
105  };
106 
107  QualityOfProtection getQop();
108 
109  typedef SspiImpersonator Impersonator;
110 
111  Win32CertificatePtr getPeerCertificate();
112 
113  PCtxtHandle getSecurityContext() const;
114 
115  protected:
116 
117  friend class SspiImpersonator;
118 
119  SspiFilter(
120  ClientStub * pClientStub,
121  const tstring & packageName,
122  const tstring & packageList,
123  bool server,
124  bool schannel);
125 
126  SspiFilter(
127  ClientStub * pClientStub,
128  QualityOfProtection qop,
129  ULONG contextRequirements,
130  const tstring & packageName,
131  const tstring & packageList,
132  bool server,
133  bool schannel);
134 
135  SspiFilter(
136  ClientStub * pClientStub,
137  QualityOfProtection qop,
138  ULONG contextRequirements,
139  const tstring & packageName,
140  const tstring & packageList,
141  bool server);
142 
143  enum Event
144  {
145  ReadIssued,
146  WriteIssued,
147  ReadCompleted,
148  WriteCompleted
149  };
150 
151  enum ContextState
152  {
153  AuthContinue,
154  AuthOk,
155  AuthOkAck,
156  AuthFailed
157  };
158 
159  enum State
160  {
161  Ready,
162  Reading,
163  Writing
164  };
165 
166  void setupCredentials(
167  const tstring &userName,
168  const tstring &password,
169  const tstring &domain);
170 
171  void setupCredentialsSchannel();
172 
173  void acquireCredentials(
174  const tstring &userName = RCF_T(""),
175  const tstring &password = RCF_T(""),
176  const tstring &domain = RCF_T(""));
177 
178  void freeCredentials();
179 
180  void init();
181  void deinit();
182  void resetState();
183 
184  void read(
185  const ByteBuffer &byteBuffer,
186  std::size_t bytesRequested);
187 
188  void write(const std::vector<ByteBuffer> &byteBuffers);
189 
190  void onReadCompleted(const ByteBuffer &byteBuffer);
191  void onWriteCompleted(std::size_t bytesTransferred);
192 
193  void handleEvent(Event event);
194  void readBuffer();
195  void writeBuffer();
196 
197  void encryptWriteBuffer();
198  bool decryptReadBuffer();
199 
200  void encryptWriteBufferSchannel();
201  bool decryptReadBufferSchannel();
202 
203  bool completeReadBlock();
204  bool completeWriteBlock();
205  bool completeBlock();
206  void resumeUserIo();
207  void resizeReadBuffer(std::size_t newSize);
208  void resizeWriteBuffer(std::size_t newSize);
209 
210  void shiftReadBuffer();
211  void trimReadBuffer();
212 
213  virtual void handleHandshakeEvent() = 0;
214 
215  protected:
216 
217  ClientStub * mpClientStub;
218 
219  const tstring mPackageName;
220  const tstring mPackageList;
221  QualityOfProtection mQop;
222  ULONG mContextRequirements;
223 
224  bool mHaveContext;
225  bool mHaveCredentials;
226  bool mImplicitCredentials;
227  SecPkgInfo mPkgInfo;
228  CtxtHandle mContext;
229  CredHandle mCredentials;
230 
231  ContextState mContextState;
232  State mPreState;
233  State mPostState;
234  Event mEvent;
235  const bool mServer;
236 
237  ByteBuffer mReadByteBufferOrig;
238  ByteBuffer mWriteByteBufferOrig;
239  std::size_t mBytesRequestedOrig;
240 
241  ByteBuffer mReadByteBuffer;
242  ReallocBufferPtr mReadBufferVectorPtr;
243  char * mReadBuffer;
244  std::size_t mReadBufferPos;
245  std::size_t mReadBufferLen;
246 
247  ByteBuffer mWriteByteBuffer;
248  ReallocBufferPtr mWriteBufferVectorPtr;
249  char * mWriteBuffer;
250  std::size_t mWriteBufferPos;
251  std::size_t mWriteBufferLen;
252 
253  std::vector<ByteBuffer> mByteBuffers;
254  ByteBuffer mTempByteBuffer;
255 
256  const bool mSchannel;
257 
258  std::size_t mMaxMessageLength;
259 
260  // Schannel-specific members.
261  Win32CertificatePtr mLocalCertPtr;
262  Win32CertificatePtr mRemoteCertPtr;
263  CertificateValidationCallback mCertValidationCallback;
264  DWORD mEnabledProtocols;
265  tstring mAutoCertValidation;
266  const std::size_t mReadAheadChunkSize;
267  std::size_t mRemainingDataPos;
268 
269  std::vector<RCF::ByteBuffer> mMergeBufferList;
270  std::vector<char> mMergeBuffer;
271 
272  bool mProtocolChecked;
273 
274  private:
275  bool mLimitRecursion;
276  RecursionState<ByteBuffer, int> mRecursionStateRead;
277  RecursionState<std::size_t, int> mRecursionStateWrite;
278 
279  void onReadCompleted_(const ByteBuffer &byteBuffer);
280  void onWriteCompleted_(std::size_t bytesTransferred);
281 
282  friend class SchannelFilterFactory;
283  };
284 
285  // server filters
286 
287  class RCF_EXPORT SspiServerFilter : public SspiFilter
288  {
289  public:
290  SspiServerFilter(
291  const tstring &packageName,
292  const tstring &packageList,
293  bool schannel = false);
294 
295  private:
296  bool doHandshakeSchannel();
297  bool doHandshake();
298  void handleHandshakeEvent();
299  };
300 
301  class NtlmServerFilter : public SspiServerFilter
302  {
303  public:
304  NtlmServerFilter();
305  int getFilterId() const;
306  };
307 
308  class KerberosServerFilter : public SspiServerFilter
309  {
310  public:
311  KerberosServerFilter();
312  int getFilterId() const;
313  };
314 
315  class NegotiateServerFilter : public SspiServerFilter
316  {
317  public:
318  NegotiateServerFilter(const tstring &packageList);
319  int getFilterId() const;
320  };
321 
322  // filter factories
323 
324  class RCF_EXPORT NtlmFilterFactory : public FilterFactory
325  {
326  public:
327  FilterPtr createFilter(RcfServer & server);
328  int getFilterId();
329  };
330 
331  class KerberosFilterFactory : public FilterFactory
332  {
333  public:
334  FilterPtr createFilter(RcfServer & server);
335  int getFilterId();
336  };
337 
338  class NegotiateFilterFactory : public FilterFactory
339  {
340  public:
341  NegotiateFilterFactory(const tstring &packageList = RCF_T("Kerberos, NTLM"));
342  FilterPtr createFilter(RcfServer & server);
343  int getFilterId();
344  private:
345  tstring mPackageList;
346  };
347 
348  // client filters
349 
350  class SspiClientFilter : public SspiFilter
351  {
352  public:
353  SspiClientFilter(
354  ClientStub * pClientStub,
355  QualityOfProtection qop,
356  ULONG contextRequirements,
357  const tstring & packageName,
358  const tstring & packageList) :
359  SspiFilter(
360  pClientStub,
361  qop,
362  contextRequirements,
363  packageName,
364  packageList,
365  BoolClient)
366  {}
367 
368  SspiClientFilter(
369  ClientStub * pClientStub,
370  QualityOfProtection qop,
371  ULONG contextRequirements,
372  const tstring & packageName,
373  const tstring & packageList,
374  bool schannel) :
375  SspiFilter(
376  pClientStub,
377  qop,
378  contextRequirements,
379  packageName,
380  packageList,
381  BoolClient,
382  schannel)
383  {}
384 
385  private:
386  bool doHandshakeSchannel();
387  bool doHandshake();
388  void handleHandshakeEvent();
389  };
390 
391  class NtlmClientFilter : public SspiClientFilter
392  {
393  public:
394  NtlmClientFilter(
395  ClientStub * pClientStub,
396  QualityOfProtection qop = SspiFilter::Encryption,
397  ULONG contextRequirements
398  = DefaultSspiContextRequirements);
399 
400  int getFilterId() const;
401  };
402 
403  class KerberosClientFilter : public SspiClientFilter
404  {
405  public:
406  KerberosClientFilter(
407  ClientStub * pClientStub,
408  QualityOfProtection qop = SspiFilter::Encryption,
409  ULONG contextRequirements
410  = DefaultSspiContextRequirements);
411 
412  int getFilterId() const;
413  };
414 
415  class NegotiateClientFilter : public SspiClientFilter
416  {
417  public:
418  NegotiateClientFilter(
419  ClientStub * pClientStub,
420  QualityOfProtection qop = SspiFilter::None,
421  ULONG contextRequirements
422  = DefaultSspiContextRequirements);
423 
424 
425  int getFilterId() const;
426  };
427 
428  typedef NtlmClientFilter NtlmFilter;
429  typedef KerberosClientFilter KerberosFilter;
430  typedef NegotiateClientFilter NegotiateFilter;
431 
432 
433  // These SSPI-prefixed typedefs make us compatible with code written for RCF 1.0.
434  typedef NtlmFilter SspiNtlmFilter;
435  typedef KerberosFilter SspiKerberosFilter;
436  typedef NegotiateFilter SspiNegotiateFilter;
437 
438  typedef NtlmServerFilter SspiNtlmServerFilter;
439  typedef KerberosServerFilter SspiKerberosServerFilter;
440  typedef NegotiateServerFilter SspiNegotiateServerFilter;
441  typedef NtlmFilterFactory SspiNtlmFilterFactory;
442  typedef KerberosFilterFactory SspiKerberosFilterFactory;
443  typedef NegotiateFilterFactory SspiNegotiateFilterFactory;
444  typedef NtlmClientFilter SspiNtlmClientFilter;
445  typedef KerberosClientFilter SspiKerberosClientFilter;
446  typedef NegotiateClientFilter SspiNegotiateClientFilter;
447 
448  typedef SspiFilter SspiFilterBase;
449  typedef SspiFilterPtr SspiFilterBasePtr;
450 
451 } // namespace RCF
452 
453 #endif // ! INCLUDE_RCF_SSPIFILTER_HPP
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:69
std::shared_ptr< Win32Certificate > Win32CertificatePtr
Reference counted wrapper for RCF::Win32Certificate.
Definition: RcfFwd.hpp:255
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())...