Notes for adaptation in Silverlight/Windows Phone 7

Aug 26, 2011 at 9:45 PM

Just doing a preliminary run through to get it to compile, I've found the following changes that need to be made for Silverlight 4/Windows Phone 7 compatibility:

First of all, both the silverlight and Windows Phone 7 projects are woefully out of date. I had to re-create them from scratch.

Also, mostly, the big changes are going to be around Silverlight's lack of synchronous calls in the socket library. All calls must be asynchronous. 

Also, I haven't looked at the SFTP code yet. I just excluded that from the library since I don't use it myself. When I have time I can go through that too and get it working for silverlight, but for now I just left it out.

 

Here are the changes so far (some of the line numbers are approximate since I don't remember what they were prior to my other changes above them):

Session.cs : line 838:

            //  Shutdown and disconnect from the socket
            if (this._socket != null)
            {
                lock (this._socket)
                {
                    if (this._socket != null)
                    {
#if SILVERLIGHT
			this._socket.Close(10000);
#else
                        this._socket.Disconnect(true);
#endif

 

Session.cs: about line 1128:

            //  Dispose of old ciphers and hash algorithms
            if (this._serverMac != null)
            {
#if SILVERLIGHT
		this._serverMac.Clear();
#else
                this._serverMac.Dispose();
#endif

Session.cs: about line 1600:

                    if (this._serverMac != null)
                    {
#if SILVERLIGHT
			this._serverMac.Clear();
#else
                        this._serverMac.Dispose();
#endif
                        this._serverMac = null;
                    }

                    if (this._clientMac != null)
                    {
#if SILVERLIGHT
                        this._clientMac.Clear();
#else
                        this._clientMac.Dispose();
#endif

 

ConnectionInfo.cs : line 247 (change to this line to use string.IsNullOrWhiteSpace(username) instead of username.IsNullOrWhiteSpace())

            if (!port.IsValidPort())
                throw new ArgumentOutOfRangeException("port");

            if (string.IsNullOrWhiteSpace(username))
                throw new ArgumentException("username");

RsaDigitalSignature.cs : line 66:

                    // Dispose managed ResourceMessages.
                    if (this._hash != null)
                    {
#if SILVERLIGHT
			this._hash.Clear();
#else
                        this._hash.Dispose();
#endif

 

DsaDigitalSignature.cs : line 174

                    // Dispose managed ResourceMessages.
                    if (this._hash != null)
                    {
#if SILVERLIGHT
			this._hash.Clear();
#else
                        this._hash.Dispose();
#endif

 

SshData.cs : line 223:

            if (length > (uint)int.MaxValue)
            {
                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue));
            }
#if SILVERLIGHT
	    return Renci.SshNet.Common.ASCIIEncoding.Current.GetString(this.ReadBytes((int)length), 0, (int)length);
#else
            return Renci.SshNet.Common.ASCIIEncoding.Current.GetString(this.ReadBytes((int)length));
#endif

The next bit is a bit more involved of a change, I don't have a replacement for it yet (at least not yet), but starting with Session.cs, line 430 is the use of NetworkStream to implement communication of the socket. Unfortunately, on silverlight, these synchronous calls are not supported. There's no NetworkStream class. You have to use the low level socket methods ConnectAsync, ReceiveAsync, and SendAsync. 

My suggestion is to re-implement this portion of the code using those methods instead of NetworkStream (which isn't available in silverlight), so you only have to maintain one version. I have this working in my telnet library, but you're more familiar with this code base, so you'd probably be able to do this faster. Here is an example of the differences between .net CLR and Silverlight Socket programming:=

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2010/03/20/silverlight-4-rc-socket-security-changes.aspx

Aug 26, 2011 at 10:11 PM

Turned into an issue item, with included patch:

http://sshnet.codeplex.com/workitem/829

Coordinator
Aug 27, 2011 at 1:21 AM

ok, thanks,

Sorry, yea, silverlight project is out o fdate, but I will update it now and will check it in.

 

Also, if you like, I can add you as a developer on this project and then you can directly to check in code that deals with silverlight, since I am not so familiar with silverlight.

 

Thanks,

Oleg

Coordinator
Aug 27, 2011 at 3:47 AM

I just checked in refreshed version of Silverlight and WindowPhone version.

Its not compilable just yet but thought it will give you a good start, it only have few errors left.

 

I will see what I can do about NetworkStream and how to replace it with something that can be used by all platforms.

You can see how I put platform specific logic into partial classes, I personally try to stay away from using #if...#else...#endif syntax since it can complicate code significantly.

So I prefer to us either partial classes or decorate method with conditinal attribute which will be included only when specific symbol is specified.

 

Let me know if you have any more questions,

Thanks,

Oleg

Aug 27, 2011 at 1:05 PM

Sounds good. I probably won't have a chance to take a look at it until Monday. For the NetworkStream functionality, I have two recommendations:

1) convert your imperative, NetworkStream-based code to a state-machine "lexer". The state machine method makes it easy to use the same parsing code whether the incoming server bytes are coming in synchronously or asynchronously. Then you just write an interface with two adapters, one using NetworkStream, and one using Async calls, and dependency inject this interface into your protocol parser to stream data in from the server. This is the method I use for my telnet protocol parser and it makes the code very modular and reusable. That was how I planned being able to plug in different versions of the protocol parser or telnet emulation using the same networking code.

2) Write a NetworkStream class conditionally compiled for Silverlight with the basic functionality needed for your existing code. This is easier in the short run, but more of a hastle to maintain in the long run.

Sep 2, 2011 at 1:33 PM

May I be added to the project so I can check in silverlight or windows-phone related changes? Thanks. I will document any check-ins on the boards for your review.

Coordinator
Sep 2, 2011 at 5:43 PM

Yea, no problem,

I just added you as a developer,

Please let me know if you have any problems or questions.

 

Thanks,

Oleg

Sep 5, 2011 at 1:45 PM
Hi Olag,
I have a question on encryption alogithem for SFTP
In a library using encryption provider SHA1CryptoServiceProvider() can we use

SHA256CryptoServiceProvider()?

Thanks & Regards

Rambhopal Reddy E