11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 51cb0ef41Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 61cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at 71cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html 81cb0ef41Sopenharmony_ci */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#ifndef _GNU_SOURCE 111cb0ef41Sopenharmony_ci# define _GNU_SOURCE 121cb0ef41Sopenharmony_ci#endif 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci#include <stdlib.h> 151cb0ef41Sopenharmony_ci#include "internal/cryptlib.h" 161cb0ef41Sopenharmony_ci#include "e_os.h" 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cichar *ossl_safe_getenv(const char *name) 191cb0ef41Sopenharmony_ci{ 201cb0ef41Sopenharmony_ci#if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE) 211cb0ef41Sopenharmony_ci if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) { 221cb0ef41Sopenharmony_ci char *val = NULL; 231cb0ef41Sopenharmony_ci int vallen = 0; 241cb0ef41Sopenharmony_ci WCHAR *namew = NULL; 251cb0ef41Sopenharmony_ci WCHAR *valw = NULL; 261cb0ef41Sopenharmony_ci DWORD envlen = 0; 271cb0ef41Sopenharmony_ci DWORD dwFlags = MB_ERR_INVALID_CHARS; 281cb0ef41Sopenharmony_ci int rsize, fsize; 291cb0ef41Sopenharmony_ci UINT curacp; 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci curacp = GetACP(); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci /* 341cb0ef41Sopenharmony_ci * For the code pages listed below, dwFlags must be set to 0. 351cb0ef41Sopenharmony_ci * Otherwise, the function fails with ERROR_INVALID_FLAGS. 361cb0ef41Sopenharmony_ci */ 371cb0ef41Sopenharmony_ci if (curacp == 50220 || curacp == 50221 || curacp == 50222 || 381cb0ef41Sopenharmony_ci curacp == 50225 || curacp == 50227 || curacp == 50229 || 391cb0ef41Sopenharmony_ci (57002 <= curacp && curacp <=57011) || curacp == 65000 || 401cb0ef41Sopenharmony_ci curacp == 42) 411cb0ef41Sopenharmony_ci dwFlags = 0; 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci /* query for buffer len */ 441cb0ef41Sopenharmony_ci rsize = MultiByteToWideChar(curacp, dwFlags, name, -1, NULL, 0); 451cb0ef41Sopenharmony_ci /* if name is valid string and can be converted to wide string */ 461cb0ef41Sopenharmony_ci if (rsize > 0) 471cb0ef41Sopenharmony_ci namew = _malloca(rsize * sizeof(WCHAR)); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci if (NULL != namew) { 501cb0ef41Sopenharmony_ci /* convert name to wide string */ 511cb0ef41Sopenharmony_ci fsize = MultiByteToWideChar(curacp, dwFlags, name, -1, namew, rsize); 521cb0ef41Sopenharmony_ci /* if conversion is ok, then determine value string size in wchars */ 531cb0ef41Sopenharmony_ci if (fsize > 0) 541cb0ef41Sopenharmony_ci envlen = GetEnvironmentVariableW(namew, NULL, 0); 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci if (envlen > 0) 581cb0ef41Sopenharmony_ci valw = _malloca(envlen * sizeof(WCHAR)); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci if (NULL != valw) { 611cb0ef41Sopenharmony_ci /* if can get env value as wide string */ 621cb0ef41Sopenharmony_ci if (GetEnvironmentVariableW(namew, valw, envlen) < envlen) { 631cb0ef41Sopenharmony_ci /* determine value string size in utf-8 */ 641cb0ef41Sopenharmony_ci vallen = WideCharToMultiByte(CP_UTF8, 0, valw, -1, NULL, 0, 651cb0ef41Sopenharmony_ci NULL, NULL); 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci if (vallen > 0) 701cb0ef41Sopenharmony_ci val = OPENSSL_malloc(vallen); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci if (NULL != val) { 731cb0ef41Sopenharmony_ci /* convert value string from wide to utf-8 */ 741cb0ef41Sopenharmony_ci if (WideCharToMultiByte(CP_UTF8, 0, valw, -1, val, vallen, 751cb0ef41Sopenharmony_ci NULL, NULL) == 0) { 761cb0ef41Sopenharmony_ci OPENSSL_free(val); 771cb0ef41Sopenharmony_ci val = NULL; 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci if (NULL != namew) 821cb0ef41Sopenharmony_ci _freea(namew); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci if (NULL != valw) 851cb0ef41Sopenharmony_ci _freea(valw); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci return val; 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci#endif 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) 921cb0ef41Sopenharmony_ci# if __GLIBC_PREREQ(2, 17) 931cb0ef41Sopenharmony_ci# define SECURE_GETENV 941cb0ef41Sopenharmony_ci return secure_getenv(name); 951cb0ef41Sopenharmony_ci# endif 961cb0ef41Sopenharmony_ci#endif 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci#ifndef SECURE_GETENV 991cb0ef41Sopenharmony_ci if (OPENSSL_issetugid()) 1001cb0ef41Sopenharmony_ci return NULL; 1011cb0ef41Sopenharmony_ci return getenv(name); 1021cb0ef41Sopenharmony_ci#endif 1031cb0ef41Sopenharmony_ci} 104