using System; using System.IO; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Xml; using Kreta.EESZTInterface.STS; using Kreta.Resources; namespace Kreta.EESZTInterface.eFT { public class DoRequest { public static (XmlDocument soapResponse, byte[] mTOMAttachment) GetSoapSamlResponse(string eftUri, X509Certificate2 sslAuthCert, string soapRequest, SamlAssertion samlAssertion) { try { HttpWebRequest request = GetHttpWebRequest(eftUri, sslAuthCert, samlAssertion); var (data, hasAttachment) = WriteToHttpStream(request, soapRequest); var msResp = new MemoryStream(data); StreamReader sr = new StreamReader(msResp); var responseString = sr.ReadToEnd(); if (!hasAttachment) { var soapResponse = ThrowIfSoapFault(responseString); return (soapResponse, null); } else { var xmlEleje = responseString.IndexOf("" + "\r\n\r\n"); byte[] boundary2 = Encoding.UTF8.GetBytes("\r\n--" + "MIME_Boundary" + "--\r\n"); var attachment = GetAttachmentData(data, boundary1, boundary2); return (soapResponse, attachment); } } catch (WebException wex) { string exMessage = wex.Message; if (wex.Response != null) { using (var responseReader = new StreamReader(wex.Response.GetResponseStream())) { exMessage = responseReader.ReadToEnd(); ThrowIfSoapFault(exMessage); } } throw new Exception(exMessage, wex); } catch { throw; } } private static HttpWebRequest GetHttpWebRequest(string stsUri, X509Certificate2 sslAuthCert, SamlAssertion samlAssertion = null) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(stsUri); request.Headers.Add("SOAPAction", ""); request.ContentType = "application/soap+xml;charset=\"utf-8\""; request.Accept = "application/soap+xml"; request.Method = "POST"; request.ClientCertificates.Add(sslAuthCert); return request; } private static (byte[] data, bool hasAttachment) WriteToHttpStream(HttpWebRequest request, string soapRequest) { using (Stream stream = request.GetRequestStream()) { MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(soapRequest)); ms.WriteTo(stream); } WebResponse response = request.GetResponse(); MemoryStream msResp = new MemoryStream(); int read; byte[] buffer = new byte[1024]; while ((read = response.GetResponseStream().Read(buffer, 0, buffer.Length)) > 0) { msResp.Write(buffer, 0, read); } return (data: msResp.ToArray(), hasAttachment: response.ContentType.Contains("multipart")); } private static byte[] GetAttachmentData(byte[] data, byte[] boundary1, byte[] boundary2) { if (data == null || boundary1 == null || boundary2 == null) return null; if (boundary1.LongLength > data.LongLength) return null; long i, j, startIndex; bool match; int boundary1Pos = 0; for (i = 0; i < data.LongLength; i++) { startIndex = i; match = true; for (j = 0; j < boundary1.LongLength; j++) { if (data[startIndex] != boundary1[j]) { match = false; break; } if (startIndex < data.LongLength) { startIndex++; } } if (match) boundary1Pos = Convert.ToInt32(startIndex - boundary1.LongLength); } int pos1 = boundary1Pos + boundary1.Length; int pos2 = data.Length - boundary2.Length; int length = pos2 - pos1; try { byte[] output = new byte[length]; Array.Copy(data, pos1, output, 0, length); return output; } catch { } return null; } private static XmlDocument ThrowIfSoapFault(string response) { XmlDocument soapMessage; try { soapMessage = ExtractDocumentFromResponse(response); if (soapMessage == null) { throw new Exception(); } } catch (Exception ex) { throw new Exception(EESZTInterfaceResource.NemMegfeleloSOAPValaszFormatum, ex); } XmlElement fault = XmlHelper.GetElement("Fault", Namespaces.soap11Ns, soapMessage.DocumentElement); if (fault == null) { return soapMessage; } var faultCodeNodes = XmlHelper.GetElement("faultcode", "", fault); var faultReasonNodes = XmlHelper.GetElement("faultstring", "", fault); var exceptionDetailNodes = XmlHelper.GetElement("detail", "", fault); throw new Exception("Hiba! Kód:" + faultCodeNodes.InnerText + " Részletek:" + faultReasonNodes.InnerText, new Exception((exceptionDetailNodes == null) ? "" : exceptionDetailNodes.InnerText)); } private static XmlDocument ExtractDocumentFromResponse(string response) { var soapResponse = new XmlDocument(); soapResponse.PreserveWhitespace = true; soapResponse.LoadXml(response); return soapResponse; } private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } } }