SSL Refusal to connect

Bug #826065 reported by Bob the Builder on 2011-08-14
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
IRC.NET
Low
Alexander Regueiro

Bug Description

Every time i try to connect to an IRC Server with SSL, the connections time out, and the IRC servers throw errors as if to say the key was never received from the IRCd

example:

[02:01:35] -irc.myserver- Exiting ssl client [@<Removed_My_IP>.38393]: SSL_write(): Internal OpenSSL error or protocol error
[02:02:14] -irc.myserver- Exiting ssl client [@<Removed_My_IP>.14102]: SSL_write(): OpenSSL functions requested a read()

Changed in ircdotnet:
assignee: nobody → Alex Regueiro (alexreg)
Alexander Regueiro (alexreg) wrote :

Could you please indicate the hostname of the IRC server that you're trying to connect to?

Also, any other detail or an attachment of your connection code would be appreciated.

Changed in ircdotnet:
status: New → Incomplete
importance: Undecided → Low
Alexander Regueiro (alexreg) wrote :

Bug reported has provided sample project using library that verifies this issue.

Changed in ircdotnet:
status: Incomplete → Confirmed
Grank (grant-bowering) wrote :

I found this old bug which seems to be the same issue I've been experiencing.
Stated on IRC yesterday:
[14:21] <+Noldorin> grantbowering: weird… other people have told me SSL works fine
Which means either this bug simply fell off Alex's radar, or not everyone is affected by it.
While possible, it's relatively unlikely to be a server configuration issue, as I tested this against freenode, which offers SSL, and experienced the same effect as on my private IRC server. It could, however, plausibly be a matter of client configuration... Bob (if you're still around), did you experience this problem across multiple machines and/or networks, or did you stick to a single dev/test machine when you were running into this?
I've attached a log of System.Net traces running the 0.4 branch's test project's ConnectTest, with the port set to 6697 and useSsl set to true, and the client1/2ConnectedEvent timeout upped to 60s. It didn't really reveal anything useful as far as I could see but I'm including it for completeness.
As far as I could see, it reaches the body of IrcClient.ConnectCompleted, enters GetDataStream, and never comes back out of it again because the SslStream.AuthenticateAsClient call never returns.

Grank (grant-bowering) wrote :

I was able to get as far as MOTD by making the following changes:
 1) switched IrcClient's private Socket declaration and instantiation for TcpClient ones, instead obtaining any necessary references to the underlying Socket through the TcpClient.Client property;
 2) changed GetDataStream to use the result of the TcpClient's GetStream() method instead of referencing the recieveStream;
 3) changed SendAsync and ReceiveAsync to call BeginWrite/BeginRead on this.dataStream instead of the equivalent methods directly on the Socket.

This approach has the following problems:
 a) The CompleteIrcClientTest fails at either RegisterTest or MotdTest, seemingly at random (the specifics possibly due to minute textual differences between freenode servers). On closer inspection it seems to be missing some server messages, including at times the 001 or the 376. Looking at the 372s it appears to only receive every second line. I'm not sure why this is occurring but I'm assuming it's a simple implementation mistake on my part.
 b) As pointed out, the Silverlight subset of the framework does not contain TcpClient anyway, so this is not a possibility going forward with the forks merged.

As far as a partial rationale for why I tried these debugging steps:
My understanding of things is that the SslStream wraps things such that you write unencrypted bytes to it and it encrypts them, and you read unencrypted bytes from it as it decrypts them. Thus, the bytes coming from and going to the underlying Socket itself would be encrypted bytes. While IrcClient.GetDataStream takes care of returning an authenticated SSL wrapper stream instead of a clear-text stream if the useSsl bool is set accordingly, the dataStream returned is never used to write to the connected Socket. IrcClient.SendAsync writes directly to the Socket instead, writing unencrypted bytes to a Socket that is expecting pre-encrypted ones. IrcClient.ReceiveAsync goes straight to the Socket to load received data into the receiveStream, and then its callback processes it from the dataStream, which would only be the same stream if useSsl is false. (I think; that part is still confusing to me and a bit of a reversed abstraction. It's definitely a leaky one though, as at the least, e.BytesTransferred would be off since one's reading unencrypted bytes but that count is from encrypted ones.)
As I write this, I begin to suspect my problem in making 3) work without 1) and 2) was a result of getting the various streams of different purposes confused; I'm going to try again.

Grank (grant-bowering) wrote :

Okay, yeah, I can get to the same point by just doing #3 above, if in GetDataStream I replace both appearances of "this.receiveStream" with "new NetworkStream(this.socket)", thus allowing the use of both Write and BeginRead on this.DataStream. I also don't misplace every second message with that approach, I just either miss the 001 off the SSL client and/or it gets "stuck" during the MOTD and never reaches 376. I'm not sure what's up with the missing 001, but I'd imagine the getting "stuck" is probably blocking due to buffer size in the stream, using NetworkStream instead of CircularBufferStream...

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers