2010-04-30 12 views
14

Estoy tratando de enviar comandos al puerto de control Tor mediante programación para que actualice la cadena. No he podido encontrar ningún ejemplo en C# y mi solución no funciona. La solicitud expira. Tengo el servicio en funcionamiento, y puedo verlo escuchando en el puerto de control.Cómo usar el protocolo de control Tor en 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; 
} 

¿Alguien puede detectar lo que estoy haciendo mal?

Editar:

Siguiendo la sugerencia de Hans, que ahora se ha borrado por alguna razón, me trataron de enviar "AUTHENTICATE \ n" en lugar de simplemente "Identificación". Ahora recibo un error de Tor: "551 Cadena entrecomillada no válida. Debe poner la contraseña entre comillas dobles". Al menos hay algún progreso.

Luego intenté enviar "AUTHENTICATE \" \ "\ n", como quiere, pero agota el tiempo mientras esperaba una respuesta.

Editar:

El comando funciona bien en el cliente Telnet de Windows. Ni siquiera tengo que agregar las comillas. No puedo entender lo que está mal. ¿Quizás las comillas dobles no están codificadas correctamente cuando se envían?

Respuesta

4

Cuando envío el comando AUTHENTICATE, StreamReader lee la respuesta hasta el final, pero no tiene fin porque, con éxito, la transmisión se mantiene abierta. Así que lo cambié para solo leer la primera línea de la respuesta en este caso.

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; 
} 
8
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(); 
    } 
0

Probablemente usando Vidalia que genera un hash de la contraseña para el acceso al puerto de control. Necesita usar la aplicación Tor Console y configurar un archivo torrc.

+2

No, no estaba usando Vidalia, y me lo resolvieron todos modos. – Edgar

1

Agregué otro ejemplo que estoy usando a continuación. También se agregaron pasos para aquellos que deseen configurar Tor que pueda aceptar comandos a través del puerto de control.

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

pasos para configurar Tor:

  1. Copiar torrc de opciones por defecto en el directorio en el que está tor.exe. directorio predeterminado si está utilizando el navegador Tor es: "~ \ Tor Browser \ Browser \ TorBrowser \ Data \ Tor"
  2. Abra una ventana de cmd
  3. chdir al directorio donde tor.exe es. El directorio predeterminado si está utilizando el navegador Tor es: "~ Tor Browser \ Browser \ TorBrowser \ Tor \"
  4. Genera una contraseña para el acceso al puerto de control Tor. tor.exe --hash-password “your_password_without_hyphens” | more
  5. Agregue su contraseña hash de contraseña a torrc-defaults en ControlPort 9151. Debería verse algo como esto: hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507. Si acepta su contraseña para ser "contraseña", puede copiar la cadena de arriba.
  6. Ahora puede acceder al control Tor a través de Telnet una vez que se inicia. Ahora el código puede ejecutarse, simplemente edite la ruta hacia donde se encuentran sus archivos Tor en el programa. prueba modificando Tor a través de Telnet:
  7. tor de inicio con el siguiente comando: tor.exe -f .\torrc-defaults
  8. abrir otra cmd de tipo puntual y: telnet localhost 9151
  9. Si todo va bien debería ver una pantalla completamente en negro. Escriba "autenticate “your_password_with_hyphens”" Si todo va bien, debería ver "250 OK".
  10. Escriba "SIGNAL NEWNYM" y obtendrá una nueva ruta, ergo nueva dirección IP. Si todo va bien, debería ver "250 OK".
  11. Tipo "setevents circ" (eventos del circuito) para permitir la salida de consola
  12. Tipo "getinfo circuit-status" para ver los circuitos de corriente
Cuestiones relacionadas