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