"Hacking" System.Net.Mail.SmtpClient

In .NET 2.0 there is a cool class called SmtpClient within System.Net.Mail.

With this class you can send mail (at least I thought).
The requirement was to send an email over a server of one of our agencies.
The mail server was secured by username/password authentication. That’s why I used the following code:

SmtpClient _client = new SmtpClient();
_client = new SmtpClient("smtp.myserver.at");

_client.UseDefaultCredentials = false;
_client.Credentials = new NetworkCredential("username", "password");

_client.Send("from@test.at", "to@test.at", "Hallo Welt", "Hallo max!!");
At execution of the last statement an exceptíon occurred:
The inner exception said "Invalid lenght for a Base-64 char array."
That didn't make any sense for me (nor helped me to fix the problem).
I had a look at the stack trace and found out, that the exception had occurred in a class called


So I used telnet to manually connect to the smtp server.

S: 220 smtp.myserver.at ESMTP
C: ehlo asd.com
S: 250-smtp.myserver.at Hello mypc.microsoft.com [xxx.xxx.xxx.xxx]
S: 250-SIZE 20971520
C: AUTH NTLM <base64 encoded string>

S: 334 NTLM supported

Seemed like the server would support NTLM.. But.. when I looked up the NTLM-SMTP specification,I found out that the server should respond with

334 <NTLM supported as base64 encoded string>

So the problem obviously is, that “NTLM supported” was not a valid Base-64 encoded string (as the inner exception above also pointed out).

So how could this problem be solved…

I digged into the private members of the SmtpClient object and found a member called transport (of type SmtpTransport).

The SmtpTransport object had private members as well, and one of them was called authenticationModules – bingo!

This is an array of ISmtpAuthenticationModules like Negotiate, NTLM, Digest and Login.

Unfortunately SmtpClient always picks the most effective supported method (in this case NTLM). As NTLM was not working I needed a way to kick out NTLM of the list of supported auth methods.

So I used reflection to modify the array and “disable” (override) NTLM in the array. Here’s what I did:

FieldInfo transport = _client.GetType().GetField("transport",
    BindingFlags.NonPublic | BindingFlags.Instance);

FieldInfo authModules = transport.GetValue(_client).GetType()
        BindingFlags.NonPublic | BindingFlags.Instance);

Array modulesArray = authModules.GetValue(transport.GetValue(_client)) as Array;
modulesArray.SetValue(modulesArray.GetValue(2), 0);
modulesArray.SetValue(modulesArray.GetValue(2), 1);
modulesArray.SetValue(modulesArray.GetValue(2), 3);


Guess which smtp authentication module will be used now 🙂

Comments (6)

  1. DannyC says:

    **** In case this helps someone else. I had the same issue and in the end it was due to the password being case sensitive. Apparently an invalid password will also throw the "Invalid lenght for a Base-64 char array." exception.

  2. Diane says:

    Hugely helpful – I had been puzzling over this for ages.

    Actually I also needed the "login" authentication Module so I replaced ONLY the ntlm authentication module :       modulesArray.SetValue(modulesArray.GetValue(2), 1)

    Worked like a dream!

  3. Lungisa says:

    I have the same code but I get "The operation has timed out."

  4. Phil says:

    Hi knom,

    Thanks for the useful article, I’m having a similar problem.

    I think I need to use this method to force the use of the "login" authenticationModule. How would I do this?


  5. Sean Gahan says:

    This is how I worked it.

    Best regards,

    Sean Gahan

    Public Sub SendMail(ByVal emailTo As String, ByVal emailSubject As String, _

    ByVal emailBody As String, ByVal nameOfFileOut As String, _

    ByVal stringAttachment As String)

    Dim a As String = String.Empty ‘//attachment

    Dim f As String = AppSettings("SendFewrMailFromThisAcct")

    Dim b As String = String.Empty ‘//body

    Dim s As String = String.Empty ‘//subject

    Dim t As String = String.Empty ‘//to

    Dim att As Attachment

    Dim MailServer As String = AppSettings("MailServer")

    Dim MailUser As String = AppSettings("MailUser")

    Dim MailPwd As String = AppSettings("MailPwd").ToString

    Dim MailUserDomain As String = AppSettings("MailUserDomain")

    Dim memStream As System.IO.MemoryStream

    Dim encoding As New Text.ASCIIEncoding

    memStream = New System.IO.MemoryStream

    Dim byteArray As Byte() = encoding.GetBytes(stringAttachment)

    Dim sm As New SmtpClient(MailServer)

    Dim SMTPUserInfo As System.Net.NetworkCredential = _

    New System.Net.NetworkCredential(MailUser, MailPwd, MailUserDomain)

    ‘//set up email stuff

    t = emailTo

    s = emailSubject

    b = emailBody

    Dim m As New MailMessage(f, t, s, b)


       If nameOfFileOut <> String.Empty Then

           memStream.Write(byteArray, 0, byteArray.Length)

           memStream.Seek(0, IO.SeekOrigin.Begin)

           att = New Attachment(memStream, nameOfFileOut, MediaTypeNames.Text.Plain)


       End If

       m.Priority = MailPriority.Normal

       sm.UseDefaultCredentials = False

       sm.Credentials = SMTPUserInfo


    Catch ex As Exception

       Throw New ApplicationException("Error: Message:" & ex.Message & vbCrLf & "Stack:" & ex.StackTrace)



       If Not att Is Nothing Then


       End If


       sm = Nothing

    End Try