Skip to content

Commit

Permalink
Master fixing 560 (#728)
Browse files Browse the repository at this point in the history
* Remove those credential files that cannot be decrypted.

* Adding comments, handler for IOException.
  • Loading branch information
ivannaranjo authored Jun 22, 2017
1 parent f920025 commit 7174cdb
Showing 1 changed file with 36 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using GoogleCloudExtension.GCloud;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
Expand Down Expand Up @@ -75,6 +76,7 @@ public IEnumerable<WindowsInstanceCredentials> GetCredentialsForInstance(Instanc
result = Directory.EnumerateFiles(instanceStoragePath)
.Where(x => Path.GetExtension(x) == PasswordFileExtension)
.Select(x => LoadEncryptedCredentials(x))
.Where(x => x != null)
.OrderBy(x => x.User);
}
_credentialsForInstance[instancePath] = result;
Expand Down Expand Up @@ -125,13 +127,43 @@ public string GetStoragePathForInstance(Instance instance)
return Path.Combine(s_credentialsStoreRoot, instancePath);
}

/// <summary>
/// Attempts to load and decrypt the credentials stored in <paramref name="path"/> and returns an
/// <seealso cref="WindowsInstanceCredentials"/> instance with the information stored in the file. If
/// the file cannot be loaded or decrypted it will return null.
///
/// Note: The function will attempt to delete the file if it cannot be decrypted, this typically means that
/// the user's key is no longer valid. The function does not attempt to delete the file in case of a <see cref="IOException"/>
/// since that will probably also throw again.
/// </summary>
private WindowsInstanceCredentials LoadEncryptedCredentials(string path)
{
var userName = GetUserName(path);
var encryptedPassword = File.ReadAllBytes(path);
var passwordBytes = ProtectedData.Unprotect(encryptedPassword, null, DataProtectionScope.CurrentUser);
try
{
var userName = GetUserName(path);
var encryptedPassword = File.ReadAllBytes(path);
var passwordBytes = ProtectedData.Unprotect(encryptedPassword, null, DataProtectionScope.CurrentUser);

return new WindowsInstanceCredentials { User = userName, Password = Encoding.UTF8.GetString(passwordBytes) };
return new WindowsInstanceCredentials { User = userName, Password = Encoding.UTF8.GetString(passwordBytes) };
}
catch (CryptographicException)
{
Debug.WriteLine($"Failed to decrypt credentials from: {path}");
try
{
File.Delete(path);
}
catch (IOException)
{
Debug.WriteLine($"Failed cleaning corrupted credentials {path}");
}
return null;
}
catch (IOException)
{
Debug.WriteLine($"Failed to load credentials from: {path}");
return null;
}
}

private void SaveEncryptedCredentials(string path, WindowsInstanceCredentials credentials)
Expand Down

0 comments on commit 7174cdb

Please sign in to comment.