Search code examples
c#email-attachments

Mimecast API - Send Attachment


We are using Mimecast API to send emails / attachments from local programs. Our emails do send out using Mimecast's example code (without attachments), but we're having problems sending attachments. (I Did check Mimecast's API forums but there are no flagged questions like this, so I thought I'd try SO.)

The attachment in question is a PDF file, and here is the code we're using. We're seeing an exception that the remote server forcibly closed the connection. We tried adding:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

But we get the same result. We tried adjusting Content-Type but to no avail (anything other than octet-stream makes Mimecast throw an unsupported object error.) The code we're using from Mimecast's API documentation is:

static void uploadAttachmentToMimecast()
{
    //Setup required variables
    string baseUrl = "https://us-api.mimecast.com";
    string uri = "/api/file/file-upload";
    String accessKey = "accesskeyhere";
    String secretKey = "secretkeyhere";
    String appId = "ourappId";
    String appKey = "ourappKey";
    string fileName = @"C:\Path\Hello.pdf";
    // thought I'd try this but it isn't working either... I was hoping it was an SSL thing. 
    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

    //Generate request header values
    string hdrDate = System.DateTime.Now.ToUniversalTime().ToString("R");
    string requestId = System.Guid.NewGuid().ToString();

    //Generate sha256 of the file to upload
    string sha256 = generateSha256(fileName);

    //Get the file size of the file to upload
    long fileSize = new System.IO.FileInfo(fileName).Length;

    //Create the HMAC SHA1 of the Base64 decoded secret key for the Authorization header
    System.Security.Cryptography.HMAC h = new System.Security.Cryptography.HMACSHA1(System.Convert.FromBase64String(secretKey));

    //Use the HMAC SHA1 value to sign the hdrDate + ":" requestId + ":" + URI + ":" + appkey
    byte[] hash = h.ComputeHash(System.Text.Encoding.Default.GetBytes(hdrDate + ":" + requestId + ":" + uri + ":" + appKey));

    //Build the signature to be included in the Authorization header in your request
    string signature = "MC " + accessKey + ":" + System.Convert.ToBase64String(hash);

    //Build Request
    System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(baseUrl + uri);
    request.Method = "POST";
    request.ContentType = "application/octet-stream";

    //Add Headers
    request.Headers[System.Net.HttpRequestHeader.Authorization] = signature;
    request.Headers.Add("x-mc-date", hdrDate);
    request.Headers.Add("x-mc-req-id", requestId);
    request.Headers.Add("x-mc-app-id", appId);
    request.Headers.Add("x-mc-arg", "{'data': [{'sha256': '" + sha256 + "', 'fileSize': " + fileSize.ToString() + "}]}");

    //Add request body
    //Create and write data to stream
    var payload = System.IO.File.ReadAllBytes(fileName);

    System.IO.Stream stream = request.GetRequestStream();
    stream.Write(payload, 0, payload.Length);
    stream.Close();

    //Send Request
    System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();

    //Output response to console
    System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
    string responseBody = "";
    string temp = null;
    while ((temp = reader.ReadLine()) != null)
    {
        responseBody += temp;
    };
    System.Console.WriteLine(responseBody);
    System.Console.ReadLine();
}

public static string generateSha256(string fileName)
{
    using (System.IO.FileStream post_stream = System.IO.File.OpenRead(fileName))
    {
        System.Security.Cryptography.SHA256Managed sha = new System.Security.Cryptography.SHA256Managed();
        byte[] file_hash = sha.ComputeHash(post_stream);
        return System.BitConverter.ToString(file_hash).Replace("-", System.String.Empty);
    }
}

The line throwing the actual error is:

System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();

If anyone has experience with using Mimecast's API and has any ideas that can help us shed some light on this, it would be much appreciated. Thank you


Solution

  • In the event anyone comes across this in the future, before banging your head against a wall, regenerate your service account keys in your Mimecast Service API portal (and revoke the previous ones.) That seemed to be the problem for some reason..