]>
Commit | Line | Data |
---|---|---|
5c39a55d | 1 | /* |
fecb3aae | 2 | * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. |
5c39a55d | 3 | * |
0e9725bc | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5c39a55d P |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #ifndef _GNU_SOURCE | |
11 | # define _GNU_SOURCE | |
12 | #endif | |
13 | ||
14 | #include <stdlib.h> | |
15 | #include "internal/cryptlib.h" | |
d5f9166b | 16 | #include "internal/e_os.h" |
5c39a55d P |
17 | |
18 | char *ossl_safe_getenv(const char *name) | |
19 | { | |
eed12622 RJ |
20 | #if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE) |
21 | if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) { | |
22 | char *val = NULL; | |
23 | int vallen = 0; | |
24 | WCHAR *namew = NULL; | |
25 | WCHAR *valw = NULL; | |
26 | DWORD envlen = 0; | |
27 | DWORD dwFlags = MB_ERR_INVALID_CHARS; | |
28 | int rsize, fsize; | |
29 | UINT curacp; | |
30 | ||
31 | curacp = GetACP(); | |
32 | ||
33 | /* | |
34 | * For the code pages listed below, dwFlags must be set to 0. | |
35 | * Otherwise, the function fails with ERROR_INVALID_FLAGS. | |
36 | */ | |
37 | if (curacp == 50220 || curacp == 50221 || curacp == 50222 || | |
38 | curacp == 50225 || curacp == 50227 || curacp == 50229 || | |
39 | (57002 <= curacp && curacp <=57011) || curacp == 65000 || | |
40 | curacp == 42) | |
41 | dwFlags = 0; | |
42 | ||
43 | /* query for buffer len */ | |
44 | rsize = MultiByteToWideChar(curacp, dwFlags, name, -1, NULL, 0); | |
45 | /* if name is valid string and can be converted to wide string */ | |
46 | if (rsize > 0) | |
47 | namew = _malloca(rsize * sizeof(WCHAR)); | |
48 | ||
49 | if (NULL != namew) { | |
50 | /* convert name to wide string */ | |
51 | fsize = MultiByteToWideChar(curacp, dwFlags, name, -1, namew, rsize); | |
52 | /* if conversion is ok, then determine value string size in wchars */ | |
53 | if (fsize > 0) | |
54 | envlen = GetEnvironmentVariableW(namew, NULL, 0); | |
55 | } | |
56 | ||
57 | if (envlen > 0) | |
58 | valw = _malloca(envlen * sizeof(WCHAR)); | |
59 | ||
60 | if (NULL != valw) { | |
61 | /* if can get env value as wide string */ | |
62 | if (GetEnvironmentVariableW(namew, valw, envlen) < envlen) { | |
63 | /* determine value string size in utf-8 */ | |
64 | vallen = WideCharToMultiByte(CP_UTF8, 0, valw, -1, NULL, 0, | |
65 | NULL, NULL); | |
66 | } | |
67 | } | |
68 | ||
69 | if (vallen > 0) | |
70 | val = OPENSSL_malloc(vallen); | |
71 | ||
72 | if (NULL != val) { | |
73 | /* convert value string from wide to utf-8 */ | |
74 | if (WideCharToMultiByte(CP_UTF8, 0, valw, -1, val, vallen, | |
75 | NULL, NULL) == 0) { | |
76 | OPENSSL_free(val); | |
77 | val = NULL; | |
78 | } | |
79 | } | |
80 | ||
81 | if (NULL != namew) | |
82 | _freea(namew); | |
83 | ||
84 | if (NULL != valw) | |
85 | _freea(valw); | |
86 | ||
87 | return val; | |
88 | } | |
89 | #endif | |
90 | ||
5c39a55d P |
91 | #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) |
92 | # if __GLIBC_PREREQ(2, 17) | |
93 | # define SECURE_GETENV | |
94 | return secure_getenv(name); | |
95 | # endif | |
96 | #endif | |
97 | ||
98 | #ifndef SECURE_GETENV | |
99 | if (OPENSSL_issetugid()) | |
100 | return NULL; | |
101 | return getenv(name); | |
102 | #endif | |
103 | } |