Added tests for Task.WhenAll w/ empty list
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Ntlm / Type1Message.cs
1 //
2 // Mono.Security.Protocol.Ntlm.Type1Message - Negotiation
3 //
4 // Author:
5 //      Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 //
10 // References
11 // a.   NTLM Authentication Scheme for HTTP, Ronald Tschalär
12 //      http://www.innovation.ch/java/ntlm.html
13 // b.   The NTLM Authentication Protocol, Copyright © 2003 Eric Glass
14 //      http://davenport.sourceforge.net/ntlm.html
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System;
37 using System.Globalization;
38 using System.Text;
39
40 namespace Mono.Security.Protocol.Ntlm {
41
42         public class Type1Message : MessageBase {
43
44                 private string _host;
45                 private string _domain;
46
47                 public Type1Message () : base (1)
48                 {
49                         // default values
50                         _domain = Environment.UserDomainName;
51                         _host = Environment.MachineName;
52                         Flags = (NtlmFlags) 0xb207;
53                 }
54
55                 public Type1Message (byte[] message) : base (1)
56                 {
57                         Decode (message);
58                 }
59
60                 // properties
61
62                 public string Domain {
63                         get { return _domain; }
64                         set {
65                                 if (value == null)
66                                         value = "";
67                                 if (value == "")
68                                         Flags &= ~NtlmFlags.NegotiateDomainSupplied;
69                                 else
70                                         Flags |= NtlmFlags.NegotiateDomainSupplied;
71
72                                 _domain = value;
73                         }
74                 }
75
76                 public string Host {
77                         get { return _host; }
78                         set {
79                                 if (value == null)
80                                         value = "";
81                                 if (value == "")
82                                         Flags &= ~NtlmFlags.NegotiateWorkstationSupplied;
83                                 else
84                                         Flags |= NtlmFlags.NegotiateWorkstationSupplied;
85
86                                 _host = value;
87                         }
88                 }
89
90                 // methods
91
92                 protected override void Decode (byte[] message) 
93                 {
94                         base.Decode (message);
95
96                         Flags = (NtlmFlags) BitConverterLE.ToUInt32 (message, 12);
97
98                         int dom_len = BitConverterLE.ToUInt16 (message, 16);
99                         int dom_off = BitConverterLE.ToUInt16 (message, 20);
100                         _domain = Encoding.ASCII.GetString (message, dom_off, dom_len);
101
102                         int host_len = BitConverterLE.ToUInt16 (message, 24);
103                         _host = Encoding.ASCII.GetString (message, 32, host_len);
104                 }
105
106                 public override byte[] GetBytes () 
107                 {
108                         short dom_len = (short) _domain.Length;
109                         short host_len = (short) _host.Length;
110
111                         byte[] data = PrepareMessage (32 + dom_len + host_len);
112
113                         data [12] = (byte) Flags;
114                         data [13] = (byte)((uint)Flags >> 8);
115                         data [14] = (byte)((uint)Flags >> 16);
116                         data [15] = (byte)((uint)Flags >> 24);
117
118                         short dom_off = (short)(32 + host_len);
119
120                         data [16] = (byte) dom_len;
121                         data [17] = (byte)(dom_len >> 8);
122                         data [18] = data [16];
123                         data [19] = data [17];
124                         data [20] = (byte) dom_off;
125                         data [21] = (byte)(dom_off >> 8);
126
127                         data [24] = (byte) host_len;
128                         data [25] = (byte)(host_len >> 8);
129                         data [26] = data [24];
130                         data [27] = data [25];
131                         data [28] = 0x20;
132                         data [29] = 0x00;
133
134                         byte[] host = Encoding.ASCII.GetBytes (_host.ToUpper (CultureInfo.InvariantCulture));
135                         Buffer.BlockCopy (host, 0, data, 32, host.Length);
136
137                         byte[] domain = Encoding.ASCII.GetBytes (_domain.ToUpper (CultureInfo.InvariantCulture));
138                         Buffer.BlockCopy (domain, 0, data, dom_off, domain.Length);
139
140                         return data;
141                 }
142         }
143 }