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