getenv.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #ifndef _GNU_SOURCE
  10. # define _GNU_SOURCE
  11. #endif
  12. #include <stdlib.h>
  13. #include "internal/cryptlib.h"
  14. #include "internal/e_os.h"
  15. char *ossl_safe_getenv(const char *name)
  16. {
  17. #if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE)
  18. if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) {
  19. char *val = NULL;
  20. int vallen = 0;
  21. WCHAR *namew = NULL;
  22. WCHAR *valw = NULL;
  23. DWORD envlen = 0;
  24. DWORD dwFlags = MB_ERR_INVALID_CHARS;
  25. int rsize, fsize;
  26. UINT curacp;
  27. curacp = GetACP();
  28. /*
  29. * For the code pages listed below, dwFlags must be set to 0.
  30. * Otherwise, the function fails with ERROR_INVALID_FLAGS.
  31. */
  32. if (curacp == 50220 || curacp == 50221 || curacp == 50222 ||
  33. curacp == 50225 || curacp == 50227 || curacp == 50229 ||
  34. (57002 <= curacp && curacp <=57011) || curacp == 65000 ||
  35. curacp == 42)
  36. dwFlags = 0;
  37. /* query for buffer len */
  38. rsize = MultiByteToWideChar(curacp, dwFlags, name, -1, NULL, 0);
  39. /* if name is valid string and can be converted to wide string */
  40. if (rsize > 0)
  41. namew = _malloca(rsize * sizeof(WCHAR));
  42. if (NULL != namew) {
  43. /* convert name to wide string */
  44. fsize = MultiByteToWideChar(curacp, dwFlags, name, -1, namew, rsize);
  45. /* if conversion is ok, then determine value string size in wchars */
  46. if (fsize > 0)
  47. envlen = GetEnvironmentVariableW(namew, NULL, 0);
  48. }
  49. if (envlen > 0)
  50. valw = _malloca(envlen * sizeof(WCHAR));
  51. if (NULL != valw) {
  52. /* if can get env value as wide string */
  53. if (GetEnvironmentVariableW(namew, valw, envlen) < envlen) {
  54. /* determine value string size in utf-8 */
  55. vallen = WideCharToMultiByte(CP_UTF8, 0, valw, -1, NULL, 0,
  56. NULL, NULL);
  57. }
  58. }
  59. if (vallen > 0)
  60. val = OPENSSL_malloc(vallen);
  61. if (NULL != val) {
  62. /* convert value string from wide to utf-8 */
  63. if (WideCharToMultiByte(CP_UTF8, 0, valw, -1, val, vallen,
  64. NULL, NULL) == 0) {
  65. OPENSSL_free(val);
  66. val = NULL;
  67. }
  68. }
  69. if (NULL != namew)
  70. _freea(namew);
  71. if (NULL != valw)
  72. _freea(valw);
  73. return val;
  74. }
  75. #endif
  76. #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
  77. # if __GLIBC_PREREQ(2, 17)
  78. # define SECURE_GETENV
  79. return secure_getenv(name);
  80. # endif
  81. #endif
  82. #ifndef SECURE_GETENV
  83. if (OPENSSL_issetugid())
  84. return NULL;
  85. return getenv(name);
  86. #endif
  87. }