/// <summary> /// The private method to connect the exchange server through MAPIHTTP transport. /// </summary> /// <param name="mailStoreUrl">The mail store Url.</param> /// <param name="domain">The domain the server is deployed.</param> /// <param name="userName">The domain account name</param> /// <param name="userDN">User's distinguished name (DN).</param> /// <param name="password">user Password.</param> /// <returns>If the method succeeds, the return value is 0. If the method fails, the return value is an implementation-specific error code.</returns> public uint Connect(string mailStoreUrl, string domain, string userName, string userDN, string password) { uint returnValue = 0; this.domain = domain; this.userPassword = password; this.mailStoreUrl = mailStoreUrl; this.userName = userName; ConnectRequestBody connectBody = new ConnectRequestBody(); connectBody.UserDN = userDN; // The server MUST NOT compress ROP response payload (rgbOut) or auxiliary payload (rgbAuxOut). connectBody.Flags = 0x00000001; // The code page in which text data is sent. connectBody.Cpid = 1252; // The local ID for everything other than sorting. connectBody.LcidString = 0x00000409; // The local ID for sorting. connectBody.LcidSort = 0x00000409; connectBody.AuxiliaryBufferSize = 0; connectBody.AuxiliaryBuffer = new byte[] { }; if (this.cookies == null) { this.cookies = new CookieCollection(); } HttpWebResponse response = SendMAPIHttpRequest(this.site, mailStoreUrl, userName, domain, password, connectBody, "Connect", this.cookies); string transferEncoding = response.Headers["Transfer-Encoding"]; string pendingInterval = response.Headers["X-PendingPeriod"]; string responseCode = response.Headers["X-ResponseCode"]; if (transferEncoding != null) { if (string.Compare(transferEncoding, "chunked") == 0) { byte[] rawBuffer = ReadHttpResponse(response); returnValue = uint.Parse(responseCode); if (returnValue == 0) { ChunkedResponse chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer); ConnectSuccessResponseBody responseSuccess = ConnectSuccessResponseBody.Parse(chunkedResponse.ResponseBodyRawData); } else { this.site.Assert.Fail("Can't connect the server through MAPI over HTTP, the error code is: {0}", responseCode); } } } response.GetResponseStream().Close(); this.cookies = response.Cookies; return(returnValue); }
/// <summary> /// Parse the Connect request type success response body. /// </summary> /// <param name="rawData">The raw data which is returned by server.</param> /// <returns>An instance of ConnectSuccessResponseBody class.</returns> public static ConnectSuccessResponseBody Parse(byte[] rawData) { ConnectSuccessResponseBody responseBody = new ConnectSuccessResponseBody(); int index = 0; responseBody.StatusCode = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.ErrorCode = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.PollsMax = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.RetryCount = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.RetryDelay = BitConverter.ToUInt32(rawData, index); index += 4; // The length in bytes of the unicode string to parse int strBytesLen = 0; // Find the string with '\0' end for (int i = index; i < rawData.Length; i++) { strBytesLen++; if (rawData[i] == 0) { break; } } byte[] prefixBuffer = new byte[strBytesLen]; Array.Copy(rawData, index, prefixBuffer, 0, strBytesLen); index += strBytesLen; responseBody.DNPrefix = Encoding.ASCII.GetString(prefixBuffer); // The length in bytes of the unicode string to parse strBytesLen = 0; // Find the string with '\0''\0' end for (int i = index; i < rawData.Length; i += 2) { strBytesLen += 2; if ((rawData[i] == 0) && (rawData[i + 1] == 0)) { break; } } byte[] displayNameBuffer = new byte[strBytesLen]; Array.Copy(rawData, index, displayNameBuffer, 0, strBytesLen); index += strBytesLen; responseBody.DisplayName = Encoding.Unicode.GetString(displayNameBuffer); responseBody.AuxiliaryBufferSize = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.AuxiliaryBuffer = new byte[responseBody.AuxiliaryBufferSize]; Array.Copy(rawData, index, responseBody.AuxiliaryBuffer, 0, responseBody.AuxiliaryBufferSize); return(responseBody); }
/// <summary> /// Parse the Connect request type success response body. /// </summary> /// <param name="rawData">The raw data which is returned by server.</param> /// <returns>An instance of ConnectSuccessResponseBody class.</returns> public static ConnectSuccessResponseBody Parse(byte[] rawData) { ConnectSuccessResponseBody responseBody = new ConnectSuccessResponseBody(); int index = 0; responseBody.StatusCode = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.ErrorCode = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.PollsMax = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.RetryCount = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.RetryDelay = BitConverter.ToUInt32(rawData, index); index += 4; // The length in bytes of the unicode string to parse int strBytesLen = 0; // Find the string with '\0' end for (int i = index; i < rawData.Length; i++) { strBytesLen++; if (rawData[i] == 0) { break; } } byte[] prefixBuffer = new byte[strBytesLen]; Array.Copy(rawData, index, prefixBuffer, 0, strBytesLen); index += strBytesLen; responseBody.DNPrefix = Encoding.ASCII.GetString(prefixBuffer); // The length in bytes of the unicode string to parse strBytesLen = 0; // Find the string with '\0''\0' end for (int i = index; i < rawData.Length; i += 2) { strBytesLen += 2; if ((rawData[i] == 0) && (rawData[i + 1] == 0)) { break; } } byte[] displayNameBuffer = new byte[strBytesLen]; Array.Copy(rawData, index, displayNameBuffer, 0, strBytesLen); index += strBytesLen; responseBody.DisplayName = Encoding.Unicode.GetString(displayNameBuffer); responseBody.AuxiliaryBufferSize = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.AuxiliaryBuffer = new byte[responseBody.AuxiliaryBufferSize]; Array.Copy(rawData, index, responseBody.AuxiliaryBuffer, 0, responseBody.AuxiliaryBufferSize); return responseBody; }
/// <summary> /// Verify the Connect success response body related requirements. /// </summary> /// <param name="connectSuccessResponseBody">The Connect success response body to be verified.</param> private void VerifyConnectSuccessResponseBody(ConnectSuccessResponseBody connectSuccessResponseBody) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R209"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R209 this.Site.CaptureRequirementIfIsInstanceOfType( connectSuccessResponseBody.StatusCode, typeof(uint), 209, @"[In Connect Request Type Success Response Body] StatusCode (4 bytes): An unsigned integer that specifies the status of the request."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1349"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1349 this.Site.CaptureRequirementIfAreEqual<uint>( 0, connectSuccessResponseBody.StatusCode, 1349, @"[In Connect Request Type Success Response Body] [StatusCode] This field MUST be set to 0x00000000."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R210"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R210 this.Site.CaptureRequirementIfIsInstanceOfType( connectSuccessResponseBody.ErrorCode, typeof(uint), 210, @"[In Connect Request Type Success Response Body] ErrorCode (4 bytes): An unsigned integer that specifies the return status of the operation."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R211"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R211 this.Site.CaptureRequirementIfIsInstanceOfType( connectSuccessResponseBody.PollsMax, typeof(uint), 211, @"[In Connect Request Type Success Response Body] PollsMax (4 bytes): An unsigned integer that specifies the number of milliseconds for the maximum polling interval."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R212"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R212 this.Site.CaptureRequirementIfIsInstanceOfType( connectSuccessResponseBody.RetryCount, typeof(uint), 212, @"[In Connect Request Type Success Response Body] RetryCount (4 bytes): An unsigned integer that specifies the number of times to retry request types."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R214"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R214 this.Site.CaptureRequirementIfIsInstanceOfType( connectSuccessResponseBody.RetryDelay, typeof(uint), 214, @"[In Connect Request Type Success Response Body] RetryDelay (4 bytes): An unsigned integer that specifies the number of milliseconds for the client to wait before retrying a failed request type."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1351"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1351 this.Site.CaptureRequirementIfIsInstanceOfType( connectSuccessResponseBody.AuxiliaryBufferSize, typeof(uint), 1351, @"[In Connect Request Type Success Response Body] AuxiliaryBufferSize (4 bytes): An unsigned integer that specifies the size, in bytes, of the AuxiliaryBuffer field."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R218"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R218 this.Site.CaptureRequirementIfIsInstanceOfType( connectSuccessResponseBody.AuxiliaryBuffer, typeof(byte[]), 218, @"[In Connect Request Type Success Response Body] AuxiliaryBuffer (variable): An array of bytes that constitute the auxiliary payload data returned from the server."); // Add the debug information this.Site.Log.Add( LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1352, the length of AuxiliaryBuffer is {0}, the value of AuxiliaryBufferSize is {1}.", connectSuccessResponseBody.AuxiliaryBuffer.Length, connectSuccessResponseBody.AuxiliaryBufferSize); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1352 this.Site.CaptureRequirementIfAreEqual<uint>( connectSuccessResponseBody.AuxiliaryBufferSize, (uint)connectSuccessResponseBody.AuxiliaryBuffer.Length, 1352, @"[In Connect Request Type Success Response Body] [AuxiliaryBuffer] The size of this field, in bytes, is specified by the AuxiliaryBufferSize field."); }