ntlmssp.h
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ntlmssp.h - NT LM security headers */
  2. /* Copyright (c) 1998 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01p,13jul01,dbs  fix up includes
  7. 01o,18sep00,nel  SPR#33730. Merge T2 OPC fixes into T3 branch.
  8. 01n,09dec99,nel  Mods to DES routines
  9. 01m,05aug99,dbs  add mutex around channel-map
  10. 01l,19jul99,dbs  add more knowledge of response header layout
  11. 01k,09jul99,dbs  use new filenames
  12. 01j,06jul99,dbs  add accessors
  13. 01i,29jun99,dbs  add more details of protocol
  14. 01h,28jun99,dbs  remove defaultInstance method
  15. 01g,24jun99,dbs  implement more of NTLM protocol
  16. 01f,23jun99,dbs  create class for NTLM authn
  17. 01e,26may99,dbs  add extra magic number
  18. 01d,26may99,dbs  adding more knowledge of protocol
  19. 01c,10may99,dbs  remove refs to rpcDceLib
  20. 01b,11mar99,dbs  add more hooks for authentication
  21. 01a,15feb99,dbs  created
  22. */
  23. /*
  24.   DESCRIPTION:
  25.   This file summarises what we know about the NTLMSSP security
  26.   provider on Windows NT. The format of the packets is 'reverse
  27.   engineered' from the wire, and assumptions have been made about the
  28.   contents of some fields.
  29.   The structure-field 'ntlmssp[8]' contains the 8 characters making up
  30.   the NULL-terminated ASCII string "NTLMSSP". The sequence field
  31.   contains a number which increments on every transaction.
  32.   The 
  33. */
  34. #ifndef __INCntlmssp_h
  35. #define __INCntlmssp_h
  36. #include <stdlib.h>
  37. #include "rpcDceProto.h"
  38. #include "dcomProxy.h"
  39. #include "RpcPdu.h"
  40. #include "private/comMisc.h"
  41. //////////////////////////////////////////////////////////////////////////
  42. //
  43. // Public 'C' globals which can be set by Project-Facility
  44. // configuration...
  45. //
  46. extern "C" DWORD g_defaultAuthnLevel;
  47. extern "C" DWORD g_defaultImpLevel;
  48. //////////////////////////////////////////////////////////////////////////
  49. //
  50. // A simple string-like structure to keep a username in...
  51. //
  52. struct username_t
  53.     {
  54.     char    txt [32];
  55.     username_t (const char* s)
  56.         { strncpy (txt, s, sizeof(txt)); }
  57.     username_t (const username_t& x)
  58.         { *this = x; }
  59.     bool operator== (const username_t& x)
  60.         { return (strcmp (txt, x.txt) == 0); }
  61.     bool operator< (const username_t& x) const
  62.         { return (strcmp (txt, x.txt) < 0); }
  63.     username_t& operator= (const username_t& x)
  64.         { strncpy (txt, x.txt, sizeof(txt)); return *this; }
  65.         
  66.     };
  67.     
  68. //////////////////////////////////////////////////////////////////////////
  69. //
  70. // NTLMSSP -- a class that encapsulates the NT Lan Manager Security
  71. // Service Provider part of the DCOM protocol. The data-members are
  72. // effectively set by calls to CoInitializeSecurity() and the only
  73. // capabilities supported is EOAC_NONE in that API.
  74. //
  75. class NTLMSSP
  76.     {
  77.   public:
  78.     
  79.     // NTLMSSP ctor -- takes required authn and impersonation levels
  80.     // for this particular instance of NTLMSSP service. The default
  81.     // parameter values result in the defaults from the globals
  82.     // 'g_defaultAuthnLevel' and 'g_defaultImpLevel' being assigned to
  83.     // this instance...
  84.     NTLMSSP
  85. (
  86. DWORD authnLvl = RPC_C_AUTHN_LEVEL_DEFAULT,
  87. DWORD impLvl = RPC_C_IMP_LEVEL_DEFAULT
  88. );
  89.     ~NTLMSSP ();
  90.     // serverBindValidate -- validates auth-trailer of received BIND
  91.     // PDUs when this instance of NTMLSSP is representing the
  92.     // server-side of a connection...
  93.     HRESULT serverBindValidate
  94. (
  95. int channelId,
  96. const RpcPdu& bindPdu,
  97. RpcPdu& reply
  98. );
  99.     // serverRequestValidate -- validates auth-trailer of received
  100.     // REQUEST PDUs when this instance of NTMLSSP is representing the
  101.     // server-side of a connection...
  102.     HRESULT serverRequestValidate
  103. (
  104. int channelId,
  105. const RpcPdu& reqPdu,
  106. RpcPdu& reply
  107. );
  108.     // serverAuth3Validate -- validates incoming auth-trailer in an
  109.     // AUTH3 packet when this instance of NTLMSSP is representing the
  110.     // server-side of a connection.
  111.     HRESULT serverAuth3Validate
  112. (
  113. int channelId,
  114. const RpcPdu& auth3Pdu
  115. );
  116.     // clientAuthnRequestAdd -- adds auth-trailer to an outgoing BIND
  117.     // PDU appropriate to the current level of authentication
  118.     // established for this instance of NTLMSSP...
  119.     HRESULT clientAuthnRequestAdd
  120. (
  121. int  channelId,
  122. RpcPdu& bindPdu
  123. );
  124.     // clientAuthnResponse -- adds auth-trailer to an outgoing AUTH3
  125.     // PDU appropriate to the current level of authentication
  126.     // established for this instance of NTLMSSP...
  127.     HRESULT clientAuthnResponse
  128. (
  129. int  channelId,
  130. const RpcPdu& bindAckPdu,
  131. bool* pbSendAuth3,
  132. RpcPdu& auth3Pdu
  133. );
  134.     // clientAuthn -- adds authn-trailer to client-side request
  135.     // packets, this is just the 'token'...
  136.     HRESULT clientAuthn
  137. (
  138. int  channelId,
  139. RpcPdu& reqPdu
  140. );
  141.     
  142.     // userAdd -- adds a user/password pair to the internal tables...
  143.     static void userAdd (const char* userName, const char* userPasswd);
  144.     // add/remove channel from table...
  145.     void channelAdd (int channelId);
  146.     void channelRemove (int channelId);
  147.     // get status of a channel...
  148.     HRESULT channelStatusGet (int cid)
  149. { return m_channelStatus [cid]; }
  150.     
  151.     // set status of a channel...
  152.     void channelStatusSet (int cid, HRESULT status)
  153. { m_channelStatus [cid] = status; }
  154.     // get current level
  155.     DWORD authnLevel () const
  156. { return m_authnLevel; }
  157.     
  158.   private:
  159.     //////////////////////////////////////////////////////////////////////
  160.     //
  161.     // There are many items in these packet-layouts which are of the
  162.     // same format, namely 2 shorts and a long, where the 2 shorts are
  163.     // the length and max-length (always the same) of a field
  164.     // (measured in bytes), and the long is the offset from the
  165.     // beginning of the 'response' structure to that field. This
  166.     // structure is described in the Samba documentation as a 'UNIHDR'
  167.     // (Unicode String Header).
  168.     //
  169.     struct UNIHDR
  170. {
  171. USHORT len;
  172. USHORT max;
  173. ULONG offset;
  174. };
  175.     //////////////////////////////////////////////////////////////////////
  176.     //
  177.     // request -- client sends this request for authentication, in the
  178.     // auth-trailer of an RPC PDU...
  179.     //
  180.     struct request
  181. {
  182. char ntlmssp [8]; // string "NTLMSSP"
  183. ULONG sequence; // sequence number
  184. ULONG ignored1; // ignored
  185. UNIHDR domainName;
  186. UNIHDR machineName;
  187. char text [1]; // machine+domain names
  188. // e.g. "BUFFYWRS-SWINDON"
  189. };
  190.     //////////////////////////////////////////////////////////////////////
  191.     //
  192.     // challenge -- server responds with this challenge, in the
  193.     // outgoing auth-trailer, in response to a received request...
  194.     //
  195.     struct challenge
  196. {
  197. char ntlmssp [8]; // string "NTLMSSP"
  198. ULONG sequence; // sequence number
  199. ULONG mbz1; // unknown
  200. ULONG magic1; // value is NTLM_MAGIC1
  201. ULONG magic2; // value is NTLM_MAGIC2
  202. char chal [8]; // 8-byte challenge
  203. ULONG mbz2; // unknown
  204. ULONG mbz3; // unknown
  205. };
  206.     enum {
  207. NTLM_MAGIC1 = 0x00000028,
  208. NTLM_MAGIC2_BIND = 0x00108201,
  209. NTLM_MAGIC2_REQ = 0x00008201
  210.     };
  211.     //////////////////////////////////////////////////////////////////////
  212.     //
  213.     // response -- the client then sends this response, which should
  214.     // include the 'response' to the previous challenge, issued by the
  215.     // server. If this response is correct, then the client is
  216.     // authenticated.
  217.     //
  218.     // The fields described in this way are the 2 encrypted blocks,
  219.     // the domain-name, username, and machine-name.
  220.     //
  221.     struct response
  222. {
  223. char ntlmssp [8]; // string "NTLMSSP"
  224. ULONG sequence; // sequence number
  225. UNIHDR block1;
  226. UNIHDR block2;
  227. UNIHDR domainName;
  228. UNIHDR userName;
  229. UNIHDR machineName;
  230. ULONG mbz1; // MBZ
  231. ULONG authLen; // same as auth-len
  232. ULONG magic2; // value same as in BIND
  233. // ...followed by domain-user-machine as wide-string, followed
  234. // by 2 lots of 24-byte encrypted response data, of which the
  235. // first 24-byte block is the NTLM response. When we are
  236. // sending an AUTH3 we put the same into the second block as
  237. // we don't have the mechanism to encrypt whatever is supposed
  238. // to be in there.
  239. };
  240.     HRESULT authTrailerCheck (const RpcPdu&);
  241.     
  242.     void encrypt (const BYTE* pwdHash, const BYTE* challenge, BYTE* p24);    
  243.     static void ndrUnihdr (UNIHDR*, DREP);
  244.     
  245.     struct lmhash
  246. {
  247. BYTE data [16];
  248. };
  249.     enum { TOKEN_LEN=16 };
  250.     
  251.     typedef STL_MAP (username_t, lmhash) USERTABLE;
  252.     typedef STL_MAP (int, HRESULT) STATUSMAP;
  253.     
  254.     DWORD m_authnLevel; // RPC_C_AUTHN_LEVEL_XXX
  255.     DWORD m_impLevel; // RPC_C_IMPL_LEVEL_XXX
  256.     STATUSMAP m_channelStatus; // channel => status
  257.     VxMutex m_mutex; // thread safety for map
  258.     
  259.     static USERTABLE s_userTable; // table of user=>passwd-hash
  260.     static BYTE s_token []; // NT token
  261.     static BYTE s_defaultChallenge [];
  262.     //////////////////////////////////////////////////////////////////////
  263.     // This class implements the Data Encryption Algorithm defined in
  264.     // Federal Information Processing Standards Publication 46, 1977 January 15,
  265.     // Specifications for the Data Encryption Standard. This algorithm is commonly
  266.     // refered to as DES.
  267.     //
  268.     // This code does not implement all DES features. It only implements the
  269.     // parts of the algorithm required by VxDCOM. It only implements an unchained
  270.     // forward DES pass. This means that it can only be used as a hash algorithm
  271.     // for validating Microsoft LAN Manager authentication.
  272.     class DES
  273.         {
  274.         public:
  275.             // 16 bit encrypt using standard LAN Manager key.
  276.             static void encrypt16 (const BYTE * input, BYTE * output)
  277.                 {
  278.                 hash (output, lmKey, input);
  279.                 hash (output + 8, lmKey, input + 7);
  280.                 };
  281.             // 24 bit encyrpt using any key.
  282.             static void encrypt24 (const BYTE * input, const BYTE * key, BYTE * output)
  283.                 {
  284.                 hash (output, key, input);
  285.                 hash (output + 8, key, input + 7);
  286.                 hash (output + 16, key, input + 14);
  287.                 };
  288.         private:
  289.             enum { sRowSize = 4 };
  290.             enum { sColSize = 16 };
  291.             enum { sSize = 8 };
  292.             enum { leftShiftSize = 16 };
  293.             enum { ipSize = 64 };
  294.             enum { ip1Size = 64 };
  295.             enum { pSize = 32 };
  296.             enum { eSize = 48 };
  297.             enum { pc1Size = 56 };
  298.             enum { pc2Size = 48 };
  299.             enum { lmKeySize = 8 };
  300.             enum { keySize = 8 };
  301.             enum { bufferSize = 64 };
  302.             // Permute table using supplied hashing table.
  303.             static void permute
  304.                 (
  305.                 BYTE * output,      /* Output buffer */
  306.                 const BYTE * input, /* Input buffer */
  307.                 const BYTE * table, /* Permute table */ 
  308.                 int n               /* Table size */
  309.                 )
  310.                 {
  311.                 int i;
  312.                 for (i = 0; i < n; i++)
  313.                     output [i] = input [table [i] - 1];
  314.                 }
  315.             // Block left shift.
  316.             static void lshift
  317.                 (
  318.                 unsigned char *p,   // Buffer
  319.                 int count,          // No of bits to shift left
  320.                 int n               // Buffer size
  321.                 )
  322.                 {
  323.                 char output [64];
  324.                 int i;
  325.                 for (i = 0; i < n; i++)
  326.                     output [i] = p [(i + count) % n];
  327.                 for (i=0;i<n;i++)
  328.                     p [i] = output [i];
  329.                 }
  330.             // Standard DES tables as defined in Data Encryption Standard.
  331.             static const BYTE s [sSize][sRowSize][sColSize]; // S1 to S8
  332.             static const BYTE noOfLeftShifts [leftShiftSize];
  333.             static const BYTE ip [ipSize];
  334.             static const BYTE ip1 [ip1Size]; // IP^-1
  335.             static const BYTE p [pSize];
  336.             static const BYTE e [eSize];
  337.             static const BYTE pc1 [pc1Size];
  338.             static const BYTE pc2 [pc2Size];
  339.             // LAN Manager decryption key.
  340.             static const BYTE lmKey [lmKeySize];
  341.             static void hash (BYTE * output, const BYTE * input, const BYTE * key);
  342.             static void dohash (BYTE * output, const BYTE * input, const BYTE * key);
  343.         };
  344.     
  345.     };
  346. #endif