30
Nov
2008

Neuvasync Over the air gCal and Google contacts to iPhone with exchange email

I have been looking for a good way to sync my Google contacts and Google calendar to my iPhone since the day I got it.  I’m not talking about some wired sync via iTunes, that setup is completely unacceptable.  The iPhone is a powerful device I don’t want to be tethered to a PC to sync it more than once a week.  I had a great piece of software on windows mobile called OggSync that allowed direct over the air sync to Google calendar and contacts and I’ve been looking for similar functionality since I got my iPhone.

The first major roadblock in getting this functionality is that the iPhone SDK does not allow the developers to have access to the iPhone calendar.  This is terrible and to me it feels like just a marketing thing to make people look to mobile.me for over the air sync calendar.  They already allow developer access to contacts so I’m not sure what the reason is to prevent it to the calendar.  I can’t think of any good technical reason to prevent developer access to the calendar, so shame on you Apple.

The geniuses over at Neuvasync have figured out a way around the Apple restrictions on the calendar.  They created an exchange gateway that looks exactly like an exchange server to the iPhone but on the back end connects to gCal and Google contacts for the contacts and calendar data.  The sync is push and full 2 way.  It’s really a dream come true for my situation.

The main rub with the Neuvasync setup is that they don’t support gateway of email from another exchange server.  My primary work email, which I like to have access to in case any situations come up that I need to deal with while I’m out of the office, is typical corporate email only available via a crazy VPN web login or on the corporate network.  They do support exchange capable mobile devices and that’s how I have been using my iPhone since the day I got it but I don’t want to get my work contacts or calendar on my personal phone.  So changing to Neuvasync meant I needed to find a way around this.  I have tried forward rules in outlook but they have disabled forwarding of emails on the exchange server.  Last night I was able to create a client side outlook VBA script that will take an incoming email and forward it to an SMTP server.  I created the rule to forward incoming emails to my gmail account and prefix the subject with my company name in brackets and then in gmail created a filter to apply a label to the email.  The end result is I end up with all my personal mail as well as my company mail in gmail and have access to it in a timely manner via regular imap mail setup. 

I’ll detail the functionality of the forwarding script in a subsequent blog post in the next few days.  If you use google calendar and google contacts definitely checkout Neuvasync it’s awesome.  My understanding is that the version as it is now will remain free as they have other ideas for monitization of the service without impacting the regular syncing solution they are currently offering.  They will be offering imap/pop sync in the near future to the solution as well and they already support plaxo if you are a plaxo user.

13
Nov
2008

LDAP authentication via .net

There are several methods to authenticate a user via an external LDAP server.  I was given the task of allowing our web application to authenticate against an external SunOne directory server.  There is quite a bit of documentation detailing how to authenticate against active directory from a web application but quite a bit less about how to authenticate against other third party LDAP servers.  I’ve been able to get our web application working against OpenLDAP as well as SunOne.  SSL was required against the SunOne server and I will detail some tips on getting that working as well.

The simplest form is authentication against active directory.  You can accomplish this with the following code, the hostname can actually be left as an empty string and it will automatically use the local host that your .net code is executing on.  If your web/iis server is part of your active directory this works really well.

Active Directory

Dim Entry As New System.DirectoryServices.DirectoryEntry(hostname, username,
      password,System.DirectoryServices.AuthenticationTypes.Secure)
Dim Searcher As New System.DirectoryServices.DirectorySearcher(Entry)

Searcher.SearchScope = DirectoryServices.SearchScope.Subtree

Try
  Dim Results As System.DirectoryServices.SearchResult = Searcher.FindOne
  Response.Write("<B>It Worked</b>")
Catch ex As Exception
  Response.Write("Error authenticating user. " & ex.Message)
End Try

LDAP

For standard LDAP many of the examples found on the net create a new search and then run the search looking for the users information.  For the AutenticationTypes you can choose None for standard socket connection or SecureSocketsLayer for an SSL connection.

Dim at As System.DirectoryServices.AuthenticationTypes
at = System.DirectoryServices.AuthenticationTypes.None
Dim entry As System.DirectoryServices.DirectoryEntry = 
      New System.DirectoryServices.DirectoryEntry(
      domainAndUsername, LuserName, LpassWord, at)

Try
  Dim search As System.DirectoryServices.DirectorySearcher =
      New System.DirectoryServices.DirectorySearcher(entry)
  search.SearchScope = System.DirectoryServices.SearchScope.Subtree
  search.Filter = "objectClass=*"
  Dim result As System.DirectoryServices.SearchResult = search.FindOne()
  Response.Write("You were authenticated correctly")
Catch ex As Exception
  Response.Write("Error authenticating user. " & ex.Message)
End Try

Alternate LDAP Method

An alternate method that can be done is to bind without a search.  I ran into a case where normal user accounts on the ldap server had search privileges revoked which caused problems trying to use the above method.  The alternate method I came up with was to query the directory name and check the status of that call.

Dim at As System.DirectoryServices.AuthenticationTypes
at = System.DirectoryServices.AuthenticationTypes.None
Dim entry As System.DirectoryServices.DirectoryEntry = 
      New System.DirectoryServices.DirectoryEntry(
      domainAndUsername, LuserName, LpassWord, at)
Dim serverName As String = ""

Try
  serverName = entry.Name
  Response.Write("You are authenticated")
Catch ex As Exception
  Response.Write("Error Authenticating user. " & ex.Message)
End Try

Troubleshooting SSL

There are three main reasons that SSL won’t work:

  • The DNS name in your binding string doesn’t match the DNS name in the cert
  • The cert is expired or not yet valid
  • The local client does not trust the server’s certificate

Essentially, these are the same reasons you get a certificate warning dialog in IE, except that LDAP always fails on these conditions. A very good way to test if the machine your code is running on is setup properly with a valid certificate is to use the ldp.exe tool which uses the same .NET connection services that you will be leveraging in your code.  I’ve been able to troubleshoot and solve several installations using this tool to illustrate that the issue was not with our product but the machine setup.  You can find the ldp.exe utility on the Server 2003 tools cd or here at Microsoft.