- From 003aa383d60530edce9b42ac77faa8b08ccf5abe Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 22 Nov 2024 12:35:56 +0100
- Subject: [PATCH 1/4] tests: Add |FileNameInfo| support to winfsinfo1
- Add |FileNameInfo| support to winfsinfo1
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/winfsinfo1/winfsinfo.c | 56 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 56 insertions(+)
- diff --git a/tests/winfsinfo1/winfsinfo.c b/tests/winfsinfo1/winfsinfo.c
- index 4832ea9..682d089 100644
- --- a/tests/winfsinfo1/winfsinfo.c
- +++ b/tests/winfsinfo1/winfsinfo.c
- @@ -388,6 +388,58 @@ typedef struct _FILE_NAME_INFORMATION4096 {
- } FILE_NAME_INFORMATION4096, *PFILE_NAME_INFORMATION4096;
- +/*
- + * |FileNameInfo| will get the absolute path of a file with symbolic
- + * links resolved
- + */
- +static
- +bool get_filenameinfo(const char *progname, const char *filename)
- +{
- + int res = EXIT_FAILURE;
- + bool ok;
- + FILE_NAME_INFORMATION4096 finfo;
- + (void)memset(&finfo, 0, sizeof(finfo));
- +
- + HANDLE fileHandle = CreateFileA(filename,
- + GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- + FILE_FLAG_BACKUP_SEMANTICS, NULL);
- + if (fileHandle == INVALID_HANDLE_VALUE) {
- + (void)fprintf(stderr,
- + "%s: Error opening file '%s'. Last error was %d.\n",
- + progname,
- + filename,
- + (int)GetLastError());
- + return EXIT_FAILURE;
- + }
- +
- + ok = GetFileInformationByHandleEx(fileHandle,
- + FileNameInfo,
- + &finfo, sizeof(finfo));
- +
- + if (!ok) {
- + (void)fprintf(stderr, "%s: GetFileInformationByHandleEx() "
- + "error. GetLastError()==%d.\n",
- + progname,
- + (int)GetLastError());
- + res = EXIT_FAILURE;
- + goto done;
- + }
- +
- + (void)printf("(\n");
- + (void)printf("\tfilename='%s'\n", filename);
- +
- + (void)printf("\tFileNameLength=%ld\n",
- + (long)finfo.FileNameLength);
- + (void)printf("\tFileName='%S'\n", finfo.FileName);
- + (void)printf(")\n");
- + res = EXIT_SUCCESS;
- +
- +done:
- + (void)CloseHandle(fileHandle);
- + return res;
- +}
- +
- +
- static
- bool get_filenormalizednameinfo(const char *progname, const char *filename)
- {
- @@ -578,6 +630,7 @@ void usage(void)
- "filebasicinfo|"
- "fileexinfostandard|"
- "filestandardinfo|"
- + "filenameinfo|"
- "filenormalizednameinfo|"
- "filecasesensitiveinfo|"
- "getfiletime"
- @@ -607,6 +660,9 @@ int main(int ac, char *av[])
- else if (!strcmp(subcmd, "filestandardinfo")) {
- return get_file_standard_info(av[0], av[2]);
- }
- + else if (!strcmp(subcmd, "filenameinfo")) {
- + return get_filenameinfo(av[0], av[2]);
- + }
- else if (!strcmp(subcmd, "filenormalizednameinfo")) {
- return get_filenormalizednameinfo(av[0], av[2]);
- }
- --
- 2.45.1
- From 067befbef48ee2162b3f9fef1df76af81b3bcc6b Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 22 Nov 2024 16:04:27 +0100
- Subject: [PATCH 2/4] mount: Reject invalid UTF-8 sequences in nfs://-URLs
- Reject invalid UTF-8 sequences in nfs://-URLs
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- mount/mount.c | 41 ++++++++++++++++++++++++++++++++---------
- 1 file changed, 32 insertions(+), 9 deletions(-)
- diff --git a/mount/mount.c b/mount/mount.c
- index db6f94c..8c6b008 100644
- --- a/mount/mount.c
- +++ b/mount/mount.c
- @@ -616,13 +616,20 @@ char *wcs2utf8str(const wchar_t *wstr)
- size_t utf8_len;
- wstr_len = wcslen(wstr);
- - utf8_len = WideCharToMultiByte(CP_UTF8, 0,
- + utf8_len = WideCharToMultiByte(CP_UTF8,
- + WC_ERR_INVALID_CHARS|WC_NO_BEST_FIT_CHARS,
- wstr, (int)wstr_len, NULL, 0, NULL, NULL);
- + if (utf8_len == 0)
- + return NULL;
- utf8str = malloc(utf8_len+1);
- - if (!utf8str)
- + if (!utf8str) {
- + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- - (void)WideCharToMultiByte(CP_UTF8, 0,
- + }
- +
- + (void)WideCharToMultiByte(CP_UTF8,
- + WC_ERR_INVALID_CHARS|WC_NO_BEST_FIT_CHARS,
- wstr, (int)wstr_len, utf8str, (int)utf8_len, NULL, NULL);
- utf8str[utf8_len] = '\0';
- return utf8str;
- @@ -636,14 +643,18 @@ wchar_t *utf8str2wcs(const char *utf8str)
- size_t wstr_len;
- utf8len = strlen(utf8str);
- - wstr_len = MultiByteToWideChar(CP_UTF8, 0,
- + wstr_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- utf8str, (int)utf8len, NULL, 0);
- + if (wstr_len == 0)
- + return NULL;
- wstr = malloc((wstr_len+1)*sizeof(wchar_t));
- - if (!wstr)
- + if (!wstr) {
- + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- + }
- - (void)MultiByteToWideChar(CP_UTF8, 0,
- + (void)MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- utf8str, (int)utf8len, wstr, (int)wstr_len);
- wstr[wstr_len] = L'\0';
- return wstr;
- @@ -692,7 +703,10 @@ static DWORD ParseRemoteName(
- */
- premotename_utf8 = wcs2utf8str(premotename);
- if (!premotename_utf8) {
- - result = ERROR_NOT_ENOUGH_MEMORY;
- + (void)fwprintf(stderr,
- + L"wcs2utf8str() failed, lasterr=%d\n.",
- + (int)GetLastError());
- + result = GetLastError();
- goto out;
- }
- @@ -705,7 +719,7 @@ static DWORD ParseRemoteName(
- if (url_parser_parse(uctx) < 0) {
- result = ERROR_BAD_ARGUMENTS;
- - (void)fwprintf(stderr, L"Error parsing nfs://-URL.\n");
- + (void)fwprintf(stderr, L"Error parsing nfs://-URL '%S'.\n", premotename_utf8);
- goto out;
- }
- @@ -777,9 +791,12 @@ static DWORD ParseRemoteName(
- hostname_wstr = utf8str2wcs(uctx->hostport.hostname);
- if (!hostname_wstr) {
- - result = ERROR_NOT_ENOUGH_MEMORY;
- + result = GetLastError();
- + (void)fwprintf(stderr, L"Cannot convert URL host '%S', lasterr=%d\n",
- + uctx->hostport.hostname, result);
- goto out;
- }
- +
- (void)wcscpy_s(premotename, NFS41_SYS_MAX_PATH_LEN, hostname_wstr);
- free(hostname_wstr);
- ConvertUnixSlashes(premotename);
- @@ -797,6 +814,12 @@ static DWORD ParseRemoteName(
- }
- pEnd = mountstrmem = utf8str2wcs(uctx->path);
- + if (!mountstrmem) {
- + result = GetLastError();
- + (void)fwprintf(stderr, L"Cannot convert URL path '%S', lasterr=%d\n",
- + uctx->path, result);
- + goto out;
- + }
- ConvertUnixSlashes(pEnd);
- }
- else
- --
- 2.45.1
- From 2991b563a693199c80eb2e27ea4b8f867d128ca4 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 22 Nov 2024 16:07:56 +0100
- Subject: [PATCH 3/4] daemon: Reject invalid UTF-8 characters from/to NFS
- server
- Reject invalid UTF-8 characters from/to NFS server
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/open.c | 3 ++-
- daemon/readdir.c | 3 ++-
- daemon/setattr.c | 18 ++++++++++++------
- daemon/symlink.c | 11 ++++++++++-
- 4 files changed, 26 insertions(+), 9 deletions(-)
- diff --git a/daemon/open.c b/daemon/open.c
- index 9be3e89..7d3ae46 100644
- --- a/daemon/open.c
- +++ b/daemon/open.c
- @@ -1081,7 +1081,8 @@ static int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *
- status = safe_write(&buffer, length, &len, sizeof(len));
- if (status) goto out;
- /* convert args->symlink to wchar */
- - if (*length <= len || !MultiByteToWideChar(CP_UTF8, 0,
- + if (*length <= len || !MultiByteToWideChar(CP_UTF8,
- + MB_ERR_INVALID_CHARS,
- args->symlink.path, args->symlink.len,
- (LPWSTR)buffer, len / sizeof(WCHAR))) {
- status = ERROR_BUFFER_OVERFLOW;
- diff --git a/daemon/readdir.c b/daemon/readdir.c
- index 62d0904..5239037 100644
- --- a/daemon/readdir.c
- +++ b/daemon/readdir.c
- @@ -512,8 +512,9 @@ static int readdir_copy_entry(
- uint32_t wname_len, wname_size, needed;
- PFILE_DIR_INFO_UNION info;
- - wname_len = MultiByteToWideChar(CP_UTF8, 0,
- + wname_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- entry->name, entry->name_len, wname, NFS4_OPAQUE_LIMIT);
- + EASSERT(wname_len > 0);
- wname_size = (wname_len - 1) * sizeof(WCHAR);
- needed = readdir_size_for_entry(args->query_class, wname_size);
- diff --git a/daemon/setattr.c b/daemon/setattr.c
- index 676d3ab..0e16a83 100644
- --- a/daemon/setattr.c
- +++ b/daemon/setattr.c
- @@ -282,12 +282,15 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
- goto out;
- }
- - dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8, 0,
- + dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8,
- + WC_ERR_INVALID_CHARS|WC_NO_BEST_FIT_CHARS,
- rename->FileName, rename->FileNameLength/sizeof(WCHAR),
- dst_path.path, NFS41_MAX_PATH_LEN, NULL, NULL);
- if (dst_path.len == 0) {
- - eprintf("WideCharToMultiByte failed to convert destination "
- - "filename %S.\n", rename->FileName);
- + eprintf("handle_nfs41_rename(args->path='%s'): "
- + "WideCharToMultiByte() failed to convert destination "
- + "filename '%S', lasterr=%d.\n",
- + args->path, rename->FileName, (int)GetLastError());
- status = ERROR_INVALID_PARAMETER;
- goto out;
- }
- @@ -433,12 +436,15 @@ static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
- (void)memset(&info, 0, sizeof(info));
- - dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8, 0,
- + dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8,
- + WC_ERR_INVALID_CHARS|WC_NO_BEST_FIT_CHARS,
- link->FileName, link->FileNameLength/sizeof(WCHAR),
- dst_path.path, NFS41_MAX_PATH_LEN, NULL, NULL);
- if (dst_path.len == 0) {
- - eprintf("WideCharToMultiByte failed to convert destination "
- - "filename %S.\n", link->FileName);
- + eprintf("handle_nfs41_link(args->path='%s'): "
- + "WideCharToMultiByte() failed to convert destination "
- + "filename '%S', lasterr=%d.\n",
- + args->path, link->FileName, (int)GetLastError());
- status = ERROR_INVALID_PARAMETER;
- goto out;
- }
- diff --git a/daemon/symlink.c b/daemon/symlink.c
- index d7ab9cd..d2ff834 100644
- --- a/daemon/symlink.c
- +++ b/daemon/symlink.c
- @@ -281,9 +281,18 @@ static int marshall_symlink(unsigned char *buffer, uint32_t *length, nfs41_upcal
- status = safe_write(&buffer, length, &len, sizeof(len));
- if (status) goto out;
- - if (*length <= len || !MultiByteToWideChar(CP_UTF8, 0,
- + if (*length <= len) {
- + status = ERROR_BUFFER_OVERFLOW;
- + goto out;
- + }
- +
- + if (!MultiByteToWideChar(CP_UTF8,
- + MB_ERR_INVALID_CHARS,
- args->target_get.path, args->target_get.len,
- (LPWSTR)buffer, len / sizeof(WCHAR))) {
- + eprintf("marshall_symlink: "
- + "MultiByteToWideChar() failed, lasterr=%d\n",
- + (int)GetLastError());
- status = ERROR_BUFFER_OVERFLOW;
- goto out;
- }
- --
- 2.45.1
- From 9c746d3ccefefb28a4156abd80d57319075bad76 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 22 Nov 2024 16:25:15 +0100
- Subject: [PATCH 4/4] cygwin: nfsurlconv should urlencode POSIX
- shell/bash/ksh93-specical characters
- nfsurlconv should urlencode POSIX shell/bash/ksh93-specical characters,
- to avoid that if users do not use '"' or "'" to quote an
- URL get a nasty suprise.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- cygwin/utils/nfsurlconv/nfsurlconv.ksh | 63 ++++++++++++++++++++------
- 1 file changed, 48 insertions(+), 15 deletions(-)
- diff --git a/cygwin/utils/nfsurlconv/nfsurlconv.ksh b/cygwin/utils/nfsurlconv/nfsurlconv.ksh
- index e11c019..d7c2671 100644
- --- a/cygwin/utils/nfsurlconv/nfsurlconv.ksh
- +++ b/cygwin/utils/nfsurlconv/nfsurlconv.ksh
- @@ -176,6 +176,7 @@ function urlencodestr
- nameref out_encodedstr=$1
- typeset in_str="$2"
- + integer posix_shell_safe=$3
- typeset ch ch_hexval dummy
- integer ch_num
- typeset url=''
- @@ -222,10 +223,20 @@ function urlencodestr
- # Only alphanumerics, "$-_.+!*'()," and reserved characters
- # ("/" for nfs://-URLS) are allowed
- #
- - if (( ch_num > 127 )) || [[ "$ch" != ~(Elr)[/$-_.+!*\'(),[:alnum:]] ]] ; then
- - url+="%$ch_hexval"
- + if (( posix_shell_safe != 0 )) ; then
- + # in POSIX shell safe mode we also encode '!', '*', '$'
- + if (( ch_num > 127 )) || [[ "$ch" != ~(Elr)[/-_.+\'(),[:alnum:]] ]] ; then
- + url+="%$ch_hexval"
- + else
- + url+="$ch"
- + fi
- +
- else
- - url+="$ch"
- + if (( ch_num > 127 )) || [[ "$ch" != ~(Elr)[/$-_.+!*\'(),[:alnum:]] ]] ; then
- + url+="%$ch_hexval"
- + else
- + url+="$ch"
- + fi
- fi
- done
- @@ -238,16 +249,24 @@ function urlencodestr
- function hostname_port_path_to_nfsurl
- {
- set -o nounset
- + set -o errexit
- - typeset hostname="$1"
- - integer port="$2"
- - typeset path="$3"
- + integer encode_posix_shell_safe=$1
- + typeset hostname="$2"
- +
- + integer port="$3"
- + typeset path="$4"
- typeset enc_path
- typeset enc_hostname
- - urlencodestr enc_hostname "$hostname"
- - urlencodestr enc_path "$path"
- + if [[ "$path" != /* ]] ; then
- + print -u2 -f $"%s: Path must be absolute.\n" "$0"
- + return 1
- + fi
- +
- + urlencodestr enc_hostname "$hostname" $encode_posix_shell_safe
- + urlencodestr enc_path "$path" $encode_posix_shell_safe
- if (( port == 2049 )) ; then
- printf 'url=nfs://%s/%s\n' "$enc_hostname" "$enc_path"
- else
- @@ -260,13 +279,16 @@ function main
- {
- set -o nounset
- + integer encode_posix_shell_safe=1
- +
- # fixme: Need better text layout for $ nfsurlconv --man #
- typeset -r nfsurlconv_usage=$'+
- - [-?\n@(#)\$Id: nfsurlconv (Roland Mainz) 2024-07-08 \$\n]
- + [-?\n@(#)\$Id: nfsurlconv (Roland Mainz) 2024-11-22 \$\n]
- [-author?Roland Mainz <roland.mainz@nrubsig.org>]
- [+NAME?nfsurlconv - convert hostname,port,path from/to a nfs://-URL]
- [+DESCRIPTION?\bnfsurlconv\b convert { hostname, port, path } from/to a nfs://-URL.]
- [D:debug?Enable debugging.]
- + [S!:posixshellsafe?urlencode shell special characters.]
- hostnameportpath2nfsurl hostname port path
- hostnamepath2nfsurl hostname path
- @@ -294,7 +316,13 @@ hostport=bbb
- path=/a/b/c
- ]
- }
- - [+?Example 4:][+?Convert URL nfs://bbb:12049//a/b/c?param1=pvalue1¶m2=pvalue2 to ( hostport=, path=, urlparameter= )]{
- + [+?Example 4:][+?Convert URL url=nfs://10.49.202.230//%e3%81%a0%e3%81%84%e3%81%99%e3%81%8d%21%e3%83%9e%e3%82%a6%e3%82%b9_2/ to ( hostport=, path= )]{
- +[+\n$ nfsurlconv.ksh url2hostportpath "nfs:://10.49.202.230//%e3%81%a0%e3%81%84%e3%81%99%e3%81%8d%21%e3%83%9e%e3%82%a6%e3%82%b9_2/"
- +hostport=10.49.202.230
- +path=/bigdisk/<japanese-characters>_2/
- +]
- +}
- + [+?Example 5:][+?Convert URL nfs://bbb:12049//a/b/c?param1=pvalue1¶m2=pvalue2 to ( hostport=, path=, urlparameter= )]{
- [+\n$ nfsurlconv.ksh url2hostportpath "nfs:://bbb::12049//a/b/c??param1=pvalue1¶m2=pvalue2"
- hostport=bbb::12049
- path=/a/b/c
- @@ -320,6 +348,9 @@ urlparameter=( name=param2 value=pvalue2 )
- 'D')
- # fixme: Implement debugging option
- ;;
- + 'S')
- + (( encode_posix_shell_safe=0 ))
- + ;;
- *)
- usage "${progname}" "${nfsurlconv_usage}"
- return $?
- @@ -342,23 +373,25 @@ urlparameter=( name=param2 value=pvalue2 )
- #
- c.args=( "${c.args[@]}" )
- + #printf 'c.args=%q\n' "${c.args[@]}"
- +
- typeset mode="${c.args[0]-}"
- case "$mode" in
- # fixme: add "hostportpath2nfsurl"
- # fixme: add "etcexports2nfsurl"
- 'hostnameportpath2nfsurl')
- - hostname_port_path_to_nfsurl "${@:2}"
- + hostname_port_path_to_nfsurl $encode_posix_shell_safe "${c.args[@]:1}"
- return $?
- ;;
- 'hostnamepath2nfsurl')
- - hostname_port_path_to_nfsurl "${@:2:1}" 2049 "${@:3:1}"
- + hostname_port_path_to_nfsurl $encode_posix_shell_safe "${c.args[@]:1:1}" 2049 "${c.args[@]:2:1}"
- return $?
- ;;
- 'url2hostnameportpath')
- compound urldata
- - parse_sshnfs_url urldata "${@:2:1}" || return 1
- + parse_sshnfs_url urldata "${c.args[@]:1:1}" || return 1
- printf 'hostname=%s\n' "${urldata.host}"
- printf 'port=%s\n' "${urldata.port-2049}"
- printf 'path=%s\n' "${urldata.path-}"
- @@ -374,7 +407,7 @@ urlparameter=( name=param2 value=pvalue2 )
- 'url2hostportpath')
- compound urldata
- - parse_sshnfs_url urldata "${@:2:1}" || return 1
- + parse_sshnfs_url urldata "${c.args[@]:1:1}" || return 1
- printf 'hostport=%s\n' "${urldata.hostport}"
- printf 'path=%s\n' "${urldata.path-}"
- if [[ -v urldata.parameters ]] ; then
- @@ -389,7 +422,7 @@ urlparameter=( name=param2 value=pvalue2 )
- 'url2compound')
- compound urldata
- - parse_sshnfs_url urldata "${@:2:1}" || return 1
- + parse_sshnfs_url urldata "${c.args[@]:1:1}" || return 1
- print -v urldata
- return 0
- ;;
- --
- 2.45.1
msnfs41client: Patches for strict nfs://-URL+paths from/to nfsd UTF-8 character sequence validation+misc, 2024-11-22
Posted by Anonymous on Fri 22nd Nov 2024 16:32
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.