Sign in to myTeamSpeak and import what the account synchronises

The myTeamSpeak client protocol and its end-to-end encryption are
reverse-engineered (docs/myteamspeak): an HTTP POST of a framed protobuf,
a PBKDF2-HMAC-SHA512 login token and account key, an AES-GCM wrapped
item key and AES-CTR items with a SHA-512 trailer.

Options on desktop and Settings on Android gain a myTeamSpeak page: sign
in and out, and the account's bookmarks and identities, each picked for
import and marked when already here. The client stays signed in the way
the official one does, keeping the derived token and key rather than the
password; each read signs in afresh, and a sign-in the server no longer
takes signs out. Nothing is written to the account.

Items are the same Item_Data as the local TeamSpeak store, so they go
through the existing decoder and importer; a bookmark chosen alone brings
the identity it connects with, found by UUID or, as some name it, by
the identity's name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 01:07:17 +00:00
parent 73a15a8cfc
commit a7aa122728
25 changed files with 3425 additions and 32 deletions

View File

@@ -9,6 +9,7 @@ import com.ts3client.config.Bookmark;
import com.ts3client.config.Bookmarks;
import com.ts3client.config.IdentityStore;
import com.ts3client.config.Settings;
import com.ts3client.myts.MyTeamSpeakLogin;
import com.ts3client.teamspeak.TeamSpeakImporter;
import com.ts3client.contacts.ContactStore;
import com.ts3client.net.ChannelNode;
@@ -55,6 +56,7 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
private final Bookmarks bookmarks = Bookmarks.load();
private final AwayMessages awayMessages = AwayMessages.load();
private final IdentityStore identities;
private final MyTeamSpeakLogin myTeamSpeak = MyTeamSpeakLogin.load();
/** Friends and blocked clients, shared by every connection. */
private final ContactStore contacts = ContactStore.load();
private final AudioBackend audio = new DesktopAudioBackend();
@@ -787,6 +789,8 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
sessions.microphoneOwner() == null ? null : sessions.microphoneOwner().connection().getMicrophone(),
selected == null ? null : selected.connection().getPlayback(),
sounds, hotkeys,
new MyTeamSpeakPanel(myTeamSpeak, new TeamSpeakImporter(identities, bookmarks, settings),
menuBar::rebuildBookmarks),
() -> {
applyOutputSettingsToAllTabs();
contactsChanged();