using System; using System.Net; using System.Net.Security; using System.Net.Sockets; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; namespace PixivLocalSniCover { internal static class Program { private static X509Certificate _serverCert; [STAThread] private static void Main() { _serverCert = new X509Certificate2(Properties.Resources.server, "server"); StartMain(); StartLive(); Console.WriteLine("Press ENTER to exit"); Console.ReadLine(); } private static void StartMain() { var svc = new TcpListener(IPAddress.Loopback, 443); Console.WriteLine($"Listening on {svc.LocalEndpoint} for Main"); svc.Start(); svc.BeginAcceptTcpClient(HandleRequestMain, svc); } private static void HandleRequestMain(IAsyncResult ar) { var svc = (TcpListener)ar.AsyncState; svc.BeginAcceptTcpClient(HandleRequestMain, svc); HandleInternal(ar, svc, CreateConnectionMain); } private static void StartLive() { var svc = new TcpListener(IPAddress.Parse("127.0.0.2"), 443); Console.WriteLine($"Listening on {svc.LocalEndpoint} for Live"); svc.Start(); svc.BeginAcceptTcpClient(HandleRequestLive, svc); } private static void HandleRequestLive(IAsyncResult ar) { var svc = (TcpListener)ar.AsyncState; svc.BeginAcceptTcpClient(HandleRequestLive, svc); HandleInternal(ar, svc, CreateConnectionLive); } private static void HandleInternal(IAsyncResult ar, TcpListener svc, Func provider) { using (var client = svc.EndAcceptTcpClient(ar)) { var clientRemoteEndPoint = client.Client.RemoteEndPoint; Console.WriteLine($"Accept from {clientRemoteEndPoint}"); var clientStream = client.GetStream(); var clientSsl = new SslStream(clientStream, false); clientSsl.AuthenticateAsServer(_serverCert); var conn = provider(); if (null != conn) { using (conn) { var send = Task.Factory.StartNew(() => { try { clientSsl.CopyTo(conn); } catch { Console.WriteLine($"Closed by local {clientRemoteEndPoint}"); } }); var recv = Task.Factory.StartNew(() => { try { conn.CopyTo(clientSsl); } catch { Console.WriteLine($"Closed by remote {clientRemoteEndPoint}"); } }); Task.WaitAny(send, recv); conn.Close(); } } client.Close(); } } private static SslStream CreateConnectionLive() { const string IpLive = "210.140.170.179"; const string certSubject = "CN=*.pixivsketch.net, OU=Domain Control Validated"; const string certSn = "255CFC7D0A8E016C94C655C0"; const string certT = "5942DD91CEC00247B492EA79CE9CA13F1DF2FADB"; try { var cl = new TcpClient(IpLive, 443); var networkStream = cl.GetStream(); var ssl = new SslStream(networkStream, false, (sender, certificate, chain, errors) => { var cert = (X509Certificate2)certificate; return cert.Subject == certSubject && cert.SerialNumber == certSn && cert.Thumbprint == certT; }); ssl.AuthenticateAsClient(""); return ssl; } catch (Exception e) { Console.WriteLine(e); return null; } } private static SslStream CreateConnectionMain() { const string ipMain = "210.140.131.224"; const string certSubject = "CN=*.pixiv.net, O=pixiv Inc., OU=Development department, L=Shibuya-ku, S=Tokyo, C=JP"; const string certSn = "73367180A6430D2C1CDF8076"; const string certT = "790E5A115639C72B371B17C2C980CF31310FABA7"; try { var cl = new TcpClient(ipMain, 443); var networkStream = cl.GetStream(); var ssl = new SslStream(networkStream, false, (sender, certificate, chain, errors) => { var cert = (X509Certificate2)certificate; return cert.Subject == certSubject && cert.SerialNumber == certSn && cert.Thumbprint == certT; }); ssl.AuthenticateAsClient(""); return ssl; } catch (Exception e) { Console.WriteLine(e); return null; } } } }