Archive for the ‘Programming’ Category

How to log System.Net

Tuesday, January 3rd, 2017

In your App.config add the following code:

<?xml version="1.0"?>
<configuration>
  <system.diagnostics>

    <trace autoflush="true"/>

    <switches>
      <add name="System.Net" value="Verbose" />
    </switches>

    <sources>
      
      <source name="System.Net">
        <listeners>
          <add name="SystemNetLogFile"/>
        </listeners>
      </source>
      
    </sources>

    <sharedListeners>
      <add name="SystemNetLogFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="d:\system.net.log"/>
    </sharedListeners>

  </system.diagnostics>
</configuration>

That’s it!

The log looks like this:

System.Net Information: 0 : [8548] SecureChannel#238379
System.Net Information: 0 : [8548] Enumerating security
System.Net Information: 0 : [8548] Negotiate
System.Net Information: 0 : [8548] NegoExtender
System.Net Information: 0 : [8548] pku2u
System.Net Information: 0 : [8548] WDigest
System.Net Information: 0 : [8548] Kerberos
System.Net Information: 0 : [8548] NTLM
System.Net Information: 0 : [8548] Schannel
System.Net Information: 0 : [8548] Microsoft Unifie
System.Net Information: 0 : [8548] TSSSP
System.Net Information: 0 : [8548] CREDSSP
System.Net Information: 0 : [8548] SecureChannel#238379
System.Net Information: 0 : [8548] Current OS installat
System.Net Information: 0 : [8548] AcquireCredentialsHa
System.Net Error: 0 : [8548] AcquireCredentialsHandle()
System.Net Information: 0 : [8548] AcquireCredentialsHa
System.Net Error: 0 : [8548] AcquireCredentialsHandle()
System.Net Information: 0 : [8548] SecureChannel#214541
System.Net Information: 0 : [8548] SecureChannel#214541
System.Net Information: 0 : [8548] AcquireCredentialsHa
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] InitializeSecurityCo
System.Net Information: 0 : [8548] Remote certificate:
V3

[Subject]
CN=mail.postecert.it, O=Postecom S.p.A., L=Roma, S=Ro
Simple Name: mail.postecert.it
DNS Name: mail.postecert.it

[Issuer]
CN=GlobalSign Organization Validation CA - SHA256 - G
Simple Name: GlobalSign Organization Validation CA -
DNS Name: GlobalSign Organization Validation CA - SHA

[Serial Number]
0A9141CFE287B47FF4273C12

[Not Before]
2016-11-02 08:01:04

[Not After]
2017-11-03 08:01:04

[Thumbprint]
F12F74096659D9CCAA4ACD3432C896AF39CA8B9E

[Signature Algorithm]
sha256RSA(1.2.840.113549.1.1.11)

[Public Key]
Algorithm: RSA
Length: 2048
Key Blob: 30 82 01 0a 02 82 01 01 00 bf a1 62 b7 64 1
System.Net Information: 0 : [8548] SecureChannel#214541
System.Net Information: 0 : [8548] ProcessAuthenticatio

Enable IMAP in Gmail

Tuesday, June 2nd, 2015
  1. Sign in to Gmail.
  2. Click the gear icon in the upper-right and select Settings.
  3. Click Forwarding and POP/IMAP.
  4. Select Enable IMAP.
  5. Remember that Gmail only allows secure SSL connections so you need to use ConnectSSL method.

Perfectly secure ‘less’ secure apps

For some (newer) Google accounts you may need to enable access for ‘less’ secure apps (for Google Apps this setting is not available – it’s enabled by default).

Please note that contrary to what the label says those applications (such as Thunderbird or Outlook) are secure – they use TLS or SSL to secure the communication.

The term ‘less secure apps’ is used only because such applications need to store the primary account password to be able to access IMAP.

‘Less’ secure apps alternatives

  1. OAuth 2.0 (OAuth 2.0 for installed applications, OAuth 2.0 for web applications, OAuth 2.0 for service accounts) which works despite the disabled ‘less secure apps’ setting.
  2. Application specific passwords (2-Step-Verification must be enabled to access this feature: Create application specific password)

2-step verification

If you use 2-Step-Verification and are seeing a “password incorrect” error when trying to access IMAP, an app password may solve the problem. An application specific password is a 16-digit password that gives an application permission to access your Google Account.

2-Step-Verification must be enabled to access this feature:
Create application specific password.

Simple .NET IMAP access sample

// C# code:

using(Imap imap = new Imap())
{
	imap.ConnectSSL("imap.gmail.com");
	imap.UseBestLogin("pat@gmail.com", "password");

	imap.SelectInbox();

	List<long> uids = imap.Search(Flag.Unseen);
	foreach (long uid in uids)
	{
		var eml = imap.GetMessageByUID(uid);
		IMail mail = new MailBuilder().CreateFromEml(eml);

		Console.WriteLine(mail.Subject);
		Console.WriteLine(mail.Text);
	}
	imap.Close();
}
' VB.NET code:

Using imap As New Imap()
	imap.ConnectSSL("imap.gmail.com")
	imap.UseBestLogin("pat@gmail.com", "password")

	imap.SelectInbox()

	Dim uids As List(Of Long) = imap.Search(Flag.Unseen)
	For Each uid As Long In uids
		Dim eml = imap.GetMessageByUID(uid)
		Dim mail As IMail = New MailBuilder().CreateFromEml(eml)

		Console.WriteLine(mail.Subject)
		Console.WriteLine(mail.Text)
	Next
	imap.Close()
End Using

More .NET IMAP samples. You can download Mail.dll IMAP library for .NET here.

Enable POP3 in Gmail

Tuesday, June 2nd, 2015
  1. Sign in to Gmail.
  2. Click the gear icon in the upper-right and select Mail settings .
  3. Click Forwarding and POP/IMAP.
  4. Select Enable POP for all mail or Enable POP for mail that arrives from now on. Here you can learn more about Gmail’s POP3 behavior
  5. Remember that Gmail only allows secure SSL connections so you need to use ConnectSSL method.

Perfectly secure ‘less’ secure apps

For some (newer) Google accounts you may need to enable access for ‘less’ secure apps.

Please note that contrary to what the label says those applications (such as Thunderbird or Outlook) are secure – they use TLS or SSL to secure the communication.

The term ‘less secure apps’ is used only because such applications need to store the primary account password to be able to access POP3.

‘Less’ secure apps alternatives

  1. IMAP and OAuth 2.0 (OAuth 2.0 for installed applications, OAuth 2.0 for web applications, OAuth 2.0 for service accounts) which works despite the disabled ‘less secure apps’ setting.
  2. Application specific passwords (2-Step-Verification must be enabled to access this feature: Create application specific password)

2-step verification

If you use 2-Step-Verification and are seeing a “password incorrect” error when trying to access POP3, an app password may solve the problem. An application specific password is a 16-digit password that gives an application permission to access your Google Account.

2-Step-Verification must be enabled to access this feature:
Create application specific password.

Simple .NET POP3 access sample

// C# code:

using(Pop3 pop3 = new Pop3())
{
	pop3.ConnectSSL("pop.gmail.com");
	pop3.Login("your_email@gmail.com", "password");

	foreach (string uid in pop3.GetAll())
	{
		var eml = pop3.GetMessageByUID(uid);
		IMail mail= new MailBuilder()
			.CreateFromEml(eml);

		Console.WriteLine(mail.Subject);
		Console.WriteLine(mail.Text);
	}
	pop3.Close();
}

' VB.NET code:

Using pop3 As New Pop3()
    pop3.ConnectSSL("pop.gmail.com")
    pop3.Login("your_email@gmail.com", "password")

    For Each uid As String In pop3.GetAll()
        Dim email As IMail = New MailBuilder() _
            .CreateFromEml(pop3.GetMessageByUID(uid))
        Console.WriteLine(email.Subject)
	Console.WriteLine(mail.Text)
    Next
    pop3.Close()
End Using

More .NET POP3 samples. You can download Mail.dll POP3 library for .NET here.

IMAP search requires parentheses

Friday, June 6th, 2014

IMAP protocol uses Polish notation (also known as prefix notation) for client queries. In general it means, that operator (in case of IMAP search it’s always a logical operator) is placed left of its operands.

Polish notation

Expression that would be written in conventional infix notation as:
(5 − 6) * 7
can be written in prefix/Polish notation as:
* (− 5 6) 7
As all mathematical operands are binary (or have defined number of operands) we don’t need parentheses to correctly evaluate this expression:
* − 5 6 7

Polish notation doesn’t require parentheses.

IMAP search needs parentheses

Although IMAP search syntax uses Polish notation it actually requires parentheses to be evaluated unambiguously.

This is because there is no explicitly defined AND operator, that takes exactly 2 operands.

RFC 3501:

When multiple keys are specified, the result is the intersection (AND function) of all the messages that match those keys.

So although it is true that Polish and reverse Polish notations don’t require parentheses, it is not true that IMAP search doesn’t require them.

‘OR/AND’ example

Expression 1a:

Regular notation:
(SUBJECT subject OR BODY body) AND FROM from

Polish notation:
AND OR SUBJECT subject BODY body FROM from

IMAP’s Polish notation (note there is no AND operator):
OR SUBJECT subject BODY body FROM from

Expression 1b:

Regular notation:
SUBJECT subject OR (BODY body AND FROM from)

Polish notation:
OR SUBJECT subject AND BODY body FROM from

IMAP’s Polish notation (note there is no AND operator):
OR SUBJECT subject BODY body FROM from

1a != 1b

Expression 1a is not equal to Expression 1b:
((a or b) and c) != (a or (b and c))

For:
a = true
b = true
c = false

We have:
((true or true) and false) != (true or (true and false))
false != true

Parentheses are needed

But when there is no AND operator, IMAP’s Polish notations look exactly the same, thus we need parentheses!

Expression 1a (IMAP’s Polish notation with parentheses):
(OR SUBJECT subject BODY body) FROM from

Expression 1b (IMAP’s Polish notation with parentheses):
OR SUBJECT subject (BODY body FROM from)

OR SUBJECT subject BODY body FROM from
is treated like
(OR SUBJECT subject BODY body) FROM from

‘NOT’ example

Expression 2a:

Regular notation:
NOT (SUBJECT subject AND BODY body)

Polish notation:
NOT AND SUBJECT subject BODY body

IMAP’s Polish notation (note there is no AND operator):
NOT SUBJECT subject BODY body

Expression 2b:

Regular notation:
(NOT SUBJECT subject) AND BODY body

Polish notation:
AND NOT SUBJECT subject BODY body

IMAP’s Polish notation (note there is no AND operator):
NOT SUBJECT subject BODY body

2a != 2b

Expression 2a is obviously not equal to Expression 2b.

Parentheses are needed

Again IMAP’s Polish notations look the same. We need parentheses!

Expression 2a (IMAP’s Polish notation with parentheses):
NOT (SUBJECT subject BODY body)

Expression 2b (IMAP’s Polish notation with parentheses):
(NOT SUBJECT subject) BODY body

NOT SUBJECT subject BODY body
is treated like
(NOT SUBJECT subject) BODY body

EnvelopedCms decrypt problem

Monday, February 3rd, 2014

.NET’s EnvelopedCms class represents a CMS/PKCS #7 structure for enveloped data. Such data are for example used in S/MIME encrypted messages.

EnvelopedCms class contains several Decrypt method overloads:

  • Decrypt()
  • Decrypt(RecipientInfo)
  • Decrypt(X509Certificate2Collection)
  • Decrypt(RecipientInfo, X509Certificate2Collection)

Each Decrypt method decrypts the contents of the decoded enveloped CMS/PKCS #7 data. Each searches the current user and local machine My stores for the appropriate certificate and private key.

Last two overloads allow passing additional collection of X509 certificates, that should be searched to find matching certificate for decryption.

There are 2 most common errors that can occur while decrypting:

  • “The enveloped-data message does not contain the specified recipient.” – Which means that no matching certificate was found in My stores and in the additional certificate collection.
  • “Cannot find object or property.” – Certificate was found, but there is no private key in it, so it can not be used to decryped the enveloped data.

There are 3 ways of adding certificates to My store, 2 of those don’t import private key:

  • “Personal” tab in CertMgr (does not import private key).
  • MMC “Certificates” snap-in (“My user account”) (does not import private key).
  • Double clicking the pfx file (imports private key).

In many cases data are encrypted using 2 or more certificates (so both sender and receiver are able to decrypt the message)

The problem with all Decrypt methods is that they try to use only the first certificate they find. The matching is based on certificate SN. First, both My stores are search, then extra store (passed certificate collection).

This leads to a problem when, both certificates are in My store, but only one contains a private key.

.NET is going to use the first certificate it finds – if it’s the one without the private key, “Cannot find object or property” exception is going to be thrown.

The only workaround for this problem is to try to decrypt the message for each ReceipientInfo separately. This way we are sure that all certificates will be tried.

Mail.dll .NET secure email component does this automatically, so no additional code is required.