private static HttpWebResponse ProcessIncomingRequestToProtectedSite(HttpListenerContext context, SiteInf siteInf) { HttpListenerRequest incomingRequest = context.Request; HttpWebResponse incomingResponse = null; // GET - create session, or POST - download session if (incomingRequest.HttpMethod == "GET") // ! разобраться с HEAD { // Запросы типа GET могут быть к защищённому сайту (за ccs или js) // или могут быть к странице Login. Те которые к Login перехватываем // и отправляем ответ прямо из файлов которые есть на прокси. Кроме того, если // запрос без адреса или к странице Login, то создаём и регистрируем новую сессию. String userAddress = null; NskdSession session = null; switch (incomingRequest.Url.AbsolutePath) { case "/": case "/login/login.html": userAddress = context.Request.RemoteEndPoint.Address.ToString(); session = new NskdSession(userAddress); RsaParameters ps = session.Rsa.ExportParameters(); String sessionId = session.SessionId; String rsaModule = Convert.ToBase64String(ps.Module); String rsaExponent = Convert.ToBase64String(ps.Exponent); server.SendLoginPage(context, sessionId, rsaModule, rsaExponent); break; case "/login/login.css": server.SendFile(context, @"Login\Login.css"); break; case "/login/login.js": server.SendFile(context, @"Login\Login.js"); break; case "/scripts/cryptico/cryptico.min.js": server.SendFile(context, @"Scripts\Cryptico\cryptico.min.js"); break; case "/scripts/nskd/nskd.js": server.SendFile(context, @"Scripts\Nskd\Nskd.js"); break; default: // если запрос типа GET не перехвачен, то перенаправляем его клиенту incomingResponse = siteInf.Client.GetResponse(context); break; } } else if (incomingRequest.HttpMethod == "POST") { incomingResponse = ProcessPost(incomingRequest, context, siteInf); } else // все остальные кроме GET и POST. ! разобраться с HEAD { incomingResponse = siteInf.Client.GetResponse(context); } return(incomingResponse); }
private static HttpWebResponse ProcessPost(HttpListenerRequest incomingRequest, HttpListenerContext context, SiteInf siteInf) { HttpWebResponse incomingResponse = null; String response = null; // Если запросы типа POST, то все их перенаправляем клиенту. // Здесь надо поймать первый запрос с общим ключём для шифрования. switch (incomingRequest.Url.AbsolutePath) { case "/": // это запрос от страницы Login - надо потом добавить проверку // сессия уже есть, в потоке зашифрованный запрос NskdSession session = null; String data = null; MemoryStream ms1 = new MemoryStream(); MemoryStream ms2 = new MemoryStream(); incomingRequest.InputStream.CopyTo(ms1); ms1.Position = 0; ms1.CopyTo(ms2); ms1.Position = 0; ms2.Position = 0; using (var sr = new StreamReader(ms1, Encoding.UTF8)) { data = sr.ReadToEnd(); } if (!String.IsNullOrWhiteSpace(data)) // поток не пустой - расшифровка { //Console.WriteLine("ProcessPost(): поток не пустой - расшифровка"); // возможно два варианта: // 1. Это первый запрос после GET. // В нем есть <sessionId + \r\n + зашифрованный_rsa_common_key + \r\n + data> // 2. Это не первый запрос после GET. // В нем <sessionId + \r\n + data> // Отличить можно по наличю общего ключа. Int32 sessionIdLength = data.IndexOf("\r\n"); if (sessionIdLength > 0) { Int32 readerPointer = 0; String sessionId = data.Substring(readerPointer, sessionIdLength); readerPointer += sessionIdLength; readerPointer += 2; // 0d 0a session = NskdSession.GetById(sessionId); //Console.WriteLine("ProcessPost(): session.SessionId " + session.SessionId); // проверяем общий ключ if (session.CryptKey == null) { // Общего ключа ещё нет. Значит он должен быть в запросе, зашифрованный RSA. readerPointer += LoadCryptKeyFromRequestDataToSession(data, readerPointer, session); readerPointer += 2; // \r\n } if (session.CryptKey != null) // или загрузился из базы или только что создан из запроса { data = data.Substring(readerPointer); response = CryptRequestParser(data, session); if (response.Length > 0) { ms2 = new MemoryStream(); //Byte[] buff = Encoding.UTF8.GetBytes(response); //ms2.Write(buff, 0, buff.Length); } } } } incomingResponse = siteInf.Client.GetResponse(context, session.SessionId, ms2); break; default: incomingResponse = siteInf.Client.GetResponse(context); break; } return(incomingResponse); }
private static void OnIncomingRequest(HttpListenerContext context) { HttpListenerRequest incomingRequest = context.Request; String address = incomingRequest.RemoteEndPoint.Address.ToString(); String method = incomingRequest.HttpMethod; String host = incomingRequest.Url.Host; Int32 port = incomingRequest.Url.Port; String path = incomingRequest.Url.AbsolutePath; String query = incomingRequest.Url.Query; // Пишем информацию о запросе в журнал. Db.Log.Write("IncomingRequest", address, method, host, port, path, query); // подбираем набор сайтов для переадресации SiteInf[] csinf = AddressTranslations.siteInfs; // подбираем набор сайтов для переадресации if (port == 80 || port == 8080) { /* * if ((new Regex("(?i)^/Prep(/.*)?$")).IsMatch(path)) * { * //Console.WriteLine(method + ", " + path); * //csinf = siteInfsPrep; * } */ if ((new Regex("(?i)^/Agrs(/.*)?$")).IsMatch(path)) { //Console.WriteLine(method + ", " + path); csinf = AddressTranslations.siteInfsAgrs; } /* * if ((new Regex("(?i)^/Items(/.*)?$")).IsMatch(path) || * (new Regex("(?i)^/Tn(/.*)?$")).IsMatch(path)) * { * Console.WriteLine(method + ", " + path); * csinf = AddressTranslations.siteInfsItems; * } */ if ((new Regex("(?i)^/ImEx(/.*)?$")).IsMatch(path)) { //Console.WriteLine(method + ", " + path); csinf = AddressTranslations.siteInfsImEx; } if ((new Regex("(?i)^/Agrs/F1(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = AddressTranslations.siteInfsAgrs1; } if ((new Regex("(?i)^/DeliverySchedule/F3(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11207, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11207, "localhost", true, false, false), new SiteInf("127.0.0.1", 11207, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11207, "::1", true, false, false) }; } if ((new Regex("(?i)^/Settings/F0(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11208, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11208, "localhost", true, false, false), new SiteInf("127.0.0.1", 11208, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11208, "::1", true, false, false) }; } if ((new Regex("(?i)^/AdminPages/F0(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11209, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11209, "localhost", true, false, false), new SiteInf("127.0.0.1", 11209, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11209, "::1", true, false, false) }; } if ((new Regex("(?i)^/Mess/F0(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11210, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11210, "localhost", true, false, false), new SiteInf("127.0.0.1", 11210, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11210, "::1", true, false, false) }; } if ((new Regex("(?i)^/Supply/F0(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11211, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11211, "localhost", true, false, false), new SiteInf("127.0.0.1", 11211, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11211, "::1", true, false, false) }; } if ((new Regex("(?i)^/MDVReports(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11212, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11212, "localhost", true, false, false), new SiteInf("127.0.0.1", 11212, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11212, "::1", true, false, false) }; } if ((new Regex("(?i)^/rd(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11213, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11213, "localhost", true, false, false), new SiteInf("127.0.0.1", 11213, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11213, "::1", true, false, false) }; } } if (port == 81 || port == 8181) { if ((new Regex("(?i)^/Agrs/F1(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = AddressTranslations.siteInfsAgrs1; } if ((new Regex("(?i)^/Reports(/.*)?$")).IsMatch(path)) { Console.WriteLine(method + ", " + path); csinf = new SiteInf[] { new SiteInf("127.0.0.1", 11206, HostIPv4.ToString(), true, false, false), new SiteInf("127.0.0.1", 11206, "localhost", true, false, false), new SiteInf("127.0.0.1", 11206, "127.0.0.1", true, false, false), new SiteInf("127.0.0.1", 11206, "::1", true, false, false) }; } } try { // Проверяем address, method, host, path. if (AddressIsAcceptable(address) && MethodIsAcceptable(method) && HostIsAcceptable(host, csinf) && PathIsAcceptable(method, path)) { // Всё в порядке - на обработку. //Console.WriteLine("d> На обработку."); HttpWebResponse incomingResponse = null; try { incomingResponse = RedirectIncomingRequest(context, csinf); } catch (Exception) { server.SendErrorPage(context, HttpStatusCode.InternalServerError); } // Ответа от клиента может и не быть если запрос перехвачен и ответ пользователю // уже отправлен внутри RedirectIncomingRequest(). if (incomingResponse != null) { try { //Console.WriteLine("OnIncomingRequest: Получен ответ"); // То что получили от клиента пресылаем пользователю SendResponse(context, incomingResponse); // Освобождаем ресурсы. incomingResponse.Close(); } catch (Exception e) { Db.Log.Write("OnIncomingRequest level 2:" + e.ToString(), address, method, host, port, path, query); } } //else { Console.WriteLine("OnIncomingRequest: Ответа нет"); } } else { // Всё остальное оставляем без ответа. //Console.WriteLine("d> Без ответа."); } // Закрываем соединение с пользователем и освобождаем ресурсы. context.Response.Close(); } catch (Exception e) { Db.Log.Write("OnIncomingRequest level 1:" + e.ToString(), address, method, host, port, path, query); } }