I am attempting to read and write from a simple Telnet server (Varnish) that needs authentication. This is done via a challenge phrase, to which I must supply the correct response.
I have a simple C# test that does something like this to get the challenge phrase (the server sends a bunch of lines, one of which contains the challenge):
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
clientSocket.Connect("1.2.3.4", 81);
byte[] inStream = new byte[65536];
NetworkStream serverStream = clientSocket.GetStream();
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
var lines = returndata.Split('\n');
var challenge = lines[1];
I now have the challenge in challenge
.
To generate the correct response, I have to build some text and SHA256 it:
var secret = "secretpassword";
var response = string.Format("{0}\n{1}\n{0}\n", challenge, secret);
char[] chars = response.ToCharArray();
var bytes = Encoding.ASCII.GetBytes(response)
var sha = SHA256Managed.Create();
var crypto = sha.ComputeHash(bytes);
var hash = string.Empty;
foreach (byte bit in crypto)
{
hash += bit.ToString("x2");
}
The end of all this is a SHA256 string.
The server expects me to send the phrase "auth " followed by the string, so I send this:
var auth = string.Format("auth {0}\n", hash);
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(auth);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
returndata = System.Text.Encoding.ASCII.GetString(inStream);
If I debug this by trying to connect via Telnet myself and then injecting the challenge phrase into my code, I can copy'n'paste the auth value into my telnet client and it works fine. It just doesn't work from my code, so I suspect the final "write to server" section is at fault.
Here's a sample of a working copy-and-paste using Putty. You can see on line 2 the challenge, and on line 5 where I send the response.
Okay, this was a ridiculous error on my part - nothing clever to do with Varnish, sockets, or anything worthwhile really.
I totally forgot to actually read the response from the auth token, so I was just checking the value of the original 'failed' result...
Last section should be: