2010-04-30 17 views
14

J'essaye d'envoyer des commandes au port de contrôle de Tor par programme pour le faire actualiser la chaîne. Je n'ai pas pu trouver d'exemples en C#, et ma solution ne fonctionne pas. La requête expire. J'ai le service en cours d'exécution, et je peux le voir en écoutant sur le port de contrôle.Comment utiliser le protocole de contrôle 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; 
} 

Quelqu'un peut-il repérer ce que je fais mal?

Edit:

la suggestion de Hans, qu'il a supprimé pour une raison quelconque, j'ai essayé d'envoyer « AUTHENTIQUE \ n » au lieu de « AUTHENTIQUE ». Maintenant, je reçois une erreur de Tor: "551 Chaîne entre guillemets non valide.Vous devez mettre le mot de passe entre guillemets." Au moins, il y a des progrès.

J'ai alors essayé d'envoyer "AUTHENTICATE \" \ "\ n", comme il veut, mais il expire en attendant une réponse.

Edit:

La commande fonctionne très bien dans le client Telnet de Windows. Je n'ai même pas besoin d'ajouter les citations. Je n'arrive pas à comprendre ce qui ne va pas. Peut-être que les guillemets doubles ne sont pas encodés correctement quand ils sont envoyés?

Répondre

4

Lorsque j'envoie la commande AUTHENTICATE, StreamReader lit la réponse à la fin, mais il n'y a pas de fin car, en cas de succès, le flux reste ouvert. Je l'ai donc modifié pour ne lire que la première ligne de la réponse dans ce cas.

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

Probablement vous à l'aide Vidalia qui génère un mot de passe pour l'accès au hachage port de contrôle. Vous devez utiliser l'application de console Tor et configurer un fichier torrc.

+2

Non, je n'utilisais pas Vidalia, et je résolus de toute façon. – Edgar

1

Ajout d'un autre exemple que je m'utilise ci-dessous. Aussi ajouté des étapes pour ceux qui voudraient installer Tor qui peut accepter des commandes via le port de contrôle.

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

étapes pour configurer Tor:

  1. Copier torrc-défaut dans le répertoire dans lequel est tor.exe. Le répertoire par défaut si vous utilisez le navigateur Tor est: "~ \ Tor Navigateur \ Browser \ TorBrowser \ Data \ Tor"
  2. Ouvrez une fenêtre d'invite cmd
  3. chdir dans le répertoire où tor.exe est. Répertoire par défaut si vous utilisez le navigateur Tor est: "~ \ Tor Navigateur \ Browser \ TorBrowser \ Tor \"
  4. Générez un mot de passe pour l'accès au port de contrôle Tor. tor.exe --hash-password “your_password_without_hyphens” | more
  5. Ajoutez votre mot de passe de mot de passe hash à torrc-defaults sous ControlPort 9151. Il devrait ressembler à ceci: hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507. Si vous acceptez que votre mot de passe soit "mot de passe", vous pouvez copier la chaîne ci-dessus.
  6. Vous pouvez maintenant accéder au contrôle Tor via Telnet une fois démarré. Maintenant, le code peut s'exécuter, il suffit de modifier le chemin d'accès à l'emplacement de vos fichiers Tor dans le programme. Test de modification Tor via Telnet:
  7. tor Démarrer avec la commande suivante: tor.exe -f .\torrc-defaults
  8. ouvrir une autre invite cmd et tapez: telnet localhost 9151
  9. Si tout va bien, vous devriez voir un écran complètement noir. Tapez "autenticate “your_password_with_hyphens”" Si tout se passe bien, vous devriez voir "250 OK".
  10. Tapez "SIGNAL NEWNYM" et vous obtiendrez une nouvelle route, ergo nouvelle IP. Si tout se passe bien, vous devriez voir "250 OK".
  11. type "setevents circ" (événements circuit) pour activer la sortie de la console
  12. type "getinfo circuit-status" pour voir les circuits actuels