Skip to content

Commit

Permalink
Add szOwner to BannedUser-struct
Browse files Browse the repository at this point in the history
User who created a ban is now stored and displayed in Banned Users
dialog.
  • Loading branch information
bear101 committed Oct 21, 2023
1 parent 25b7d0e commit d1dde4e
Show file tree
Hide file tree
Showing 19 changed files with 125 additions and 26 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Default Qt Client
- Fixed state of "Close when completed" checkbox on "Transfer file" dialog
- Support for 320 KBit MP3 recording (Windows only)
- Support for banning IP-address as subnet, e.g. 192.168.0.0/24 or 2a02:09b0:402b:eed8::/63
- Username of user creating a ban is visible in "Banned Users" dialog
Android Client
- Fixed importing of tt files on newer android versions
- It is now possible to select a language of TeamTalk on Android 13 and above from app languages settings.
Expand All @@ -20,6 +21,7 @@ Server
- User right to prevent private text messages
- User right to prevent channel text messages
- Support for banning IP-address as subnet, e.g. 192.168.0.0/24 or 2a02:09b0:402b:eed8::/63
- Owner of ban is stored

Version 5.14, 2023/08/16
Default Qt Client
Expand Down
3 changes: 2 additions & 1 deletion Client/jSpamBot/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ if (Java_FOUND)

option (BUILD_TEAMTALK_JTEAMTALKSPAMBOT "Build TeamTalk Anti Spam Bot" ON)

set (JAVA_SOURCES src/SpamBotSession.java src/WebLogin.java src/Main.java src/TeamTalkServer.java)
set (JAVA_SOURCES src/SpamBotSession.java src/WebLogin.java
src/Main.java src/TeamTalkServer.java src/IPBan.java)

if (BUILD_TEAMTALK_JTEAMTALKSPAMBOT)

Expand Down
23 changes: 21 additions & 2 deletions Client/jSpamBot/src/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public static void main(String[] args) throws IOException, InterruptedException,

WebLogin weblogin = new WebLogin(username, passwd);

IPBan bans = new IPBan();
bans.loadFile("vpnips.txt");

Map<String, String> files_badwords = new HashMap<>();
// languages must be lower case
files_badwords.put("", "badwords.txt");
Expand Down Expand Up @@ -80,15 +83,18 @@ public static void main(String[] args) throws IOException, InterruptedException,
// update list of spambot servers
if (System.nanoTime() >= serverlistUpdateTimeout) {
System.out.println("Updating server list...");
var servers = weblogin.getServerList();
var servers = getServerList();
if (servers.size() == 0)
servers = weblogin.getServerList();

if (!lastServers.equals(servers)) {
System.out.println("Dirty server list. Updating...");
for (var session : sessions) {
session.close();
}
sessions.clear();
for (var server : servers) {
sessions.add(new SpamBotSession(server, weblogin, lang_badwords));
sessions.add(new SpamBotSession(server, weblogin, bans, lang_badwords));
}
lastServers = servers;
}
Expand Down Expand Up @@ -135,4 +141,17 @@ static String getInput(String prompt, String def) {
System.out.print(prompt);
return getInput(def);
}

static Vector<TeamTalkServer> getServerList() {
Vector<TeamTalkServer> servers = new Vector<>();
String ipaddr = System.getProperty("dk.bearware.test.server.ipaddr");
if (ipaddr != null) {
int tcpport = Integer.parseInt(System.getProperty("dk.bearware.test.server.tcpport"));
int udpport = Integer.parseInt(System.getProperty("dk.bearware.test.server.udpport"));
int encrypted = Integer.parseInt(System.getProperty("dk.bearware.test.server.encrypted"));
TeamTalkServer s = new TeamTalkServer(ipaddr, tcpport, udpport, encrypted != 0);
servers.add(s);
}
return servers;
}
}
58 changes: 45 additions & 13 deletions Client/jSpamBot/src/SpamBotSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,21 @@ public class SpamBotSession

TeamTalkServer server;
WebLogin loginsession;
IPBan bans;
Vector<String> badwords;
Map<String, Vector<String>> langbadwords;
enum CmdComplete {
CMD_NONE,
CMD_LISTBANS
}
Map<Integer, CmdComplete> activecommands = new HashMap<>();

int cmdid_completed = 0, cmdid_success = 0;

SpamBotSession(TeamTalkServer srv, WebLogin loginsession, Map<String, Vector<String>> langbadwords) {
SpamBotSession(TeamTalkServer srv, WebLogin loginsession, IPBan bans, Map<String, Vector<String>> langbadwords) {
this.server = srv;
this.loginsession = loginsession;
this.bans = bans;
this.langbadwords = langbadwords;
handler.addConnectionListener(this);
handler.addCommandListener(this);
Expand Down Expand Up @@ -213,27 +220,31 @@ public void onCmdMyselfLoggedIn(int userid, UserAccount useraccount) {
if((useraccount.uUserRights & UserRight.USERRIGHT_BAN_USERS) != 0)
System.out.println("\tBan users");
if((useraccount.uUserRights & UserRight.USERRIGHT_MODIFY_CHANNELS) != 0)
System.out.println("\tModify all channels");
System.out.println("\tModify all channels");
if((useraccount.uUserRights & UserRight.USERRIGHT_TRANSMIT_VOICE) != 0)
System.out.println("\tTransmit voice");
System.out.println("\tTransmit voice");
if((useraccount.uUserRights & UserRight.USERRIGHT_TRANSMIT_VIDEOCAPTURE) != 0)
System.out.println("\tTransmit video from webcam");
System.out.println("\tTransmit video from webcam");
if((useraccount.uUserRights & UserRight.USERRIGHT_TRANSMIT_DESKTOP) != 0)
System.out.println("\tTransmit desktop");
System.out.println("\tTransmit desktop");
if((useraccount.uUserRights & UserRight.USERRIGHT_TRANSMIT_DESKTOPINPUT) != 0)
System.out.println("\tControl desktops");
System.out.println("\tControl desktops");
if((useraccount.uUserRights & UserRight.USERRIGHT_TRANSMIT_MEDIAFILE_VIDEO) != 0)
System.out.println("\tTransmit media files containing video");
System.out.println("\tTransmit media files containing video");
if((useraccount.uUserRights & UserRight.USERRIGHT_TRANSMIT_MEDIAFILE_AUDIO) != 0)
System.out.println("\tTransmit media files containing audio");
System.out.println("\tTransmit media files containing audio");
if((useraccount.uUserRights & UserRight.USERRIGHT_DOWNLOAD_FILES) != 0)
System.out.println("\tDownload files");
System.out.println("\tDownload files");
if((useraccount.uUserRights & UserRight.USERRIGHT_UPLOAD_FILES) != 0)
System.out.println("\tUpload files");
System.out.println("\tUpload files");

joinChannel(useraccount);
setupBadWords(useraccount);
syncBans(useraccount);
}

void joinChannel(UserAccount account) {
// see if spambot should join initial channel
UserAccount account = new UserAccount();
ttclient.getMyUserAccount(account);
if (!account.szInitChannel.isEmpty()) {
int chanid = ttclient.getChannelIDFromPath(account.szInitChannel);
Channel chan = new Channel();
Expand All @@ -247,7 +258,9 @@ public void onCmdMyselfLoggedIn(int userid, UserAccount useraccount) {
}
ttclient.doJoinChannel(chan);
}
}

void setupBadWords(UserAccount account) {
badwords = new Vector<>();
for (String lang : account.szNote.toLowerCase(Locale.ROOT).split(",")) {
if (langbadwords.get(lang) != null) {
Expand All @@ -257,15 +270,34 @@ public void onCmdMyselfLoggedIn(int userid, UserAccount useraccount) {
}
}

void syncBans(UserAccount account) {
if ((account.uUserRights & UserRight.USERRIGHT_BAN_USERS) == UserRight.USERRIGHT_BAN_USERS) {
activecommands.put(ttclient.doListBans(0, 0, 1000000), CmdComplete.CMD_LISTBANS);
}
}


@Override
public void onCmdMyselfLoggedOut() {
ttclient.disconnect();
}

@Override
public void onCmdProcessing(int cmdid, boolean complete) {
if(complete)
if(complete) {
cmdid_completed = cmdid;

var v = activecommands.get(cmdid);
switch (v == null ? CmdComplete.CMD_NONE : v) {
case CmdComplete.CMD_LISTBANS :
this.bans.syncBans(this.ttclient);
break;
}
activecommands.remove(cmdid);
// if (activecommands.get(cmdid) == CmdComplete.CMD_LISTBANS) {

// }
}
}

@Override
Expand Down
28 changes: 23 additions & 5 deletions Client/qtTeamTalk/bannedusersdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum
COLUMN_INDEX_USERNAME,
COLUMN_INDEX_BANTYPE,
COLUMN_INDEX_BANTIME,
COLUMN_INDEX_OWNER,
COLUMN_INDEX_CHANPATH,
COLUMN_INDEX_IPADDRESS,
COLUMN_COUNT_BANNEDUSERS
Expand All @@ -54,6 +55,7 @@ QVariant BannedUsersModel::headerData ( int section, Qt::Orientation orientation
case COLUMN_INDEX_USERNAME: return tr("Username");
case COLUMN_INDEX_BANTYPE: return tr("Ban type");
case COLUMN_INDEX_BANTIME: return tr("Ban Time");
case COLUMN_INDEX_OWNER: return tr("Owner");
case COLUMN_INDEX_CHANPATH: return tr("Channel");
case COLUMN_INDEX_IPADDRESS: return tr("IP-address");
}
Expand Down Expand Up @@ -92,6 +94,8 @@ QVariant BannedUsersModel::data ( const QModelIndex & index, int role /*= Qt::Di
}
case COLUMN_INDEX_BANTIME :
return _Q(m_users[index.row()].szBanTime);
case COLUMN_INDEX_OWNER :
return _Q(m_users[index.row()].szOwner);
case COLUMN_INDEX_CHANPATH :
return _Q(m_users[index.row()].szChannelPath);
case COLUMN_INDEX_IPADDRESS :
Expand All @@ -100,7 +104,21 @@ QVariant BannedUsersModel::data ( const QModelIndex & index, int role /*= Qt::Di
break;
case Qt::AccessibleTextRole :
{
return QString("%1: %2, %3: %4, %5: %6, %7: %8, %9: %10, %11: %12").arg(headerData(COLUMN_INDEX_NICKNAME, Qt::Horizontal, Qt::DisplayRole).toString()).arg(data(createIndex(index.row(), COLUMN_INDEX_NICKNAME, index.internalId()), Qt::DisplayRole).toString()).arg(headerData(COLUMN_INDEX_USERNAME, Qt::Horizontal, Qt::DisplayRole).toString()).arg(data(createIndex(index.row(), COLUMN_INDEX_USERNAME, index.internalId()), Qt::DisplayRole).toString()).arg(headerData(COLUMN_INDEX_BANTYPE, Qt::Horizontal, Qt::DisplayRole).toString()).arg(data(createIndex(index.row(), COLUMN_INDEX_BANTYPE, index.internalId()), Qt::DisplayRole).toString()).arg(headerData(COLUMN_INDEX_BANTIME, Qt::Horizontal, Qt::DisplayRole).toString()).arg(data(createIndex(index.row(), COLUMN_INDEX_BANTIME, index.internalId()), Qt::DisplayRole).toString()).arg(headerData(COLUMN_INDEX_CHANPATH, Qt::Horizontal, Qt::DisplayRole).toString()).arg(data(createIndex(index.row(), COLUMN_INDEX_CHANPATH, index.internalId()), Qt::DisplayRole).toString()).arg(headerData(COLUMN_INDEX_IPADDRESS, Qt::Horizontal, Qt::DisplayRole).toString()).arg(data(createIndex(index.row(), COLUMN_INDEX_IPADDRESS, index.internalId()), Qt::DisplayRole).toString());
return QString("%1: %2, %3: %4, %5: %6, %7: %8, %9: %10, %11: %12, %13: %14")
.arg(headerData(COLUMN_INDEX_NICKNAME, Qt::Horizontal, Qt::DisplayRole).toString())
.arg(data(createIndex(index.row(), COLUMN_INDEX_NICKNAME, index.internalId()), Qt::DisplayRole).toString())
.arg(headerData(COLUMN_INDEX_USERNAME, Qt::Horizontal, Qt::DisplayRole).toString())
.arg(data(createIndex(index.row(), COLUMN_INDEX_USERNAME, index.internalId()), Qt::DisplayRole).toString())
.arg(headerData(COLUMN_INDEX_BANTYPE, Qt::Horizontal, Qt::DisplayRole).toString())
.arg(data(createIndex(index.row(), COLUMN_INDEX_BANTYPE, index.internalId()), Qt::DisplayRole).toString())
.arg(headerData(COLUMN_INDEX_BANTIME, Qt::Horizontal, Qt::DisplayRole).toString())
.arg(data(createIndex(index.row(), COLUMN_INDEX_BANTIME, index.internalId()), Qt::DisplayRole).toString())
.arg(headerData(COLUMN_INDEX_OWNER, Qt::Horizontal, Qt::DisplayRole).toString())
.arg(data(createIndex(index.row(), COLUMN_INDEX_OWNER, index.internalId()), Qt::DisplayRole).toString())
.arg(headerData(COLUMN_INDEX_CHANPATH, Qt::Horizontal, Qt::DisplayRole).toString())
.arg(data(createIndex(index.row(), COLUMN_INDEX_CHANPATH, index.internalId()), Qt::DisplayRole).toString())
.arg(headerData(COLUMN_INDEX_IPADDRESS, Qt::Horizontal, Qt::DisplayRole).toString())
.arg(data(createIndex(index.row(), COLUMN_INDEX_IPADDRESS, index.internalId()), Qt::DisplayRole).toString());
}
}
return QVariant();
Expand Down Expand Up @@ -210,11 +228,11 @@ void BannedUsersDlg::slotClose()

void BannedUsersDlg::slotUnbanUser()
{
int index = m_bannedproxy->mapToSource(ui.bannedTreeView->currentIndex()).row();
if(index<0)
auto index = m_bannedproxy->mapToSource(ui.bannedTreeView->currentIndex());
if (!index.isValid())
return;
m_unbannedmodel->addBannedUser(m_bannedmodel->getUsers()[index], true);
m_bannedmodel->delBannedUser(index);
m_unbannedmodel->addBannedUser(m_bannedmodel->getUsers()[index.row()], true);
m_bannedmodel->delBannedUser(index.row());
}

void BannedUsersDlg::slotBanUser()
Expand Down
3 changes: 3 additions & 0 deletions Library/TeamTalk.NET/TeamTalk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2067,6 +2067,9 @@ public struct BannedUser
public string szUsername;
/** @brief The type of ban that applies to this banned user. */
public BanType uBanTypes;
/** @brief The username of the user who made the ban */
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TeamTalkBase.TT_STRLEN)]
public string szOwner;
}

/** @ingroup users
Expand Down
4 changes: 4 additions & 0 deletions Library/TeamTalkJNI/jni/ttconvert-jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1628,13 +1628,15 @@ void setBannedUser(JNIEnv* env, BannedUser& banned, jobject lpBannedUser, JConve
jfieldID fid_nick = env->GetFieldID(cls_ban, "szNickname", "Ljava/lang/String;");
jfieldID fid_username = env->GetFieldID(cls_ban, "szUsername", "Ljava/lang/String;");
jfieldID fid_bantype = env->GetFieldID(cls_ban, "uBanTypes", "I");
jfieldID fid_owner = env->GetFieldID(cls_ban, "szOwner", "Ljava/lang/String;");

assert(fid_ipaddr);
assert(fid_chan);
assert(fid_time);
assert(fid_nick);
assert(fid_username);
assert(fid_bantype);
assert(fid_owner);

if (conv == N2J)
{
Expand All @@ -1644,6 +1646,7 @@ void setBannedUser(JNIEnv* env, BannedUser& banned, jobject lpBannedUser, JConve
env->SetObjectField(lpBannedUser, fid_nick, NEW_JSTRING(env, banned.szNickname));
env->SetObjectField(lpBannedUser, fid_username, NEW_JSTRING(env, banned.szUsername));
env->SetIntField(lpBannedUser, fid_bantype, banned.uBanTypes);
env->SetObjectField(lpBannedUser, fid_owner, NEW_JSTRING(env, banned.szOwner));
}
else
{
Expand All @@ -1654,6 +1657,7 @@ void setBannedUser(JNIEnv* env, BannedUser& banned, jobject lpBannedUser, JConve
TT_STRCPY(banned.szNickname, ttstr(env, (jstring)env->GetObjectField(lpBannedUser, fid_nick)));
TT_STRCPY(banned.szUsername, ttstr(env, (jstring)env->GetObjectField(lpBannedUser, fid_username)));
banned.uBanTypes = env->GetIntField(lpBannedUser, fid_bantype);
TT_STRCPY(banned.szOwner, ttstr(env, (jstring)env->GetObjectField(lpBannedUser, fid_owner)));
}
}

Expand Down
4 changes: 2 additions & 2 deletions Library/TeamTalkJNI/src/dk/bearware/BannedUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@

package dk.bearware;

public class BannedUser
{
public class BannedUser {
public String szIPAddress;
public String szChannelPath;
public String szBanTime;
public String szNickname;
public String szUsername;
public int uBanTypes = 0;
public String szOwner;
}
3 changes: 3 additions & 0 deletions Library/TeamTalkJNI/test/dk/bearware/TeamTalkTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,9 @@ public void testListBannedUsers() {
assertTrue("list bans (expect 1)", ttclient.doListBans(ttclient.getMyChannelID(), 0, 100)>0);

assertTrue("wait ban list", waitForEvent(ttclient, ClientEvent.CLIENTEVENT_CMD_BANNEDUSER, DEF_WAIT, msg));
UserAccount account = new UserAccount();
assertTrue("get my account", ttclient.getMyUserAccount(account));
assertEquals("owner set", account.szUsername, msg.banneduser.szOwner);
msg = new TTMessage();
assertTrue("wait done msg", ttclient.getMessage(msg, DEF_WAIT));
assertEquals("done msg, only one ban expected", msg.nClientEvent, ClientEvent.CLIENTEVENT_CMD_SUCCESS);
Expand Down
2 changes: 2 additions & 0 deletions Library/TeamTalkLib/bin/dll/Convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,7 @@ void Convert(const teamtalk::BannedUser& banuser, BannedUser& result)
ACE_OS::strsncpy(result.szNickname, banuser.nickname.c_str(), TT_STRLEN);
ACE_OS::strsncpy(result.szUsername, banuser.username.c_str(), TT_STRLEN);
ACE_OS::strsncpy(result.szBanTime, teamtalk::DateToString( banuser.bantime ).c_str(), TT_STRLEN);
ACE_OS::strsncpy(result.szOwner, banuser.owner.c_str(), TT_STRLEN);
result.uBanTypes = BanTypes(banuser.bantype);
}

Expand All @@ -1498,6 +1499,7 @@ void Convert(const BannedUser& banuser, teamtalk::BannedUser& result)
result.ipaddr = banuser.szIPAddress;
result.nickname = banuser.szNickname;
result.username = banuser.szUsername;
result.owner = banuser.szOwner;
}

void Convert(const teamtalk::FileTransfer& transfer, FileTransfer& result)
Expand Down
4 changes: 3 additions & 1 deletion Library/TeamTalkLib/bin/ttsrv/ServerGuard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,9 @@ ErrorMsg ServerGuard::DeleteRegUser(const ServerUser& user, const ACE_TString& u

ErrorMsg ServerGuard::AddUserBan(const ServerUser& banner, const ServerUser& banee, BanTypes bantype)
{
return AddUserBan(banner, banee.GenerateBan(bantype));
auto ban = banee.GenerateBan(bantype);
ban.owner = banner.GetUsername();
return AddUserBan(banner, ban);
}

ErrorMsg ServerGuard::AddUserBan(const ServerUser& banner, const BannedUser& ban)
Expand Down
4 changes: 4 additions & 0 deletions Library/TeamTalkLib/bin/ttsrv/ServerXML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,9 @@ namespace teamtalk{
banElement.Attribute("address"))
tmp = banElement.Attribute("address"); // pre XML v5.1
ban.ipaddr = Utf8ToUnicode(tmp.c_str());
tmp.clear();
GetString(banElement, "owner", tmp);
ban.owner = Utf8ToUnicode(tmp.c_str());
return true;
}

Expand All @@ -1220,6 +1223,7 @@ namespace teamtalk{
PutString(banElement, "nickname", UnicodeToUtf8(ban.nickname).c_str());
PutString(banElement, "username", UnicodeToUtf8(ban.username).c_str());
PutString(banElement, "channel-path", UnicodeToUtf8(ban.chanpath).c_str());
PutString(banElement, "owner", UnicodeToUtf8(ban.owner).c_str());
}

int ServerXML::GetUserBanCount()
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkLib/teamtalk/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
#define TT_TOTVOICE ACE_TEXT("voicetot") // v5.12
#define TT_TOTMEDIAFILE ACE_TEXT("mediafiletot") // v5.12
#define TT_TRANSFERKEY ACE_TEXT("filetxkey") // v5.13
#define TT_BANOWNER ACE_TEXT("owner") // v5.13

// Client ---> Server
// -------------------------
Expand Down
3 changes: 2 additions & 1 deletion Library/TeamTalkLib/teamtalk/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ namespace teamtalk {
ACE_TString chanpath;
ACE_Time_Value bantime;
ACE_TString nickname;
ACE_TString username;
ACE_TString username; // banned username
ACE_TString owner; // who made the ban
BannedUser() : bantype(BANTYPE_NONE) { bantime = ACE_OS::gettimeofday(); }
bool Same(const BannedUser& user) const;
bool Match(const BannedUser& user) const;
Expand Down
1 change: 1 addition & 0 deletions Library/TeamTalkLib/teamtalk/client/ClientNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5871,6 +5871,7 @@ void ClientNode::HandleBannedUser(const mstrings_t& properties)
GetProperty(properties, TT_NICKNAME, ban.nickname);
GetProperty(properties, TT_USERNAME, ban.username);
GetProperty(properties, TT_BANTIME, ban.bantime);
GetProperty(properties, TT_BANOWNER, ban.owner);

m_listener->OnBannedUser(ban);
}
Expand Down
Loading

0 comments on commit d1dde4e

Please sign in to comment.