我试图用C#进行身份验证。
它在尝试登录时发送HTTP GET
请求,如下所示:
https://goldenarmy.eu/studios/id/cman/clogin.php?name=abc&password=abc
这只是70个字符。但是我收到“请求URI太长”错误。
编辑:似乎模拟工作正常,但不是通过TcpClient发送时发送!!
Clientmanager:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
public class ClientManager
{
private static TcpListener listener;
public static void Main()
{
ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
listener = new TcpListener(IPAddress.Any, 10250);
listener.Start();
Console.WriteLine("*** ClientManager started ***");
Console.WriteLine("Listening to port 10250, make sure not used.");
StartAccept();
while (true)
{
System.Threading.Thread.Sleep(1000);
string cmd = Console.ReadLine();
if (cmd.Equals("exit"))
{
Console.WriteLine("*** Stopping cman... ***");
Environment.Exit(0);
}
if (cmd.StartsWith("auth"))
{
Console.WriteLine("[" + "simulate" + "] Using auth cred to authenticate.");
char c = '|';
string[] args = cmd.Split(c);
if (!(args.Length > 2))
{
Console.WriteLine("INVALID_DATA_GIVEN");
}
string username = args[1];
string password = args[2];
Console.WriteLine("[" + "simulate" + "] Using credentials: " + username + " and " + password);
string response = GetAsync(("https://goldenarmy.eu/studios/id/cman/clogin.php?name=" + username + "&password=" + password + "&test=1"));
Console.WriteLine("https://goldenarmy.eu/studios/id/cman/clogin.php?name=" + username + "&password=" + password);
Console.WriteLine(response);
if (response.Equals("ERROR_FAILED_CONNECTION"))
{
Console.WriteLine("ERROR_SERVERERROR");
}
else if (response.Equals("INVALID_USERNAME"))
{
Console.WriteLine("INVALID_DATA_GIVEN");
}
else if (response.Equals("INVALID_PASSWORD"))
{
Console.WriteLine("INVALID_DATA_GIVEN");
}
else if (response.Equals("INVALID_CRED"))
{
Console.WriteLine("ERROR_AUTH_INVALID_CRED");
}
else if (response.Equals("IS_BANNED"))
{
Console.WriteLine("ERROR_AUTH_BANNED");
}
else
{
Console.WriteLine("[" + "simulate" + "] LOGIN OK | RESPONSE: " + response);
}
}
}
}
private static void StartAccept()
{
listener.BeginAcceptSocket(HandleAsyncConnection, listener);
}
private static void HandleAsyncConnection(IAsyncResult res)
{
StartAccept();
TcpClient client = listener.EndAcceptTcpClient(res);
string clientSession = "NULL";
string ip = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();
Console.WriteLine("[" + ip + "] Incoming connection.");
while (true)
{
try
{
System.Threading.Thread.Sleep(250);
Console.WriteLine("Trying to read data from " + ip);
NetworkStream stream = null;
Byte[] data = new Byte[8192];
String responseData = String.Empty;
Int32 bytes = 0;
stream = client.GetStream();
bytes = stream.Read(data, 0, data.Length);
Console.WriteLine("Bytes: " + bytes + " Data: " + System.Text.Encoding.ASCII.GetString(data));
responseData = System.Text.Encoding.ASCII.GetString(data);
Console.WriteLine("[" + ip + "] " + responseData);
if (responseData.StartsWith("close"))
{
Console.WriteLine("[" + ip + "] Connection closed.");
break;
}else if (responseData.StartsWith("useauthtoken"))
{
Console.WriteLine("[" + ip + "] Using auth token to authenticate.");
char c = '|';
string[] args = responseData.Split(c);
if (!(args.Length > 1))
{
SendMessage(stream, "INVALID_DATA_GIVEN");
}
string response = GetAsync("http://goldenarmy.eu/studios/id/cman/cauthtokencheck.php?auth=" + args[1]);
if (response.Equals("yes"))
{
clientSession = args[1];
SendMessage(stream, "OK");
}
else
{
SendMessage(stream, "ERROR_AUTH_INVALID");
}
}
else if (responseData.StartsWith("auth"))
{
Console.WriteLine("[" + ip + "] Using auth cred to authenticate.");
char c = '|';
string[] args = responseData.Split(c);
Console.WriteLine("Data splitted");
if (!(args.Length > 2))
{
SendMessage(stream, "INVALID_DATA_GIVEN");
}
string username = args[1];
string password = args[2];
Console.WriteLine("[" + ip + "] Using credentials: " + username + " and " + password);
Console.WriteLine("Logging in...");
string response = GetAsync(("https://goldenarmy.eu/studios/id/cman/clogin.php?name=" + username + "&password=" + password + ""));
Console.WriteLine("Login attempt completed, with " + response);
if (response.Equals("ERROR_FAILED_CONNECTION"))
{
SendMessage(stream, "ERROR_SERVERERROR");
}
else if (response.Equals("INVALID_USERNAME"))
{
SendMessage(stream, "INVALID_DATA_GIVEN");
}
else if (response.Equals("INVALID_PASSWORD"))
{
SendMessage(stream, "INVALID_DATA_GIVEN");
}
else if (response.Equals("INVALID_CRED"))
{
SendMessage(stream, "ERROR_AUTH_INVALID_CRED");
}
else if (response.Equals("IS_BANNED"))
{
SendMessage(stream, "ERROR_AUTH_BANNED");
}
else
{
Console.WriteLine("[" + ip + "] LOGIN OK | RESPONSE: " + response);
if (response == null) response = "Response was null?";
SendMessage(stream, response);
Console.WriteLine("Sended message...");
clientSession = response;
}
}
if ((!responseData.StartsWith("auth") || !responseData.StartsWith("useauthtoken") || !responseData.StartsWith("close")) && clientSession.Equals("NULL"))
{
SendMessage(stream, "ERROR_AUTH_MISSING");
}
if (responseData.Equals("endGame"))
{
char c = '|';
string[] args = responseData.Split(c);
if (!(args.Length > 3))
{
SendMessage(stream, "INVALID_DATA_GIVEN");
}
string won = args[0];
string kills = args[1];
string singleplayer = args[2];
string response = GetAsync("https://goldenarmy.eu/studios/id/cman/cgameend.php?session=" + client + "&won=" + won + "&kills=" + kills + "&singleplayer=" + singleplayer);
if (response.Equals("ERROR_FAILED_CONNECTION"))
{
SendMessage(stream, "ERROR_SERVERERROR");
}
else if (response.Equals("SESSION_INVALID"))
{
SendMessage(stream, "ERROR_AUTH_MISSING");
}
else if (response.Equals("SUCCESS"))
{
SendMessage(stream, "SUCCESS");
}
}
}
catch (Exception e)
{
Console.WriteLine("[" + ip + "] Connection closed: " + e.Message);
break;
}
}
}
public static string GetAsync(string uri, Action<WebHeaderCollection> headers = null)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
//request.Headers.Set(HttpRequestHeader.ContentLocation, uri);
//request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
Console.WriteLine(request.RequestUri);
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
public static void SendMessage(NetworkStream stream, string msg)
{
Byte[] sendBytes = Encoding.ASCII.GetBytes(msg);
stream.Write(sendBytes, 0, sendBytes.Length);
}
/*public static string login(string username, string password)
{
Console.WriteLine("https://goldenarmy.eu/studios/id/cman/clogin.php?name=" + username + "&password=" + password);
string response = GetAsync(("https://goldenarmy.eu/studios/id/cman/clogin.php?name=" + username + "&password=" + password));
Console.WriteLine(response);
return response;
}*/
public static bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool isOk = true;
return isOk;
}
}
clogin.php:
<?php
$conn = new mysqli("localhost", "root", "not-the-real-password", "topdown");
if ($conn->connect_error) {
die("ERROR_FAILED_CONNECTION");
}
$name = $_GET["name"];
$password = $_GET["password"];
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
function endsWith($haystack, $needle)
{
$length = strlen($needle);
if ($length == 0) {
return true;
}
return (substr($haystack, -$length) === $needle);
}
$sql = "SELECT `password`,`banned` FROM `accounts` WHERE `name`='".$name."';";
$result = $conn->query($sql);
if ($result->num_rows < 1) {
die("INVALID_CRED");
die();
}
$found = "";
$banned = false;
while($row = $result->fetch_assoc()) {
$found = $row["password"];
$banned = $row["banned"];
}
if($found == $password){
if($banned==1){
die("IS_BANNED");
}
$session = generateRandomString(16);
$sql = "UPDATE `accounts` SET `clientsession`='".$session."' WHERE `name`='".$name."'";
if ($conn->query($sql) === TRUE) {
die($session);
}else{
die("ERROR_FAILED_CONNECTION");
}
}else{
die("INVALID_CRED");
}
?>
答案 0 :(得分:0)
该消息来自服务器,而不是客户端。请参阅以下答案以获取可能的解决方案: How do I resolve a HTTP 414 "Request URI too long" error?
答案 1 :(得分:0)
您的模拟不能反映您在非模拟情况下向服务器发送的内容,因此您无法在模拟中重现错误。
在模拟情况下,您读了一行,而字符串cmd
的长度就是行的长度。在非模拟情况下,您改为读取缓冲区data
,缓冲区的大小为8192字节。这意味着,如果您读取auth|abc|abc
的响应,则data
的内容将为auth|abc|abc\0\0\0\0....
,即服务器发送的内容,然后是8180(8192-12)个字符{{1} }(即\0
,\x00
,不过也可以用C#编写。)
在您\000
之后,密码(即responseData.Split
)将不是您所期望的args[2]
,而是abc
。这再次意味着应该为abc\0\0\0\0....
的URL实际上为https://....?user=abc&pass=abc
。 https://....?user=abc&pass=abc\0\0\0....
需要使用\0
的URL编码进行编码,这会导致%00
所有这些8180 https://....?user=abc&pass=abc%00%00%00....
已经单独在URL中导致24540个字符,这解释了为什么服务器抱怨URL太大。查看服务器访问日志或错误日志也可能会显示此类问题。