public void Dispose() { Sessions.ToList().ForEach(kp => kp.Value.Dispose()); Sessions.Clear(); // We could clear the sequence but since it's in cleartext on // the filesystem, I won't bother. // OK we only live once, I'll do it (???) HashUtils.ClearByteArray(_sequence); }
public SecureSession CreateSession(IPAddress clientIp) { var sess = new SecureSession(clientIp); // At some point Sessions was a List //Sessions.Add(sess); // We could, in theory, have a collision of sessions. // I'm going to take that risk. // We need to hash(hashed_sequence + session_id) // Both of these are byte arrays, so we need to build a bigger byte array. // Then clear that byte array once we no longer need it. byte[] hashedId = HashUtils.HashBytes(HashUtils.ConcatByteArrays(_sequence, sess.SessionId)); Sessions.TryAdd(HashUtils.ByteArrayToHexString(hashedId), sess); HashUtils.ClearByteArray(hashedId); return(sess); }
public OpenSessionResult OpenSession(LoginRequestBody login, IPAddress clientIp) { // Check if we got that session. // Trying to get something that doesn't exist from // a dictionnary throws exceptions. We should actually // do that to be completely thread safe. if (Sessions.ContainsKey(login.SessionId)) { var sess = Sessions[login.SessionId]; // Check if the IP address is correct: if (sess.ClientIp.Equals(clientIp)) { // Now try to load the file into the session with // the decrypted password from it: if (login.DataFile >= 0 && _dataFiles.Count >= login.DataFile) { sess.Data = new PasswordManagerData(getFullDataPath(_dataFiles[login.DataFile])); byte[] mPwd = null; byte[] dKey = null; try { dKey = generateSessionKey(sess); mPwd = AES256.DecryptToByteArray(login.Password, dKey); sess.Data.ReadFromFile(mPwd, dKey); _notificationManager.NotifyMostChannels( NotificationManager.CauseLoginSuccess, "Successful login", null, clientIp ); return(OpenSessionResult.Success); } catch (Exception ex) { Console.Error.WriteLine($"Password Data File processing error: {ex.ToString()}"); sess.Data = null; _notificationManager.NotifyMostChannels( NotificationManager.CauseLoginFailure, "Failed login attempt", null, clientIp ); return(OpenSessionResult.InvalidPasswordOrFSError); } finally { // This is a little redundant. if (mPwd != null) { HashUtils.ClearByteArray(mPwd); } if (dKey != null) { HashUtils.ClearByteArray(dKey); } } } else { return(OpenSessionResult.DataFileError); } } else { _notificationManager.NotifyMostChannels( NotificationManager.CauseLoginFailure, "Login attempt with IP address different from session", null, clientIp ); return(OpenSessionResult.IpAddressNotAllowed); } } else { _notificationManager.NotifyMostChannels( NotificationManager.CauseLoginFailure, "Login attempt with wrong session ID or sequence", login.SessionId, clientIp ); return(OpenSessionResult.InvalidSessionId); } }