Unverified Commit 0800ff46 authored by Jehonathan Thomas's avatar Jehonathan Thomas Committed by GitHub

Merge pull request #538 from justcoding121/master

Beta 3.0.866+
parents 29901cf9 b6aaa812
## Titanium Web Proxy
A light weight HTTP(S) proxy server written in C#
A lightweight HTTP(S) proxy server written in C#.
<a href="https://ci.appveyor.com/project/justcoding121/titanium-web-proxy">![Build Status](https://ci.appveyor.com/api/projects/status/p5vvtbpx9yp250ol?svg=true)</a> [![Join the chat at https://gitter.im/Titanium-Web-Proxy/Lobby](https://badges.gitter.im/Titanium-Web-Proxy/Lobby.svg)](https://gitter.im/Titanium-Web-Proxy/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Kindly report only issues/bugs here . For programming help or questions use [StackOverflow](http://stackoverflow.com/questions/tagged/titanium-web-proxy) with the tag Titanium-Web-Proxy.
Kindly report only issues/bugs here. For programming help or questions use [StackOverflow](http://stackoverflow.com/questions/tagged/titanium-web-proxy) with the tag Titanium-Web-Proxy.
* [API Documentation](https://justcoding121.github.io/Titanium-Web-Proxy/docs/api/Titanium.Web.Proxy.ProxyServer.html)
* [Wiki & Contribution guidelines](https://github.com/justcoding121/Titanium-Web-Proxy/wiki)
### Features
* Multithreaded & fully asynchronous proxy employing server connection pooling, certificate cache & buffer pooling
* View/modify/redirect/block requests & responses
* Multi-threaded fully asynchronous proxy employing server connection pooling, certificate cache, and buffer pooling
* View/modify/redirect/block requests and responses
* Supports mutual SSL authentication, proxy authentication & automatic upstream proxy detection
* Kerberos/NTLM authentication over HTTP protocols for windows domain
......@@ -48,7 +48,7 @@ Supports
### Usage
Refer the HTTP Proxy Server library in your project, look up Test project to learn usage.
Refer the HTTP Proxy Server library in your project and look up the test project to learn usage.
Setup HTTP proxy:
......@@ -228,7 +228,7 @@ public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs
```
### Note to contributors
#### Roadmap
#### Road map
* Support HTTP 2.0
......
......@@ -128,7 +128,7 @@
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsLinux.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsLinux%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L50">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L47">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsLinux_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsLinux*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsLinux" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsLinux">IsLinux</h4>
......@@ -158,7 +158,7 @@
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsMac.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsMac%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L63">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L60">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsMac_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsMac*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsMac" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsMac">IsMac</h4>
......@@ -188,7 +188,7 @@
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsUwpOnWindows.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsUwpOnWindows%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L58">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L55">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsUwpOnWindows_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsUwpOnWindows*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsUwpOnWindows" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsUwpOnWindows">IsUwpOnWindows</h4>
......@@ -218,7 +218,7 @@
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime_IsWindows.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime.IsWindows%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
</span>
<span class="small pull-right mobile-hide">
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L56">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L53">View Source</a>
</span>
<a id="Titanium_Web_Proxy_Helpers_RunTime_IsWindows_" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsWindows*"></a>
<h4 id="Titanium_Web_Proxy_Helpers_RunTime_IsWindows" data-uid="Titanium.Web.Proxy.Helpers.RunTime.IsWindows">IsWindows</h4>
......@@ -254,7 +254,7 @@
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/new/master/apiSpec/new?filename=Titanium_Web_Proxy_Helpers_RunTime.md&amp;value=---%0Auid%3A%20Titanium.Web.Proxy.Helpers.RunTime%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A" class="contribution-link">Improve this Doc</a>
</li>
<li>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L13" class="contribution-link">View Source</a>
<a href="https://github.com/justcoding121/Titanium-Web-Proxy/blob/master/src/Titanium.Web.Proxy/Helpers/RunTime.cs/#L10" class="contribution-link">View Source</a>
</li>
</ul>
</div>
......
using System.Linq;
using System;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace Titanium.Web.Proxy.Helpers
{
internal class NetworkHelper
{
private static readonly string localhostName = Dns.GetHostName();
private static readonly IPHostEntry localhostEntry = Dns.GetHostEntry(string.Empty);
/// <summary>
/// Adapated from below link
/// http://stackoverflow.com/questions/11834091/how-to-check-if-localhost
......@@ -19,55 +24,52 @@ namespace Titanium.Web.Proxy.Helpers
return true;
}
// get local IP addresses
var localIPs = Dns.GetHostAddresses(Dns.GetHostName());
// test if any host IP equals to any local IP or to localhost
return localIPs.Contains(address);
// test if host IP equals any local IP
return localhostEntry.AddressList.Contains(address);
}
internal static bool IsLocalIpAddress(string hostName)
{
hostName = hostName.ToLower();
if (hostName == "127.0.0.1"
|| hostName == "localhost")
if (IPAddress.TryParse(hostName, out var ipAddress)
&& IsLocalIpAddress(ipAddress))
{
return true;
}
var localhostDnsName = Dns.GetHostName().ToLower();
//if hostname matches current machine DNS name
if (hostName == localhostDnsName)
if (hostName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
return true;
}
var isLocalhost = false;
IPHostEntry hostEntry = null;
//check if parsable to an IP Address
if (IPAddress.TryParse(hostName, out var ipAddress))
//if hostname matches local host name
if (hostName.Equals(localhostName, StringComparison.OrdinalIgnoreCase))
{
hostEntry = Dns.GetHostEntry(localhostDnsName);
isLocalhost = hostEntry.AddressList.Any(x => x.Equals(ipAddress));
return true;
}
if (!isLocalhost)
// if hostname matches fully qualified local DNS name
if (hostName.Equals(localhostEntry.HostName, StringComparison.OrdinalIgnoreCase))
{
try
{
hostEntry = Dns.GetHostEntry(hostName);
isLocalhost = hostEntry.AddressList.Any(x => hostEntry.AddressList.Any(x.Equals));
}
catch (SocketException)
return true;
}
try
{
// do reverse DNS lookup even if hostName is an IP address
var hostEntry = Dns.GetHostEntry(hostName);
// if DNS resolved hostname matches local DNS name,
// or if host IP address list contains any local IP address
if (hostEntry.HostName.Equals(localhostEntry.HostName, StringComparison.OrdinalIgnoreCase)
|| hostEntry.AddressList.Any(hostIP => localhostEntry.AddressList.Contains(hostIP)))
{
return true;
}
}
catch (SocketException)
{
}
return isLocalhost;
return false;
}
}
}
using System;
using System.Runtime.InteropServices;
using System.Text;
#if NETSTANDARD2_0
using System.Runtime.InteropServices;
#endif
namespace Titanium.Web.Proxy.Helpers
{
......
......@@ -2,6 +2,7 @@
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Titanium.Web.Proxy.Helpers;
namespace Titanium.Web.Proxy.Network
{
......@@ -13,24 +14,24 @@ namespace Titanium.Web.Proxy.Network
private string rootCertificatePath;
private string certificatePath;
public X509Certificate2 LoadRootCertificate(string name, string password, X509KeyStorageFlags storageFlags)
public X509Certificate2 LoadRootCertificate(string pathOrName, string password, X509KeyStorageFlags storageFlags)
{
string filePath = getRootCertificatePath(name);
return loadCertificate(filePath, password, storageFlags);
string path = getRootCertificatePath(pathOrName);
return loadCertificate(path, password, storageFlags);
}
public void SaveRootCertificate(string name, string password, X509Certificate2 certificate)
public void SaveRootCertificate(string pathOrName, string password, X509Certificate2 certificate)
{
string filePath = getRootCertificatePath(name);
string path = getRootCertificatePath(pathOrName);
byte[] exported = certificate.Export(X509ContentType.Pkcs12, password);
File.WriteAllBytes(filePath, exported);
File.WriteAllBytes(path, exported);
}
/// <inheritdoc />
public X509Certificate2 LoadCertificate(string subjectName, X509KeyStorageFlags storageFlags)
{
string filePath = Path.Combine(getCertificatePath(), subjectName + defaultCertificateFileExtension);
return loadCertificate(filePath, string.Empty, storageFlags);
string path = Path.Combine(getCertificatePath(), subjectName + defaultCertificateFileExtension);
return loadCertificate(path, string.Empty, storageFlags);
}
/// <inheritdoc />
......@@ -55,12 +56,12 @@ namespace Titanium.Web.Proxy.Network
certificatePath = null;
}
private X509Certificate2 loadCertificate(string filePath, string password, X509KeyStorageFlags storageFlags)
private X509Certificate2 loadCertificate(string path, string password, X509KeyStorageFlags storageFlags)
{
byte[] exported;
try
{
exported = File.ReadAllBytes(filePath);
exported = File.ReadAllBytes(path);
}
catch (IOException)
{
......@@ -71,15 +72,15 @@ namespace Titanium.Web.Proxy.Network
return new X509Certificate2(exported, password, storageFlags);
}
private string getRootCertificatePath(string filePath)
private string getRootCertificatePath(string pathOrName)
{
if (Path.IsPathRooted(filePath))
if (Path.IsPathRooted(pathOrName))
{
return filePath;
return pathOrName;
}
return Path.Combine(getRootCertificateDirectory(),
string.IsNullOrEmpty(filePath) ? defaultRootCertificateFileName : filePath);
string.IsNullOrEmpty(pathOrName) ? defaultRootCertificateFileName : pathOrName);
}
private string getCertificatePath()
......@@ -104,17 +105,32 @@ namespace Titanium.Web.Proxy.Network
{
if (rootCertificatePath == null)
{
string assemblyLocation = GetType().Assembly.Location;
// dynamically loaded assemblies returns string.Empty location
if (assemblyLocation == string.Empty)
if (RunTime.IsUwpOnWindows)
{
rootCertificatePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
}
else if (RunTime.IsLinux)
{
assemblyLocation = Assembly.GetEntryAssembly().Location;
rootCertificatePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
else if (RunTime.IsMac)
{
rootCertificatePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
else
{
string assemblyLocation = GetType().Assembly.Location;
string path = Path.GetDirectoryName(assemblyLocation);
// dynamically loaded assemblies returns string.Empty location
if (assemblyLocation == string.Empty)
{
assemblyLocation = Assembly.GetEntryAssembly().Location;
}
rootCertificatePath = path ?? throw new NullReferenceException();
string path = Path.GetDirectoryName(assemblyLocation);
rootCertificatePath = path ?? throw new NullReferenceException();
}
}
return rootCertificatePath;
......
......@@ -7,12 +7,12 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// Loads the root certificate from the storage.
/// </summary>
X509Certificate2 LoadRootCertificate(string name, string password, X509KeyStorageFlags storageFlags);
X509Certificate2 LoadRootCertificate(string pathOrName, string password, X509KeyStorageFlags storageFlags);
/// <summary>
/// Saves the root certificate to the storage.
/// </summary>
void SaveRootCertificate(string name, string password, X509Certificate2 certificate);
void SaveRootCertificate(string pathOrName, string password, X509Certificate2 certificate);
/// <summary>
/// Loads certificate from the storage. Returns true if certificate does not exist.
......
......@@ -14,13 +14,22 @@
<copyright>Copyright &#x00A9; Titanium. All rights reserved.</copyright>
<tags></tags>
<dependencies>
<dependency id="StreamExtended" version="1.0.179" />
<dependency id="Portable.BouncyCastle" version="1.8.2" />
<dependency id="BrotliSharpLib" version="0.3.1" />
<group targetFramework="net45">
<dependency id="StreamExtended" version="1.0.179" />
<dependency id="Portable.BouncyCastle" version="1.8.2" />
<dependency id="BrotliSharpLib" version="0.3.1" />
</group>
<group targetFramework="netstandard2.0">
<dependency id="StreamExtended" version="1.0.179" />
<dependency id="Portable.BouncyCastle" version="1.8.2" />
<dependency id="BrotliSharpLib" version="0.3.1" />
<dependency id="Microsoft.Win32.Registry" version="4.4.0" />
<dependency id="System.Security.Principal.Windows" version="4.4.1" />
</group>
</dependencies>
</metadata>
<files>
<file src="bin\$configuration$\net45\Titanium.Web.Proxy.dll" target="lib\net45" />
<file src="bin\$configuration$\netstandard2.0\Titanium.Web.Proxy.*" target="lib\netstandard2.0" />
<file src="bin\$configuration$\netstandard2.0\Titanium.Web.Proxy.dll" target="lib\netstandard2.0" />
</files>
</package>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment