@@ -24,6 +24,7 @@ import {
24
24
import {
25
25
API_VERSION_QUERY_PARAMETER_NAME ,
26
26
AUTHORIZATION_HEADER_NAME ,
27
+ AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES ,
27
28
HttpMethod ,
28
29
METADATA_HEADER_NAME ,
29
30
ManagedIdentityEnvironmentVariableNames ,
@@ -32,12 +33,18 @@ import {
32
33
RESOURCE_BODY_OR_QUERY_PARAMETER_NAME ,
33
34
} from "../../utils/Constants" ;
34
35
import { NodeStorage } from "../../cache/NodeStorage" ;
35
- import { readFileSync } from "fs" ;
36
+ import { readFileSync , statSync } from "fs" ;
36
37
import { ManagedIdentityTokenResponse } from "../../response/ManagedIdentityTokenResponse" ;
37
38
import { ManagedIdentityId } from "../../config/ManagedIdentityId" ;
39
+ import path from "path" ;
38
40
39
41
export const ARC_API_VERSION : string = "2019-11-01" ;
40
42
43
+ export const SUPPORTED_AZURE_ARC_PLATFORMS = {
44
+ win32 : `${ process . env [ "ProgramData" ] } \\AzureConnectedMachineAgent\\Tokens\\` ,
45
+ linux : "/var/opt/azcmagent/tokens/" ,
46
+ } ;
47
+
41
48
/**
42
49
* Original source of code: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/AzureArcManagedIdentitySource.cs
43
50
*/
@@ -168,10 +175,60 @@ export class AzureArc extends BaseManagedIdentitySource {
168
175
) ;
169
176
}
170
177
171
- const secretFile = wwwAuthHeader . split ( "Basic realm=" ) [ 1 ] ;
178
+ const secretFilePath = wwwAuthHeader . split ( "Basic realm=" ) [ 1 ] ;
179
+
180
+ // throw an error if the managed identity application is not being run on Windows or Linux
181
+ if (
182
+ ! SUPPORTED_AZURE_ARC_PLATFORMS . hasOwnProperty ( process . platform )
183
+ ) {
184
+ throw createManagedIdentityError (
185
+ ManagedIdentityErrorCodes . platformNotSupported
186
+ ) ;
187
+ }
188
+
189
+ // get the expected Windows or Linux file path)
190
+ const expectedSecretFilePath : string =
191
+ SUPPORTED_AZURE_ARC_PLATFORMS [ process . platform as string ] ;
192
+
193
+ // throw an error if the file in the file path is not a .key file
194
+ const fileName : string = path . basename ( secretFilePath ) ;
195
+ if ( ! fileName . endsWith ( ".key" ) ) {
196
+ throw createManagedIdentityError (
197
+ ManagedIdentityErrorCodes . invalidFileExtension
198
+ ) ;
199
+ }
200
+
201
+ /*
202
+ * throw an error if the file path from the www-authenticate header does not match the
203
+ * expected file path for the platform (Windows or Linux) the managed identity application
204
+ * is running on
205
+ */
206
+ if ( expectedSecretFilePath + fileName !== secretFilePath ) {
207
+ throw createManagedIdentityError (
208
+ ManagedIdentityErrorCodes . invalidFilePath
209
+ ) ;
210
+ }
211
+
212
+ let secretFileSize ;
213
+ // attempt to get the secret file's size, in bytes
214
+ try {
215
+ secretFileSize = await statSync ( secretFilePath ) . size ;
216
+ } catch ( e ) {
217
+ throw createManagedIdentityError (
218
+ ManagedIdentityErrorCodes . unableToReadSecretFile
219
+ ) ;
220
+ }
221
+ // throw an error if the secret file's size is greater than 4096 bytes
222
+ if ( secretFileSize > AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES ) {
223
+ throw createManagedIdentityError (
224
+ ManagedIdentityErrorCodes . invalidSecret
225
+ ) ;
226
+ }
227
+
228
+ // attempt to read the contents of the secret file
172
229
let secret ;
173
230
try {
174
- secret = readFileSync ( secretFile , "utf-8" ) ;
231
+ secret = readFileSync ( secretFilePath , "utf-8" ) ;
175
232
} catch ( e ) {
176
233
throw createManagedIdentityError (
177
234
ManagedIdentityErrorCodes . unableToReadSecretFile
0 commit comments