/*******************************************************************************
Jimm - Mobile Messaging - J2ME ICQ clone
Copyright (C) 2003-05 Jimm Project
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************
File: src/jimm/comm/ConnectPacket.java
Version: ###VERSION### Date: ###DATE###
Author(s): Manuel Linsmayer, Andreas Rossbacher
*******************************************************************************/
// #sijapp cond.if protocols_ICQ is "true" #
package protocol.icq.packet;
import jimm.JimmException;
import jimm.comm.*;
public class ConnectPacket extends Packet {
// Packet types
public static final int SRV_CLI_HELLO = 1;
public static final int CLI_COOKIE = 2;
public static final int CLI_IDENT = 3;
// Cookie (!= null only if packet type is CLI_COOKIE)
protected byte[] cookie;
// UIN (!= null only if packet type is CLI_IDENT)
protected String uin;
// Password (unencrypted, != null only if packet type is CLI_IDENT)
protected String password;
// Constructs a SRV_HELLO/CLI_HELLO packet
public ConnectPacket() {
this.cookie = null;
this.uin = null;
this.password = null;
}
// Constructs a CLI_COOKIE packet
public ConnectPacket(byte[] cookie) {
this.cookie = new byte[cookie.length];
System.arraycopy(cookie, 0, this.cookie, 0, cookie.length);
this.uin = null;
this.password = null;
}
// Constructs a CLI_IDENT packet
public ConnectPacket(String uin, String password) {
this.cookie = null;
this.uin = uin;
this.password = password;
}
// Returns the packet type
public int getType() {
if ((this.cookie == null) && (this.uin == null)) {
return (ConnectPacket.SRV_CLI_HELLO);
} else if (this.uin != null) {
return (ConnectPacket.CLI_IDENT);
} else {
return (ConnectPacket.CLI_COOKIE);
}
}
// Returns the cookie, or null if packet type is not CLI_COOKIE
public byte[] getCookie() {
if (ConnectPacket.CLI_COOKIE == this.getType()) {
byte[] result = new byte[this.cookie.length];
System.arraycopy(this.cookie, 0, result, 0, this.cookie.length);
return (result);
} else {
return (null);
}
}
public static void putVersion(OutStream stream, boolean first) {
if (first) {
stream.writeTLV(0x4C, null);
}
stream.writeTLVWord(0xA2, 0x05);
stream.writeTLVWord(0xA3, 0x05);
stream.writeTLVWord(0xA4, 0x00);
stream.writeTLVWord(0xA5, 0x17F2);
stream.writeTLV(0x03, "ICQ Client".getBytes());
stream.writeTLVWord(0x17, 20);
//stream.writeTLVWord(0x1B, 0x00);
stream.writeTLVWord(0x18, 52);
stream.writeTLVWord(0x19, 0);
stream.writeTLVWord(0x1A, 3003);
stream.writeTLVWord(0x16, 266);
stream.writeTLV(0x14, new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x3D});
stream.writeTLV(0x0F, "en".getBytes());
stream.writeTLV(0x0E, "us".getBytes());
if (!first) {
stream.writeTLVWord(0x9e, 0x0002);
}
if (!first) {
stream.writeTLVWord(0x9F, 0x0000);
stream.writeTLVWord(0xA0, 0x0000);
stream.writeTLVWord(0xA1, 0x08AF);
stream.writeTLVByte(0x94, 0x00);
}
stream.writeTLVByte(0x4A, 0x01);
if (!first) {
stream.writeTLVByte(0xAC, 0x00);
}
}
public static void putLiteVersion(OutStream stream, boolean first) {
if (first) {
stream.writeTLV(0x4C, null);
}
stream.writeTLVWord(0xA2, 0x05);
stream.writeTLVWord(0xA3, 0x05);
stream.writeTLVWord(0xA4, 0x00);
stream.writeTLVWord(0xA5, 0x17F2);
stream.writeTLV(0x03, "ICQ Client".getBytes());
stream.writeTLVWord(0x17, 0x14);
//stream.writeTLVWord(0x1B, 0x00);
stream.writeTLVWord(0x18, 0x34);
stream.writeTLVWord(0x19, 0x00);
stream.writeTLVWord(0x1A, 0x0BBB);
stream.writeTLVWord(0x16, 0x010A);
stream.writeTLV(0x14, new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x3D});
stream.writeTLV(0x0F, "ru".getBytes());
stream.writeTLV(0x0E, "ru".getBytes());
if (!first) {
stream.writeTLVWord(0x9e, 0x0002);
}
if (!first) {
stream.writeTLVWord(0x9F, 0x0000);
stream.writeTLVWord(0xA0, 0x0000);
stream.writeTLVWord(0xA1, 0x08AF);
stream.writeTLVByte(0x94, 0x00);
}
stream.writeTLVByte(0x4A, 0x01);
if (!first) {
stream.writeTLVByte(0xAC, 0x00);
}
}
// Returns the package as byte array
public byte[] toByteArray() {
OutStream buf = new OutStream();
// header
buf.writeZeroes(6);
// Assemble HELLO.HELLO
buf.writeDWordBE(0x00000001);
// Assemble CLI_COOKIE
if (this.getType() == ConnectPacket.CLI_COOKIE) {
// HELLO.COOKIE
buf.writeTLV(0x0006, this.cookie);
// Assemble CLI_IDENT
} else if (this.getType() == ConnectPacket.CLI_IDENT) {
if (-1 != uin.indexOf('@')) {
buf.writeTLV(0x0056, null);
}
// HELLO.UIN
buf.writeTLV(0x0001, StringUtils.stringToByteArray(this.uin));
// HELLO.PASSWORD
buf.writeTLV(0x0002, Util.decipherPassword(
StringUtils.stringToByteArray(this.password)));
} else {
buf.writeTLVDWord(0x8003, 0x00100000);
}
if (this.getType() == ConnectPacket.CLI_COOKIE) {
ConnectPacket.putVersion(buf, false);
buf.writeTLVDWord(0x8003, 0x00100000);
} else if (this.getType() == ConnectPacket.CLI_IDENT) {
if (0 < uin.indexOf('@')) {
ConnectPacket.putVersion(buf, true);
buf.writeTLVDWord(0x8003, 0x00100000);
}
}
byte[] _buf = buf.toByteArray();
assembleFlapHeader(_buf, 0x01);
return _buf;
}
// Parses given byte array and returns a Packet object
public static Packet parse(byte[] flapData) throws JimmException {
// Check HELLO
if ((flapData.length < 4) || (Util.getDWordBE(flapData, 0) != 0x00000001)) {
throw new JimmException(132, 0);
}
// Variables for all possible TLVs
byte[] cookie = null;
String uin = null;
String password = null;
String version = null;
byte[] unknown = null;
// Read all TLVs
ArrayReader marker = new ArrayReader(flapData, 4);
while (marker.isNotEnd()) {
int tlvType = marker.getTlvType();
byte[] tlvValue = marker.getTlv();
if (tlvValue == null) {
throw new JimmException(132, 1);
}
// Save value
switch (tlvType) {
case 0x0006: // cookie
cookie = tlvValue;
break;
case 0x0001: // uin
uin = StringUtils.byteArrayToAsciiString(tlvValue);
break;
case 0x0002: // password
password = StringUtils.byteArrayToAsciiString(Util.decipherPassword(tlvValue));
break;
case 0x0003: // version
version = StringUtils.byteArrayToAsciiString(tlvValue);
break;
case 0x0016: // unknown
unknown = tlvValue;
break;
}
}
// SRV_HELLO/CLI_HELLO
if ((cookie == null) && (uin == null) && (password == null) && (version == null) && (unknown == null)) {
return new ConnectPacket();
// SRV_COOKIE
} else if ((cookie != null) && (uin == null) && (password == null) && (version == null) && (unknown == null)) {
return new ConnectPacket(cookie);
// CLI_IDENT
} else if ((cookie == null) && (uin != null) && (password != null) && (version != null) && (unknown != null)) {
return new ConnectPacket(uin, password);
// Other TLV combinations are not valid
} else {
throw new JimmException(132, 3);
}
}
}
// #sijapp cond.end #