Skip to content

Commit b96a706

Browse files
committed
Added auth to ClientQuery and fixed QueryType detection
1 parent 1d08af0 commit b96a706

File tree

11 files changed

+92
-154
lines changed

11 files changed

+92
-154
lines changed

Deployment/Deploy.target

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<PropertyGroup>
66
<RootDirectory>..</RootDirectory>
77
<Config>Release</Config>
8-
<ReleaseVersion>1.2.0.0</ReleaseVersion>
8+
<ReleaseVersion>1.2.1.0</ReleaseVersion>
99
<ReleaseVersionEscaped>$(ReleaseVersion.Replace(".", "_"))</ReleaseVersionEscaped>
1010
<ReleaseName>TS3QueryLib.Net.V$(ReleaseVersionEscaped)</ReleaseName>
1111
<ReleaseDirectory>Releases\$(ReleaseVersionEscaped)</ReleaseDirectory>
@@ -34,7 +34,7 @@
3434

3535
<Target Name="Build">
3636
<Message Text="Cleaning Solution"/>
37-
<MSBuild Projects="$(RootDirectory)\TS3QueryLib.Net 2010.sln" Properties="Configuration=$(Config)" Targets="Clean"/>
37+
<MSBuild Projects="$(RootDirectory)\TS3QueryLib.Net 2010.sln" Properties="Configuration=$(Config)" Targets="Clean" />
3838

3939
<Message Text="Building Solution"/>
4040
<MSBuild Projects="$(RootDirectory)\TS3QueryLib.Net 2010.sln" Properties="Configuration=$(Config)"/>

Deployment/DeployLocal.bat

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11

2-
"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" Deploy.target /target:Deploy
3-
pause
2+
"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" Deploy.target /target:Deploy /v:m

TS3QueryLib.ClientQuery.TestApp/MainWindow.xaml.cs

+18
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,26 @@ public void Connect()
7474
private void QueryDispatcher_ReadyForSendingCommands(object sender, System.EventArgs e)
7575
{
7676
Model.ConnectionState = ConnectionState.Connected;
77+
78+
string apiKey = Microsoft.VisualBasic.Interaction.InputBox("Api-Key:", "Please provide your API-Key");
79+
80+
if (string.IsNullOrWhiteSpace(apiKey))
81+
{
82+
Disconnect();
83+
return;
84+
}
85+
7786
// you can only run commands on the queryrunner when this event has been raised first!
7887
QueryRunner = new QueryRunner(QueryDispatcher);
88+
SimpleResponse authResponse = QueryRunner.Authenticate(apiKey);
89+
90+
if (authResponse.IsErroneous)
91+
{
92+
MessageBox.Show("Api-Key was wrong!");
93+
Disconnect();
94+
return;
95+
}
96+
7997
QueryRunner.Notifications.ChannelTalkStatusChanged += Notifications_ChannelTalkStatusChanged;
8098
QueryRunner.RegisterForNotifications(ClientNotifyRegisterEvent.Any);
8199

TS3QueryLib.ClientQuery.TestApp/TS3QueryLib.ClientQuery.TestApp.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<WarningLevel>4</WarningLevel>
4141
</PropertyGroup>
4242
<ItemGroup>
43+
<Reference Include="Microsoft.VisualBasic" />
4344
<Reference Include="System" />
4445
<Reference Include="System.Data" />
4546
<Reference Include="System.Xml" />

TS3QueryLib.Core.Silverlight/AsyncTcpDispatcher.cs

+25-67
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
#if !SILVERLIGHT
34
using System.Diagnostics;
45
using System.Linq;
@@ -265,87 +266,44 @@ private void MessageReceived(object sender, SocketAsyncEventArgs socketAsyncEven
265266
else
266267
{
267268
string greeting = _receiveRepository.ToString();
268-
if (!IsValidGreetingPart(greeting))
269-
GreetingFailed();
270-
271269
QueryType? queryType = GetQueryTypeFromGreeting(greeting);
272270

273-
if (queryType.HasValue)
271+
if (!queryType.HasValue)
274272
{
275-
int requiredGreetingLength = queryType == QueryType.Client ? CLIENT_GREETING.Length : SERVER_GREETING.Length;
273+
GreetingFailed();
274+
return;
275+
}
276276

277-
if (greeting.Length >= requiredGreetingLength)
278-
{
279-
bool greetingCorrect;
280-
switch (queryType.Value)
281-
{
282-
case QueryType.Client:
283-
greetingCorrect = HandleClientQueryGreeting(greeting);
284-
break;
285-
case QueryType.Server:
286-
greetingCorrect = HandleServerQueryGreeting(greeting);
287-
break;
288-
default:
289-
throw new InvalidOperationException("Forgott to implement query type: " + queryType);
290-
}
277+
_greetingReceived = true;
291278

292-
if (_greetingReceived && !greetingCorrect)
293-
GreetingFailed();
294-
}
279+
switch (queryType.Value)
280+
{
281+
case QueryType.Client:
282+
HandleClientQueryGreeting(greeting);
283+
break;
284+
case QueryType.Server:
285+
break;
286+
default:
287+
throw new InvalidOperationException("Forgott to implement query type: " + queryType);
295288
}
289+
290+
_receiveRepository.Remove(0, greeting.Length);
291+
ThreadPool.QueueUserWorkItem(x => OnReadyForSendingCommands());
296292
}
297293

298294
ReceiveMessage(socketAsyncEventArgs);
299295
});
300296
}
301297

302-
private bool HandleClientQueryGreeting(string greeting)
303-
{
304-
if (!greeting.StartsWith(CLIENT_GREETING, StringComparison.InvariantCultureIgnoreCase))
305-
{
306-
_greetingReceived = true;
307-
return false;
308-
}
309-
310-
greeting = greeting.Substring(CLIENT_GREETING.Length);
311-
312-
const string PATTERN_STATIC_PART = "selected schandlerid=";
313-
const string PATTERN = PATTERN_STATIC_PART + @"(?<id>\d+)" + Ts3Util.QUERY_REGEX_LINE_BREAK;
314-
315-
if (!PATTERN_STATIC_PART.StartsWith(greeting, StringComparison.InvariantCultureIgnoreCase) && !greeting.StartsWith(PATTERN_STATIC_PART, StringComparison.InvariantCultureIgnoreCase))
316-
{
317-
_greetingReceived = true;
318-
return false;
319-
}
320-
321-
if (!greeting.Contains(Ts3Util.QUERY_LINE_BREAK))
322-
return false;
323-
324-
_greetingReceived = true;
325-
Match match = Regex.Match(greeting, PATTERN, RegexOptions.IgnoreCase | RegexOptions.Singleline);
326-
327-
if (!match.Success)
328-
return false;
329-
330-
LastServerConnectionHandlerId = Convert.ToInt32(match.Groups["id"].Value);
331-
// greeting was correct!
332-
_receiveRepository.Remove(0, CLIENT_GREETING.Length + match.Length);
333-
ThreadPool.QueueUserWorkItem(x => OnReadyForSendingCommands());
334-
335-
return true;
336-
}
337-
338-
private bool HandleServerQueryGreeting(string greeting)
298+
private void HandleClientQueryGreeting(string greeting)
339299
{
340-
_greetingReceived = true;
341-
if (!greeting.StartsWith(SERVER_GREETING, StringComparison.InvariantCultureIgnoreCase))
342-
return false;
300+
string[] greetingLines = greeting.Split(new[] {Ts3Util.QUERY_LINE_BREAK}, StringSplitOptions.RemoveEmptyEntries);
301+
const string PATTERN = @"selected schandlerid=(?<id>\d+)";
343302

344-
// greeting was correct!
345-
_receiveRepository.Remove(0, SERVER_GREETING.Length);
346-
ThreadPool.QueueUserWorkItem(x => OnReadyForSendingCommands());
347-
348-
return true;
303+
Match match = greetingLines.Select(l => Regex.Match(l, PATTERN, RegexOptions.IgnoreCase | RegexOptions.Singleline)).FirstOrDefault(m => m.Success);
304+
305+
if (match?.Success == true)
306+
LastServerConnectionHandlerId = Convert.ToInt32(match.Groups["id"].Value);
349307
}
350308

351309
private void GreetingFailed()

TS3QueryLib.Core.Silverlight/Client/CommandName.cs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace TS3QueryLib.Core.Client
44
{
55
public enum CommandName
66
{
7+
Auth,
78
ChannelConnectInfo,
89
ClientNotifyRegister,
910
ServerConnectionHandlerList,

TS3QueryLib.Core.Silverlight/Client/QueryRunner.cs

+16
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ public QueryRunner(IQueryDispatcher queryDispatcher) : base(queryDispatcher)
3434

3535
#region Public Methods
3636

37+
/// <summary>
38+
/// Authenticate against the local query client
39+
/// </summary>
40+
/// <param name="apiKey">The api key used to authenticate</param>
41+
public SimpleResponse Authenticate(string apiKey)
42+
{
43+
Command command = CommandName.Auth.CreateCommand();
44+
45+
if (apiKey == null)
46+
throw new ArgumentNullException("apiKey");
47+
48+
command.AddParameter("apikey", apiKey);
49+
50+
return ResponseBase<SimpleResponse>.Parse(SendCommand(command));
51+
}
52+
3753
/// <summary>
3854
/// This command allows you to listen to events that the client encounters. Events
3955
/// are things like people starting or stopping to talk, people joining or leaving,

TS3QueryLib.Core.Silverlight/Properties/AssemblyInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
[assembly: AssemblyTrademark("")]
99
[assembly: AssemblyCulture("")]
1010
[assembly: ComVisible(false)]
11-
[assembly: AssemblyVersion("1.2.0.0")]
12-
[assembly: AssemblyFileVersion("1.2.0.0")]
11+
[assembly: AssemblyVersion("1.2.1.0")]
12+
[assembly: AssemblyFileVersion("1.2.1.0")]

TS3QueryLib.Core.Silverlight/SyncTcpDispatcher.cs

+21-66
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4+
using System.Linq;
45
using System.Net;
56
using System.Net.Sockets;
67
using System.Text;
@@ -108,106 +109,60 @@ public void Connect()
108109
}
109110

110111
greeting = string.Concat(greeting, receiveResult.Value);
111-
112-
if (!IsValidGreetingPart(greeting))
113-
GreetingFailed(greeting);
114-
115112
QueryType? queryType = GetQueryTypeFromGreeting(greeting);
116113

117114
if (!queryType.HasValue)
118-
continue;
119-
120-
int requiredGreetingLength = queryType == QueryType.Client ? CLIENT_GREETING.Length : SERVER_GREETING.Length;
121-
122-
if (greeting.Length < requiredGreetingLength)
123-
continue;
115+
{
116+
GreetingFailed();
117+
return;
118+
}
124119

125-
bool greetingCorrect;
126120
switch (queryType.Value)
127121
{
128122
case QueryType.Client:
129-
greetingCorrect = HandleClientQueryGreeting(greeting);
123+
HandleClientQueryGreeting(greeting);
130124
break;
131125
case QueryType.Server:
132-
greetingCorrect = HandleServerQueryGreeting(greeting);
126+
HandleServerQueryGreeting(greeting);
133127
break;
134128
default:
135129
throw new InvalidOperationException("Forgott to implement query type: " + queryType);
136130
}
137131

138-
if (!greetingCorrect)
139-
GreetingFailed(greeting);
140-
141132
break;
142133
}
143134
}
144135

145-
private bool HandleClientQueryGreeting(string greeting)
136+
private void HandleClientQueryGreeting(string greeting)
146137
{
147-
if (!greeting.StartsWith(CLIENT_GREETING, StringComparison.InvariantCultureIgnoreCase))
148-
return false;
149-
150-
greeting = greeting.Substring(CLIENT_GREETING.Length);
151-
152-
const string PATTERN_STATIC_PART = "selected schandlerid=";
153-
const string PATTERN = PATTERN_STATIC_PART+@"(?<id>\d+)" + Ts3Util.QUERY_REGEX_LINE_BREAK;
154-
155-
while (true)
156-
{
157-
if (!PATTERN_STATIC_PART.StartsWith(greeting, StringComparison.InvariantCultureIgnoreCase) && !greeting.StartsWith(PATTERN_STATIC_PART, StringComparison.InvariantCultureIgnoreCase))
158-
return false;
159-
160-
if (!greeting.Contains(Ts3Util.QUERY_LINE_BREAK))
161-
{
162-
KeyValuePair<SocketError, string> receiveResult = ReceiveMessage(SocketAsyncEventArgs);
163-
164-
if (receiveResult.Key != SocketError.Success)
165-
{
166-
Disconnect();
167-
throw new SocketException((int)receiveResult.Key);
168-
}
169-
170-
greeting = string.Concat(greeting, receiveResult.Value);
171-
continue;
172-
}
138+
string[] greetingLines = greeting.Split(new[] { Ts3Util.QUERY_LINE_BREAK }, StringSplitOptions.RemoveEmptyEntries);
139+
const string PATTERN = @"selected schandlerid=(?<id>\d+)";
173140

174-
Match match = Regex.Match(greeting, PATTERN, RegexOptions.IgnoreCase | RegexOptions.Singleline);
175-
176-
if (!match.Success)
177-
return false;
141+
Match match = greetingLines.Select(l => Regex.Match(l, PATTERN, RegexOptions.IgnoreCase | RegexOptions.Singleline)).FirstOrDefault(m => m.Success);
178142

143+
if (match?.Success == true)
179144
LastServerConnectionHandlerId = Convert.ToInt32(match.Groups["id"].Value);
180-
181-
break;
182-
}
183-
184-
return true;
185145
}
186146

187-
private static bool HandleServerQueryGreeting(string greeting)
147+
private static void HandleServerQueryGreeting(string greeting)
188148
{
189-
if (!greeting.StartsWith(SERVER_GREETING, StringComparison.InvariantCultureIgnoreCase))
190-
return false;
191-
192-
greeting = greeting.Substring(SERVER_GREETING.Length);
149+
string lastGreetingLine = greeting.Split(new[] { Ts3Util.QUERY_LINE_BREAK }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
193150

194-
if (greeting.Length > 0)
195-
{
196-
SimpleResponse response = SimpleResponse.Parse(greeting);
151+
if (lastGreetingLine == null || !lastGreetingLine.Contains("="))
152+
return;
197153

198-
if (response.IsBanned)
199-
throw new InvalidOperationException("You are banned from the server: " + response.BanExtraMessage);
200-
}
154+
SimpleResponse response = SimpleResponse.Parse(lastGreetingLine);
201155

202-
return true;
156+
if (response.IsBanned)
157+
throw new InvalidOperationException("You are banned from the server: " + response.BanExtraMessage);
203158
}
204159

205-
private void GreetingFailed(string greeting)
160+
private void GreetingFailed()
206161
{
207162
Disconnect();
208163

209164
#if !SILVERLIGHT
210-
Trace.WriteLine("Greeting was wrong! Greeting was: " + greeting);
165+
Trace.WriteLine("Greeting was wrong! ");
211166
#endif
212167

213168
throw new SocketException((int)SocketError.ProtocolNotSupported);

TS3QueryLib.Core.Silverlight/TcpDispatcherBase.cs

-13
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ public abstract class TcpDispatcherBase : IQueryDispatcher
2323

2424
protected const string CLIENT_GREETING_FIRST_LINE = "TS3 Client" + Ts3Util.QUERY_LINE_BREAK;
2525
protected const string SERVER_GREETING_FIRST_LINE = "TS3" + Ts3Util.QUERY_LINE_BREAK;
26-
protected const string SERVER_GREETING = SERVER_GREETING_FIRST_LINE + "Welcome to the TeamSpeak 3 ServerQuery interface, type \"help\" for a list of commands and \"help <command>\" for information on a specific command." + Ts3Util.QUERY_LINE_BREAK;
27-
protected const string CLIENT_GREETING = CLIENT_GREETING_FIRST_LINE + "Welcome to the TeamSpeak 3 ClientQuery interface, type \"help\" for a list of commands and \"help <command>\" for information on a specific command." + Ts3Util.QUERY_LINE_BREAK;
2826
protected const int RECEIVE_BUFFER_SIZE = 4 * 1024;
2927

3028
#endregion
@@ -137,17 +135,6 @@ public virtual void DetachAllEventListeners()
137135

138136
#region Non Public Methods
139137

140-
protected bool IsValidGreetingPart(string greetingPart)
141-
{
142-
if (greetingPart.IsNullOrTrimmedEmpty())
143-
return false;
144-
145-
return SERVER_GREETING_FIRST_LINE.StartsWith(greetingPart, StringComparison.InvariantCultureIgnoreCase) ||
146-
greetingPart.StartsWith(SERVER_GREETING_FIRST_LINE, StringComparison.InvariantCultureIgnoreCase) ||
147-
CLIENT_GREETING_FIRST_LINE.StartsWith(greetingPart, StringComparison.InvariantCultureIgnoreCase) ||
148-
greetingPart.StartsWith(CLIENT_GREETING_FIRST_LINE, StringComparison.InvariantCultureIgnoreCase);
149-
}
150-
151138
protected QueryType? GetQueryTypeFromGreeting(string greetingPart)
152139
{
153140
if (greetingPart != null)

0 commit comments

Comments
 (0)