File: SspiHelper.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (372 lines) | stat: -rw-r--r-- 11,599 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.IdentityModel
{
    using System.Runtime.InteropServices;
    using System.Security.Authentication.ExtendedProtection;
    using System.Security.Cryptography.X509Certificates;

    internal enum CredentialUse
    {
        Inbound = 0x1,
        Outbound = 0x2,
        Both = 0x3,
    }

    internal enum Endianness
    {
        Network = 0x00,
        Native = 0x10,
    }

    internal enum CertificateEncoding
    {
        Zero = 0,
        X509AsnEncoding = unchecked((int)0x00000001),
        X509NdrEncoding = unchecked((int)0x00000002),
        Pkcs7AsnEncoding = unchecked((int)0x00010000),
        Pkcs7NdrEncoding = unchecked((int)0x00020000),
        AnyAsnEncoding = X509AsnEncoding | Pkcs7AsnEncoding
    }

    internal enum BufferType
    {
        Empty = 0x00,
        Data = 0x01,
        Token = 0x02,
        Parameters = 0x03,
        Missing = 0x04,
        Extra = 0x05,
        Trailer = 0x06,
        Header = 0x07,
        Padding = 0x09,
        Stream = 0x0A,
        ChannelBindings = 0x0E,
    }

    internal enum SecurityStatus
    {
        OK = 0x00000000,
        OutOfMemory = unchecked((int)0x80090300),
        InvalidHandle = unchecked((int)0x80090301),
        Unsupported = unchecked((int)0x80090302),
        TargetUnknown = unchecked((int)0x80090303),
        InternalError = unchecked((int)0x80090304),
        PackageNotFound = unchecked((int)0x80090305),
        NotOwner = unchecked((int)0x80090306),
        CannotInstall = unchecked((int)0x80090307),
        InvalidToken = unchecked((int)0x80090308),
        LogonDenied = unchecked((int)0x8009030C),
        UnknownCredential = unchecked((int)0x8009030D),
        NoCredentials = unchecked((int)0x8009030E),
        MessageAltered = unchecked((int)0x8009030F),

        ContinueNeeded = unchecked((int)0x00090312),
        CompleteNeeded = unchecked((int)0x00090313),
        CompAndContinue = unchecked((int)0x00090314),
        ContextExpired = unchecked((int)0x00090317),
        IncompleteMessage = unchecked((int)0x80090318),
        IncompleteCred = unchecked((int)0x80090320),
        BufferNotEnough = unchecked((int)0x80090321),
        WrongPrincipal = unchecked((int)0x80090322),
        UntrustedRoot = unchecked((int)0x80090325),
        UnknownCertificate = unchecked((int)0x80090327),

        CredentialsNeeded = unchecked((int)0x00090320),
        Renegotiate = unchecked((int)0x00090321),
    }

    internal enum ContextAttribute
    {
        //
        // look into <sspi.h> and <schannel.h>
        //
        Sizes = 0x00,
        Names = 0x01,
        Lifespan = 0x02,
        DceInfo = 0x03,
        StreamSizes = 0x04,
        //KeyInfo             = 0x05, must not be used, see ConnectionInfo instead
        Authority = 0x06,
        // SECPKG_ATTR_PROTO_INFO          = 7,
        // SECPKG_ATTR_PASSWORD_EXPIRY     = 8,
        SessionKey = 0x09,
        PackageInfo = 0x0A,
        // SECPKG_ATTR_USER_FLAGS          = 11,
        NegotiationInfo = 0x0C,
        // SECPKG_ATTR_NATIVE_NAMES        = 13,
        // SECPKG_ATTR_FLAGS               = 14,
        Flags = 0x0E,
        // SECPKG_ATTR_USE_VALIDATED       = 15,
        // SECPKG_ATTR_CREDENTIAL_NAME     = 16,
        // SECPKG_ATTR_TARGET_INFORMATION  = 17,
        // SECPKG_ATTR_ACCESS_TOKEN        = 18,
        // SECPKG_ATTR_TARGET              = 19,
        // SECPKG_ATTR_AUTHENTICATION_ID   = 20,
        // SECPKG_ATTR_CLIENT_SPECIFIED_TARGET 27
        SpecifiedTarget = 0x1B,
        RemoteCertificate = 0x53,
        LocalCertificate = 0x54,
        RootStore = 0x55,
        IssuerListInfoEx = 0x59,
        ConnectionInfo = 0x5A,
        EapKey = 0x5B
    }

    internal enum CredentialStatus
    {
        InValidParameter = unchecked((int)0x57),
        NoSuchPackage = unchecked((int)0x554),
        NotSupported = unchecked((int)0x32),
        Cancelled = unchecked((int)0x4C7),
        Success = unchecked((int)0x0),
    }

    [StructLayout(LayoutKind.Sequential)]
    internal unsafe struct SecurityBufferStruct
    {
        public int count;
        public BufferType type;
        public IntPtr token;

        public static readonly int Size = sizeof(SecurityBufferStruct);
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    internal struct AuthIdentityEx
    {
        // see SEC_WINNT_AUTH_IDENTITY_EX
        internal int Version;

        internal int Length;

        internal string UserName;

        internal int UserNameLength;

        internal string Domain;

        internal int DomainLength;

        internal string Password;

        internal int PasswordLength;

        internal int Flags;

        internal string PackageList;

        internal int PackageListLength;

        // sspi.h: #define SEC_WINNT_AUTH_IDENTITY_VERSION 0x200
        static readonly int WinNTAuthIdentityVersion = 0x200;

        internal AuthIdentityEx(string userName, string password, string domain, params string[] additionalPackages)
        {
            Version = WinNTAuthIdentityVersion;
            Length = Marshal.SizeOf(typeof(AuthIdentityEx));
            UserName = userName;
            UserNameLength = userName == null ? 0 : userName.Length;
            Password = password;
            PasswordLength = password == null ? 0 : password.Length;
            Domain = domain;
            DomainLength = domain == null ? 0 : domain.Length;

            // Flags are 2 for Unicode and 1 for ANSI. We use 2 on NT 
            Flags = 2;

            if (null == additionalPackages)
            {
                PackageList = null;
                PackageListLength = 0;
            }
            else
            {
                PackageList = String.Join(",", additionalPackages);
                PackageListLength = PackageList.Length;
            }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct SecureCredential
    {
        /*
        typedef struct _SCHANNEL_CRED
        {
            DWORD           dwVersion;      // always SCHANNEL_CRED_VERSION
            DWORD           cCreds;
            PCCERT_CONTEXT *paCred;
            HCERTSTORE      hRootStore;

            DWORD           cMappers;
            struct _HMAPPER **aphMappers;

            DWORD           cSupportedAlgs;
            ALG_ID *        palgSupportedAlgs;

            DWORD           grbitEnabledProtocols;
            DWORD           dwMinimumCipherStrength;
            DWORD           dwMaximumCipherStrength;
            DWORD           dwSessionLifespan;
            DWORD           dwFlags;
            DWORD           reserved;
        } SCHANNEL_CRED, *PSCHANNEL_CRED;
        */
        public const int CurrentVersion = 0x4;

        public int version;
        public int cCreds;

        // ptr to an array of pointers
        // Cannot convert it to SafeHandle because it gets wrapped with another pointer
        // right before native AcquireCredentialsHandle call
        public IntPtr certContextArray;

        private IntPtr rootStore; // == always null, OTHERWISE NOT RELIABLE
        public int cMappers;
        private IntPtr phMappers; // == always null, OTHERWISE NOT RELIABLE
        public int cSupportedAlgs;
        private IntPtr palgSupportedAlgs; // == always null, OTHERWISE NOT RELIABLE
        public SchProtocols grbitEnabledProtocols;
        public int dwMinimumCipherStrength;
        public int dwMaximumCipherStrength;
        public int dwSessionLifespan;
        public SecureCredential.Flags dwFlags;
        public int reserved;

        [Flags]
        public enum Flags
        {
            Zero = 0,
            NoSystemMapper = 0x02,
            NoNameCheck = 0x04,
            ValidateManual = 0x08,
            NoDefaultCred = 0x10,
            ValidateAuto = 0x20
        }

        public SecureCredential(int version, X509Certificate2 certificate,
            SecureCredential.Flags flags, SchProtocols protocols)
        {
            //Setting default values
            rootStore = phMappers = palgSupportedAlgs = certContextArray = IntPtr.Zero;
            cCreds = cMappers = cSupportedAlgs = 0;
            dwMinimumCipherStrength = dwMaximumCipherStrength = 0;
            dwSessionLifespan = reserved = 0;

            this.version = version;
            dwFlags = flags;
            grbitEnabledProtocols = protocols;
            if (certificate != null)
            {
                certContextArray = certificate.Handle;
                cCreds = 1;
            }
        }
    } // SecureCredential

    static class IntPtrHelper
    {
        private const string KERNEL32 = "kernel32.dll";

        //internal static bool IsZero(IntPtr a) 
        //{
        //    return ((long) a)==0;
        //}

        //internal static IntPtr Add(IntPtr a, IntPtr b) 
        //{
        //    return (IntPtr) ((long) a + (long) b);
        //}

        //internal static IntPtr Add(IntPtr a, long b) 
        //{
        //    return (IntPtr) ((long) a + b);
        //}

        //internal static IntPtr Add(long a, IntPtr b) 
        //{
        //    return (IntPtr) (a + (long) b);
        //}

        internal static IntPtr Add(IntPtr a, int b)
        {
            return (IntPtr)((long)a + (long)b);
        }

        //internal static IntPtr Add(int a, IntPtr b) 
        //{
        //    return (IntPtr) ((long) a + (long) b);
        //}
    }

    [StructLayout(LayoutKind.Sequential)]
    internal unsafe class SecurityBufferDescriptor
    {
        /*
        typedef struct _SecBufferDesc {
            ULONG        ulVersion;
            ULONG        cBuffers;
            PSecBuffer   pBuffers;
        } SecBufferDesc, * PSecBufferDesc;
        */
        public readonly int Version;
        public readonly int Count;
        public void* UnmanagedPointer;

        public SecurityBufferDescriptor(int count)
        {
            Version = 0;
            Count = count;
            UnmanagedPointer = null;
        }
    } // SecurityBufferDescriptor

    internal class SecurityBuffer
    {
        /*
        typedef struct _SecBuffer {
            ULONG        cbBuffer;
            ULONG        BufferType;
            PVOID        pvBuffer;
        } SecBuffer, *PSecBuffer;
        */
        public int size;
        public BufferType type;
        public byte[] token;
        public int offset;
        public SafeHandle unmanagedToken;

        public SecurityBuffer(byte[] data, int offset, int size, BufferType tokentype)
        {
            this.offset = offset;
            this.size = (data == null) ? 0 : size;
            this.type = tokentype;
            this.token = data;
        }

        public SecurityBuffer(byte[] data, BufferType tokentype)
        {
            this.size = (data == null) ? 0 : data.Length;
            this.type = tokentype;
            this.token = data;
        }

        public SecurityBuffer(int size, BufferType tokentype)
        {
            this.size = size;
            this.type = tokentype;
            this.token = size == 0 ? null : DiagnosticUtility.Utility.AllocateByteArray(size);
        }

        public SecurityBuffer(ChannelBinding channelBinding)
        {
            this.size = channelBinding.Size;
            this.type = BufferType.ChannelBindings;
            this.unmanagedToken = channelBinding;
        }
    }
}