I'm trying to send commands to the Tor control port programmatically to make it refresh the chain. I haven't been able to find any examples in C#, and my solution's not working. The request times out. I have the service running, and I can see it listening on the control port.
public string Refresh()
{
TcpClient client = new TcpClient("localhost", 9051);
string response = string.Empty;
string authenticate = MakeTcpRequest("AUTHENTICATE\r\n", client);
if (authenticate.Equals("250"))
{
response = MakeTcpRequest("SIGNAL NEWNYM\r\n", client);
}
client.Close();
return response;
}
public string MakeTcpRequest(string message, TcpClient client)
{
client.ReceiveTimeout = 20000;
client.SendTimeout = 20000;
string proxyResponse = string.Empty;
try
{
// Send message
StreamWriter streamWriter = new StreamWriter(client.GetStream());
streamWriter.Write(message);
streamWriter.Flush();
// Read response
StreamReader streamReader = new StreamReader(client.GetStream());
proxyResponse = streamReader.ReadToEnd();
}
catch (Exception ex)
{
// Ignore
}
return proxyResponse;
}
Can anyone spot what I'm doing wrong?
Edit:
Following Hans's suggestion, which he has now deleted for some reason, I tried to send "AUTHENTICATE\n" instead of just "AUTHENTICATE". Now I'm getting back an error from Tor: "551 Invalid quoted string. You need to put the password in double quotes." At least there's some progress.
I then tried to send "AUTHENTICATE \"\"\n", like it wants to, but it times out while waiting for a response.
Edit:
The command works fine in the Windows Telnet client. I don't even have to add the quotes. Can't figure out what's wrong. Maybe the double quotes aren't encoded correctly when they're sent?
public static void CheckIfBlocked(ref HtmlDocument htmlDoc, string ypURL, HtmlWeb hw)
{
if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
{
Console.WriteLine("Getting Blocked");
Utils.RefreshTor();
htmlDoc = hw.Load(ypURL, "127.0.0.1", 8118, null, null);
if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
{
Console.WriteLine("Getting Blocked");
Utils.RefreshTor();
}
}
}
public static void RefreshTor()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9051);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
server.Connect(ip);
}
catch (SocketException e)
{
Console.WriteLine("Unable to connect to server.");
RefreshTor();
return;
}
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"butt\"\n"));
byte[] data = new byte[1024];
int receivedDataLength = server.Receive(data);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (stringData.Contains("250"))
{
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM\r\n"));
data = new byte[1024];
receivedDataLength = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (!stringData.Contains("250"))
{
Console.WriteLine("Unable to signal new user to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
RefreshTor();
}
}
else
{
Console.WriteLine("Unable to authenticate to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
RefreshTor();
}
server.Shutdown(SocketShutdown.Both);
server.Close();
}