public void TestVirtualMachineDetection() { Login login1; Login login2; Login login3; CreateTestData(out login1, out login2, out login3); MachineInformation machineInformation = new MachineInformation(); machineInformation.MachineValues = new List <DeviceInfo>(); using (CSSDataContext db = new CSSDataContext()) { // Get all machine records for login 1. var machineRecords = db.MachineRecords.Where(p => p.LoginId == 1); foreach (var machineRecord in machineRecords) { machineInformation.MachineValues.Add(new DeviceInfo() { Name = machineRecord.MachineRecordType.Name, Type = (DeviceType)machineRecord.MachineRecordType.Id, Value = machineRecord.Identifier }); } Assert.IsFalse(VirtualMachineMarker.IsMachineInformationFromAVirtualMachine(db, machineInformation, login1)); machineInformation.MachineValues.Add(new DeviceInfo() { Name = "HardDisk", Type = DeviceType.HardDisk, Value = "3951160193|Virtual HD|0|Virtual HD" }); Assert.IsTrue(VirtualMachineMarker.IsMachineInformationFromAVirtualMachine(db, machineInformation, login1)); } }
/// <summary> /// Finds associated active key for these credentials and then /// decrypts the envelope. /// </summary> /// <param name="machineInfo">Resultant Machine Information retrieved from envelope.</param> public static CheckInStatus CheckIn(string username, string password, byte[] encryptedEnvelope, out Session session) { using (var db = new CSSDataContext()) { var succeeded = false; session = null; MachineInformation machineInfo = null; //Check if username/password is valid, and account is not banned/locked. Login login; LoginStatus loginStatus; if (Login.TryGetAuthenticatedLogin(db, username, password, out login, out loginStatus) == false) { return(CheckInStatus.InvalidCredentials); } //Find user's session var currentSession = login.FindCurrentSession(); //If session is not found, envelope cannot be decrypted. if (currentSession == null) { return(CheckInStatus.InvalidCredentials); } try { //Retrieve the machine information var activeKey = currentSession.ActiveKey; var decryptedData = Encryption.DecryptRSA(encryptedEnvelope, activeKey.RSACspBlob.ToArray()); machineInfo = MachineInformation.Deserialize(decryptedData); //Record machine info & match identities bool wasMerged; Identity identity; Identity.MatchIdentity(db, login, machineInfo, out identity, out wasMerged); if (login.Identity != identity) { login.Identity = identity; } if (VirtualMachineMarker.IsMachineInformationFromAVirtualMachine(db, machineInfo, login) == true) { if (Identity.CanUseVirtualMachine(db, login) == false) { return(CheckInStatus.VirtualMachineBlocked); } } else { if (login.AllowVirtualMachineLogin == false) { login.AllowVirtualMachineLogin = true; } } //Check if black box has timed out if (!currentSession.ValidateSessionTimeout()) { return(CheckInStatus.Timeout); } else //Otherwise, ensure session status is marked active { currentSession.SessionStatusType = SessionStatusEnum.Active; } //Verify the token is correct if (machineInfo.Token != activeKey.Token) { return(CheckInStatus.InvalidHash); } //Verify the login is not banned if (login.IsBanned) { return(CheckInStatus.InvalidCredentials); } //Check-in succeeded if (currentSession.SessionStatusType == SessionStatusEnum.Active) { succeeded = true; currentSession.DateLastCheckIn = DateTime.Now; session = currentSession; if (wasMerged == true) { return(CheckInStatus.AccountLinked); } else { return(CheckInStatus.Ok); } } return(CheckInStatus.InvalidCredentials); } catch (Exception error) { Error.Write(error); return(CheckInStatus.InvalidHash); } finally { //If not successful, mark session closed. if (!succeeded) { currentSession.SessionStatusType = SessionStatusEnum.Closed; } db.SubmitChanges(); } } }