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