public void Variables_SessionFlood_Parallel_Create_Decay() { using (var gate = new NetGate(null)) { gate.Configure(CONFIG_SESSION.AsLaconicConfig()); gate.Start(); Rule rule; Assert.AreEqual(GateAction.Allow, gate.CheckTraffic(new GeneralTraffic { FromAddress = "170.12.14.12" }, out rule)); Assert.IsNull(rule); gate.IncreaseVariable(TrafficDirection.Incoming, "5.5.5.5", "newSession", 8); Assert.AreEqual(GateAction.Deny, gate.CheckTraffic(new GeneralTraffic { FromAddress = "5.5.5.5" }, out rule)); Assert.IsNotNull(rule); Assert.AreEqual("Session Flood", rule.Name); const int CNT = 10000; System.Threading.Tasks.Parallel.For(0, CNT, (i) => { var address = "addr-{0}".Args(i); gate.IncreaseVariable(TrafficDirection.Incoming, address, "newSession", 8); Rule lr; Assert.AreEqual(GateAction.Deny, gate.CheckTraffic(new GeneralTraffic { FromAddress = address }, out lr)); Assert.IsNotNull(lr); Assert.AreEqual("Session Flood", lr.Name); System.Threading.Thread.Sleep(ExternalRandomGenerator.Instance.NextScaledRandomInteger(1, 5)); }); Assert.AreEqual(CNT + 1, gate[TrafficDirection.Incoming].NetState.Count); System.Threading.Thread.Sleep(12000); Assert.AreEqual(0, gate[TrafficDirection.Incoming].NetState.Count); Assert.AreEqual(GateAction.Allow, gate.CheckTraffic(new GeneralTraffic { FromAddress = "5.5.5.5" }, out rule)); Assert.IsNull(rule); } }
/// <summary> /// Override to get session object using whatever parameters are available in response context (i.e. a cookie), /// or create a new one if 'onlyExisting'=false(default) /// </summary> protected internal virtual void FetchExistingOrMakeNewSession(WorkContext work, bool onlyExisting = false) { if (work.Session != null) { return; } WaveSession session = null; ulong sidSecret = 0; var sid = ExtractSessionID(work, out sidSecret); if (sid.HasValue) { session = App.ObjectStore.CheckOut(sid.Value) as WaveSession; if (session != null && session.IDSecret != sidSecret) { App.ObjectStore.UndoCheckout(sid.Value); session = null;//The secret password does not match if (Server.m_InstrumentationEnabled) { Interlocked.Increment(ref Server.m_Stat_SessionInvalidID); } } } if (session == null) { if (onlyExisting) { return; //do not create anything } if (NetGate != null && NetGate.Enabled) { NetGate.IncreaseVariable(IO.Net.Gate.TrafficDirection.Incoming, work.Request.RemoteEndPoint.Address.ToString(), NETGATE_NEWSESSION_VAR_NAME, 1); } session = MakeNewSession(work); } else if (Server.m_InstrumentationEnabled) { Interlocked.Increment(ref Server.m_Stat_SessionExisting); } session.Acquire(); if (work.GeoEntity != null) { session.GeoEntity = work.GeoEntity; } work.m_Session = session; ApplicationModel.ExecutionContext.__SetThreadLevelSessionContext(session); }
public void Variables_SessionFlood_2() { using (var gate = new NetGate(null)) { gate.Configure(CONFIG_SESSION.AsLaconicConfig()); gate.Start(); Rule rule; Assert.AreEqual(GateAction.Allow, gate.CheckTraffic(new GeneralTraffic { FromAddress = "170.12.14.12" }, out rule)); Assert.IsNull(rule); gate.IncreaseVariable(TrafficDirection.Incoming, "5.5.5.5", "newSession", 5); Assert.AreEqual(GateAction.Allow, gate.CheckTraffic(new GeneralTraffic { FromAddress = "170.12.14.12" }, out rule)); Assert.IsNull(rule); Assert.AreEqual(GateAction.Allow, gate.CheckTraffic(new GeneralTraffic { FromAddress = "170.1.99.144" }, out rule)); Assert.IsNull(rule); Assert.AreEqual(GateAction.Deny, gate.CheckTraffic(new GeneralTraffic { FromAddress = "5.5.5.5" }, out rule)); Assert.IsNotNull(rule); Assert.AreEqual("Session Flood", rule.Name); System.Threading.Thread.Sleep(5000); Assert.AreEqual(GateAction.Allow, gate.CheckTraffic(new GeneralTraffic { FromAddress = "5.5.5.5" }, out rule)); Assert.IsNull(rule); Assert.AreEqual(GateAction.Allow, gate.CheckTraffic(new GeneralTraffic { FromAddress = "170.1.99.144" }, out rule)); Assert.IsNull(rule); } }
/// <summary> /// Override to get session object using whatever parameters are available in response context (i.e. a cookie), /// or create a new one if 'onlyExisting'=false(default) /// </summary> protected internal virtual void FetchExistingOrMakeNewSession(WorkContext work, bool onlyExisting = false) { if (work.Session != null) { return; } WaveSession session = null; ulong sidSecret = 0; var sid = ExtractSessionID(work, out sidSecret); if (sid.HasValue) { session = App.ObjectStore.CheckOut(sid.Value) as WaveSession; if (session != null && session.IDSecret != sidSecret) { App.ObjectStore.UndoCheckout(sid.Value); session = null;//The secret password does not match if (Server.m_InstrumentationEnabled) { Interlocked.Increment(ref Server.m_stat_SessionInvalidID); } } } var foundExisting = true; if (session == null) { //20160124 DKh to use long term tokens //if (onlyExisting) return;//do not create anything if (onlyExisting) { session = TryMakeSessionFromExistingLongTermToken(work); if (session == null) { return; //do not create anything } } if (session == null) { foundExisting = false; if (NetGate != null && NetGate.Enabled) { NetGate.IncreaseVariable(IO.Net.Gate.TrafficDirection.Incoming, work.EffectiveCallerIPEndPoint.Address.ToString(), NETGATE_NEWSESSION_VAR_NAME, 1); } session = MakeNewSession(work); } } if (foundExisting && Server.m_InstrumentationEnabled) { Interlocked.Increment(ref Server.m_stat_SessionExisting); } session.Acquire(); if (work.GeoEntity != null) { session.GeoEntity = work.GeoEntity; } work.m_Session = session; ApplicationModel.ExecutionContext.__SetThreadLevelSessionContext(session); work.SetAuthenticated(session.User.IsAuthenticated); }
//We always make a new in-memory ephemeral session which gets collected right after this request protected override WaveSession MakeNewSessionInstance(WorkContext work) { const string BASIC = WebConsts.AUTH_SCHEME_BASIC + " "; const string BEARER = WebConsts.AUTH_SCHEME_BEARER + " "; //Always create new session var session = base.MakeNewSessionInstance(work); //try to inject session.DataContextName var dch = DataContextHeader; if (dch.IsNotNullOrWhiteSpace()) { var dcn = work.Request.Headers[dch]; if (dcn.IsNotNullOrWhiteSpace()) { dcn = dcn.Trim().TakeFirstChars(1024);//hard limit safeguard session.DataContextName = dcn; } } string hdr = null; var altHdrName = AltAuthorizationHeader; if (altHdrName.IsNotNullOrWhiteSpace()) { hdr = work.Request.Headers[altHdrName]?.TrimStart(' '); } if (hdr.IsNullOrWhiteSpace()) { //real AUTHORIZATION header hdr = work.Request.Headers[WebConsts.HTTP_HDR_AUTHORIZATION]?.TrimStart(' '); if (hdr.IsNullOrWhiteSpace()) { var mockHdrName = DefaultImpersonationAuthorizationHeaderValue; if (mockHdrName.IsNotNullOrEmpty()) { hdr = mockHdrName; } else { return(session);//unauthorized } } } Credentials credentials = null; try { if (hdr.StartsWith(BASIC, StringComparison.OrdinalIgnoreCase)) { var basic = hdr.Substring(BASIC.Length).Trim(); credentials = IDPasswordCredentials.FromBasicAuth(basic); } else if (hdr.StartsWith(BEARER, StringComparison.OrdinalIgnoreCase)) { var pfxBasic = BearerBasicPrefix; var bearer = hdr.Substring(BEARER.Length).Trim(); if (pfxBasic.IsNotNullOrWhiteSpace() && bearer.IsNotNullOrWhiteSpace() && bearer.StartsWith(pfxBasic)) { var basicContent = bearer.Substring(pfxBasic.Length).Trim(); credentials = IDPasswordCredentials.FromBasicAuth(basicContent); } else { credentials = new BearerCredentials(bearer); } } } catch { } if (credentials == null) { throw HTTPStatusException.BadRequest_400("Bad [Authorization] header"); } var user = App.SecurityManager.Authenticate(credentials);//authenticate the user session.User = user; work.SetAuthenticated(user.IsAuthenticated); //gate traffic if (!user.IsAuthenticated && NetGate != null && NetGate.Enabled) { var vn = GateBadAuthVar; if (vn.IsNotNullOrWhiteSpace()) { NetGate.IncreaseVariable(IO.Net.Gate.TrafficDirection.Incoming, work.EffectiveCallerIPEndPoint.Address.ToString(), vn, 1); } } return(session); }