Clientinit is finally being accepted
[DEBUG] error id=525 msg=client\sis\smodified
This commit is contained in:
+9
-21
@@ -151,6 +151,8 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
|||||||
} else if (packet.getBody() instanceof PacketBody2Command) {
|
} else if (packet.getBody() instanceof PacketBody2Command) {
|
||||||
SimpleCommand command = ((PacketBody2Command) packet.getBody()).parse();
|
SimpleCommand command = ((PacketBody2Command) packet.getBody()).parse();
|
||||||
|
|
||||||
|
Ts3Debugging.debug(command.build());
|
||||||
|
|
||||||
if (command.getName().equalsIgnoreCase("initivexpand2")) {
|
if (command.getName().equalsIgnoreCase("initivexpand2")) {
|
||||||
// 3.2.2 initivexpand2 (Client <- Server)
|
// 3.2.2 initivexpand2 (Client <- Server)
|
||||||
|
|
||||||
@@ -160,9 +162,9 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
|||||||
throw new IllegalArgumentException("ot constant != 1: " + command.get("ot").getValue());
|
throw new IllegalArgumentException("ot constant != 1: " + command.get("ot").getValue());
|
||||||
|
|
||||||
byte[] license = Base64.getDecoder().decode(command.get("l").getValue());
|
byte[] license = Base64.getDecoder().decode(command.get("l").getValue());
|
||||||
byte[] licsense_validation = !command.has("tvd") ?
|
/*byte[] licsense_validation = !command.has("tvd") && command.get("tvd").getValue() != null ?
|
||||||
null :
|
null :
|
||||||
Base64.getDecoder().decode(command.get("tvd").getValue());
|
Base64.getDecoder().decode(command.get("tvd").getValue());*/
|
||||||
|
|
||||||
byte[] beta = Base64.getDecoder().decode(command.get("beta").getValue()); // beta
|
byte[] beta = Base64.getDecoder().decode(command.get("beta").getValue()); // beta
|
||||||
byte[] omega = Base64.getDecoder().decode(command.get("omega").getValue()); // omega
|
byte[] omega = Base64.getDecoder().decode(command.get("omega").getValue()); // omega
|
||||||
@@ -187,29 +189,19 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
|||||||
|
|
||||||
Ts3Debugging.debug("Sending clientek...");
|
Ts3Debugging.debug("Sending clientek...");
|
||||||
|
|
||||||
PacketBody2Command clientek = new PacketBody2Command(ProtocolRole.CLIENT);
|
getClient().sendCommand(
|
||||||
clientek.setText(
|
|
||||||
new SimpleCommand(
|
new SimpleCommand(
|
||||||
"clientek", ProtocolRole.CLIENT,
|
"clientek", ProtocolRole.CLIENT,
|
||||||
new CommandSingleParameter("ek", Base64.getEncoder().encodeToString(keyPair.getKey())),
|
new CommandSingleParameter("ek", Base64.getEncoder().encodeToString(keyPair.getKey())),
|
||||||
new CommandSingleParameter("proof", Base64.getEncoder().encodeToString(signature))
|
new CommandSingleParameter("proof", Base64.getEncoder().encodeToString(signature))
|
||||||
).build()
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Ts3Debugging.debug(clientek.getText());
|
getClient().setSecureParameters(Ts3Crypt.cryptoInit2(license, alphaBytes, beta, keyPair.getValue()));
|
||||||
|
|
||||||
getClient().writePacket(clientek);
|
|
||||||
|
|
||||||
getClient().setSecureParameters(
|
|
||||||
Ts3Crypt.cryptoInit2(license, alphaBytes, omega, proof, beta, keyPair.getValue())
|
|
||||||
);
|
|
||||||
|
|
||||||
Ts3Debugging.debug("Sending clientinit...");
|
Ts3Debugging.debug("Sending clientinit...");
|
||||||
|
|
||||||
PacketBody2Command clientinit = new PacketBody2Command(ProtocolRole.CLIENT);
|
getClient().sendCommand(new SimpleCommand(
|
||||||
|
|
||||||
clientinit.setText(
|
|
||||||
new SimpleCommand(
|
|
||||||
"clientinit",
|
"clientinit",
|
||||||
ProtocolRole.CLIENT,
|
ProtocolRole.CLIENT,
|
||||||
new CommandSingleParameter("client_nickname", "test"),
|
new CommandSingleParameter("client_nickname", "test"),
|
||||||
@@ -235,12 +227,8 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
|||||||
"hwid",
|
"hwid",
|
||||||
"+LyYqbDqOvJJpN5pdAbF8/v5kZ0="
|
"+LyYqbDqOvJJpN5pdAbF8/v5kZ0="
|
||||||
)
|
)
|
||||||
).build()
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Ts3Debugging.debug(clientinit.getText());
|
|
||||||
|
|
||||||
getClient().writePacket(clientinit);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-17
@@ -5,6 +5,7 @@ import com.github.manevolent.ts3j.command.response.CommandResponse;
|
|||||||
import com.github.manevolent.ts3j.identity.Identity;
|
import com.github.manevolent.ts3j.identity.Identity;
|
||||||
import com.github.manevolent.ts3j.protocol.NetworkPacket;
|
import com.github.manevolent.ts3j.protocol.NetworkPacket;
|
||||||
import com.github.manevolent.ts3j.protocol.Packet;
|
import com.github.manevolent.ts3j.protocol.Packet;
|
||||||
|
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||||
import com.github.manevolent.ts3j.protocol.SocketRole;
|
import com.github.manevolent.ts3j.protocol.SocketRole;
|
||||||
import com.github.manevolent.ts3j.protocol.client.ClientConnectionState;
|
import com.github.manevolent.ts3j.protocol.client.ClientConnectionState;
|
||||||
import com.github.manevolent.ts3j.protocol.header.ClientPacketHeader;
|
import com.github.manevolent.ts3j.protocol.header.ClientPacketHeader;
|
||||||
@@ -36,9 +37,9 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
|
|
||||||
private final Object connectionStateLock = new Object();
|
private final Object connectionStateLock = new Object();
|
||||||
private final LinkedBlockingDeque<Packet> readQueue = new LinkedBlockingDeque<>(65536);
|
private final LinkedBlockingDeque<Packet> readQueue = new LinkedBlockingDeque<>(65536);
|
||||||
private final Map<PacketBodyType, Reassembly> reassemblyQueue = new LinkedHashMap<>();
|
private final Map<PacketBodyType, Reassembly> reassemblyQueue = new ConcurrentHashMap<>();
|
||||||
private final Map<String, Object> clientOptions = new LinkedHashMap<>();
|
private final Map<String, Object> clientOptions = new ConcurrentHashMap<>();
|
||||||
private final Map<Integer, PacketResponse> sendQueue = new LinkedHashMap<>();
|
private final Map<Integer, PacketResponse> sendQueue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private Identity identity = null;
|
private Identity identity = null;
|
||||||
private ClientConnectionState connectionState = null;
|
private ClientConnectionState connectionState = null;
|
||||||
@@ -153,12 +154,12 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a command to the remote server.
|
* Sends a command to the remote.
|
||||||
* @param command Command to send.
|
* @param command Command to send.
|
||||||
* @return Command response object to track command response.
|
* @return Command response object to track command response.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public CommandResponse sendCommand(Command command) throws IOException {
|
public CommandResponse sendCommand(Command command) throws IOException, TimeoutException {
|
||||||
if (command.willExpectResponse() && !isConnected())
|
if (command.willExpectResponse() && !isConnected())
|
||||||
throw new IOException("not connected");
|
throw new IOException("not connected");
|
||||||
|
|
||||||
@@ -175,9 +176,12 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
|
|
||||||
response.setDispatchedTime(System.currentTimeMillis());
|
response.setDispatchedTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
writePacket(new PacketBody2Command(ProtocolRole.CLIENT, command));
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writePacket(PacketBody body) throws IOException, TimeoutException {
|
public void writePacket(PacketBody body) throws IOException, TimeoutException {
|
||||||
PacketHeader header;
|
PacketHeader header;
|
||||||
@@ -316,7 +320,7 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
|
|
||||||
// Find if the packet must be acknowledged and create a promise for that action
|
// Find if the packet must be acknowledged and create a promise for that action
|
||||||
boolean willAcknowledge = packet.getHeader().getType().getAcknolwedgedBy() != null;
|
boolean willAcknowledge = packet.getHeader().getType().getAcknolwedgedBy() != null;
|
||||||
PacketResponse response;
|
final PacketResponse response;
|
||||||
|
|
||||||
if (willAcknowledge)
|
if (willAcknowledge)
|
||||||
sendQueue.put(
|
sendQueue.put(
|
||||||
@@ -342,15 +346,14 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
if (getState() == ClientConnectionState.DISCONNECTED)
|
if (getState() == ClientConnectionState.DISCONNECTED)
|
||||||
throw new IllegalStateException("no longer connected");
|
throw new IllegalStateException("no longer connected");
|
||||||
|
|
||||||
response.getFuture().get(1000L, TimeUnit.MILLISECONDS);
|
// Wait one cycle for an ACK
|
||||||
|
response.waitForAcknowledgement(1000);
|
||||||
break;
|
break;
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
response.resend();
|
response.resend();
|
||||||
} catch (CancellationException e) {
|
} catch (CancellationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -456,9 +459,11 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
// Find if the packet is itself an acknowledgement
|
// Find if the packet is itself an acknowledgement
|
||||||
switch (packet.getHeader().getType()) {
|
switch (packet.getHeader().getType()) {
|
||||||
case ACK:
|
case ACK:
|
||||||
int packetId = packet.getHeader().getPacketId();
|
int packetId = ((PacketBody6Ack)packet.getBody()).getPacketId();
|
||||||
PacketResponse response = sendQueue.get(packetId);
|
PacketResponse response = sendQueue.get(packetId);
|
||||||
if (response != null) response.getFuture().complete(packet);
|
if (response != null) {
|
||||||
|
response.acknowledge(packet);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACK_LOW:
|
case ACK_LOW:
|
||||||
break;
|
break;
|
||||||
@@ -578,9 +583,9 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
|
|
||||||
private class PacketResponse {
|
private class PacketResponse {
|
||||||
private final NetworkPacket sentPacket;
|
private final NetworkPacket sentPacket;
|
||||||
private final CompletableFuture future = new CompletableFuture<>();
|
private final CompletableFuture<Packet> future = new CompletableFuture<>();
|
||||||
private long lastSent = 0L;
|
private long lastSent = 0L;
|
||||||
private int tries, maxTries;
|
private int tries = 1, maxTries;
|
||||||
private boolean willResend;
|
private boolean willResend;
|
||||||
|
|
||||||
public PacketResponse(NetworkPacket sentPacket,int maxTries) {
|
public PacketResponse(NetworkPacket sentPacket,int maxTries) {
|
||||||
@@ -596,10 +601,23 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
|
|
||||||
public void resend() throws IOException {
|
public void resend() throws IOException {
|
||||||
AbstractTeamspeakClientSocket.this.writeNetworkPacket(sentPacket);
|
AbstractTeamspeakClientSocket.this.writeNetworkPacket(sentPacket);
|
||||||
|
setLastSent(System.currentTimeMillis());
|
||||||
tries ++;
|
tries ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean waitForAcknowledgement()
|
||||||
|
throws ExecutionException, InterruptedException {
|
||||||
|
Packet acknowledgement = future.get();
|
||||||
|
return acknowledgement != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean waitForAcknowledgement(long millis)
|
||||||
|
throws TimeoutException, ExecutionException, InterruptedException {
|
||||||
|
Packet acknowledgement = future.get(millis, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
return acknowledgement != null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isWillResend() {
|
public boolean isWillResend() {
|
||||||
return willResend;
|
return willResend;
|
||||||
}
|
}
|
||||||
@@ -616,8 +634,8 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
return lastSent;
|
return lastSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture getFuture() {
|
public void acknowledge(Packet p) {
|
||||||
return future;
|
future.complete(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastSent(long lastSent) {
|
public void setLastSent(long lastSent) {
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ public class LocalTeamspeakClientSocket extends AbstractTeamspeakClientSocket {
|
|||||||
setGenerationId(0);
|
setGenerationId(0);
|
||||||
|
|
||||||
setOption("client.hostname", remote.getHostString());
|
setOption("client.hostname", remote.getHostString());
|
||||||
setOption("client.password", password);
|
//setOption("client.password", password);
|
||||||
|
|
||||||
socket.connect(remote);
|
socket.connect(remote);
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public final class Ts3Crypt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Ts3Crypt.SecureChannelParameters cryptoInit2(byte[] license, byte[] alpha,
|
public static Ts3Crypt.SecureChannelParameters cryptoInit2(byte[] license, byte[] alpha,
|
||||||
byte[] omega, byte[] proof,
|
|
||||||
byte[] beta, byte[] privateKey) {
|
byte[] beta, byte[] privateKey) {
|
||||||
// 3.2.2.2 Parsing the license
|
// 3.2.2.2 Parsing the license
|
||||||
List<License> licenses = License.readLicenses(ByteBuffer.wrap(license));
|
List<License> licenses = License.readLicenses(ByteBuffer.wrap(license));
|
||||||
|
|||||||
@@ -15,13 +15,11 @@ public class CryptoInit2Test extends TestCase {
|
|||||||
public void testParser() throws Exception {
|
public void testParser() throws Exception {
|
||||||
byte[] licenseBytes = hexStringToByteArray("0100358541498A24ACD30157918B8F50955C0DAE970AB65372CBE407415FCF3E029B02084D15E00AA793600700000020416E6F6E796D6F7573000047D9E4DC25AA2E90ACD4DB5FA61C8FED369B346D84C2CA2FCCCA86F73AFEF092200A77C8810A787141");
|
byte[] licenseBytes = hexStringToByteArray("0100358541498A24ACD30157918B8F50955C0DAE970AB65372CBE407415FCF3E029B02084D15E00AA793600700000020416E6F6E796D6F7573000047D9E4DC25AA2E90ACD4DB5FA61C8FED369B346D84C2CA2FCCCA86F73AFEF092200A77C8810A787141");
|
||||||
byte[] alpha = hexStringToByteArray("9500A5DB3B50ACECAB81");
|
byte[] alpha = hexStringToByteArray("9500A5DB3B50ACECAB81");
|
||||||
byte[] omega = hexStringToByteArray("304B03020700020120022025D13CF0C5A17A467961B04418E015941D6C6558DA6AEC79CFFDDA1DEF8AB55202200F3B3F0D3A4F1C5C02AD1F9A3A5114AC58E89905792FBB83AD4FFE7F82ACAADA");
|
|
||||||
byte[] proof = hexStringToByteArray("3046022100F4B921DDB2C9737D9AB100BA251D11216DF1601C62AF17150E6FC29A2C6EEC0F022100FC8948E595BBD895A2FDFE0EB22A5241655BD47591F8D2733035CF76A72245AD");
|
|
||||||
byte[] beta = hexStringToByteArray("EAFFC9A8BC996B25C8AA700264E99E372ECCDEB1C121D6EC0F4D49FB46CEEBA4E3C724B3070FD70CB03D7BC08129205690ECE228CA7C");
|
byte[] beta = hexStringToByteArray("EAFFC9A8BC996B25C8AA700264E99E372ECCDEB1C121D6EC0F4D49FB46CEEBA4E3C724B3070FD70CB03D7BC08129205690ECE228CA7C");
|
||||||
byte[] privateKey = hexStringToByteArray("102E591ABA4508129E812FF3437E2DDD3CA1F1EC341117CA3514CC347A7C2A77");
|
byte[] privateKey = hexStringToByteArray("102E591ABA4508129E812FF3437E2DDD3CA1F1EC341117CA3514CC347A7C2A77");
|
||||||
|
|
||||||
Ts3Crypt.SecureChannelParameters result =
|
Ts3Crypt.SecureChannelParameters result =
|
||||||
Ts3Crypt.cryptoInit2(licenseBytes, alpha, omega, proof, beta, privateKey);
|
Ts3Crypt.cryptoInit2(licenseBytes, alpha, beta, privateKey);
|
||||||
|
|
||||||
assertEquals(Ts3Debugging.getHex(result.getIvStruct()), "E4082A92F71C96A947452F5582EF2879B2051ED2D3F2C6B0643CF5A266EE6B5180573C2F5F3F1C4AC579188366F16AE0EADC3AAF860805D8F2A831E9E49F4513");
|
assertEquals(Ts3Debugging.getHex(result.getIvStruct()), "E4082A92F71C96A947452F5582EF2879B2051ED2D3F2C6B0643CF5A266EE6B5180573C2F5F3F1C4AC579188366F16AE0EADC3AAF860805D8F2A831E9E49F4513");
|
||||||
assertEquals(Ts3Debugging.getHex(result.getFakeSignature()), "54F2B4D661E0F9AB");
|
assertEquals(Ts3Debugging.getHex(result.getFakeSignature()), "54F2B4D661E0F9AB");
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class ServerConnectionTest {
|
|||||||
client.setIdentity(localIdentity);
|
client.setIdentity(localIdentity);
|
||||||
|
|
||||||
client.connect(new InetSocketAddress(
|
client.connect(new InetSocketAddress(
|
||||||
"voice.teamspeak.com",
|
"ts.teamlixo.net",
|
||||||
9987),
|
9987),
|
||||||
null,
|
null,
|
||||||
10000L
|
10000L
|
||||||
|
|||||||
Reference in New Issue
Block a user