Ejemplo n.º 1
0
        /// <summary>
        /// Parsing segment -> UPD, BPD
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="BLZ"></param>
        /// <param name="HBCIVersion"></param>
        /// <param name="Message"></param>
        /// <returns></returns>
        public static List <HBCIBankMessage> Parse_Segments(FinTsClient client, string Message)
        {
            try
            {
                var connDetails = client.ConnectionDetails;
                List <HBCIBankMessage> result = new List <HBCIBankMessage>();

                List <string> rawSegments = SplitEncryptedSegments(Message);

                List <Segment> segments = new List <Segment>();
                foreach (var item in rawSegments)
                {
                    Segment segment = Parse_Segment(item);
                    if (segment != null)
                    {
                        segments.Add(segment);
                    }
                }

                // BPD
                string bpd      = string.Empty;
                var    bpaMatch = Regex.Match(Message, @"(HIBPA.+?)\b(HITAN|HNHBS|HISYN|HIUPA)\b");
                if (bpaMatch.Success)
                {
                    bpd = bpaMatch.Groups[1].Value;
                }
                if (bpd.Length > 0)
                {
                    SaveBPD(connDetails.Blz, bpd);
                    BPD.ParseBpd(bpd);
                }

                // UPD
                string upd      = string.Empty;
                var    upaMatch = Regex.Match(Message, @"(HIUPA.+?)\b(HITAN|HNHBS)\b");
                if (upaMatch.Success)
                {
                    upd = upaMatch.Groups[1].Value;
                }
                if (upd.Length > 0)
                {
                    SaveUPD(connDetails.Blz, connDetails.UserId, upd);
                    UPD.ParseUpd(upd);
                }

                if (UPD.AccountList != null)
                {
                    //Add BIC to Account information (Not retrieved bz UPD??)
                    foreach (AccountInformation accInfo in UPD.AccountList)
                    {
                        accInfo.AccountBic = connDetails.Bic;
                    }
                }

                foreach (var segment in segments)
                {
                    if (segment.Name == "HIRMG")
                    {
                        // HIRMG:2:2+9050::Die Nachricht enthält Fehler.+9800::Dialog abgebrochen+9010::Initialisierung fehlgeschlagen, Auftrag nicht bearbeitet.
                        // HIRMG:2:2+9800::Dialogabbruch.

                        string[] HIRMG_messages = segment.Payload.Split('+');
                        foreach (var HIRMG_message in HIRMG_messages)
                        {
                            var message = Parse_BankCode_Message(HIRMG_message);
                            if (message != null)
                            {
                                result.Add(message);
                            }
                        }
                    }

                    if (segment.Name == "HIRMS")
                    {
                        // HIRMS:3:2:2+9942::PIN falsch. Zugang gesperrt.'
                        string[] HIRMS_messages = segment.Payload.Split('+');
                        foreach (var HIRMS_message in HIRMS_messages)
                        {
                            var message = Parse_BankCode_Message(HIRMS_message);
                            if (message != null)
                            {
                                result.Add(message);
                            }
                        }

                        var securityMessage = result.FirstOrDefault(m => m.Code == "3920");
                        if (securityMessage != null)
                        {
                            string message = securityMessage.Message;

                            string TAN  = string.Empty;
                            string TANf = string.Empty;

                            string[] procedures = Regex.Split(message, @"\D+");

                            foreach (string value in procedures)
                            {
                                if (!string.IsNullOrEmpty(value) && int.TryParse(value, out int i))
                                {
                                    if (Convert.ToString(i).StartsWith("9"))
                                    {
                                        if (string.IsNullOrEmpty(TAN))
                                        {
                                            TAN = i.ToString();
                                        }

                                        if (string.IsNullOrEmpty(TANf))
                                        {
                                            TANf = i.ToString();
                                        }
                                        else
                                        {
                                            TANf += $";{i}";
                                        }
                                    }
                                }
                            }
                            if (string.IsNullOrEmpty(client.HIRMS))
                            {
                                client.HIRMS = TAN;
                            }
                            else
                            {
                                if (!TANf.Contains(client.HIRMS))
                                {
                                    throw new Exception($"Invalid HIRMS/Tan-Mode {client.HIRMS} detected. Please choose one of the allowed modes: {TANf}");
                                }
                            }
                            client.HIRMSf = TANf;

                            // Parsing TAN processes
                            if (!string.IsNullOrEmpty(client.HIRMS))
                            {
                                Parse_TANProcesses(client, bpd);
                            }
                        }
                    }

                    if (segment.Name == "HNHBK")
                    {
                        var ID = Parse_String(segment.Payload, "+1+", ":1");
                        client.HNHBK = ID;
                    }

                    if (segment.Name == "HISYN")
                    {
                        client.SystemId = segment.Payload;
                        Log.Write("Customer System ID: " + client.SystemId);
                    }

                    if (segment.Name == "HNHBS")
                    {
                        if (segment.Payload == null || segment.Payload == "0")
                        {
                            client.HNHBS = 2;
                        }
                        else
                        {
                            client.HNHBS = Convert.ToInt32(segment.Payload) + 1;
                        }
                    }

                    if (segment.Name == "HISALS")
                    {
                        client.HISALS = segment.Version;
                    }

                    if (segment.Name == "HITANS")
                    {
                        if (client.HITANS != 0 && segment.Version == 7) // Torsten: Rücknahme der Freigabe. Sparkassen ausserhalb der
                        // Pilotphase senden in der BPD bereits das Segment, welches in der UPD noch nicht zur Verfügung steht und somit
                        // zu Abbrüchen führt.
                        //if (client.HITANS != 0) // Torsten: Freigabe HKTAN#7 in libfintx
                        {
                            ; // Ignore HKTAN version 7 if other version is available and version 7 isn't implemented in libfintx
                        }
                        else
                        {
                            client.HITANS = segment.Version;
                        }
                    }

                    if (segment.Name == "HITAN")
                    {
                        client.HITAN = Parse_String(segment.Payload.Replace("?+", "??"), "++", "+").Replace("??", "?+");
                    }

                    if (segment.Name == "HIKAZS")
                    {
                        if (client.HIKAZS == 0)
                        {
                            client.HIKAZS = segment.Version;
                        }
                        else
                        {
                            if (segment.Version > client.HIKAZS)
                            {
                                client.HIKAZS = segment.Version;
                            }
                        }
                    }

                    if (segment.Name == "HISPAS")
                    {
                        if (segment.Payload.Contains("pain.001.001.03"))
                        {
                            client.HISPAS = 1;
                        }
                        else if (segment.Payload.Contains("pain.001.002.03"))
                        {
                            client.HISPAS = 2;
                        }
                        else if (segment.Payload.Contains("pain.001.003.03"))
                        {
                            client.HISPAS = 3;
                        }

                        if (client.HISPAS == 0)
                        {
                            client.HISPAS = 3; // -> Fallback. Most banks accept the newest pain version
                        }
                    }
                }

                // Fallback if HIKAZS is not delivered by BPD (eg. Postbank)
                if (client.HIKAZS == 0)
                {
                    client.HIKAZS = 0;
                }

                return(result);
            }
            catch (Exception ex)
            {
                Log.Write(ex.ToString());

                throw new InvalidOperationException($"Software error.", ex);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parsing segment -> UPD, BPD
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="BLZ"></param>
        /// <param name="HBCIVersion"></param>
        /// <param name="Message"></param>
        /// <returns></returns>
        public static List <HBCIBankMessage> Parse_Segments(FinTsClient client, string Message)
        {
            try
            {
                var connDetails = client.ConnectionDetails;
                List <HBCIBankMessage> result = new List <HBCIBankMessage>();

                List <string> rawSegments = SplitEncryptedSegments(Message);

                List <Segment> segments = new List <Segment>();
                foreach (var item in rawSegments)
                {
                    Segment segment = Parse_Segment(item);
                    if (segment != null)
                    {
                        segments.Add(segment);
                    }
                }

                // BPD
                string bpd      = string.Empty;
                var    bpaMatch = Regex.Match(Message, @"(HIBPA.+?)\b(HITAN|HNHBS|HISYN|HIUPA)\b");
                if (bpaMatch.Success)
                {
                    bpd = bpaMatch.Groups[1].Value;
                }
                if (bpd.Length > 0)
                {
                    SaveBPD(connDetails.Blz, bpd);
                    BPD.ParseBpd(bpd);
                }

                // UPD
                string upd      = string.Empty;
                var    upaMatch = Regex.Match(Message, @"(HIUPA.+?)\b(HITAN|HNHBS)\b");
                if (upaMatch.Success)
                {
                    upd = upaMatch.Groups[1].Value;
                }
                if (upd.Length > 0)
                {
                    SaveUPD(connDetails.Blz, connDetails.UserId, upd);
                    UPD.ParseUpd(upd);
                }

                if (UPD.AccountList != null)
                {
                    //Add BIC to Account information (Not retrieved bz UPD??)
                    foreach (AccountInformation accInfo in UPD.AccountList)
                    {
                        accInfo.AccountBic = connDetails.Bic;
                    }
                }

                foreach (var segment in segments)
                {
                    if (segment.Name == "HIRMG")
                    {
                        // HIRMG:2:2+9050::Die Nachricht enthält Fehler.+9800::Dialog abgebrochen+9010::Initialisierung fehlgeschlagen, Auftrag nicht bearbeitet.
                        // HIRMG:2:2+9800::Dialogabbruch.

                        string[] HIRMG_messages = segment.Payload.Split('+');
                        foreach (var HIRMG_message in HIRMG_messages)
                        {
                            var message = Parse_BankCode_Message(HIRMG_message);
                            if (message != null)
                            {
                                result.Add(message);
                            }
                        }
                    }

                    if (segment.Name == "HIRMS")
                    {
                        // HIRMS:3:2:2+9942::PIN falsch. Zugang gesperrt.'
                        string[] HIRMS_messages = segment.Payload.Split('+');
                        foreach (var HIRMS_message in HIRMS_messages)
                        {
                            var message = Parse_BankCode_Message(HIRMS_message);
                            if (message != null)
                            {
                                result.Add(message);
                            }
                        }

                        var securityMessage = result.FirstOrDefault(m => m.Code == "3920");
                        if (securityMessage != null)
                        {
                            string message = securityMessage.Message;

                            string TAN  = string.Empty;
                            string TANf = string.Empty;

                            string[] procedures = Regex.Split(message, @"\D+");

                            foreach (string value in procedures)
                            {
                                if (!string.IsNullOrEmpty(value) && int.TryParse(value, out int i))
                                {
                                    if (value.StartsWith("9"))
                                    {
                                        if (string.IsNullOrEmpty(TAN))
                                        {
                                            TAN = i.ToString();
                                        }

                                        if (string.IsNullOrEmpty(TANf))
                                        {
                                            TANf = i.ToString();
                                        }
                                        else
                                        {
                                            TANf += $";{i}";
                                        }
                                    }
                                }
                            }
                            if (string.IsNullOrEmpty(client.HIRMS))
                            {
                                client.HIRMS = TAN;
                            }
                            else
                            {
                                if (!TANf.Contains(client.HIRMS))
                                {
                                    throw new Exception($"Invalid HIRMS/Tan-Mode {client.HIRMS} detected. Please choose one of the allowed modes: {TANf}");
                                }
                            }
                            client.HIRMSf = TANf;

                            // Parsing TAN processes
                            if (!string.IsNullOrEmpty(client.HIRMS))
                            {
                                Parse_TANProcesses(client, bpd);
                            }
                        }
                    }

                    if (segment.Name == "HNHBK")
                    {
                        var ID = Parse_String(segment.Payload, "+1+", ":1");
                        client.HNHBK = ID;
                    }

                    if (segment.Name == "HISYN")
                    {
                        client.SystemId = segment.Payload;
                        Log.Write("Customer System ID: " + client.SystemId);
                    }

                    if (segment.Name == "HNHBS")
                    {
                        if (segment.Payload == null || segment.Payload == "0")
                        {
                            client.HNHBS = 2;
                        }
                        else
                        {
                            client.HNHBS = Convert.ToInt32(segment.Payload) + 1;
                        }
                    }

                    if (segment.Name == "HISALS")
                    {
                        client.HISALS = segment.Version;
                    }

                    if (segment.Name == "HITANS")
                    {
                        var hitans = (HITANS)segment;
                        if (client.HIRMS == null)
                        {
                            // Die höchste HKTAN-Version auswählen, welche in den erlaubten TAN-Verfahren (3920) enthalten ist.
                            var tanProcessesHirms = client.HIRMSf.Split(';').Select(tp => Convert.ToInt32(tp));
                            if (hitans.TanProcesses.Select(tp => tp.TanCode).Intersect(tanProcessesHirms).Any())
                            {
                                client.HITANS = segment.Version;
                            }
                        }
                        else
                        {
                            if (hitans.TanProcesses.Any(tp => tp.TanCode == Convert.ToInt32(client.HIRMS)))
                            {
                                client.HITANS = segment.Version;
                            }
                        }
                    }

                    if (segment.Name == "HITAN")
                    {
                        // HITAN:5:7:3+S++8578-06-23-13.22.43.709351
                        // HITAN:5:7:4+4++8578-06-23-13.22.43.709351+Bitte Auftrag in Ihrer App freigeben.
                        var match = Regex.Match(segment.Payload, @"\w+\+.*?\+(?<ref>[^\+]+)(\+)?");
                        if (!match.Success)
                        {
                            throw new ArgumentException($"Could not parse HITAN: {segment}");
                        }

                        client.HITAN = match.Groups["ref"].Value;
                    }

                    if (segment.Name == "HIKAZS")
                    {
                        if (client.HIKAZS == 0)
                        {
                            client.HIKAZS = segment.Version;
                        }
                        else
                        {
                            if (segment.Version > client.HIKAZS)
                            {
                                client.HIKAZS = segment.Version;
                            }
                        }
                    }

                    if (segment.Name == "HISPAS")
                    {
                        if (segment.Payload.Contains("pain.001.001.03"))
                        {
                            client.HISPAS = 1;
                        }
                        else if (segment.Payload.Contains("pain.001.002.03"))
                        {
                            client.HISPAS = 2;
                        }
                        else if (segment.Payload.Contains("pain.001.003.03"))
                        {
                            client.HISPAS = 3;
                        }

                        if (client.HISPAS == 0)
                        {
                            client.HISPAS = 3; // -> Fallback. Most banks accept the newest pain version
                        }
                    }
                }

                // Fallback if HIKAZS is not delivered by BPD (eg. Postbank)
                if (client.HIKAZS == 0)
                {
                    client.HIKAZS = 0;
                }

                return(result);
            }
            catch (Exception ex)
            {
                Log.Write(ex.ToString());

                throw new InvalidOperationException($"Software error.", ex);
            }
        }