public override void Debug(StreamWriter output) { base.Debug(output); output.WriteLine("config login: "******"config address: " + address); output.WriteLine("config maxsize: " + maxsize); output.WriteLine("config state: " + stateFile); output.WriteLine("config findtime: " + findtime); output.WriteLine("config count: " + count); output.WriteLine("config ipv4_prefix: " + ipv4_prefix); output.WriteLine("config ipv6_prefix: " + ipv6_prefix); lock (lockSuccess) { foreach (var item in success) { IPAddress addr = item.Key; LoginSlidingHistory data = item.Value; output.WriteLine("status address success " + addr); data.Debug(output); } } lock (lockFailure) { foreach (var item in failure) { IPAddress addr = item.Key; LoginSlidingHistory data = item.Value; output.WriteLine("status address failure " + addr); data.Debug(output); } } }
private void WriteState(string filename) { Cleanup(); using (Stream stream = File.Open(filename, FileMode.Create)) using (BinaryWriter writer = new BinaryWriter(stream)) { lock (lockSuccess) { writer.Write(success.Count); foreach (var item in success) { IPAddress addr = item.Key; LoginSlidingHistory data = item.Value; writer.Write(addr.GetAddressBytes()); data.Save(writer); } } lock (lockFailure) { writer.Write(failure.Count); foreach (var item in failure) { IPAddress addr = item.Key; LoginSlidingHistory data = item.Value; writer.Write(addr.GetAddressBytes()); data.Save(writer); } } } }
private void ReadState(string filename) { using (Stream stream = File.Open(filename, FileMode.Open)) using (BinaryReader reader = new BinaryReader(stream)) { lock (lockSuccess) { int nsuccess = reader.ReadInt32(); for (int i = 0; i < nsuccess; i++) { IPAddress addr = new IPAddress(reader.ReadBytes(16)); LoginSlidingHistory data = new LoginSlidingHistory(reader, TimeSpan.FromSeconds(findtime).Ticks, count); if (data.Count > 0) { success[addr] = data; } } } lock (lockFailure) { int nfailure = reader.ReadInt32(); for (int i = 0; i < nfailure; i++) { IPAddress addr = new IPAddress(reader.ReadBytes(16)); LoginSlidingHistory data = new LoginSlidingHistory(reader, TimeSpan.FromSeconds(findtime).Ticks, count); if (data.Count > 0) { failure[addr] = data; } } } } }
public override string Execute(EventEntry evtlog) { if (count != 0) { // get network address for given IP and prefix IPAddress addr = evtlog.Address; int prefix = ipv6_prefix; if (evtlog.Address.IsIPv4MappedToIPv6) { prefix = ipv4_prefix; if (prefix <= 32) { prefix += 96; } } if (prefix != 128) { addr = Utils.GetNetwork(evtlog.Address, prefix); } // apply sliding windows for success/failure logins int cnt; LoginSlidingHistory history; long timestamp = evtlog.Created.ToUniversalTime().Ticks; evtlog.SetProcData("Login.Last", Name); cnt = 0; history = null; lock (lockSuccess) { if (!success.TryGetValue(evtlog.Address, out history)) { // number of records stored in dictionary has maxsize limit if (evtlog.Login == LoginStatus.SUCCESS && (maxsize == 0 || success.Count < maxsize)) { history = new LoginSlidingHistory(TimeSpan.FromSeconds(findtime).Ticks, count); success[evtlog.Address] = history; } } if (history != null) { if (evtlog.Login == LoginStatus.SUCCESS) { cnt = history.Add(timestamp); } else { cnt = history.Count; } } } // Store address historical data only if there was at least one // successfull login. This should limit number of records stored // in memory (unless malicious use of stolen username+password // e.g. for spam using SMTP AUTH ... in that case we should // limit number of records in success/failure dictionaries) if (cnt > 0) { evtlog.SetProcData(Name + ".Success", cnt); cnt = 0; history = null; lock (lockFailure) { if (!failure.TryGetValue(evtlog.Address, out history)) { if (evtlog.Login == LoginStatus.FAILURE) { history = new LoginSlidingHistory(TimeSpan.FromSeconds(findtime).Ticks, count); failure[evtlog.Address] = history; } } if (history != null) { if (evtlog.Login == LoginStatus.FAILURE) { cnt = history.Add(timestamp); } else { cnt = history.Count; } } } evtlog.SetProcData(Name + ".Failure", cnt); } else { evtlog.SetProcData(Name + ".Success", 0); evtlog.SetProcData(Name + ".Failure", 0); } } if (evtlog.Login == LoginStatus.SUCCESS) { return goto_success; } else if (evtlog.Login == LoginStatus.FAILURE) { return goto_failure; } else { return goto_next; } }
public override string Execute(EventEntry evtlog) { string strLogin = evtlog.GetProcData <string>(login, "unknown"); if (count != 0) { // get network address for given IP and prefix string strAddress = evtlog.GetProcData <string>(address); if (string.IsNullOrEmpty(strAddress)) { Log.Info("Login[" + Name + "]: empty address attribute: " + address); return(goto_error); } IPAddress addr = null; try { addr = IPAddress.Parse(strAddress.Trim()).MapToIPv6(); } catch (FormatException ex) { Log.Info("Login[" + Name + "]: invalid address " + address + "[" + strAddress + "]: " + ex.Message); return(goto_error); } int prefix = ipv6_prefix; if (addr.IsIPv4MappedToIPv6) { prefix = ipv4_prefix; if (prefix <= 32) { prefix += 96; } } if (prefix != 128) { addr = Utils.GetNetwork(addr, prefix); } // apply sliding windows for success/failure logins int cnt; LoginSlidingHistory history; long timestamp = evtlog.Created.ToUniversalTime().Ticks; evtlog.SetProcData("Login.Last", Name); cnt = 0; history = null; lock (lockSuccess) { if (!success.TryGetValue(addr, out history)) { // number of records stored in dictionary has maxsize limit if (strLogin == "success" && (maxsize == 0 || success.Count < maxsize)) { history = new LoginSlidingHistory(TimeSpan.FromSeconds(findtime).Ticks, count); success[addr] = history; } } if (history != null) { if (strLogin == "success") { cnt = history.Add(timestamp); } else { cnt = history.Count; } } } // Store address historical data only if there was at least one // successfull login. This should limit number of records stored // in memory (unless malicious use of stolen username+password // e.g. for spam using SMTP AUTH ... in that case we should // limit number of records in success/failure dictionaries) if (cnt > 0) { evtlog.SetProcData(Name + ".Success", cnt); cnt = 0; history = null; lock (lockFailure) { if (!failure.TryGetValue(addr, out history)) { if (strLogin == "failed") { history = new LoginSlidingHistory(TimeSpan.FromSeconds(findtime).Ticks, count); failure[addr] = history; } } if (history != null) { if (strLogin == "failed") { cnt = history.Add(timestamp); } else { cnt = history.Count; } } } evtlog.SetProcData(Name + ".Failure", cnt); } else { evtlog.SetProcData(Name + ".Success", 0); evtlog.SetProcData(Name + ".Failure", 0); } } if (strLogin == "success") { return(goto_success); } else if (strLogin == "failed") { return(goto_failure); } else { return(goto_next); } }