/src/openssl31/crypto/getenv.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
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" |
16 | | #include "internal/e_os.h" |
17 | | |
18 | | char *ossl_safe_getenv(const char *name) |
19 | 30.2k | { |
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 | | |
91 | 30.2k | #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) |
92 | 30.2k | # if __GLIBC_PREREQ(2, 17) |
93 | 30.2k | # define SECURE_GETENV |
94 | 30.2k | return secure_getenv(name); |
95 | 30.2k | # endif |
96 | 30.2k | #endif |
97 | | |
98 | | #ifndef SECURE_GETENV |
99 | | if (OPENSSL_issetugid()) |
100 | | return NULL; |
101 | | return getenv(name); |
102 | | #endif |
103 | 30.2k | } |