Writing to NetworkStream to authenticate with Varnish fails

139 views Asked by At

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. enter image description here

CLI Authentication: The Gory Details

1

There are 1 answers

0
Cylindric On BEST ANSWER

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:

var auth = string.Format("auth {0}\n", hash);

byte[] outStream = System.Text.Encoding.ASCII.GetBytes(auth);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize); // Don't forget to read the response!!
returndata = System.Text.Encoding.ASCII.GetString(inStream);