private IRadiusPacket Interim(IRadiusPacket packet) { var user = UsernameDomain.Parse(packet.GetAttribute <String>("User-Name")); var msisdn = packet.GetAttribute <String>("Calling-Station-Id"); var acctSessionId = packet.GetAttribute <String>("Acct-Session-Id"); var acctStatusType = "Alive"; // duuh var acctInputOctets = packet.GetAttribute <UInt32>("Acct-Input-Octets"); var acctOutputOctets = packet.GetAttribute <UInt32>("Acct-Output-Octets"); var acctSessionTime = packet.GetAttribute <UInt32>("Acct-Session-Time"); var acctInputGigawords = packet.GetAttribute <UInt32?>("Acct-Input-Gigawords"); var acctOutputGigawords = packet.GetAttribute <UInt32?>("Acct-Output-Gigawords"); var nasIpAddress = packet.GetAttribute <IPAddress>("NAS-IP-Address"); var mccmnc = Utils.GetMccMncFrom3GPPLocationInfo(packet.GetAttribute <Byte[]>("3GPP-User-Location-Info")).mccmnc; _log.Debug($"Handling interim packet for {msisdn} on {mccmnc} with AcctSessionId {acctSessionId}"); using (var db = _contextFactory.GetContext()) { db.AccountingInterim(user.Username, user.Domain, msisdn, acctStatusType, acctSessionId, acctInputOctets, acctOutputOctets, (int)acctSessionTime, acctInputGigawords, acctOutputGigawords); } Task.Factory.StartNew(() => { if (CheckDisconnect(acctSessionId)) { _disconnector.DisconnectUserByMsisdn(msisdn); } }, TaskCreationOptions.LongRunning); return(packet.CreateResponsePacket(PacketCode.AccountingResponse)); }
private IRadiusPacket Stop(IRadiusPacket packet) { var user = UsernameDomain.Parse(packet.GetAttribute <String>("User-Name")); var msisdn = packet.GetAttribute <String>("Calling-Station-Id"); var acctSessionId = packet.GetAttribute <String>("Acct-Session-Id"); var acctStatusType = "Stop"; // duuh var acctInputOctets = packet.GetAttribute <UInt32>("Acct-Input-Octets"); var acctOutputOctets = packet.GetAttribute <UInt32>("Acct-Output-Octets"); var acctSessionTime = packet.GetAttribute <UInt32>("Acct-Session-Time"); var acctTerminateCause = packet.GetAttribute <UInt32>("Acct-Terminate-Cause"); // oh crap, guess i need values as well... var acctInputGigawords = packet.GetAttribute <UInt32?>("Acct-Input-Gigawords"); var acctOutputGigawords = packet.GetAttribute <UInt32?>("Acct-Output-Gigawords"); _log.Debug($"Handling stop packet for {msisdn} with AcctSessionId {acctSessionId}"); try { using (var db = _contextFactory.GetContext()) { db.AccountingStop(user.Username, user.Domain, msisdn, acctStatusType, acctSessionId, acctInputOctets, acctOutputOctets, (int)acctSessionTime, acctTerminateCause.ToString(), acctInputGigawords, acctOutputGigawords); } } catch (EntityCommandExecutionException ex) { if (ex.InnerException?.Message.Contains("duplicate") ?? false) { _log.Warn($"Duplicate stop packet for AcctSessionId {acctSessionId}"); } else { throw; } } return(packet.CreateResponsePacket(PacketCode.AccountingResponse)); }
private IRadiusPacket Start(IRadiusPacket packet) { var user = UsernameDomain.Parse(packet.GetAttribute <String>("User-Name")); var msisdn = packet.GetAttribute <String>("Calling-Station-Id"); var acctSessionId = packet.GetAttribute <String>("Acct-Session-Id"); var acctStatusType = "Start"; // duuh var locationInfo = Utils.GetMccMncFrom3GPPLocationInfo(packet.GetAttribute <Byte[]>("3GPP-User-Location-Info")); _log.Debug($"Handling start packet for {msisdn} with AcctSessionId {acctSessionId}"); try { using (var db = _contextFactory.GetContext()) { db.AccountingStart(user.Username, user.Domain, msisdn, acctStatusType, acctSessionId, locationInfo.mccmnc); } Task.Factory.StartNew(() => _welcomeSender.CheckWelcomeSms(msisdn), TaskCreationOptions.LongRunning); } catch (EntityCommandExecutionException ex) { if (ex.InnerException?.Message.Contains("duplicate") ?? false) { _log.Warn($"Duplicate start packet for AcctSessionId {acctSessionId}"); } else { throw; } } return(packet.CreateResponsePacket(PacketCode.AccountingResponse)); }
/// <summary> /// Authenticate user through proxy or locally /// </summary> /// <param name="packet"></param> /// <returns></returns> private IRadiusPacket AuthenticateUser(IRadiusPacket packet) { var usernamedomain = packet.GetAttribute <String>("User-Name").ToLowerInvariant(); var packetPassword = packet.GetAttribute <String>("User-Password"); var proxyresponse = _authProxy.ProxyAuthentication(usernamedomain, packetPassword); if (proxyresponse.HasValue) { _log.Info($"Got response from proxy for username {usernamedomain}"); return(packet.CreateResponsePacket(proxyresponse.Value)); } else { using (var db = _contextFactory.GetContext()) { var username = UsernameDomain.Parse(usernamedomain); var userid = _userAuthProvider.AuthenticateAsync(username.Username, username.Domain, packetPassword).Result; if (userid.HasValue) { return(packet.CreateResponsePacket(PacketCode.AccessAccept)); } else { var user = db.users.SingleOrDefault(o => o.username == username.Username && o.realm == username.Domain); if (user == null) { _log.Warn($"Username {usernamedomain} not found"); } else if (user.status != 1) { _log.Warn($"Username {usernamedomain} is not active, email: {user.email}"); } else { _log.Warn($"Bad password for user {usernamedomain}, password is {packetPassword.Length} characters, email: {user.email}"); } var location = packet.GetAttribute <String>("Ipass-Location-Description"); if (!String.IsNullOrEmpty(location)) { _log.Warn($"iPass location description: {location}"); } return(packet.CreateResponsePacket(PacketCode.AccessReject)); } } } }
/// <summary> /// Accounting /// </summary> /// <param name="packet"></param> /// <returns></returns> private IRadiusPacket HandleAccountingPacket(IRadiusPacket packet) { var acctStatusType = packet.GetAttribute <AcctStatusType>("Acct-Status-Type"); if (acctStatusType == AcctStatusType.Start || acctStatusType == AcctStatusType.Stop) { var usernamedomain = UsernameDomain.Parse(packet.GetAttribute <String>("User-Name")); var nodeid = GetUserNodeId(usernamedomain.Username, usernamedomain.Domain); _log.Info($"Handling {acctStatusType} packet for {usernamedomain}"); try { using (var db = _contextFactory.GetContext()) { var entry = new radiatoraccounting { username = usernamedomain.Username, realm = usernamedomain.Domain, node_id = nodeid, ACCTSTATUSTYPE = (packet.GetAttribute <AcctStatusType>("Acct-Status-Type")).ToString(), ACCTINPUTOCTETS = Convert.ToUInt32(packet.GetAttribute <UInt32?>("Acct-Input-Octets")), ACCTOUTPUTOCTETS = Convert.ToUInt32(packet.GetAttribute <UInt32?>("Acct-Output-Octets")), ACCTSESSIONID = packet.GetAttribute <String>("Acct-Session-Id"), ACCTSESSIONTIME = Convert.ToInt32(packet.GetAttribute <UInt32?>("Acct-Session-Time")), NASIDENTIFIER = packet.GetAttribute <String>("NAS-Identifier"), NASPORT = packet.GetAttribute <UInt32?>("NAS-Port"), NASPORTTYPE = packet.GetAttribute <UInt32?>("NAS-Port-Type").ToString(), WISPrLocationName = packet.GetAttribute <String>("WISPr-Location-Name"), temp = packet.GetAttribute <String>("Ipass-Location-Description"), timestamp_datetime = packet.Attributes.ContainsKey("Timestamp") ? (DateTime?)DateTimeOffset.FromUnixTimeSeconds(packet.GetAttribute <Int32>("Timestamp")).UtcDateTime : DateTime.UtcNow }; db.radiatoraccountings.Add(entry); db.SaveChanges(); } } catch (DbUpdateConcurrencyException) { _log.Info($"Duplicate {acctStatusType} request received"); } catch (Exception ex) { _log.Error("Something went wrong", ex); } if (acctStatusType == AcctStatusType.Start) { try { using (var db = _contextFactory.GetContext()) { db.radiatoronlines.Add(new radiatoronline { username = usernamedomain.Username, realm = usernamedomain.Domain, node_id = nodeid, ACCTSESSIONID = packet.GetAttribute <String>("Acct-Session-Id"), timestamp_datetime = packet.Attributes.ContainsKey("Timestamp") ? (DateTime?)DateTimeOffset.FromUnixTimeSeconds(packet.GetAttribute <Int32>("Timestamp")).UtcDateTime : DateTime.UtcNow, NASIDENTIFIER = packet.GetAttribute <String>("NAS-Identifier"), NASPORT = packet.GetAttribute <UInt32?>("NAS-Port"), NASPORTTYPE = packet.GetAttribute <UInt32?>("NAS-Port-Type").ToString(), WISPrLocationName = packet.GetAttribute <String>("Ipass-Location-Description") }); db.SaveChanges(); } } catch (DbUpdateConcurrencyException) { _log.Info("Cannot insert duplicate in radiatoronline"); } } if (acctStatusType == AcctStatusType.Stop) { try { using (var db = _contextFactory.GetContext()) { var acctsessionid = packet.GetAttribute <String>("Acct-Session-Id"); var online = db.radiatoronlines.SingleOrDefault(o => o.ACCTSESSIONID == acctsessionid); if (online != null) { db.radiatoronlines.Remove(online); db.SaveChanges(); } } } catch (DbUpdateConcurrencyException) { _log.Info("Nothing to remove from online"); } } } return(packet.CreateResponsePacket(PacketCode.AccountingResponse)); }