【问题标题】:How to use Tor control protocol in C#?如何在 C# 中使用 Tor 控制协议?
【发布时间】:2011-02-14 06:34:35
【问题描述】:

我正在尝试以编程方式向 Tor 控制端口发送命令,以使其刷新链。我无法在 C# 中找到任何示例,并且我的解决方案不起作用。请求超时。我的服务正在运行,我可以看到它正在侦听控制端口。

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;
}

谁能发现我做错了什么?

编辑:

按照 Hans 的建议(由于某种原因他现在已将其删除),我尝试发送“AUTHENTICATE\n”而不仅仅是“AUTHENTICATE”。现在我从 Tor 收到一个错误:“551 无效的引号字符串。您需要将密码放在双引号中。”至少有一些进展。

然后我尝试发送“AUTHENTICATE \"\"\n”,就像它想要的那样,但它在等待响应时超时。

编辑:

该命令在 Windows Telnet 客户端中运行良好。我什至不必添加引号。无法弄清楚出了什么问题。也许双引号在发送时没有正确编码?

【问题讨论】:

    标签: c# .net network-programming tcpclient tor


    【解决方案1】:
        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();
        }
    

    【讨论】:

      【解决方案2】:

      当我发送 AUTHENTICATE 命令时,StreamReader 正在读取结束的响应,但没有结束,因为成功时流保持打开状态。所以我把它改成了在这种情况下只读取响应的第一行。

      public static string MakeTcpRequest(string message, TcpClient client, bool readToEnd)
      {
          client.ReceiveTimeout = 20000;
          client.SendTimeout = 20000;
          string proxyResponse = string.Empty;
      
          try
          {
              // Send message
              using (StreamWriter streamWriter = new StreamWriter(client.GetStream()))
              {
                  streamWriter.Write(message);
                  streamWriter.Flush();
              }
      
              // Read response
              using (StreamReader streamReader = new StreamReader(client.GetStream()))
              {
                  proxyResponse = readToEnd ? streamReader.ReadToEnd() : streamReader.ReadLine();
              }
          }
          catch (Exception ex)
          {
              throw ex;
          }
      
          return proxyResponse;
      }
      

      【讨论】:

      • 感谢您的回答。我有一个使用提到的代码的 c# 项目。我运行 Tor 浏览器并通过第一个 Tor IP 发出请求,但是当我调用 Refresh(如提到的代码)时,IP 没有改变,它似乎只是在更改 IP 后使用了第一个 IP。我该怎么办?
      【解决方案3】:

      在下面添加了我自己使用的另一个示例。还为那些想要设置可以通过控制端口接受命令的 Tor 的人添加了步骤。

      Socket server = null;
      
      //Authenticate using control password
      IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9151);
      server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      server.Connect(endPoint);
      server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"your_password\"" + Environment.NewLine));
      byte[] data = new byte[1024];
      int receivedDataLength = server.Receive(data);
      string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
      
      //Request a new Identity
      server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM" + Environment.NewLine));
      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();
      }
      else
      {
          Console.WriteLine("SIGNAL NEWNYM sent successfully");
      }
      

      配置 Tor 的步骤:

      1. 将torrc-defaults 复制到tor.exe 所在的目录中。如果您使用 Tor 浏览器,默认目录为:“~\Tor Browser\Browser\TorBrowser\Data\Tor”
      2. 打开一个 cmd 提示窗口
      3. chdir 到 tor.exe 所在的目录。如果您使用 Tor 浏览器,默认目录是:“~\Tor Browser\Browser\TorBrowser\Tor\”
      4. 为 Tor 控制端口访问生成密码。 tor.exe --hash-password “your_password_without_hyphens” | more
      5. 将您的密码密码哈希添加到 ControlPort 9151 下的 torrc-defaults。它应该类似于:hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507。如果您接受密码为“密码”,则可以复制上面的字符串。
      6. 现在,一旦启动 Tor,您就可以通过 Telnet 访问 Tor 控制。现在代码可以运行了,只需编辑程序中 Tor 文件所在的路径即可。 通过 Telnet 测试修改 Tor:
      7. 使用以下命令启动 tor:tor.exe -f .\torrc-defaults
      8. 打开另一个 cmd 提示符并输入:telnet localhost 9151
      9. 如果一切顺利,您应该会看到完全黑屏。输入“autenticate “your_password_with_hyphens””如果一切顺利,您应该会看到“250 OK”。
      10. 键入“SIGNAL NEWNYM”,您将获得一条新路由,即新 IP。如果一切顺利,您应该会看到“250 OK”。
      11. 键入“setevents circ”(电路事件)以启用控制台输出
      12. 输入“getinfo circuit-status”查看当前电路

      【讨论】:

        【解决方案4】:

        可能您使用的 Vidalia 会生成一个散列密码来控制端口访问。您需要使用 Tor 控制台应用程序并配置一个 torrc 文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-15
          • 1970-01-01
          相关资源
          最近更新 更多