C# Test if proxies are working before using them - c#

I want to check if the the proxies in my list are working before using them, is it possible?
It's easy for HTTP/HTTPS since you only have to use the webclient but for socks?
I tough this could work for all
public static bool SoketConnect(string addresse)
{
string[] proxy = addresse.Split(':');
if (proxy.Count() == 2)
{
string host = proxy[0];
int port = Convert.ToInt32(proxy[1]);
var is_success = false;
try
{
var connsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 200);
System.Threading.Thread.Sleep(500);
var hip = IPAddress.Parse(host);
var ipep = new IPEndPoint(hip, port);
connsock.Connect(ipep);
try
{
byte[] outStream = System.Text.Encoding.ASCII.GetBytes("ping");
byte[] inStream = new byte[100];
connsock.Send(outStream);
connsock.ReceiveTimeout = 500;
connsock.Receive(inStream);
string message = System.Text.Encoding.ASCII.GetString(inStream);
foreach (var bytes in inStream)
{
if (bytes != 0)
{
is_success = true;
break;
}
}
connsock.Disconnect(false);
}
catch(Exception ex)
{
is_success = false;
}
connsock.Close();
}
catch (Exception ex)
{
is_success = false;
}
return is_success;
}
else
return false;
}
but i always get the exception
"The underlying connection was closed: The connection was closed
unexpectedly." System.Net.WebException
tldr; How to check if my socks proxies are working ( Which comes back to how to use a socks proxy)
EDIT: still doesn't help,need an answer
EDIT2 : Only pinging the proxy isn't the right thing to do

As far as I know you have to use them to see if they are working. I suggeset one of the following:
ping - With Ping class in:
using System.Net.NetworkInformation;
private static bool CanPing(string address)
{
Ping myping = new Ping();
try
{
PingReply reply = myping.Send(address, 2000);
if (reply == null)
return false;
return (reply.Status == IPStatus.Success);
}
catch (PingException e)
{
return false;
}
}
Do a "Whats my IP?" through a proxy:
public static void TestProxies()
{
var lowp = new List<WebProxy> { new WebProxy("1.2.3.4", 8080), new WebProxy("5.6.7.8", 80) };
Parallel.ForEach(lowp, wp => {
var success = false;
var errorMsg = "";
var sw = new Stopwatch();
try
{
sw.Start();
var response = new RestClient
{
BaseUrl = "https://webapi.theproxisright.com/",
Proxy = wp
}.Execute(new RestRequest { Resource = "api/ip", Method = Method.GET, Timeout = 10000, RequestFormat = DataFormat.Json });
if (response.ErrorException != null)
throw response.ErrorException;
success = (response.Content == wp.Address.Host);
}
catch (Exception ex)
{
errorMsg = ex.Message;
}
finally
{
sw.Stop();
}
});
}

Related

TCP client - server connection

I'm trying to make client get some data from server using TCP.
But it works only once. Then stream.DataAvailable is always false.
Client code:
while (!StopEvent.WaitOne(WaitTime, true))
{
try
{
if (TcpClient == null || !TcpClient.Connected)
{
if (TcpClient != null)
{
TcpClient.Close();
TcpClient = null;
}
TcpClient = new TcpClient(MasterHost, MasterMonitoringPort) {NoDelay = true};
}
var stream = TcpClient.GetStream();
stream.WriteTimeout = TimeoutMs;
stream.ReadTimeout = TimeoutMs;
stream.Write(GetMasterStateRequestBytes, 0, GetMasterStateRequestBytes.Length);
var serialisedDataBuilder = new StringBuilder();
if (stream.DataAvailable)
{
while (stream.DataAvailable)
{
var bytesRead = stream.Read(BytesBuffer, 0, BytesBuffer.Length);
serialisedDataBuilder.Append(Encoding.UTF8.GetString(BytesBuffer, 0, bytesRead));
}
var responses = MonitoringResponse.StringToResponses(serialisedDataBuilder.ToString());
foreach (var response in responses)
{
if (response.MonitoringResponseType == MonitoringResponseType.ProvideMasterStateInfo && response.Parameters is MasterStateInfo masterStateInfo)
MasterStateInfo = masterStateInfo;
}
}
}
catch (Exception exception)
{
LastException = exception;
TcpClient?.Close();
TcpClient = null;
}
Thread.Sleep(10*1000);
}
Server code :
while (!StopEvent.WaitOne(WaitTime, true))
{
try
{
if (TcpListener == null)
{
Application.Tracer.Trace(this, TracerEventKind.Info, "Starting TcpListener");
TcpListener = new TcpListener(IPAddress.Any, MasterNetworkServer.MonitoringPort);
TcpListener.Start();
}
if (TcpListener.Pending())
{
Application.Tracer.Trace(this, TracerEventKind.Info, "TcpListener is pending, start processing");
var client = TcpListener.AcceptTcpClient();
var stream = client.GetStream();
stream.WriteTimeout = TimeoutMs;
stream.ReadTimeout = TimeoutMs;
var serialisedDataBuilder = new StringBuilder();
if (stream.DataAvailable)
{
do
{
var bytesRead = stream.Read(BytesBuffer, 0, BytesBuffer.Length);
serialisedDataBuilder.Append(Encoding.UTF8.GetString(BytesBuffer, 0, bytesRead));
} while (stream.DataAvailable);
Application.Tracer.Trace(this, TracerEventKind.Info, "Bytes received");
var requests =
MonitoringRequest.StringToRequests(serialisedDataBuilder.ToString(), distinct: true);
var responses = new List<MonitoringResponse>();
if (requests.Any())
{
Application.Tracer.Trace(this, TracerEventKind.Info,
$"Start to processing {requests.Count} requests");
foreach (var request in requests)
{
responses.Add(HandleMonitoringRequest(request));
Application.Tracer.Trace(this, TracerEventKind.Info, "Response made");
}
Application.Tracer.Trace(this, TracerEventKind.Info, "All responses made");
}
var responsesBytes = MonitoringResponse.ResponsesToBytes(responses);
stream.Write(responsesBytes, 0, responsesBytes.Length);
}
}
}
catch(Exception exception)
{
Application.Tracer.Trace(this, TracerEventKind.Info, $"Monitoring network service exception: {exception.Message}");
}
Thread.Sleep(0);
Avoiding stupid restrictions text.
Avoiding stupid restrictions text.
Avoiding stupid restrictions text.
Avoiding stupid restrictions text.
Avoiding stupid restrictions text.
Avoiding stupid restrictions text.
The way to fix it was to close stream and client (with method .Close()) after each session and also add some sleep before checking isDataAvailable

JS: Call API from server side

The following JavaScript code is working fine on old i9 browser but not on the latest one. Now I want to call API from server side as this code is not working due to cross domain cores issue.
var xmlHttpDevice = new XMLHttpRequest();
xmlHttpDevice.open("DEVICEINFO", "http://127.0.0.1:" + PortNumber + "/getDeviceInfo", true);
xmlHttpDevice.onload = function (e) {
if (xmlHttpDevice.readyState === 4) {
if (xmlHttpDevice.status === 200) {
alert(xmlHttpDevice.responseText);
} else {
alert(xmlHttpDevice.statusText);
}
}
};
xmlHttpDevice.onerror = function (e) {
console.error(xmlHttpDevice.statusText);
};
var params = "rdverb=DEVICEINFO&URL=''";
xmlHttpDevice.send(params);
my server side code :
TcpClient socket = new TcpClient();
try
{
// Call EndGetContext to complete the asynchronous operation.
HttpListenerContext context = listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
string strPortNumber = string.Empty;
string strRDVerb = "";
int PortNumberStartRange = 11099;
result.AsyncWaitHandle.WaitOne();
if (context.Request.InputStream != null)
{
var body = new StreamReader(context.Request.InputStream).ReadToEnd();
GetPostedData(ref strPortNumber, ref strRDVerb, body);
}
else
{
strPortNumber = "12345";
strRDVerb = "RDSERVICE";
}
if (strRDVerb != "RDSERVICE" && strRDVerb != "DEVICEINFO")
{
strRDVerb = "CAPTURE";
}
//var body = new StreamReader(context.Request.InputStream).ReadToEnd();
string response = string.Empty;
//Get the stream that will be used to send/receive data
ExecuteRecoveryCode(ref socket, PortNumberStartRange);
NetworkStream ns = socket.GetStream();
//Write the HTTP Header info to the stream
StreamWriter sw = new StreamWriter(ns);
if (strRDVerb == "DEVICEINFO")
{
var message = "rdverb=DEVICEINFO&URL=''";
//var data = System.Text.Encoding.ASCII.GetBytes(message);
sw.Write(message, 0, message.Length);
sw.WriteLine(string.Format(strRDVerb + " /getDeviceInfo HTTP/1.1"));
sw.WriteLine(string.Format("HOST:127.0.0.1:11100"));
}
sw.Flush();
//Save the data that lives in the stream
string packet = string.Empty;
StreamReader sr = new StreamReader(ns);
int count = 0;
string EndString = string.Empty;
GetServiceMethod(strRDVerb, ref count, ref EndString);
for (int i = 0; i < count; i++)
{
packet = sr.ReadLine();
response += packet;
}
HttpListenerResponse resp = context.Response;
//byte[] buffer = System.Text.Encoding.UTF8.GetBytes("<HTML><BODY> " + response + EndString + "</BODY></HTML>");
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(response + EndString);
resp.StatusDescription = response;
resp.ContentLength64 = buffer.Length;
System.IO.Stream output = resp.OutputStream;
resp.StatusCode = (int)HttpStatusCode.OK;
output.Write(buffer, 0, buffer.Length);
output.Close();
resp.Close();
}
catch (Exception ex)
{
//throw ex;
}
finally
{
socket.Close();
listener.BeginGetContext(new AsyncCallback(OnRequestReceive), listener);
}

Validate SMTP user credentials before calling send method in C#

I am trying to validate smtp user as method suggested in this post by kazakov.nickolay.
First, I tried to use VRFY command, It gives me error response as
"Invalid command".
Next, I tried with AUTH command directly, In this case I got error response as-
"Issue starttls command first."
When I tried STARTTLS command first and then AUTH, then thread went into infinite loop. This may be happens because socket.Available count was zero and I was not able to do anything afterwards.
Below is the sample code-
public bool ValidateUser()
{
bool isValid = true;
string useremail = "user#mail.com";
string password = "userPassword";
string smtpserver = "smtp.server.name"
int port = 587;
try
{
const string EOF = "\r\n";
IPHostEntry hostEntry = Dns.GetHostEntry(smtpserver);
IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], port);
using (Socket tcpSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
try
{
tcpSocket.Connect(endPoint);
if (!CheckResponse(tcpSocket, 220))
isValid = false;
SendBytes(tcpSocket, $"EHLO {Dns.GetHostName()}{EOF}");
if (!CheckResponse(tcpSocket, 250))
isValid = false;
//SendBytes(tcpSocket, $"VRFY {useremail} {EOF}");
//if (!CheckResponse(tcpSocket, 250) || !CheckResponse(tcpSocket, 251))
// isValid = false;
//SendBytes(tcpSocket, $"STARTTLS{EOF}");
//if (!CheckResponse(tcpSocket, 220))
// isValid = false;
SendBytes(tcpSocket, $"AUTH {useremail} {EOF}");
if (!CheckResponse(tcpSocket, 334))
isValid = false;
SendBytes(tcpSocket, Convert.ToBase64String(Encoding.UTF8.GetBytes($"{useremail}")) + EOF);
if (!CheckResponse(tcpSocket, 334))
{
return false;
}
SendBytes(tcpSocket, Convert.ToBase64String(Encoding.UTF8.GetBytes($"{password}")) + EOF);
if (!CheckResponse(tcpSocket, 235))
{
return false;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
tcpSocket.Dispose();
}
}
}
catch (Exception)
{
throw;
}
return isValid;
}
private bool CheckResponse(Socket socket, int expectedCode)
{
bool isResponse = true;
try
{
if (socket == null)
return false;
while (socket.Available == 0)
{
System.Threading.Thread.Sleep(100);
}
byte[] responseArray = new byte[1024];
socket.Receive(responseArray, 0, socket.Available, SocketFlags.None);
string responseData = Encoding.ASCII.GetString(responseArray);
int responseCode = Convert.ToInt32(responseData.Substring(0, 3));
if (responseCode != expectedCode)
{
isResponse = false;
}
}
catch (Exception ex) { throw ex; }
return isResponse;
}
private void SendBytes(Socket socket, string data)
{
if (socket == null)
return;
byte[] bytes = Encoding.UTF8.GetBytes(data);
socket.Send(bytes, 0, bytes.Length, SocketFlags.None);
}
I also tried the another approach that is with SSL enabled.
On following line of code _sslStream.AuthenticateAsClient(smtpserver);, I got the exception-
"The handshake failed due to an unexpected packet format."
Can anybody please suggest me proper steps to validate user before calling send method?
Please note - I do not want to call send method if user is not a valid user. Also I do not want to send the dummy mail to check the same.

Java Equivalent Method to Test TCP Connection

In C# to test if UltraVNC was up and running on a local machine I would do this
public static bool TestAvailablility(int port, string responseStartsWith)
{
bool toReturn = false;
try
{
using (TcpClient client1 = new TcpClient())
{
client1.ReceiveTimeout = 10000;
client1.SendTimeout = 10000;
client1.Connect("localhost", port);
using (NetworkStream stream = client1.GetStream())
{
Byte[] response = new Byte[4096];
Int32 bytes = 0;
string serverReturnString = null;
bytes = stream.Read(response, 0, response.Length);
serverReturnString = System.Text.Encoding.ASCII.GetString(response, 0, bytes);
Console.WriteLine("TestAvailablility: serverReturnString = {0}", serverReturnString);
if (serverReturnString.StartsWith(responseStartsWith, StringComparison.OrdinalIgnoreCase))
{
toReturn = true;
}
}
}
}
catch (Exception ex) // SocketException for connect, IOException for the read.
{
Console.WriteLine("TestAvailable - Could not connect to VNC server. Exception info: ", ex);
}
return toReturn;
}
I'm new to Java so I'm hoping someone can help me with an equivalent method to preform this action.
Here's what I came up with:
FYI using Autocomplete in Eclipse + Java API you can translate C# to Java pretty easily.
public static boolean testAvailablility(int port, String responseStartsWith) {
boolean toReturn = false;
try {
Socket client1 = new Socket();
client1.setSoTimeout(10000);
client1.bind(new InetSocketAddress("localhost", port));
InputStream stream = client1.getInputStream();
byte[] response = new byte[4096];
int bytes = 0;
String serverReturnString = null;
bytes = stream.read(response, 0, response.length);
serverReturnString = String.valueOf(bytes);
System.out.println("TestAvailablility: serverReturnString = {0} " + serverReturnString);
if (serverReturnString.toLowerCase().startsWith(responseStartsWith.toLowerCase()))
toReturn = true;
} catch (Exception ex) // SocketException for connect, IOException for
// the read.
{
System.out.println("TestAvailable - Could not connect to VNC server. Exception info: ");
ex.printStackTrace();
}
return toReturn;
}

Testing SMTP server is running via C#

How can I test SMTP is up and running via C# without sending a message.
I could of course try:
try{
// send email to "nonsense#example.com"
}
catch
{
// log "smtp is down"
}
There must be a more tidy way to do this.
You can try saying EHLO to your server and see if it responds with 250 OK. Of course this test doesn't guarantee you that you will succeed sending the mail later, but it is a good indication.
And here's a sample:
class Program
{
static void Main(string[] args)
{
using (var client = new TcpClient())
{
var server = "smtp.gmail.com";
var port = 465;
client.Connect(server, port);
// As GMail requires SSL we should use SslStream
// If your SMTP server doesn't support SSL you can
// work directly with the underlying stream
using (var stream = client.GetStream())
using (var sslStream = new SslStream(stream))
{
sslStream.AuthenticateAsClient(server);
using (var writer = new StreamWriter(sslStream))
using (var reader = new StreamReader(sslStream))
{
writer.WriteLine("EHLO " + server);
writer.Flush();
Console.WriteLine(reader.ReadLine());
// GMail responds with: 220 mx.google.com ESMTP
}
}
}
}
}
And here's the list of codes to expect.
I use this method and classes to validate the credentials (link to github):
public static bool ValidateCredentials(string login, string password, string server, int port, bool enableSsl) {
SmtpConnectorBase connector;
if (enableSsl) {
connector = new SmtpConnectorWithSsl(server, port);
} else {
connector = new SmtpConnectorWithoutSsl(server, port);
}
if (!connector.CheckResponse(220)) {
return false;
}
connector.SendData($"HELO {Dns.GetHostName()}{SmtpConnectorBase.EOF}");
if (!connector.CheckResponse(250)) {
return false;
}
connector.SendData($"AUTH LOGIN{SmtpConnectorBase.EOF}");
if (!connector.CheckResponse(334)) {
return false;
}
connector.SendData(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{login}")) + SmtpConnectorBase.EOF);
if (!connector.CheckResponse(334)) {
return false;
}
connector.SendData(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{password}")) + SmtpConnectorBase.EOF);
if (!connector.CheckResponse(235)) {
return false;
}
return true;
}
SmtpConnectorBase:
internal abstract class SmtpConnectorBase {
protected string SmtpServerAddress { get; set; }
protected int Port { get; set; }
public const string EOF = "\r\n";
protected SmtpConnectorBase(string smtpServerAddress, int port) {
SmtpServerAddress = smtpServerAddress;
Port = port;
}
public abstract bool CheckResponse(int expectedCode);
public abstract void SendData(string data);
}
SmtpConnectorWithoutSsl:
internal class SmtpConnectorWithoutSsl : SmtpConnectorBase {
private Socket _socket = null;
public SmtpConnectorWithoutSsl(string smtpServerAddress, int port) : base(smtpServerAddress, port) {
IPHostEntry hostEntry = Dns.GetHostEntry(smtpServerAddress);
IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], port);
_socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
//try to connect and test the rsponse for code 220 = success
_socket.Connect(endPoint);
}
~SmtpConnectorWithoutSsl() {
try {
if (_socket != null) {
_socket.Close();
_socket.Dispose();
_socket = null;
}
} catch (Exception) {
;
}
}
public override bool CheckResponse(int expectedCode) {
while (_socket.Available == 0) {
System.Threading.Thread.Sleep(100);
}
byte[] responseArray = new byte[1024];
_socket.Receive(responseArray, 0, _socket.Available, SocketFlags.None);
string responseData = Encoding.UTF8.GetString(responseArray);
int responseCode = Convert.ToInt32(responseData.Substring(0, 3));
if (responseCode == expectedCode) {
return true;
}
return false;
}
public override void SendData(string data) {
byte[] dataArray = Encoding.UTF8.GetBytes(data);
_socket.Send(dataArray, 0, dataArray.Length, SocketFlags.None);
}
}
SmtpConnectorWithSsl:
internal class SmtpConnectorWithSsl : SmtpConnectorBase {
private SslStream _sslStream = null;
private TcpClient _client = null;
public SmtpConnectorWithSsl(string smtpServerAddress, int port) : base(smtpServerAddress, port) {
TcpClient client = new TcpClient(smtpServerAddress, port);
_sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
// The server name must match the name on the server certificate.
try {
_sslStream.AuthenticateAsClient(smtpServerAddress);
} catch (AuthenticationException e) {
_sslStream = null;
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null) {
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
}
}
~SmtpConnectorWithSsl() {
try {
if (_sslStream != null) {
_sslStream.Close();
_sslStream.Dispose();
_sslStream = null;
}
} catch (Exception) {
;
}
try {
if (_client != null) {
_client.Close();
_client = null;
}
} catch (Exception) {
;
}
}
// The following method is invoked by the RemoteCertificateValidationDelegate.
private static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors) {
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
return false;
}
public override bool CheckResponse(int expectedCode) {
if (_sslStream == null) {
return false;
}
var message = ReadMessageFromStream(_sslStream);
int responseCode = Convert.ToInt32(message.Substring(0, 3));
if (responseCode == expectedCode) {
return true;
}
return false;
}
public override void SendData(string data) {
byte[] messsage = Encoding.UTF8.GetBytes(data);
// Send hello message to the server.
_sslStream.Write(messsage);
_sslStream.Flush();
}
private string ReadMessageFromStream(SslStream stream) {
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do {
bytes = stream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF.
if (messageData.ToString().IndexOf(EOF) != -1) {
break;
}
} while (bytes != 0);
return messageData.ToString();
}
}
You could open up the port (25) with a socket or TcpClient and see if it responds.
Open a socket connection to the smtp server on port 25 and see if you get anything. If not, no smtp server.
Here is a nice open source tool (does more than MX):
http://www.codeproject.com/KB/IP/DNS_NET_Resolver.aspx

Categories

Resources