Getting a response from the browser (HTTPS, C#) - c#

It is necessary to receive data from the browser, I mean the authorization code. I use the OAuth2 from Yahoo service. This code is displayed in the address bar of the browser after successful authorization, than redirect to redirect_uri=.... Process is used to start the browser, after that I try to listen on port XXXX with HttpListener, however even if I get some response, it is a meaningless set of characters . (UTF-8, etc. tried, the result is the same)
How can I get the authorization code from the browser after successful authorization?
Code with HttpListener
static void SniffPort()
{
byte[] input = new byte[] { 1 };
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
socket.Bind(new IPEndPoint(IPAddress.Broadcast, 5000));
socket.IOControl(IOControlCode.ReceiveAll, input, null);
byte[] buffer = new byte[4096];
Task.Factory.StartNew(() =>
{
while (true)
{
int len = socket.Receive(buffer);
if (len <= 40) continue;
string bin = Encoding.Default.GetString(buffer, 0, len);
Console.WriteLine(bin);
}
});
}
static HttpListener _httpListener = new HttpListener();
static void Main(string[] args)
{
Console.WriteLine("Starting server...");
_httpListener.Prefixes.Add("https://localhost:5000/");
_httpListener.Start();
Console.WriteLine("Server started.");
SniffPort();
ProcessStartInfo startInfo = new ProcessStartInfo(#"C:\Users\User\Desktop\chrome-win\chrome.exe");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
Process p = new Process();
startInfo.Arguments = "--app=https://api.login.yahoo.com/oauth2/request_auth?client_id=CLIENT_ID&redirect_uri=https://localhost:5000/&response_type=code&language=en-us";
p.StartInfo = startInfo;
p.Start();
p.WaitForExit();
}
Also I had idea with the FiddlerCore, but after using it, you have to change the settings related to the proxy in inetcpl.cpl. It also doesn't work if the browser remembers the user and logs in immediately after starting the browser, FiddlerCore does not provide this information.
Code with FiddlerCore
public class HttpProxy : IDisposable
{
public HttpProxy()
{
Fiddler.FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
Fiddler.FiddlerApplication.Startup(5000, true, false);
}
void FiddlerApplication_BeforeRequest(Fiddler.Session oSession)
{
Console.WriteLine(String.Format("REQ: {0}", oSession.url));
}
public void Dispose()
{
Fiddler.FiddlerApplication.Shutdown();
}
}
static HttpListener _httpListener = new HttpListener();
static void Main(string[] args)
{
HttpProxy httpProxy = new HttpProxy();
//Launching the browser as in the code above.
}

Related

HTTP Listener not getting external calls

I have this Windows form app that wants to receive some calls from some external source.
I did some example based on this :
https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistener?view=net-5.0
Its almost the same thing, i just did it to run on another thread.
private static Form1 form;
public static Thread httpServer;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form1();
form.Load += OnFormLoad;
Application.Run(form);
}
private static void OnFormLoad(object sender, EventArgs e)
{
httpServer = CreateHttp();
}
private static Thread CreateHttp()
{
HttpListener listener = new HttpListener();
string[] prefixes = new string[1];
prefixes[0] = "http://+:3070/";
foreach (string s in prefixes)
{
listener.Prefixes.Add(s);
}
listener.Start();
var listeningThread = new Thread(() =>
{
while (true)
{
HttpListenerContext context = listener.GetContext();
ThreadPool.QueueUserWorkItem(param =>
{
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
string url = request.RawUrl;
string responseString = "<HTML><BODY> Hello World </BODY></HTML>";
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}, null);
}
});
listeningThread.IsBackground = true;
listeningThread.Start();
return listeningThread;
}
When I call from localhost:3070 or 127.0.0.1:3070 it works, but if i try from ipadress:3070 I only get timeouts.
I'm already included this "3070" ports in my firewall....I also tried turning off my entire firewall
Also checked if the listener is working with the command :
netstat -na | find "3070"
TCP 0.0.0.0:3070 0.0.0.0:0 LISTENING
TCP [::]:3070 [::]:0 LISTENING
And also checked if this url is reserved with the command:
"netsh http show urlacl"
URL reservada : http://+:3070/
Usuário: \Todos
Escutar: Yes
Delegar: No
SDDL: D:(A;;GX;;;WD)
Anything I'm missing ?

C# - What's the best way to use TcpListener (async)

I would create a tcp server with TcpListener, but I don't know what's the best solution to do that.
I tried with 3 examples. See below.
Example 1
(I used BeginAcceptTcpClient)
class Program
{
static void Main(string[] args)
{
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
var listener = new TcpListener(endPoint);
listener.Start();
AcceptTcpClient(listener);
while (true)
{
}
}
public static void AcceptTcpClient(TcpListener listener)
{
listener.BeginAcceptTcpClient(ClientConnected, listener);
}
public static void ClientConnected(IAsyncResult asyncResult)
{
var listener = (TcpListener)asyncResult.AsyncState;
var client = listener.EndAcceptTcpClient(asyncResult);
AcceptTcpClient(listener);
DoAsync(client);
}
}
Example 2
(I used BeginAcceptTcpClient with AutoResetEvent)
class Program1
{
private static readonly AutoResetEvent CONNECTION_WAIT_HANDLE = new AutoResetEvent(false);
static void Main(string[] args)
{
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
var listener = new TcpListener(endPoint);
listener.Start();
while (true)
{
listener.BeginAcceptTcpClient(ClientConnectedHandle, listener);
CONNECTION_WAIT_HANDLE.WaitOne();
CONNECTION_WAIT_HANDLE.Reset();
}
}
public static void ClientConnectedHandle(IAsyncResult asyncResult)
{
var listener = (TcpListener)asyncResult.AsyncState;
var client = listener.EndAcceptTcpClient(asyncResult);
CONNECTION_WAIT_HANDLE.Set();
DoAsync(client);
}
}
Example 3
(I used AcceptTcpClientAsync)
class Program2
{
static async Task Main(string[] args)
{
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
var listener = new TcpListener(endPoint);
listener.Start();
while (true)
{
var client = await listener.AcceptTcpClientAsync();
DoAsync(client);
}
}
public static void AcceptTcpClient(TcpListener listener)
{
listener.BeginAcceptTcpClient(ClientConnected, listener);
}
public static void ClientConnected(IAsyncResult asyncResult)
{
var listener = (TcpListener)asyncResult.AsyncState;
var client = listener.EndAcceptTcpClient(asyncResult);
AcceptTcpClient(listener);
DoAsync(client);
}
}
I think the best solution is the last (Example 3) but I'm not sure. What do you think of that?
This is the code that I'm using in my project. It's a receive only asynchronous server but you can modify it to your liking according to your needs in Task.Run(). I have commented out the code so that you can understand how it works.
static async Task Main(string[] args)
{
await RunServer();
}
static async Task RunServer()
{
TcpListener Listener = new TcpListener(IPAddress.Any, YOURPORTHERE); // Set your listener
Listener.Start(); // Start your listener
while (true) // Permanent loop, it may not be the best solution
{
TcpClient Client = await Listener.AcceptTcpClientAsync(); // Waiting for a connection
_ = Task.Run(() => { // Connection opened. Queues the specified job to run in the ThreadPool, meanwhile the server is ready to accept other connections in parallel
try
{
var Stream = Client.GetStream(); // (read-only) get data bytes
if (Stream.CanRead) // Verify if the stream can be read.
{
byte[] Buffer = new byte[Client.ReceiveBufferSize]; // Initialize a new empty byte array with the data length.
StringBuilder SB = new StringBuilder();
do // Start converting bytes to string
{
int BytesReaded = Stream.Read(Buffer, 0, Buffer.Length);
SB.AppendFormat("{0}", Encoding.ASCII.GetString(Buffer, 0, BytesReaded));
} while (Stream.DataAvailable); // Until stream data is available
if (SB != null) // Stream data is ready and converted to string
// Do some stuffs
}
}
catch (Exception Ex) // In case of errors catch it to avoid the app crash
{
ConsoleMessage.Error(Ex.ToString()); // Detailed exception
}
});
}
}

HttpListener BeginGetContext suddenly stopping?

I have a HttpListener which I want to not shut down after each request, so I'm using BeginGetContext to retrieve requests asynchronously. It's just not working properly.
Main starts properly, finding and assigning my IP address for the StartListening() function. However, when I get to listener.BeginGetContext(new AsyncCallback(OnRequest), listener); in StartListening() and it jumps to Response.StartListening(ips); in Main and then just stops. I'm not sure why. Any hints?
Here's what I have so far.
This is where I start listening for requests:
public static void StartListening(string[] prefixes)
{
HttpListener listener = new HttpListener();
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
foreach (string s in prefixes)
{
listener.Prefixes.Add("http://" + s + "/");
}
listener.Start();
Console.WriteLine("\nListening...");
listener.BeginGetContext(new AsyncCallback(OnRequest), listener);
}
And here's where I handle the requests:
public static void OnRequest(IAsyncResult result)
{
HttpListener listener = (HttpListener) result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
string url = context.Request.RawUrl;
string[] split = url.Split('/');
int lastIndex = split.Length - 1;
int x, y, z;
x = Convert.ToInt32(split[lastIndex]);
y = Convert.ToInt32(split[lastIndex - 1]);
z = Convert.ToInt32(split[lastIndex - 2]);
HttpListenerResponse response = context.Response;
Regex imageRegex = new Regex(#"SomethingSomething");
var matches = imageRegex.Match(url);
if (matches.Success)
{
string path = #"C:\SomeDir";
path = String.Format(path, matches.Groups[1].Captures[0],
matches.Groups[2].Captures[0],
matches.Groups[3].Captures[0]);
// Load the image
Bitmap bm = new Bitmap(path);
MemoryStream bmStream = new MemoryStream();
bm.Save(bmStream, ImageFormat.Png);
byte[] buffer = bmStream.ToArray();
// Get a response stream and write the response to it.
response.ContentLength64 = bmStream.Length;
response.ContentType = "image/png";
response.KeepAlive = true;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
// You must close the output stream.
output.Close();
listener.Stop();
}
response.Close();
listener.BeginGetContext(new AsyncCallback(OnRequest), listener);
}
And here's my main:
class Program
{
static void Main(string[] args)
{
string name = (args.Length < 1) ? Dns.GetHostName() : args[0];
try
{ //Find the IPv4 address
IPAddress[] addrs = Array.FindAll(Dns.GetHostEntry(string.Empty).AddressList,
a => a.AddressFamily == AddressFamily.InterNetwork);
Console.WriteLine("Your IP address is: ");
foreach (IPAddress addr in addrs)
Console.WriteLine("{0} {1}", name, addr);
//Automatically set the IP address
string[] ips = addrs.Select(ip => ip.ToString()).ToArray();
Response.StartListening(ips);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
After BeginGetContext, it fetches requests asynchronously, so it does not block the calling thread (the Main thread, in this case). And because it doesn't block it, the Main thread ends and thus your program also ends, because it's the Main thread.
You can fix this, by using a ManualResetEvent (in the System.Threading namespace). This blocks the Main thread.
class Program
{
public static ManualResetEvent ServerManualResetEvent;
static void Main(string[] args)
{
try
{
// your code to start the server
ServerManualResetEvent = new ManualResetEvent(false);
ServerManualResetEvent.WaitOne();
}
catch
{
// your catch code
}
}
}
Now the Main thread is blocked and your program only stops if you close it, or if you stop it from code:
Program.ServerManualResetEvent.Set();
Then it does not block the Main thread anymore.

TCP/IP Socket is not reading data from machine when running as Windows Service in c#

I have a simple TCP/IP program to read data from a machine and write it into text file. I want to run it as Windows Service so that data gets written into text file continuously with out any intervention. Now when I try to run the program under debug mode of Visual Studio, it is reading the data from the machine and saving into text file, but as soon as I add it as Windows Service and try to start the service, it is giving following error message..
windows service could not start the service on the local computer
error:1053 The service did not respond to the start or the control request in a timely fashion
Here is my main applications code..
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
Here is my code to communicate to the machine using TCP/IP and read/write data into text file..
protected override void OnStart(string[] args)
{
ipaddress = "";
int port = int.Parse("");
textfileSaveLocation = "";
byte[] data = new byte[1024];
string stringData;
IPAddress ipadd = IPAddress.Parse(ipaddress);
IPEndPoint ipend = new IPEndPoint(ipadd, port);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.NoDelay = false;
try
{
sock.Connect(ipend);
}
catch (Exception dfg)
{
return;
}
try
{
buf = String.Format("SMDR", "PCCSMDR");
bBuf = Encoding.ASCII.GetBytes(buf);
sock.Send(bBuf);
while (true)
{
data = new byte[1024];
int recv = sock.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, recv);
string df = "";
try
{
FileStream dr = new FileStream(textfileSaveLocation, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
StreamReader fg = new StreamReader(dr);
df = fg.ReadToEnd();
fg.Dispose();
dr.Dispose();
}
catch (Exception dfjdfs)
{
}
try
{
FileStream cd = new FileStream(textfileSaveLocation, FileMode.Create);
StreamWriter cdf = new StreamWriter(cd);
cdf.WriteLine(df);
cdf.WriteLine(stringData);
cdf.Dispose();
cd.Dispose();
}
catch (Exception hgy)
{
}
}
sock.Shutdown(SocketShutdown.Both);
sock.Close();
}
catch (Exception DFGFD)
{
}
}
My only aim with this program is to run it as Windows Service through installer and start the service. Once the service is started, it should read the data from the given ip and port of the machine and save it into text file. Also I need this service to continuously monitor for the data from the machine and once new data comes to the machine, it should read and write into the text file.
Do I need to implement Multi-threading in the program?
The system expects the OnStart method to return in a timely fashion (~30 seconds), so long-running tasks like monitoring for data need to be moved to another thread. This can be as simple as:
private System.Threading.Thread _thread;
protected override void OnStart(string[] args)
{
_thread = new Thread(DoWork);
_thread.Start();
}
private void DoWork()
{
// create and monitor socket here...
}
Note that while your while (true) loop is sufficient to keep the thread running, it makes it difficult to stop it when the service stops. For this, I use a ManualResetEvent like so.
using System.Threading;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private void DoWork()
{
// initialize socket and file
// thread loop
while (!_shutdownEvent.Wait(0))
{
// read socket, write to file
}
// close socket and file
}
protected override void OnStop()
{
_shutdownEvent.Set();
_thread.Join(); // wait for thread to stop
}
I agree with Matt's answer.
Also, In general , it is good to add an option to debug your service, here is an example:
protected override void OnStart(string[] args)
{
bool launchDebugger = false;
if (args.Count() > 0)
{
launchDebugger = args[0].ToLower() == "debug";
}
if (launchDebugger)
{
Debugger.Launch();
}
}
When you run the service with an argument: "debug", it will trigger a fake exception,
allowing you to debug the service with visual studio.

Socket program in c# is not reading On Windows Service while reading On Debug mode of Visual Studio

I have a Socket program in my Windows Service application to monitor particular Socket for reading and writing data into text file.I need my application to establish the connection and continuously read/write the data from the machine as soon as new data enters into the machine.
Now when i am trying to do the above explained task in debug mode of my visual studio it is happening perfectly but as soon as i try to run it from services.msc it is neither dumping(writing) any data into text file from the machine..
I am using Visual Studio Setup project to create and install the Setup...
Now here is my Applications code..
This is my main program code..
static void Main()
{
if DEBUG
Service1 myservice = new Service1();
myservice.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
endif
}
and this is my Socket logic codes..
string ipaddress, textfileSaveLocation;
Byte[] bBuf;
string buf;
private System.Threading.Thread _thread;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
string df = "";
public Service1()
{
InitializeComponent();
}
public void OnDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
_thread = new Thread(DoWork);
_thread.Start();
}
private void DoWork()
{
// create and monitor socket here...
ipaddress = "";
int port = int.Parse("");
textfileSaveLocation = "";
byte[] data = new byte[1024];
string stringData;
IPAddress ipadd = IPAddress.Parse(ipaddress);
IPEndPoint ipend = new IPEndPoint(ipadd, port);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.NoDelay = false;
try
{
sock.Connect(ipend);
}
catch (Exception dfg)
{
return;
}
try
{
buf = String.Format("Client Here");
bBuf = Encoding.ASCII.GetBytes(buf);
sock.Send(bBuf);
while (!_shutdownEvent.WaitOne(0))
{
data = new byte[1024];
int recv = sock.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, recv);
try
{
FileStream cd = new FileStream(textfileSaveLocation, FileMode.OpenOrCreate);
StreamWriter cdf = new StreamWriter(cd);
cdf.WriteLine(df);
cdf.WriteLine(stringData);
cdf.Dispose();
cd.Dispose();
}
catch (Exception abcd)
{
}
}
sock.Shutdown(SocketShutdown.Both);
sock.Close();
}
catch (Exception DFGFD)
{
}
}
protected override void OnStop()
{
_shutdownEvent.Set();
_thread.Join(); // wait for thread to stop
}
}
I have build the application under the release mode and used that to create the Visual Studio Setup project file to install the application as Windows Service..
But i am not getting where i am missing the logic or flow..
Also I am trying to install this service through remote login by using Team Viewer Access.

Categories