1
+ // ----------------------------------------------------------------------------------
2
+ //
3
+ // Copyright Microsoft Corporation
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ // ----------------------------------------------------------------------------------
14
+ using Microsoft . Azure . Commands . Common . Authentication ;
15
+ using Microsoft . Azure . Commands . Common . Authentication . Abstractions ;
16
+ using Microsoft . Azure . Commands . Common . Authentication . Models ;
17
+ using Microsoft . Azure . Commands . Common . Authentication . ResourceManager ;
18
+ using System ;
19
+ using System . Collections ;
20
+ using System . Collections . Generic ;
21
+ using System . IO ;
22
+ using System . Linq ;
23
+ using System . Security ;
24
+
25
+ namespace Microsoft . Azure . Commands . ResourceManager . Common
26
+ {
27
+ /// <summary>
28
+ /// Helper class to store service principal keys and retrieve them
29
+ /// from the Windows Credential Store.
30
+ /// </summary>
31
+ public class AzureRmServicePrincipalKeyStore : IServicePrincipalKeyStore
32
+ {
33
+ public const string Name = "ServicePrincipalKeyStore" ;
34
+ private IDictionary < string , SecureString > _credentials { get ; set ; }
35
+
36
+ public AzureRmServicePrincipalKeyStore ( ) : this ( null ) { }
37
+
38
+ public AzureRmServicePrincipalKeyStore ( IAzureContextContainer profile )
39
+ {
40
+ _credentials = new Dictionary < string , SecureString > ( ) ;
41
+ if ( profile != null && profile . Accounts != null )
42
+ {
43
+ foreach ( var account in profile . Accounts )
44
+ {
45
+ if ( account != null && account . ExtendedProperties . ContainsKey ( AzureAccount . Property . ServicePrincipalSecret ) )
46
+ {
47
+ var appId = account . Id ;
48
+ var tenantId = account . GetTenants ( ) . FirstOrDefault ( ) ;
49
+ var key = CreateKey ( appId , tenantId ) ;
50
+ var servicePrincipalSecret = account . ExtendedProperties [ AzureAccount . Property . ServicePrincipalSecret ] ;
51
+ _credentials [ key ] = ConvertToSecureString ( servicePrincipalSecret ) ;
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ public void SaveKey ( string appId , string tenantId , SecureString serviceKey )
58
+ {
59
+ var key = CreateKey ( appId , tenantId ) ;
60
+ _credentials [ key ] = serviceKey ;
61
+ }
62
+
63
+ public SecureString GetKey ( string appId , string tenantId )
64
+ {
65
+ IntPtr pCredential = IntPtr . Zero ;
66
+ try
67
+ {
68
+ var key = CreateKey ( appId , tenantId ) ;
69
+ return _credentials [ key ] ;
70
+
71
+ }
72
+ catch
73
+ {
74
+ // we could be running in an environment that does not have credentials store
75
+ }
76
+
77
+ return null ;
78
+ }
79
+
80
+
81
+ public void DeleteKey ( string appId , string tenantId )
82
+ {
83
+ try
84
+ {
85
+ var key = CreateKey ( appId , tenantId ) ;
86
+ _credentials . Remove ( key ) ;
87
+ }
88
+ catch
89
+ {
90
+ }
91
+ }
92
+
93
+ private string CreateKey ( string appId , string tenantId )
94
+ {
95
+ return $ "{ appId } _{ tenantId } ";
96
+ }
97
+
98
+ internal SecureString ConvertToSecureString ( string password )
99
+ {
100
+ if ( password == null )
101
+ throw new ArgumentNullException ( "password" ) ;
102
+
103
+ var securePassword = new SecureString ( ) ;
104
+
105
+ foreach ( char c in password )
106
+ securePassword . AppendChar ( c ) ;
107
+
108
+ securePassword . MakeReadOnly ( ) ;
109
+ return securePassword ;
110
+ }
111
+ }
112
+ }
0 commit comments