diff options
author | Heiko Hund <heiko.hund@sophos.com> | 2012-02-10 15:13:42 +0100 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2012-02-13 17:11:50 +0100 |
commit | 71bbbd76c62630c88441237d72fe5b61f0b45b2a (patch) | |
tree | 715f8c8183c6e47bb26f0a10c0f6b14f9b9f83a2 /options.c | |
parent | 2ee0dc2bd72ec318fcc227af54e5ca7e1384a6cc (diff) | |
download | openvpn-71bbbd76c62630c88441237d72fe5b61f0b45b2a.tar.gz openvpn-71bbbd76c62630c88441237d72fe5b61f0b45b2a.tar.xz openvpn-71bbbd76c62630c88441237d72fe5b61f0b45b2a.zip |
handle Windows unicode paths
Openvpn for Windows is not compiled as a Unicode binary and thus cannot
handle paths which contain non-ASCII characters using the argv vector.
Characters that are not present in the system codepage are simply replaced
with a question mark, e.g. if started as 'openvpn --config домой.ovpn'
the file '?????.ovpn' is tried to be opened as configuration.
The same applies to paths in config files which need to be UTF-8
encoded if they contain non ASCII characters. The option line
'key лев.pem' will lead to openvpn trying to open 'лев.pem' on a
system with codepage 1252.
This patch makes openvpn read the command line in UCS-2 and convert
it to UTF-8 internally. Windows stores names in the filesystem in UCS-2.
When using a paths openvpn converts it from UTF-8 to UCS-2 and uses the
wide character Windows API function.
Signed-off-by: Heiko Hund <heiko.hund@sophos.com>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>
Diffstat (limited to 'options.c')
-rw-r--r-- | options.c | 37 |
1 files changed, 32 insertions, 5 deletions
@@ -2620,18 +2620,18 @@ check_file_access(const int type, const char *file, const int mode, const char * char *fullpath = strdup(file); /* POSIX dirname() implementaion may modify its arguments */ char *dirpath = dirname(fullpath); - if (access (dirpath, mode|X_OK) != 0) + if (openvpn_access (dirpath, mode|X_OK) != 0) errcode = errno; free(fullpath); } /* Is the file itself accessible? */ - if (!errcode && (type & CHKACC_FILE) && (access (file, mode) != 0) ) + if (!errcode && (type & CHKACC_FILE) && (openvpn_access (file, mode) != 0) ) errcode = errno; /* If the file exists and is accessible, is it writable? */ - if (!errcode && (type & CHKACC_FILEXSTWR) && (access (file, F_OK) == 0) ) - if (access (file, W_OK) != 0) + if (!errcode && (type & CHKACC_FILEXSTWR) && (openvpn_access (file, F_OK) == 0) ) + if (openvpn_access (file, W_OK) != 0) errcode = errno; /* Scream if an error is found */ @@ -3737,7 +3737,7 @@ read_config_file (struct options *options, if (streq (file, "stdin")) fp = stdin; else - fp = fopen (file, "r"); + fp = openvpn_fopen (file, "r"); if (fp) { line_num = 0; @@ -3814,6 +3814,33 @@ parse_argv (struct options *options, { int i, j; +#ifdef WIN32 + /* + * Windows replaces Unicode characters in argv[] that are not present + * in the current codepage with '?'. Get the wide char command line and + * convert it to UTF-8 ourselves. + */ + int wargc; + WCHAR **wargv; + char **uargv; + + wargv = CommandLineToArgvW (GetCommandLineW (), &wargc); + if (wargv == NULL || wargc != argc) + usage (); + + uargv = gc_malloc (wargc * sizeof (*uargv), false, &options->gc); + + for (i = 0; i < wargc; i++) + { + int n = WideCharToMultiByte (CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL); + uargv[i] = gc_malloc (n, false, &options->gc); + WideCharToMultiByte (CP_UTF8, 0, wargv[i], -1, uargv[i], n, NULL, NULL); + } + + LocalFree (wargv); + argv = uargv; +#endif + /* usage message */ if (argc <= 1) usage (); |