Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [JAVA]Client per rete Direct Connect

    Salve volevo fare un client per la rete DirectConnect (una cosa banale,non un nuovo DC++ )
    solo che sono incappato in alcuni problemi e purtroppo nè sul forum ufficiale http://dcpp.net nè altrove (non trovo prog open source in java per DC) riesco a trovare ispirazione. Il codice è il seguente:

    codice:
    /**
      * Contributed by dCoy (method for calculating the key) 
      * @author Chrisvoo
      */
      
    import java.net.*;
    import java.io.*;
    
      class getLock {
    	  public static void main(String[]args){
    		  
    	 boolean error=false;
    	 
    		    try {
    			    
    			    // Sockets and IO channels
    		     Socket s=new Socket(args[0].toString(),Integer.parseInt(args[1]));
    		     BufferedReader ego = new BufferedReader(new InputStreamReader(System.in));
    		     DataOutputStream egout = new DataOutputStream(s.getOutputStream());
    		     BufferedReader from_server = new BufferedReader(new InputStreamReader(s.getInputStream())); 
    /* qualcuno ha suggerito di aggiungerci "ISO-8859-1" al parametro di ISReader ma non funziona lo stesso */
    		     
    		     System.out.println("Connecting...");
    		     
    		     /* Ok here method readLine() waits for '\n',but even if I use InputStream
    		      * and method read() to wait for "|",the server seems not to care about me..*/
    		      
    		     String answer=from_server.readLine();
    		     System.out.println("Server's answered,calculating key...");
    		     String key=generateKey(answer);
    		     System.out.println("The $lock sent is: "+answer);
    		     System.out.println("The key sent is: "+key);
    		     System.out.println("Let's send the key..");
    		     egout.writeBytes("$Key <"+key+">|"+"$ValidateNick "+"<ChrisVoo>|\r\n");
    		     System.out.println("Mandata...");
    		     answer=from_server.readLine();
    		     System.out.println(answer);
    		     egout.writeBytes("$Version <0.68>|$MyINFO <nothing>|$GetNickList|\r\n");
    		     
    		     
    		     
    	        }catch(UnknownHostException e){
    		        System.out.println("Host unknown");
    	        }catch(IOException i){
    		        System.out.println("Error I/O");
    	        }catch(ArrayIndexOutOfBoundsException a){
    		        System.out.println("You have to digit \"java getLock nameOfTheHub port\"");
                }
         }
    
    
    
    /* It's pretty copied from wiki */
    
     public static String generateKey(String lockString){
        int i = 0;
        byte[] lock = null;
        byte[] key = null;
    
        lockString = lockString.substring(0,lockString.indexOf(' '));
        lockString.trim();
        lock = lockString.getBytes();
        key = new byte[lock.length];
    
        for(i=1;i<lock.length;i++){
            key[i] = (byte)((lock[i] ^ lock[i-1]) & 0xFF);
        }
    
        key[0] = (byte)((((lock[0] ^ lock[lock.length-1]) ^ lock[lock.length-2]) ^ 5) & 0xFF);
    
        for(i=0;i<key.length;i++){
            key[i] = (byte)((((key[i]<<4) & 0xF0) | ((key[i]>>4) & 0x0F)) & 0xFF);
        }
    
        return(dcnEncode(new String(key)));
    }
    
    public static String dcnEncode(String string){
        char[] replacements = null;
        int i = 0;
        int index = 0;
    
        replacements = new char[]{0,5,36,96,124,126};
    
        for(i=0;i<replacements.length;i++){
            while((index = string.indexOf(replacements[i])) >=0 ){
                string = string.substring(0,index)
                    + "/%DCN"+leadz(replacements[i])+"%/"
                    + string.substring(index+1,string.length());
            }
        }
    
        return(string);
      }
    
    
    
    private static String leadz(int nr){
        if(nr < 100 && nr > 10){
            return("0"+nr);
        } else if(nr < 10){
            return("00"+nr);
        } else{
            return(""+nr);
        }
      }
    }
       /*this is my version 'cause I noticed that Coy's code takes a only a little part
        of the string sent by the server..
    	      
    	      public static String generateKey(String lockString){
                    int i = 0;
                    byte[] lock = null;
                    byte[] key = null;
    
             //     lockString = lockString.substring(0,lockString.indexOf(' ')); the line above was modified by me
             //     otherwise the method took only "$Lock" to calculate the key
                    lockString = lockString.substring(lockString.indexOf(' ')+1,lockString.length()-1);
    	            lockString = lockString.substring(0,lockString.indexOf(' '));
                    lockString.trim();
                    lock = lockString.getBytes();
                    key = new byte[lock.length];
    
                    for(i=1;i<lock.length;i++){
                            key[i] = (byte)((lock[i] ^ lock[i-1]) & 0xFF);
                    }
    
                    key[0] = (byte)((((lock[0] ^ lock[lock.length-1]) ^ lock[lock.length-2]) ^ 5) & 0xFF);
    
                    for(i=0;i<key.length;i++){
                            key[i] = (byte)((((key[i]<<4) & 0xF0) | ((key[i]>>4) & 0x0F)) & 0xFF);
                    }
    
                    return(dcnEncode(new String(key)));
            }
            public static String dcnEncode(String string){
                    char[] replacements = null;
                    int i = 0;
                    int index = 0;
    
                    replacements = new char[]{0,5,36,96,124,126};
    
                    for(i=0;i<replacements.length;i++){
                            while((index = string.indexOf(replacements[i])) >=0 ){
                                    string = string.substring(0,index) + "/%DCN"+leadz(replacements[i])+"%/" + string.substring(index+1,string.length());
                            }
                    }
    
                    return(string);
            }
    
            private static String leadz(int nr){
                    if(nr < 100 && nr > 10){
                            return("0"+nr);
                    }
                    else if(nr < 10){
                            return("00"+nr);
                    }
                    else{
                            return(""+nr);
                    }
            }
        }   */
    Ho incluso una mia versione per il calcolo del Lock key,dalla stringa spedita dal server,perchè non mi pare che quella indicata sul wiki agisca correttamente.
    In pratica il problema avviene nella mancata connessione con il server: con BufferReader il programma si ferma a "Connecting",perchè probabilmente non riceve il carattere "\n" dal server ma anche se leggo i caratteri uno per volta con InputStream e read() ricevo la stringa dal server e la visualizzo subito ma il server non "percepisce" la mia risposta. Io la mando ma lui non risponde subito e quindi mi viene ritornato l'errore "Il client non ha risposto entro un certo tot di tempo,ecc".
    Anche qui nessuno mai si è cimentato nella relaizzazione di un client DC in java? Mi interessava analizzare il protocollo DC,non fare chissà cosa,però non riesco manco a collegarmi agli hub!!

    Se qualcuno ha suggerimenti ringrazio
    /* Chris */

  2. #2
    Qual è la procedura (mi riferisco ai comandi del protocollo) che il client deve rispettare per connettersi ad un hub? Hai prestato fede all'RFC?
    Cimentarsi in un hack di questo tipo richiede parecchio tempo speso dietro alla lettura delle specifiche, non è una cosa semplice, specie per un protocollo vasto come quello di direct connect (tempo fa avevo avuto una mezza idea di scrivere qualcosa in Python ma dopo aver visto la mole di documentazione da studiare mi sono demoralizzato e ho abbandonato :-\).
    Un mio personalissimo consiglio: una cosa che ti può facilitare molto quando lavori a progetti di questo tipo è il fare un po' di 'reversing' facendo girare un client DC preesistente e funzionante (come DC++ appunto) e sniffare la sessione tra lui ed il server (nel tuo caso la sola [connessione/autenticazione all'hub]), osservando i comandi che si scambiano.
    Hai gia provato questa via?

    Hope this helps
    Rilasciata Python FTP Server library 0.5.1
    http://code.google.com/p/pyftpdlib/

    We'll be those who'll make the italian folks know how difficult can be defecating in Southern California without having the crap flying all around the house.

  3. #3
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,466

    Moderazione

    Ho spostato la discussione nel forum dedicato a Java.
    In futuro, poni qui le tue domande relative a questo linguaggio.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  4. #4
    Originariamente inviato da billiejoex
    Qual è la procedura (mi riferisco ai comandi del protocollo) che il client deve rispettare per connettersi ad un hub? Hai prestato fede all'RFC?
    Penso di si.
    Cimentarsi in un hack di questo tipo richiede parecchio tempo speso dietro alla lettura delle specifiche, non è una cosa semplice, specie per un protocollo vasto come quello di direct connect
    Si è vero,il fatto è che tutti i programmi fatti per questa rete sono in C++ o VB. Ad ogni modo non mi pare di aver visto tutta questa gran mole di documentazione nei siti ufficiali:

    Altre fonti non ne ho trovate,hai magari fonti migliori?
    Un mio personalissimo consiglio: [..] fare un po' di 'reversing' facendo girare un client DC preesistente e funzionante e sniffare la sessione tra lui ed il server. Hai gia provato questa via?
    Seriamente non l'ho ancora fatto per bene: ho provato a sniffare il traffico con Windump filtrando il solo traffico sulla porta 411,ma i messaggi sono impastati in maniera confusa (cioè non c'è una bella formattazione come per i messaggi HTTP),senza contare che non ho ben afferrato che set di caratteri usi,alcuni sono intraducibili...
    Cmq grazie per l'interessamento,se altri hanno ulteriori suggerimenti o fonti da segnalare li ringrazio anticipamente
    /* Chris */

  5. #5
    Originariamente inviato da billiejoex
    Qual è la procedura (mi riferisco ai comandi del protocollo) che il client deve rispettare per connettersi ad un hub? Hai prestato fede all'RFC?

    Penso di si.
    Il processo di log-in mi pare abbastanza semplice, dando una rapida occhiata alle specifiche:
    http://gempond.com/odcps/page.php?key=loggingin
    Dovrai, in pratica:
    - connetterti al server tramite una banale socket.connect()
    - lanciare un socket.recv() e ricevere il comando $Lock dal server
    - inviare al server key + nickname (socket.send('$key$tuo_nick'))
    - Se il server risponde con un '$ValidateDenide' significa che il nickname è gia in uso e dovrai ripetere il punto 3.
    - Il "3 way handshake" si concluderà col server che ritornerà $nome_hub. Log-in terminato. Da qui in poi potrai iniziare a dialogare con l'hub.

    ...tutto questo ipotizzando che il server non preveda autenticazioni di sorta (ma tu stesso hai detto di voler fare una cosa 'semplice', 'just for trying'), in quel caso si aggiungono ulteriori comandi con conseguente allungamento del codice.

    Si è vero,il fatto è che tutti i programmi fatti per questa rete sono in C++ o VB. Ad ogni modo non mi pare di aver visto tutta questa gran mole di documentazione nei siti ufficiali:
    * Opera DC protocol;
    * Wiki DC++;
    * Forum ufficiale;
    Altre fonti non ne ho trovate,hai magari fonti migliori?
    Sinceramente non ricordo. E' passato troppo tempo.
    Seriamente non l'ho ancora fatto per bene: ho provato a sniffare il traffico con Windump filtrando il solo traffico sulla porta 411,ma i messaggi sono impastati in maniera confusa (cioè non c'è una bella formattazione come per i messaggi HTTP),senza contare che non ho ben afferrato che set di caratteri usi,alcuni sono intraducibili...
    Non ricordo come sia Windump ma per questo genere di cose io ormai mi sono abituato ad utilizzare sempre e comunque l'ottimo Ethereal che ti consiglio più che vivamente.
    Nota: se non vado errato, forse nelle funzioni di ricerca o altro, direct connect impiega anche UDP (e, aggiungo io, magari utilizzando numeri di porta di valore sempre variabile). Se vai più avanti con i progressi, quindi, non ti sarà sufficiente sniffare il solo traffico inerente 441 TCP. Ti conviene non filtrare nulla e cercare di limitare il più possibile l'utilizzo di altre applicazioni che ti potrebbero sporcare i risultati della sessione di sniffing.

    saluti
    Rilasciata Python FTP Server library 0.5.1
    http://code.google.com/p/pyftpdlib/

    We'll be those who'll make the italian folks know how difficult can be defecating in Southern California without having the crap flying all around the house.

  6. #6
    Originariamente inviato da billiejoex
    - lanciare un socket.recv() e ricevere il comando $Lock dal server
    - inviare al server key + nickname (socket.send('$key$tuo_nick'))
    Il problema sta proprio qui:sembra banale pure a me ma praticamente,anche osservando il codice,il problema sta nel fatto che è come se il server mi "snobbasse",non riceve i messaggi che gli spedisco. Il tipico messaggio che il server manda (che varia a seconda del software che viene usato per l'hub server -YnHub,Ptokax,ecc) quando ti connetti è:
    codice:
    $Lock <lock> Pk=<pk>|
    Se bufferizzo le stringhe non vedo subito il messaggio con il codice che ho scritto e il server non riceve la risposta perchè si blocca tutto il codice sul metodo di ricezione delle stringhe (probabilmente non arrivando il carattere \n si sospende lì fintando che non arriva quando ormai il server ha chiuso la connessione). Se lavoro carattere per carattere e attendo "|" come ultimo carattere per spedire la risposta,il server non mi risponde comunque. cioè il problema principale sta proprio nel fatto che il server non vede la risposta e purtroppo non capisco il perchè.
    Originariamente inviato da billiejoex
    direct connect impiega anche UDP. Se vai più avanti con i progressi, quindi, non ti sarà sufficiente sniffare il solo traffico inerente 441 TCP. Ti conviene quindi non filtrare nulla e cercare di limitare il più possibile l'utilizzo di altre applicazioni che ti potrebbero sporcare i risultati della sessione di sniffing.
    Capisco,io sniffavo TCP sulla 411 perchè nelle mie prove stavo interagendo con un hub che usava tale protocollo e tale porta. Entrambi i protocolli sono utilizzabili ma non credo vengano utilizzati entrambi contemporaneamente nella comunicazione client/server poi magari mi sbaglio! Proverò a non filtrare nulla. Grazie.
    /* Chris */

  7. #7
    A questo punto credo ti convenga chiedere sul forum straniero di DC che ho visto essere anche molto popolato, tra l'altro.
    Rilasciata Python FTP Server library 0.5.1
    http://code.google.com/p/pyftpdlib/

    We'll be those who'll make the italian folks know how difficult can be defecating in Southern California without having the crap flying all around the house.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.