# icq login



## nameac (6. Jul 2006)

hallo, 


```
import java.io.*;
import java.net.*;

public class Client {
	public static void serverAntwort(Socket clientSocket) {
		String sentence = "";
		BufferedReader inFromServer;
		
		try {
			if(clientSocket.getInputStream()==null){
			System.out.println("scheisse");	
			}
			inFromServer = new BufferedReader(new InputStreamReader(
					clientSocket.getInputStream()));
			while ((sentence = inFromServer.readLine()) != null) {
				System.out.println(sentence);
			}
		} catch (IOException e) {
			System.out.println("Server antwortet seltsam");

		}
	}

	public static void verbindeMit(String host, int port, String nachricht){
		try {
			Socket clientSocket = new Socket(host, port);
			DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
			//outToServer.writeBytes(nachricht);
			serverAntwort(clientSocket);
			clientSocket.close();
		} catch (Exception e) {
			System.out.println("fehler");
		}
	}

	public static void main(String[] args){
		
		
		verbindeMit("login.icq.com", 80, "");
		
	}

}
```
so jetzt hab ich schon verschiedenste varianten für die variable "nachricht eingegeben allerding antwortet der server so das ich nicht weiß was und beendet die verbindung"

varianten zusammengestellt von http://www.micq.org/ICQ-OSCAR-Protocol-v7-v8-v9/Packets/Flap1.html

kann mir jemand sagen was ich eingeben muss damit mich der login server nicht gleich wieder abstöst?


----------



## Roar (6. Jul 2006)

auf der seite steht doch, was du senden musst...
vielleicht solltest du dir auch mal noch was grundlegendererereres zu icq durchlesen, was TLVs FLAPs und SNACs sind.
auf der seite die du da gepostet hast gibts das auch, eine andere gute ist diese: http://iserverd1.khstu.ru/oscar/

mit einem BufferedReader (serverAntwort()) wirst du übrigens nix anfangen können, ICQ ist byte-orientiert.


----------



## nameac (7. Jul 2006)

heißt das das ich byte arrays verschicken und empfangen muss könntest du mir ein beispiel posten was man verschickt damit der login erfolgreich ist um das auslesen kann ich mich dann selbst kümmern wenn ich seh wie die absender info implementiert wird.


----------



## nameac (7. Jul 2006)

```
public static void serverAntwort(Socket clientSocket) {
		byte[] b;
		try {
			if(clientSocket.getInputStream()!=null){
			DataInputStream data=new DataInputStream(clientSocket.getInputStream());
			b=new byte[data.available()];
			data.read(b);
			System.out.println(b.length);
		  }
		} catch (IOException e) {
			System.out.println("Server scheisse");

		}
	}
public static void verbindeMit(String host, int port, byte[] nachricht){
		try {
			Socket clientSocket = new Socket(host, port);
			DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
			outToServer.write(nachricht);
			serverAntwort(clientSocket);
			clientSocket.close();
		} catch (Exception e) {
			System.out.println("fehler");
		}
	}

	public static void main(String[] args){
		byte[] nachricht={};
		verbindeMit("login.icq.com", 80, nachricht);
```

könnte mir jemand erklären womit ich das byte array auffüllen muss damit das klappt


----------



## nameac (7. Jul 2006)

wie übersetz ich denn negative bytes in das richtige hex zeichen das dafür steht z.B. (byte)(-89)


----------



## Roar (7. Jul 2006)

hier steht, wie du das bytearray auffüllen musst: http://www.micq.org/ICQ-OSCAR-Protocol-v7-v8-v9/Packets/Flap1.html
byte[] b = new byte[] {0, 0, 0, 1};
senden(b);
b = new byte[] { bla bla  }

im übrigen finde ich diese seite besser udn einfacher gemacht: http://iserverd1.khstu.ru/oscar/login.html

dann wünsch ich dir noch viel spaß, allein die login sequenz nimmt bei mir so 160 zeilen ein mit bytes auffüllen und senden


----------



## nameac (9. Jul 2006)

ist es eigentlich egal in welcher reihen folge ich die infos ins paket schreibe? und noch mal zu der frage wie ist das mit negativen bytes welchen zeichen steckt da dahinter wie werden die interpretiert?


----------



## Roar (9. Jul 2006)

nein, die reihenfolge ist nicht egal. wenn du irgendein byte auslässt, ein TLV korrupt ist oder sonstwas wird die verbindung sofort getrennt.

wie meinst du das mit deinen negativen bytes? du brauchst an den server gar keine negativen bytes zu senden.
wenn du eine zahl hast, die den wertebereich von byte überschreitet, aber vom server nur ein byte erwartet wird, benutze DataOutputStream#writeByte(int). das nimmt einen integer und schreibt ihn als ein byte raus, so dass der server ihn lesen kann.


----------



## nameac (9. Jul 2006)

in die byte arrays kann man integer werte von -128 bis 127 schreiben die positiven sind ja leicht in zeichen umzuwandeln aber die negativen mit den kann ich nichts anfangen.


----------



## nameac (10. Jul 2006)

k das mit den negativen bytes z.B. F2 versteh ich zwar immer noch nicht aber ich weiß welchen int wert man ihnen zuordnet.

könntest du mir das mit den SNAC FLAP TLV erklähren

TLV sind die sequenzen die ankündigen was als nächstes kommt passwort oder uin, könnte man diese auch in anderer reihenfolge bringen?

FLAP ist die anfangs sequenz die ankündigt das es sich um ein icq protokoll handelt oder?

ich bräuchte hier ein wenig erklährungs hilfe weil ich nicht versteh was die ganzen anderen Bytes in dem bsp. machen das ist für mich bisher überflüssiges zeug.


----------



## nameac (11. Jul 2006)

@roar hast du die mails erhalten?


----------



## Roar (11. Jul 2006)

ja ich hab die mail und die PN gekriegt, aber wenn du glaubst du kannst mir nen dicken ethereal dump schicken und ich soll da auf anhieb erkennen was da falsch ist irrst du :autsch:
zu FLAPs TLVs und SNACs lies dir das hier durch: http://iserverd1.khstu.ru/oscar/basic.html
und für den login das: http://iserverd1.khstu.ru/oscar/login.html
ethereal mitschneiden und dann versuchen die gleichen bytes zu senden bringt nix. wenn du dir das dokument zur login sequenz durchgelesen hast, weißt du warum.

zum thema zahlen: F2 = 242. wenn du F2 an den server senden willst, benutze: dataOutputStream.writeByte(0xF2)


----------



## nameac (11. Jul 2006)

ja ich versteh das jedoch nicht komplett sonst würdes ja funzen der ethereal dump ist nicht irgend was da hab ich die infos gefiltert die auch auf den seiten erklährt werden, ich schreibe die byte arrays doch mit DataStream; das erste byte array ist mein login,und ich weiß garnicht ob man so einfach anfangen kann aber das bsp auf der seite sieht genauso aus (prinzip), wollte nur sehen ob das mit den infos auf der seite übereinstimmt und ich musste nicht nach der icq version und so zeug suchen. vll mach ich irgend was grund legendes falsch der quellcode ist ja auch nicht hölle groß, kann ja sein du findest noch mal fünf min um da drüber zugucken.

trotzdem danke für den link;

 

```
import java.io.*;
import java.net.*;

public class Client {
	public static byte[] serverAntwort(Socket clientSocket) {
		byte[] b=new byte[1000];
		try {
			if(clientSocket.getInputStream()!=null){
			DataInputStream data=new DataInputStream(clientSocket.getInputStream());
			data.read(b);
		  }
		} catch (IOException e) {
			System.out.println("Server antwortet seltsam");

		}
		return b;
	}

	public static Socket verbindeMit(String host, int port){
		Socket clientSocket=null;
		try {
			clientSocket = new Socket(host, port);
		} catch (Exception e) {
			System.out.println("fehler");
		}
		return clientSocket;
	}

	public static void main(String[] args)throws Exception{
		Protokoll login=new Protokoll();
		byte[] nachricht=login.getNachricht(""+
  "2a 01 11 af 00 5b 00 00 00 01"+
  "00 01 00 09 32 35 30 31 33 32 31 37 34 00 02 00"+
  "08 bf 48 b1 b5 76 c3 98 eb 00 03 00 08 49 43 51"+
  "42 61 73 69 63 00 16 00 02 01 0a 00 17 00 02 00"+
  "14 00 18 00 02 00 34 00 19 00 02 00 00 00 1a 00"+
  "02 0b b8 00 14 00 04 00 00 04 42 00 0f 00 02 65"+
  "6e 00 0e 00 02 75 73");
		
		Socket client=verbindeMit("login.icq.com", 80);
		DataOutputStream outToServer = new DataOutputStream(client.getOutputStream());
		outToServer.write(nachricht);
		client.close();
	}
```


```
public class Protokoll {
public byte[] getNachricht(String nachricht){
	nachricht=nachricht.replaceAll(" ","");
	int beit;
	byte[] b=new byte[nachricht.length()/2];
	for(int i=0;i<nachricht.length();i+=2){
		beit=0;
		for(int j=0;j<2;j++){
		char zeichen=nachricht.charAt(i+j);
		if((zeichen>57||zeichen<48)){
			beit+=((Character.toUpperCase(zeichen))-55)*(int)Math.pow(16,1-j);
			
	  }else{
		 beit+=(zeichen-48)*(int)Math.pow(16,1-j);

	  }
		}  
		b[i/2]=(byte)beit;
	}
	return b;
}
public String decode(String decode){
	String hex="";
	for(int i=0;i<decode.length();i++){
	hex+=toHex((int)decode.charAt(i))+" ";
	}
	return hex;
}
```


----------



## nameac (11. Jul 2006)

wenn der stop knopf im eclipse nicht mehr rot leuchtet heißt das doch das server die verbindung getrennt hat irgend ein oder mehr falsche bytes müssen da gesetzt sein.


----------



## Roar (11. Jul 2006)

ok nochmal von vorne. erstmal vergiss das mit den byte dumps in java code einzubauen das geht so nicht.
dann zurück auf die seite: http://iserverd1.khstu.ru/oscar/login.html
da steht das erste paket was du senden musst ist "CLI_IDENT ". hier steht beschrieben welche bytes du senden musst: http://iserverd1.khstu.ru/oscar/cli_ident.html
erst wird ein 00 00 00 01 gesendet, dann mehrere TLVs mit entsprechenden daten drin. dafür wird natürlich vorausgesetzt, dass du weißt was ein TLV ist (siehe link in meinem letzten psot).
dann gehst du wieder zurück auf die erste seite, und siehst, dass du da auch wieder was empfangen musst, nämlich das paket hier: http://iserverd1.khstu.ru/oscar/srv_cookie.html in deinem code liest du nirgends was aus vom server!?
und das war noch nichtmal der login, der kommt erst jetzt, nachdem du von dem server disconnectest und reconnectes zu dem server, der dir in srv_cookie geliefert wurde. und dann komtm der rest der hier beschrieben ist: http://iserverd1.khstu.ru/oscar/login.html erst danach bist du eingeloggt. das ist mehr als du denkst, keine paar bytes die man fix aus ethereal kopieren kann.


----------



## nameac (11. Jul 2006)

das erste paket das ich sende ist doch nach dem vorbild der anleitung + angepasst auf mich.

```
public static void main(String[] args)throws Exception{
		Protokoll login=new Protokoll();
		byte[] nachricht=login.getNachricht("2a 01 11 af 00 5b 00 00 00 01"+
  "00 01 00 09 32 35 30 31 33 32 31 37 34 00 02 00"+
  "08 bf 48 b1 b5 76 c3 98 eb 00 03 00 08 49 43 51"+
  "42 61 73 69 63 00 16 00 02 01 0a 00 17 00 02 00"+
  "14 00 18 00 02 00 34 00 19 00 02 00 00 00 1a 00"+
  "02 0b b8 00 14 00 04 00 00 04 42 00 0f 00 02 65"+
  "6e 00 0e 00 02 75 73");
		
		Socket client=verbindeMit("bos-d017a.blue.aol.com", 80);
		DataOutputStream outToServer = new DataOutputStream(client.getOutputStream());
		outToServer.write(nachricht);
		byte[] r=serverAntwort(client);
		for(int i=0;i<r.length;i++){
			System.out.println(r[i]);
		}
		client.close();
	}

}
```

das ist die antwort: 2a 01 5d b8 00 04 00 00 00 01

den fehler code hab ich gelesen aber uin und passwort(bereits xor verschlüsselt) stimmen soweit


----------



## nameac (19. Jul 2006)

k ab hier komm ich einfach nicht weiter ich krieg keine verbindung zum bos server oder besser gesagt ich kann das cli_cookie nicht an ihn schicken.

```
public static void main(String[] args)throws Exception{
		I_OSever io=new I_OSever("login.icq.com",80);
		Paket paket=new Paket("250132174","Ln0qOECy");
		io.serverAntwort();
		DataOutputStream outToServer = new DataOutputStream(io.verbindung.getOutputStream());
		outToServer.write(ToByte.getBytes(paket.getPaket(0),"hex"));//cli_ident
		io.serverAntwort();
		ausgabe(ToHex.getHex(io.serverRe));
		System.out.println();
		outToServer.write(ToByte.getBytes(paket.getPaket(1),"hex"));//disconnect
		io=new I_OSever("login.icq.com",80);
		outToServer.write(ToByte.getBytes(paket.getPaket(2),"hex"));//cli_cookie
		io.serverAntwort();
		//ausgabe(ToHex.getHex(io.serverRe));
		io.verbindung.close();
				
	}
```
Fehlermeldung: Exception in thread "main" java.net.SocketException: Connection reset by peer: socket write error
	at java.net.SocketOutputStream.socketWrite0(Native Method)
	at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
	at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
	at java.io.DataOutputStream.write(DataOutputStream.java:90)
	at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
	at Client.main(Client.java:27)

meine fragen sind verbinde ich überhaupt zum bos sever? muss ich den socket closen und dann neu verbinden oder geht das so("2a 04 00 02 00 00")?

z.Z. ist noch vieles static wird später erst geändert.


----------

