← Commit list

7bbaf2fffd

Daniel Stenberg
Daniel Stenberg
2026-09-12
SUCCESS Duration: 423s

Subject

SMB: drop support

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

.circleci/config.yml +1 -4.github/labeler.yml +0 -8.github/scripts/pyspelling.words +0 -2.github/workflows/checksrc.yml +0 -2.github/workflows/http3-linux.yml +0 -10.github/workflows/linux.yml +5 -13.github/workflows/macos.yml +0 -9.github/workflows/windows.yml +0 -13CMakeLists.txt +0 -6README.md +1 -1RELEASE-NOTES +0 -1configure.ac +0 -23docs/CURL-DISABLE.md +0 -4docs/FAQ.md +1 -1docs/FEATURES.md +0 -7docs/HISTORY.md +2 -0docs/INSTALL-CMAKE.md +0 -1docs/MANUAL.md +0 -9docs/TODO.md +0 -7docs/URL-SYNTAX.md +3 -14docs/cmdline-opts/_DESCRIPTION.md +2 -2docs/cmdline-opts/_PROTOCOLS.md +0 -2docs/libcurl/opts/CURLINFO_PROTOCOL.md +2 -2docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.md +1 -1docs/libcurl/opts/CURLOPT_FILETIME.md +0 -1docs/libcurl/opts/CURLOPT_PROTOCOLS.md +0 -8docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.md +3 -2docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.md +0 -8docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md +7 -2docs/libcurl/symbols-in-versions +2 -2docs/tests/FILEFORMAT.md +0 -3docs/tests/TEST-SUITE.md +1 -2lib/Makefile.inc +0 -2lib/curl_config-cmake.h.in +0 -3lib/protocol.c +0 -33lib/protocol.h +0 -5lib/smb.c +0 -1243lib/smb.h +0 -31lib/urldata.h +0 -1lib/version.c +0 -6projects/OS400/README.OS400 +0 -1scripts/cd2nroff +0 -2tests/Makefile.am +0 -2tests/data/Makefile.am +0 -5tests/data/test1451 +0 -38tests/data/test1627 +1 -1tests/data/test1850 +0 -39tests/requirements.txt +0 -5tests/serverhelp.pm +1 -1tests/servers.pm +1 -135tests/smbserver.py +0 -440tests/unit/unit1627.c +3 -6
.circleci/config.yml+1 -4
@@ -45,9 +45,7 @@ commands:
steps:
- run:
command: |
- sudo apt-get update && sudo apt-get install -y libpsl-dev libbrotli-dev libzstd-dev zlib1g-dev python3-pip
- python3 -m venv ~/venv
- ~/venv/bin/pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/requirements.txt
+ sudo apt-get update && sudo apt-get install -y libpsl-dev libbrotli-dev libzstd-dev zlib1g-dev
configure:
steps:
@@ -104,7 +102,6 @@ commands:
steps:
- run:
command: |
- source ~/venv/bin/activate
# Revert a CircleCI-specific local setting that makes test 1459
# return 67 (CURLE_LOGIN_DENIED) instead of the
# expected 60 (CURLE_PEER_FAILED_VERIFICATION).
.github/labeler.yml+0 -8
@@ -454,14 +454,6 @@ script:
scripts/**\
}"
-SMB:
- - all:
- - changed-files:
- - any-glob-to-all-files: "{\
- lib/smb.*,\
- tests/smbserver.py\
- }"
-
SMTP:
- all:
- changed-files:
.github/scripts/pyspelling.words+0 -2
@@ -792,9 +792,7 @@ slist
sln
Slowloris
SMB
-smb
SMBS
-smbs
SMBv
SMTP
smtp
.github/workflows/checksrc.yml+0 -2
@@ -80,7 +80,6 @@ jobs:
pip: |
-r .github/scripts/requirements.txt
-r tests/http/requirements.txt
- -r tests/requirements.txt
- name: 'REUSE check'
background: true
@@ -142,7 +141,6 @@ jobs:
pytype==2024.10.11
-r .github/scripts/requirements.txt
-r tests/http/requirements.txt
- -r tests/requirements.txt
- name: 'check'
run: |
.github/workflows/http3-linux.yml+0 -10
@@ -840,21 +840,12 @@ jobs:
make -C bld V=1 -C tests
fi
- - name: 'install test prereqs'
- if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
- run: |
- python3 -m venv ~/venv
- if bld/src/curl --disable -V 2>/dev/null | grep smb; then
- ~/venv/bin/pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/requirements.txt
- fi
-
- name: 'run tests'
if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
env:
TFLAGS: '${{ matrix.build.tflags }}'
run: |
TFLAGS+=' -n'
- source ~/venv/bin/activate
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose --target test-ci
else
@@ -865,7 +856,6 @@ jobs:
if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
run: |
export TFLAGS='-j6 --min=4 HTTP/3'
- source ~/venv/bin/activate
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
cmake --build bld --verbose --target test-ci
else
.github/workflows/linux.yml+5 -13
@@ -78,7 +78,7 @@ jobs:
- name: 'awslc'
install_steps: awslc pytest
LDFLAGS: -Wl,-rpath,/home/runner/awslc/lib
- configure: --with-openssl=/home/runner/awslc --enable-ech --enable-ntlm --enable-smb
+ configure: --with-openssl=/home/runner/awslc --enable-ech --enable-ntlm
- name: 'awslc'
install_packages: libidn2-dev
@@ -271,7 +271,7 @@ jobs:
- name: 'openssl !ipv6 !--libcurl !--digest-auth'
image: ubuntu-24.04-arm
- configure: --with-openssl --disable-ipv6 --enable-debug --disable-unity --disable-libcurl-option --disable-digest-auth --enable-ntlm --enable-smb
+ configure: --with-openssl --disable-ipv6 --enable-debug --disable-unity --disable-libcurl-option --disable-digest-auth --enable-ntlm
- name: 'curl_global_init_mem debug valgrind'
image: ubuntu-24.04-arm
@@ -280,7 +280,7 @@ jobs:
configure: >-
--enable-init-mem-debug
--with-openssl --disable-debug --enable-unity
- --enable-ntlm --enable-smb
+ --enable-ntlm
- name: 'openssl https-only'
image: ubuntu-24.04-arm
@@ -291,7 +291,7 @@ jobs:
--disable-imap --disable-pop3 --disable-smtp
--disable-rtsp
--without-libssh2 --without-libssh
- --disable-tftp --disable-ftp --disable-file --disable-smb
+ --disable-tftp --disable-ftp --disable-file
--enable-ntlm
- name: 'openssl torture 1'
@@ -433,7 +433,7 @@ jobs:
- name: 'event-based'
install_packages: libssh-dev
- configure: --enable-debug --enable-static --disable-shared --disable-threaded-resolver --with-libssh --with-openssl --enable-ntlm --enable-smb
+ configure: --enable-debug --enable-static --disable-shared --disable-threaded-resolver --with-libssh --with-openssl --enable-ntlm
tflags: '-n --test-event --min=1420'
- name: 'duphandle'
@@ -926,14 +926,6 @@ jobs:
make -C bld V=1 -C tests
fi
- - name: 'install test prereqs'
- if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') && matrix.build.container == null }}
- run: |
- python3 -m venv ~/venv
- if bld/src/curl --disable -V 2>/dev/null | grep smb; then
- ~/venv/bin/pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/requirements.txt
- fi
-
- name: 'run tests'
if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
timeout-minutes: ${{ contains(matrix.build.install_packages, 'valgrind') && 20 || 10 }}
.github/workflows/macos.yml+0 -9
@@ -544,14 +544,6 @@ jobs:
make -C bld V=1 -C tests
fi
- - name: 'install test prereqs'
- if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
- run: |
- python3 -m venv ~/venv
- if bld/src/curl --disable -V 2>/dev/null | grep smb; then
- ~/venv/bin/pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/requirements.txt
- fi
-
- name: 'run tests'
if: ${{ !contains(matrix.build.install_steps, 'skipall') && !contains(matrix.build.install_steps, 'skiprun') }}
timeout-minutes: ${{ contains(matrix.build.install_steps, 'torture') && 20 || 10 }}
@@ -563,7 +555,6 @@ jobs:
if [ "${TEST_TARGET}" != 'test-ci' ]; then
TFLAGS+=' --buildinfo' # only test-ci sets this by default, set it manually for test-torture
fi
- source ~/venv/bin/activate
if [[ "${MATRIX_INSTALL_STEPS}" = *'codeset-test1'* ]]; then
locale || true
unset LANG
.github/workflows/windows.yml+0 -13
@@ -767,14 +767,6 @@ jobs:
key: ${{ runner.os }}-stunnel-${{ env.STUNNEL_VERSION }}-amd64
fail-on-cache-miss: true
- - name: 'install test prereqs'
- if: ${{ matrix.tflags != 'skipall' && matrix.tflags != 'skiprun' }}
- timeout-minutes: 2
- run: |
- if bld/src/curl.exe --disable -V 2>/dev/null | grep smb; then
- python3 -m pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/requirements.txt
- fi
-
- name: 'run tests'
if: ${{ matrix.tflags != 'skipall' && matrix.tflags != 'skiprun' }}
timeout-minutes: 10
@@ -1003,8 +995,6 @@ jobs:
image: 'windows-11-arm'
openssh: 'OpenSSH-Windows'
tflags: '--min=1720'
- # leave SMB disabled to save 30-60 seconds by omitting prereqs,
- # to counteract the slower test run step
config: >-
-DENABLE_DEBUG=ON
-DCURL_USE_SCHANNEL=ON
@@ -1204,9 +1194,6 @@ jobs:
sha256sum pkg.bin && sha256sum pkg.bin | grep -qwF -- "${OPENSSH_WINDOWS_SHA256_WIN64}" && unzip pkg.bin && rm -f pkg.bin
fi
fi
- if "bld/src/${MATRIX_TYPE}/curl.exe" --disable -V 2>/dev/null | grep smb; then
- python3 -m pip --disable-pip-version-check --no-input --no-cache-dir install --progress-bar off --prefer-binary -r tests/requirements.txt
- fi
- name: 'run tests'
if: ${{ matrix.tflags != 'skipall' && matrix.tflags != 'skiprun' }}
CMakeLists.txt+0 -6
@@ -498,8 +498,6 @@ option(CURL_DISABLE_SHA512_256 "Disable SHA-512/256 hash algorithm" OFF)
mark_as_advanced(CURL_DISABLE_SHA512_256)
option(CURL_DISABLE_SHUFFLE_DNS "Disable shuffle DNS feature" OFF)
mark_as_advanced(CURL_DISABLE_SHUFFLE_DNS)
-option(CURL_ENABLE_SMB "Enable SMB" OFF)
-mark_as_advanced(CURL_ENABLE_SMB)
option(CURL_DISABLE_SMTP "Disable SMTP" OFF)
mark_as_advanced(CURL_DISABLE_SMTP)
option(CURL_DISABLE_SOCKETPAIR "Disable use of socketpair for curl_multi_poll()" OFF)
@@ -1992,10 +1990,6 @@ curl_add_if("POP3" NOT CURL_DISABLE_POP3)
curl_add_if("POP3S" NOT CURL_DISABLE_POP3 AND _ssl_enabled)
curl_add_if("IMAP" NOT CURL_DISABLE_IMAP)
curl_add_if("IMAPS" NOT CURL_DISABLE_IMAP AND _ssl_enabled)
-curl_add_if("SMB" CURL_ENABLE_SMB AND
- _use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4))
-curl_add_if("SMBS" CURL_ENABLE_SMB AND _ssl_enabled AND
- _use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4))
curl_add_if("SMTP" NOT CURL_DISABLE_SMTP)
curl_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND _ssl_enabled)
curl_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH)
README.md+1 -1
@@ -9,7 +9,7 @@ SPDX-License-Identifier: curl
curl is a command-line tool for transferring data from or to a server using
URLs. It supports these protocols: DICT, FILE, FTP, FTPS, GOPHER, GOPHERS,
HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP,
-SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
+SFTP, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
Learn how to use curl by reading [the
man page](https://curl.se/docs/manpage.html) or [everything
RELEASE-NOTES+0 -1
@@ -85,7 +85,6 @@ Planned upcoming removals include:
o HTTP/2 Server Push
o local crypto implementations
o NTLM
- o SMB
See https://curl.se/dev/deprecate.html
configure.ac+0 -23
@@ -1058,23 +1058,6 @@ AS_HELP_STRING([--disable-imap],[Disable IMAP support]),
AC_MSG_RESULT(yes)
)
-AC_MSG_CHECKING([whether to support smb])
-AC_ARG_ENABLE(smb,
-AS_HELP_STRING([--enable-smb],[Enable SMB support])
-AS_HELP_STRING([--disable-smb],[Disable SMB support]),
-[ case "$enableval" in
- yes)
- AC_MSG_RESULT(yes)
- AC_DEFINE(CURL_ENABLE_SMB, 1, [to enable SMB])
- CURL_ENABLE_SMB=1
- ;;
- *)
- AC_MSG_RESULT(no)
- ;;
- esac ],
- AC_MSG_RESULT(no)
-)
-
AC_MSG_CHECKING([whether to support smtp])
AC_ARG_ENABLE(smtp,
AS_HELP_STRING([--enable-smtp],[Enable SMTP support])
@@ -5477,12 +5460,6 @@ if test "$CURL_DISABLE_IMAP" != "1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS IMAPS"
fi
fi
-if test "$CURL_ENABLE_SMB" = "1" && test "$use_curl_ntlm_core" = "yes"; then
- SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMB"
- if test "$SSL_ENABLED" = "1"; then
- SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMBS"
- fi
-fi
if test "$CURL_DISABLE_SMTP" != "1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS SMTP"
if test "$SSL_ENABLED" = "1"; then
docs/CURL-DISABLE.md+0 -4
@@ -161,10 +161,6 @@ Disable the SHA-512/256 hash algorithm.
Disable the shuffle DNS feature
-## `CURL_ENABLE_SMB`
-
-Enable the SMB(S) protocols
-
## `CURL_DISABLE_SMTP`
Disable the SMTP(S) protocols
docs/FAQ.md+1 -1
@@ -22,7 +22,7 @@ The curl project produces two products:
A client-side URL transfer library, supporting DICT, FILE, FTP, FTPS, GOPHER,
GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S,
-RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
+RTSP, SCP, SFTP, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading,
Kerberos, SPNEGO, HTTP form based upload, proxies, cookies, user+password
docs/FEATURES.md+0 -7
@@ -184,13 +184,6 @@ SPDX-License-Identifier: curl
- upload
- resume
-## SMB
-
-- SMBv1 over TCP and SSL
-- download
-- upload
-- authentication with NTLMv1
-
## SMTP
- authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM, Kerberos 5 and
docs/HISTORY.md+2 -0
@@ -503,3 +503,5 @@ December 15: the website served 78 TB over the last month.
## 2026
April: removed support for RTMP
+
+September: removed support for SMB
docs/INSTALL-CMAKE.md+0 -1
@@ -246,7 +246,6 @@ target_link_libraries(my_target PRIVATE CURL::libcurl)
- `CURL_ENABLE_APPLE_FAST_UDP`: Use Apple fast UDP (experimental). Default: `OFF`
- `CURL_ENABLE_NTLM`: Enable NTLM support. Default: `OFF`
-- `CURL_ENABLE_SMB`: Enable SMB. Default: `OFF`
- `CURL_ENABLE_SSL`: Enable SSL support. Default: `ON`
- `CURL_WINDOWS_SSPI`: Enable SSPI on Windows. Default: =`CURL_USE_SCHANNEL`
- `ENABLE_IPV6`: Enable IPv6 support. Default: `ON` if target supports IPv6.
docs/MANUAL.md+0 -9
@@ -63,10 +63,6 @@ Get the main page from an IPv6 web server:
curl "http://[2001:1890:1112:1::20]/"
-Get a file from an SMB server:
-
- curl -u "domain\username:passwd" smb://server.example.com/share/file.txt
-
## Download to a File
Get a webpage and store in a local file with a specific name:
@@ -244,11 +240,6 @@ fashion similar to:
curl --proxytunnel -x proxy:port -T localfile ftp.example.com
-### SMB / SMBS
-
- curl -T file.txt -u "domain\username:passwd"
- smb://server.example.com/share/
-
### HTTP
Upload all data on stdin to a specified HTTPS site:
docs/TODO.md+0 -7
@@ -930,13 +930,6 @@ http operations (for which we have test servers).
Make the test suite work on more platforms. OpenBSD and macOS. Remove fork()s
and it should become even more portable.
-## write an SMB test server to replace impacket
-
-This would allow us to run SMB tests on more platforms and do better and more
-covering tests.
-
-See [curl issue 15697](https://github.com/curl/curl/issues/15697)
-
## Use the RFC 6265 test suite
A test suite made for HTTP cookies (RFC 6265) by Adam Barth [is
docs/URL-SYNTAX.md+3 -14
@@ -141,8 +141,8 @@ curl supports the following schemes on URLs specified to transfer. They are
matched case insensitively:
`dict`, `file`, `ftp`, `ftps`, `gopher`, `gophers`, `http`, `https`, `imap`,
-`imaps`, `ldap`, `ldaps`, `mqtt`, `pop3`, `pop3s`, `rtsp`, `smb`, `smbs`,
-`smtp`, `smtps`, `telnet`, `tftp`
+`imaps`, `ldap`, `ldaps`, `mqtt`, `pop3`, `pop3s`, `rtsp`, `smtp`, `smtps`,
+`telnet`, `tftp`
When the URL is specified to identify a proxy, curl recognizes the following
schemes:
@@ -243,7 +243,7 @@ number based on the provide scheme:
DICT 2628, FTP 21, FTPS 990, GOPHER 70, GOPHERS 70, HTTP 80, HTTPS 443, IMAP
143, IMAPS 993, LDAP 389, LDAPS 636, MQTT 1883, POP3 110, POP3S 995, RTSP 554,
-SCP 22, SFTP 22, SMB 445, SMBS 445, SMTP 25, SMTPS 465, TELNET 23, TFTP 69
+SCP 22, SFTP 22, SMTP 25, SMTPS 465, TELNET 23, TFTP 69
## Path
@@ -398,17 +398,6 @@ path ends with a slash (`/`) then a directory listing is returned instead of a
file. If the path is omitted entirely then the directory listing for the root
/ home directory is returned.
-## SMB
-The path part of an SMB request specifies the file to retrieve and from what
-share and directory or the share to upload to and as such, may not be omitted.
-If the username is embedded in the URL then it must contain the domain name
-and as such, the backslash must be URL encoded as %2f.
-
-When uploading to SMB, the size of the file needs to be known ahead of time,
-meaning that you can upload a file passed to curl over a pipe like stdin.
-
-curl supports SMB version 1 (only)
-
## SMTP
The path part of an SMTP request specifies the hostname to present during
docs/cmdline-opts/_DESCRIPTION.md+2 -2
@@ -4,8 +4,8 @@
**curl** is a tool for transferring data from or to a server using URLs. It
supports these protocols: DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS,
-IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB,
-SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS.
+IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMTP,
+SMTPS, TELNET, TFTP, WS and WSS.
curl is powered by libcurl for all transfer-related features. See
*libcurl(3)* for details.
docs/cmdline-opts/_PROTOCOLS.md+0 -2
@@ -36,8 +36,6 @@ curl supports RTSP 1.0 downloads.
curl supports SSH version 2 scp transfers.
## SFTP
curl supports SFTP (draft 5) done over SSH version 2.
-## SMB(S)
-curl supports SMB version 1 for upload and download.
## SMTP(S)
Uploading contents to an SMTP server means sending an email. With or without
TLS.
docs/libcurl/opts/CURLINFO_PROTOCOL.md+2 -2
@@ -40,8 +40,8 @@ CURLPROTO_GOPHER, CURLPROTO_HTTP, CURLPROTO_HTTPS, CURLPROTO_IMAP,
CURLPROTO_IMAPS, CURLPROTO_LDAP, CURLPROTO_LDAPS, CURLPROTO_POP3,
CURLPROTO_POP3S, CURLPROTO_RTMP, CURLPROTO_RTMPE, CURLPROTO_RTMPS,
CURLPROTO_RTMPT, CURLPROTO_RTMPTE, CURLPROTO_RTMPTS, CURLPROTO_RTSP,
-CURLPROTO_SCP, CURLPROTO_SFTP, CURLPROTO_SMB, CURLPROTO_SMBS, CURLPROTO_SMTP,
-CURLPROTO_SMTPS, CURLPROTO_TELNET, CURLPROTO_TFTP, CURLPROTO_MQTT
+CURLPROTO_SCP, CURLPROTO_SFTP, CURLPROTO_SMTP, CURLPROTO_SMTPS,
+CURLPROTO_TELNET, CURLPROTO_TFTP, CURLPROTO_MQTT
~~~
# %PROTOCOLS%
docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.md+1 -1
@@ -35,7 +35,7 @@ name.
Use one of these protocol (scheme) names:
dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3,
-pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
+pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp
An unknown or unsupported protocol causes error *CURLE_UNSUPPORTED_PROTOCOL*
when libcurl parses a URL without a scheme. Parsing happens when
docs/libcurl/opts/CURLOPT_FILETIME.md+0 -1
@@ -12,7 +12,6 @@ Protocol:
- FTP
- SFTP
- FILE
- - SMB
Added-in: 7.5
---
docs/libcurl/opts/CURLOPT_PROTOCOLS.md+0 -8
@@ -56,17 +56,9 @@ CURLPROTO_LDAPS
CURLPROTO_MQTT
CURLPROTO_POP3
CURLPROTO_POP3S
-CURLPROTO_RTMP
-CURLPROTO_RTMPE
-CURLPROTO_RTMPS
-CURLPROTO_RTMPT
-CURLPROTO_RTMPTE
-CURLPROTO_RTMPTS
CURLPROTO_RTSP
CURLPROTO_SCP
CURLPROTO_SFTP
-CURLPROTO_SMB
-CURLPROTO_SMBS
CURLPROTO_SMTP
CURLPROTO_SMTPS
CURLPROTO_TELNET
docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.md+3 -2
@@ -42,8 +42,7 @@ set, it returns error.
These are the available protocols:
DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS,
-MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET,
-TFTP, WS, WSS
+MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET, TFTP, WS, WSS
You can set "ALL" as a short-cut to enable all protocols. Note that by setting
all, you may enable protocols that were not supported the day you write this
@@ -87,6 +86,8 @@ int main(int argc, char *argv[])
RTMP and its related protocol schemes are not supported since curl 8.20.0
+SMB and SMBS were removed in curl 8.23.0
+
# %AVAILABILITY%
# RETURN VALUE
docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.md+0 -8
@@ -61,17 +61,9 @@ CURLPROTO_LDAPS
CURLPROTO_MQTT
CURLPROTO_POP3
CURLPROTO_POP3S
-CURLPROTO_RTMP
-CURLPROTO_RTMPE
-CURLPROTO_RTMPS
-CURLPROTO_RTMPT
-CURLPROTO_RTMPTE
-CURLPROTO_RTMPTS
CURLPROTO_RTSP
CURLPROTO_SCP
CURLPROTO_SFTP
-CURLPROTO_SMB
-CURLPROTO_SMBS
CURLPROTO_SMTP
CURLPROTO_SMTPS
CURLPROTO_TELNET
docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.md+7 -2
@@ -46,8 +46,7 @@ By default libcurl allows HTTP, HTTPS, FTP and FTPS on redirects (since
These are the available protocols:
DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS,
-MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET,
-TFTP, WS, WSS
+MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET, TFTP, WS, WSS
You can set "ALL" as a short-cut to enable all protocols. Note that by setting
all, you may enable protocols that were not supported the day you write this
@@ -89,6 +88,12 @@ int main(int argc, char *argv[])
}
~~~
+# HISTORY
+
+RTMP and its related protocol schemes are not supported since curl 8.20.0
+
+SMB and SMBS were removed in curl 8.23.0
+
# %AVAILABILITY%
# RETURN VALUE
docs/libcurl/symbols-in-versions+2 -2
@@ -992,8 +992,8 @@ CURLPROTO_RTMPTS 7.21.0 8.20.0
CURLPROTO_RTSP 7.20.0
CURLPROTO_SCP 7.19.4
CURLPROTO_SFTP 7.19.4
-CURLPROTO_SMB 7.40.0
-CURLPROTO_SMBS 7.40.0
+CURLPROTO_SMB 7.40.0 8.23.0
+CURLPROTO_SMBS 7.40.0 8.23.0
CURLPROTO_SMTP 7.20.0
CURLPROTO_SMTPS 7.20.0
CURLPROTO_TELNET 7.19.4
docs/tests/FILEFORMAT.md+0 -3
@@ -193,8 +193,6 @@ Available substitute variables include:
- `%RESOLVE` - server/resolve command
- `%RTSP6PORT` - IPv6 port number of the RTSP server
- `%RTSPPORT` - Port number of the RTSP server
-- `%SMBPORT` - Port number of the SMB server
-- `%SMBSPORT` - Port number of the SMBS server
- `%SMTP6PORT` - IPv6 port number of the SMTP server
- `%SMTPPORT` - Port number of the SMTP server
- `%SOCKSPORT` - Port number of the SOCKS4/5 server
@@ -453,7 +451,6 @@ What server(s) this test case requires/uses. Available servers:
- `rtsp-ipv6`
- `scp`
- `sftp`
-- `smb`
- `smtp`
- `socks4`
- `socks5`
docs/tests/TEST-SUITE.md+1 -2
@@ -46,8 +46,7 @@ output from the servers used in the test.
## Requires to run
- `perl` (and a Unix-style shell)
-- `python` (and a Unix-style shell, for SMB and TELNET tests)
-- `python-impacket` (for SMB tests)
+- `python` (and a Unix-style shell, for TELNET tests)
- `diff` (when a test fails, a diff is shown)
- `stunnel` (for HTTPS and FTPS tests)
- `openssl` (the command line tool, for generating test server certificates)
lib/Makefile.inc+0 -2
@@ -274,7 +274,6 @@ LIB_CFILES = \
setopt.c \
sha256.c \
slist.c \
- smb.c \
smtp.c \
socketpair.c \
socks.c \
@@ -409,7 +408,6 @@ LIB_HFILES = \
setup-win32.h \
sigpipe.h \
slist.h \
- smb.h \
smtp.h \
sockaddr.h \
socketpair.h \
lib/curl_config-cmake.h.in+0 -3
@@ -148,9 +148,6 @@
/* disabled shuffle DNS feature */
#cmakedefine CURL_DISABLE_SHUFFLE_DNS 1
-/* disables SMB */
-#cmakedefine CURL_ENABLE_SMB 1
-
/* disables SMTP */
#cmakedefine CURL_DISABLE_SMTP 1
lib/protocol.c+0 -33
@@ -36,7 +36,6 @@
#include "mqtt.h"
#include "pop3.h"
#include "rtsp.h"
-#include "smb.h"
#include "smtp.h"
#include "telnet.h"
#include "tftp.h"
@@ -308,32 +307,6 @@ const struct Curl_scheme Curl_scheme_scp = {
PORT_SSH, /* defport */
};
-const struct Curl_scheme Curl_scheme_smb = {
- "smb", /* scheme */
-#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE)
- &Curl_protocol_smb,
-#else
- ZERO_NULL,
-#endif
- CURLPROTO_SMB, /* protocol */
- CURLPROTO_SMB, /* family */
- PROTOPT_NONE, /* flags */
- PORT_SMB, /* defport */
-};
-
-const struct Curl_scheme Curl_scheme_smbs = {
- "smbs", /* scheme */
-#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) && defined(USE_SSL)
- &Curl_protocol_smb,
-#else
- ZERO_NULL,
-#endif
- CURLPROTO_SMBS, /* protocol */
- CURLPROTO_SMB, /* family */
- PROTOPT_SSL, /* flags */
- PORT_SMBS, /* defport */
-};
-
const struct Curl_scheme Curl_scheme_smtp = {
"smtp", /* scheme */
#ifdef CURL_DISABLE_SMTP
@@ -486,8 +459,6 @@ static const struct Curl_scheme *three_letter_scheme(const char *scheme)
else if(s0 == 's') {
if(s1 == 'c' && s2 == 'p')
return &Curl_scheme_scp;
- if(s1 == 'm' && s2 == 'b')
- return &Curl_scheme_smb;
}
return NULL;
}
@@ -544,10 +515,6 @@ static const struct Curl_scheme *four_letter_scheme(const char *scheme)
if(s1 == 'i' && s2 == 'c' && s3 == 't')
return &Curl_scheme_dict;
}
- else if(s0 == 's') {
- if(s1 == 'm' && s2 == 'b' && s3 == 's')
- return &Curl_scheme_smbs;
- }
return NULL;
}
lib/protocol.h+0 -5
@@ -45,8 +45,6 @@ struct easy_pollset;
#define PORT_IMAPS 993
#define PORT_POP3 110
#define PORT_POP3S 995
-#define PORT_SMB 445
-#define PORT_SMBS 445
#define PORT_SMTP 25
#define PORT_SMTPS 465 /* sometimes called SSMTP */
#define PORT_RTSP 554
@@ -85,7 +83,6 @@ typedef curl_off_t curl_prot_t;
CURLPROTO_WSS)
#define PROTO_FAMILY_FTP (CURLPROTO_FTP | CURLPROTO_FTPS)
#define PROTO_FAMILY_POP3 (CURLPROTO_POP3 | CURLPROTO_POP3S)
-#define PROTO_FAMILY_SMB (CURLPROTO_SMB | CURLPROTO_SMBS)
#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP | CURLPROTO_SMTPS)
#define PROTO_FAMILY_SSH (CURLPROTO_SCP | CURLPROTO_SFTP)
@@ -278,8 +275,6 @@ extern const struct Curl_scheme Curl_scheme_pop3s;
extern const struct Curl_scheme Curl_scheme_rtsp;
extern const struct Curl_scheme Curl_scheme_scp;
extern const struct Curl_scheme Curl_scheme_sftp;
-extern const struct Curl_scheme Curl_scheme_smb;
-extern const struct Curl_scheme Curl_scheme_smbs;
extern const struct Curl_scheme Curl_scheme_smtp;
extern const struct Curl_scheme Curl_scheme_smtps;
extern const struct Curl_scheme Curl_scheme_socks;
lib/smb.c+0 -1243
@@ -1,1243 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
- * Copyright (C) Bill Nagel <[email protected]>, Exacq Technologies
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-#include "curl_setup.h"
-#include "urldata.h"
-
-#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE)
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h> /* for htons() */
-#endif
-
-#include "smb.h"
-#include "url.h"
-#include "sendf.h"
-#include "curl_trc.h"
-#include "cfilters.h"
-#include "connect.h"
-#include "progress.h"
-#include "transfer.h"
-#include "select.h"
-#include "curl_ntlm_core.h"
-#include "escape.h"
-#include "curl_endian.h"
-#include "curlx/strcopy.h"
-
-/* meta key for storing protocol meta at easy handle */
-#define CURL_META_SMB_EASY "meta:proto:smb:easy"
-/* meta key for storing protocol meta at connection */
-#define CURL_META_SMB_CONN "meta:proto:smb:conn"
-
-enum smb_conn_state {
- SMB_NOT_CONNECTED = 0,
- SMB_CONNECTING,
- SMB_NEGOTIATE,
- SMB_SETUP,
- SMB_CONNECTED
-};
-
-/* SMB connection data, kept at connection */
-struct smb_conn {
- enum smb_conn_state state;
- const char *user;
- char *domain;
- char *share;
- unsigned char challenge[8];
- unsigned int session_key;
- unsigned short uid;
- char *recv_buf;
- char *send_buf;
- size_t upload_size;
- size_t send_size;
- size_t sent;
- size_t got;
-};
-
-/* SMB request state */
-enum smb_req_state {
- SMB_REQUESTING,
- SMB_TREE_CONNECT,
- SMB_OPEN,
- SMB_DOWNLOAD,
- SMB_UPLOAD,
- SMB_CLOSE,
- SMB_TREE_DISCONNECT,
- SMB_DONE
-};
-
-/* SMB request data, kept at easy handle */
-struct smb_request {
- enum smb_req_state state;
- char *path;
- unsigned short tid; /* Even if we connect to the same tree as another */
- unsigned short fid; /* request, the tid will be different */
- CURLcode result;
-};
-
-/*
- * Definitions for SMB protocol data structures
- */
-#if defined(_MSC_VER) || defined(__ILEC400__)
-# define PACK
-# pragma pack(push)
-# pragma pack(1)
-#elif defined(__GNUC__)
-# define PACK __attribute__((packed))
-#else
-# define PACK
-#endif
-
-#define SMB_COM_CLOSE 0x04
-#define SMB_COM_READ_ANDX 0x2e
-#define SMB_COM_WRITE_ANDX 0x2f
-#define SMB_COM_TREE_DISCONNECT 0x71
-#define SMB_COM_NEGOTIATE 0x72
-#define SMB_COM_SETUP_ANDX 0x73
-#define SMB_COM_TREE_CONNECT_ANDX 0x75
-#define SMB_COM_NT_CREATE_ANDX 0xa2
-#define SMB_COM_NO_ANDX_COMMAND 0xff
-
-#define SMB_WC_CLOSE 0x03
-#define SMB_WC_READ_ANDX 0x0c
-#define SMB_WC_WRITE_ANDX 0x0e
-#define SMB_WC_SETUP_ANDX 0x0d
-#define SMB_WC_TREE_CONNECT_ANDX 0x04
-#define SMB_WC_NT_CREATE_ANDX 0x18
-
-#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
-#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
-/* #define SMB_FLAGS2_UNICODE_STRINGS 0x8000 */
-#define SMB_FLAGS2_IS_LONG_NAME 0x0040
-#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
-
-#define SMB_CAP_LARGE_FILES 0x08
-#define SMB_GENERIC_WRITE 0x40000000
-#define SMB_GENERIC_READ 0x80000000
-#define SMB_FILE_SHARE_ALL 0x07
-#define SMB_FILE_OPEN 0x01
-#define SMB_FILE_OVERWRITE_IF 0x05
-
-#define SMB_ERR_NOACCESS 0x00050001
-
-struct smb_header {
- unsigned char nbt_type;
- unsigned char nbt_flags;
- unsigned short nbt_length;
- unsigned char magic[4];
- unsigned char command;
- unsigned int status;
- unsigned char flags;
- unsigned short flags2;
- unsigned short pid_high;
- unsigned char signature[8];
- unsigned short pad;
- unsigned short tid;
- unsigned short pid;
- unsigned short uid;
- unsigned short mid;
-} PACK;
-
-struct smb_negotiate_response {
- struct smb_header h;
- unsigned char word_count;
- unsigned short dialect_index;
- unsigned char security_mode;
- unsigned short max_mpx_count;
- unsigned short max_number_vcs;
- unsigned int max_buffer_size;
- unsigned int max_raw_size;
- unsigned int session_key;
- unsigned int capabilities;
- unsigned int system_time_low;
- unsigned int system_time_high;
- unsigned short server_time_zone;
- unsigned char encryption_key_length;
- unsigned short byte_count;
- char bytes[1];
-} PACK;
-
-struct andx {
- unsigned char command;
- unsigned char pad;
- unsigned short offset;
-} PACK;
-
-struct smb_setup {
- unsigned char word_count;
- struct andx andx;
- unsigned short max_buffer_size;
- unsigned short max_mpx_count;
- unsigned short vc_number;
- unsigned int session_key;
- unsigned short lengths[2];
- unsigned int pad;
- unsigned int capabilities;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_tree_connect {
- unsigned char word_count;
- struct andx andx;
- unsigned short flags;
- unsigned short pw_len;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_nt_create {
- unsigned char word_count;
- struct andx andx;
- unsigned char pad;
- unsigned short name_length;
- unsigned int flags;
- unsigned int root_fid;
- unsigned int access;
- curl_off_t allocation_size;
- unsigned int ext_file_attributes;
- unsigned int share_access;
- unsigned int create_disposition;
- unsigned int create_options;
- unsigned int impersonation_level;
- unsigned char security_flags;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_nt_create_response {
- struct smb_header h;
- unsigned char word_count;
- struct andx andx;
- unsigned char op_lock_level;
- unsigned short fid;
- unsigned int create_disposition;
-
- curl_off_t create_time;
- curl_off_t last_access_time;
- curl_off_t last_write_time;
- curl_off_t last_change_time;
- unsigned int ext_file_attributes;
- curl_off_t allocation_size;
- curl_off_t end_of_file;
-} PACK;
-
-struct smb_read {
- unsigned char word_count;
- struct andx andx;
- unsigned short fid;
- unsigned int offset;
- unsigned short max_bytes;
- unsigned short min_bytes;
- unsigned int timeout;
- unsigned short remaining;
- unsigned int offset_high;
- unsigned short byte_count;
-} PACK;
-
-struct smb_write {
- struct smb_header h;
- unsigned char word_count;
- struct andx andx;
- unsigned short fid;
- unsigned int offset;
- unsigned int timeout;
- unsigned short write_mode;
- unsigned short remaining;
- unsigned short pad;
- unsigned short data_length;
- unsigned short data_offset;
- unsigned int offset_high;
- unsigned short byte_count;
- unsigned char pad2;
-} PACK;
-
-struct smb_close {
- unsigned char word_count;
- unsigned short fid;
- unsigned int last_mtime;
- unsigned short byte_count;
-} PACK;
-
-struct smb_tree_disconnect {
- unsigned char word_count;
- unsigned short byte_count;
-} PACK;
-
-#if defined(_MSC_VER) || defined(__ILEC400__)
-# pragma pack(pop)
-#endif
-
-#define MAX_PAYLOAD_SIZE 0x8000
-#define MAX_MESSAGE_SIZE (MAX_PAYLOAD_SIZE + 0x1000)
-#define CLIENTNAME "curl"
-#define SERVICENAME "?????"
-
-/* SMB is mostly little endian */
-#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
- defined(__OS400__)
-static unsigned short smb_swap16(unsigned short x)
-{
- return (unsigned short)((x << 8) | ((x >> 8) & 0xff));
-}
-
-static unsigned int smb_swap32(unsigned int x)
-{
- return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
- ((x >> 24) & 0xff);
-}
-
-static curl_off_t smb_swap64(curl_off_t x)
-{
- return ((curl_off_t)smb_swap32((unsigned int)x) << 32) |
- smb_swap32((unsigned int)(x >> 32));
-}
-
-#else
-# define smb_swap16(x) (x)
-# define smb_swap32(x) (x)
-# define smb_swap64(x) (x)
-#endif
-
-static void conn_state(struct Curl_easy *data, struct smb_conn *smbc,
- enum smb_conn_state newstate)
-{
-#if defined(DEBUGBUILD) && defined(CURLVERBOSE)
- /* For debug purposes */
- static const char * const names[] = {
- "SMB_NOT_CONNECTED",
- "SMB_CONNECTING",
- "SMB_NEGOTIATE",
- "SMB_SETUP",
- "SMB_CONNECTED",
- /* LAST */
- };
-
- if(smbc->state != newstate)
- infof(data, "SMB conn %p state change from %s to %s",
- (void *)smbc, names[smbc->state], names[newstate]);
-#else
- (void)data;
-#endif
- smbc->state = newstate;
-}
-
-static void request_state(struct Curl_easy *data,
- enum smb_req_state newstate)
-{
- struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
- if(req) {
-#if defined(DEBUGBUILD) && defined(CURLVERBOSE)
- /* For debug purposes */
- static const char * const names[] = {
- "SMB_REQUESTING",
- "SMB_TREE_CONNECT",
- "SMB_OPEN",
- "SMB_DOWNLOAD",
- "SMB_UPLOAD",
- "SMB_CLOSE",
- "SMB_TREE_DISCONNECT",
- "SMB_DONE",
- /* LAST */
- };
-
- if(req->state != newstate)
- infof(data, "SMB request %p state change from %s to %s",
- (void *)req, names[req->state], names[newstate]);
-#endif
-
- req->state = newstate;
- }
-}
-
-static void smb_easy_dtor(const void *key, size_t klen, void *entry)
-{
- struct smb_request *req = entry;
- (void)key;
- (void)klen;
- curlx_safefree(req->path);
- curlx_free(req);
-}
-
-static void smb_conn_dtor(const void *key, size_t klen, void *entry)
-{
- struct smb_conn *smbc = entry;
- (void)key;
- (void)klen;
- curlx_safefree(smbc->share);
- curlx_safefree(smbc->domain);
- curlx_safefree(smbc->recv_buf);
- curlx_safefree(smbc->send_buf);
- curlx_free(smbc);
-}
-
-static CURLcode smb_parse_url_path(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- char *path;
- char *slash, *s;
- CURLcode result;
-
- /* URL decode the path */
- result = Curl_urldecode(data->state.up.path, 0, &path, NULL, REJECT_CTRL);
- if(result)
- return result;
-
- /* Parse the path for the share */
- curlx_safefree(smbc->share);
- smbc->share = curlx_strdup((*path == '/' || *path == '\\')
- ? path + 1 : path);
- curlx_free(path);
- if(!smbc->share)
- return CURLE_OUT_OF_MEMORY;
-
- slash = strchr(smbc->share, '/');
- if(!slash)
- slash = strchr(smbc->share, '\\');
-
- /* The share must be present */
- if(!slash) {
- curlx_safefree(smbc->share);
- failf(data, "missing share in URL path for SMB");
- return CURLE_URL_MALFORMAT;
- }
-
- /* Parse the path for the file path converting any forward slashes into
- backslashes */
- *slash++ = 0;
- for(s = slash; *s; s++) {
- if(*s == '/')
- *s = '\\';
- }
- /* keep a copy at easy struct to not share this with connection state */
- req->path = curlx_strdup(slash);
- if(!req->path)
- return CURLE_OUT_OF_MEMORY;
-
- return CURLE_OK;
-}
-
-/* this should setup things in the connection, not in the easy
- handle */
-static CURLcode smb_setup_connection(struct Curl_easy *data,
- struct connectdata *conn)
-{
- struct smb_conn *smbc;
- struct smb_request *req;
-
- /* Initialize the connection state */
- smbc = curlx_calloc(1, sizeof(*smbc));
- if(!smbc ||
- Curl_conn_meta_set(conn, CURL_META_SMB_CONN, smbc, smb_conn_dtor))
- return CURLE_OUT_OF_MEMORY;
-
- /* Initialize the request state */
- req = curlx_calloc(1, sizeof(*req));
- if(!req ||
- Curl_meta_set(data, CURL_META_SMB_EASY, req, smb_easy_dtor))
- return CURLE_OUT_OF_MEMORY;
-
- /* Parse the URL path */
- return smb_parse_url_path(data, smbc, req);
-}
-
-static CURLcode smb_connect(struct Curl_easy *data, bool *done)
-{
- struct connectdata *conn = data->conn;
- struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
- const char *slash;
- const char *user = Curl_creds_user(conn->creds);
-
- (void)done;
- if(!smbc)
- return CURLE_FAILED_INIT;
-
- /* Check we have a username and password to authenticate with */
- if(!Curl_creds_has_user(data->state.creds))
- return CURLE_LOGIN_DENIED;
-
- /* Initialize the connection state */
- smbc->state = SMB_CONNECTING;
- smbc->recv_buf = curlx_malloc(MAX_MESSAGE_SIZE);
- if(!smbc->recv_buf)
- return CURLE_OUT_OF_MEMORY;
- smbc->send_buf = curlx_malloc(MAX_MESSAGE_SIZE);
- if(!smbc->send_buf)
- return CURLE_OUT_OF_MEMORY;
-
- /* Parse the username, domain, and password */
- slash = strchr(user, '/');
- if(!slash)
- slash = strchr(user, '\\');
-
- if(slash) {
- smbc->user = slash + 1;
- smbc->domain = curlx_strdup(user);
- if(!smbc->domain)
- return CURLE_OUT_OF_MEMORY;
- smbc->domain[slash - user] = 0;
- }
- else {
- smbc->user = user;
- smbc->domain = curlx_strdup(conn->origin->hostname);
- if(!smbc->domain)
- return CURLE_OUT_OF_MEMORY;
- }
-
- return CURLE_OK;
-}
-
-static CURLcode smb_recv_message(struct Curl_easy *data,
- struct smb_conn *smbc,
- void **msg)
-{
- char *buf = smbc->recv_buf;
- size_t bytes_read;
- size_t nbt_size;
- size_t msg_size = sizeof(struct smb_header);
- size_t len = MAX_MESSAGE_SIZE - smbc->got;
- CURLcode result;
-
- result = Curl_xfer_recv(data, buf + smbc->got, len, &bytes_read);
- if(result)
- return result;
-
- if(!bytes_read)
- return CURLE_OK;
-
- smbc->got += bytes_read;
-
- /* Check for a 32-bit nbt header */
- if(smbc->got < sizeof(unsigned int))
- return CURLE_OK;
-
- nbt_size = Curl_read16_be((const unsigned char *)
- (buf + sizeof(unsigned short))) +
- sizeof(unsigned int);
- if(nbt_size > MAX_MESSAGE_SIZE) {
- failf(data, "too large NetBIOS frame size %zu", nbt_size);
- return CURLE_RECV_ERROR;
- }
- else if(nbt_size < msg_size) {
- /* Each SMB message must be at least this large, e.g. 32 bytes */
- failf(data, "too small NetBIOS frame size %zu", nbt_size);
- return CURLE_RECV_ERROR;
- }
-
- if(smbc->got < nbt_size)
- return CURLE_OK;
-
- if(nbt_size >= msg_size + 1) {
- /* Add the word count */
- msg_size += 1 + (((unsigned char)buf[msg_size]) * sizeof(unsigned short));
- if(nbt_size >= msg_size + sizeof(unsigned short)) {
- /* Add the byte count */
- msg_size += sizeof(unsigned short) +
- Curl_read16_le((const unsigned char *)&buf[msg_size]);
- if(nbt_size < msg_size)
- return CURLE_RECV_ERROR;
- }
- }
-
- *msg = buf;
-
- return CURLE_OK;
-}
-
-static void smb_pop_message(struct smb_conn *smbc)
-{
- smbc->got = 0;
-}
-
-static void smb_format_message(struct smb_conn *smbc,
- struct smb_request *req,
- struct smb_header *h,
- unsigned char cmd, size_t len)
-{
- const unsigned int pid = 0xbad71d; /* made up */
-
- memset(h, 0, sizeof(*h));
- h->nbt_length = htons((unsigned short)(sizeof(*h) - sizeof(unsigned int) +
- len));
- memcpy((char *)h->magic, "\xffSMB", 4);
- h->command = cmd;
- h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES;
- h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME);
- h->uid = smb_swap16(smbc->uid);
- h->tid = smb_swap16(req->tid);
- h->pid_high = smb_swap16((unsigned short)(pid >> 16));
- h->pid = smb_swap16((unsigned short)pid);
-}
-
-static CURLcode smb_send(struct Curl_easy *data, struct smb_conn *smbc,
- size_t len, size_t upload_size)
-{
- size_t bytes_written;
- CURLcode result;
-
- result = Curl_xfer_send(data, smbc->send_buf, len, FALSE, &bytes_written);
- if(result)
- return result;
-
- if(bytes_written != len) {
- smbc->send_size = len;
- smbc->sent = bytes_written;
- }
-
- smbc->upload_size = upload_size;
-
- return CURLE_OK;
-}
-
-static CURLcode smb_flush(struct Curl_easy *data, struct smb_conn *smbc)
-{
- size_t bytes_written;
- size_t len = smbc->send_size - smbc->sent;
- CURLcode result;
-
- if(!smbc->send_size)
- return CURLE_OK;
-
- result = Curl_xfer_send(data, smbc->send_buf + smbc->sent, len, FALSE,
- &bytes_written);
- if(result)
- return result;
-
- if(bytes_written != len)
- smbc->sent += bytes_written;
- else
- smbc->send_size = 0;
-
- return CURLE_OK;
-}
-
-static CURLcode smb_send_message(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req,
- unsigned char cmd,
- const void *msg, size_t msg_len)
-{
- if((MAX_MESSAGE_SIZE - sizeof(struct smb_header)) < msg_len) {
- DEBUGASSERT(0);
- return CURLE_SEND_ERROR;
- }
- smb_format_message(smbc, req, (struct smb_header *)smbc->send_buf,
- cmd, msg_len);
- memcpy(smbc->send_buf + sizeof(struct smb_header), msg, msg_len);
-
- return smb_send(data, smbc, sizeof(struct smb_header) + msg_len, 0);
-}
-
-static CURLcode smb_send_negotiate(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- static const char msg[] = "\x00\x0c\x00\x02NT LM 0.12";
-
- return smb_send_message(data, smbc, req, SMB_COM_NEGOTIATE, msg,
- sizeof(msg));
-}
-
-static CURLcode smb_send_setup(struct Curl_easy *data)
-{
- struct connectdata *conn = data->conn;
- struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
- struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
- struct smb_setup msg;
- char *p = msg.bytes;
- unsigned char lm_hash[21];
- unsigned char lm[24];
- unsigned char nt_hash[21];
- unsigned char nt[24];
- size_t byte_count;
- const char *passwd = Curl_creds_passwd(conn->creds);
-
- if(!smbc || !req)
- return CURLE_FAILED_INIT;
-
- byte_count = sizeof(lm) + sizeof(nt) +
- strlen(smbc->user) + strlen(smbc->domain) +
- CURL_CSTRLEN(CURL_OS) + CURL_CSTRLEN(CLIENTNAME) + 4; /* 4 null chars */
- if(byte_count > sizeof(msg.bytes))
- return CURLE_FILESIZE_EXCEEDED;
-
- Curl_ntlm_core_mk_lm_hash(passwd, lm_hash);
- Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
- Curl_ntlm_core_mk_nt_hash(passwd, nt_hash);
- Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
-
- memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes));
- msg.word_count = SMB_WC_SETUP_ANDX;
- msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
- msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE);
- msg.max_mpx_count = smb_swap16(1);
- msg.vc_number = smb_swap16(1);
- msg.session_key = smb_swap32(smbc->session_key);
- msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES);
- msg.lengths[0] = smb_swap16(sizeof(lm));
- msg.lengths[1] = smb_swap16(sizeof(nt));
- memcpy(p, lm, sizeof(lm));
- p += sizeof(lm);
- memcpy(p, nt, sizeof(nt));
- p += sizeof(nt);
- p += curl_msnprintf(p, byte_count - sizeof(nt) - sizeof(lm),
- "%s%c" /* user */
- "%s%c" /* domain */
- "%s%c" /* OS */
- "%s", /* client name */
- smbc->user, 0, smbc->domain, 0, CURL_OS, 0, CLIENTNAME);
- p++; /* count the final null-termination */
- DEBUGASSERT(byte_count == (size_t)(p - msg.bytes));
- msg.byte_count = smb_swap16((unsigned short)byte_count);
-
- return smb_send_message(data, smbc, req, SMB_COM_SETUP_ANDX, &msg,
- sizeof(msg) - sizeof(msg.bytes) + byte_count);
-}
-
-static CURLcode smb_send_tree_connect(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- struct smb_tree_connect msg;
- struct connectdata *conn = data->conn;
- char *p = msg.bytes;
- const size_t byte_count = strlen(conn->origin->hostname) +
- strlen(smbc->share) +
- CURL_CSTRLEN(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
-
- if(byte_count > sizeof(msg.bytes))
- return CURLE_FILESIZE_EXCEEDED;
-
- memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes));
- msg.word_count = SMB_WC_TREE_CONNECT_ANDX;
- msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
- msg.pw_len = 0;
-
- p += curl_msnprintf(p, byte_count,
- "\\\\%s\\" /* hostname */
- "%s%c" /* share */
- "%s", /* service */
- conn->origin->hostname, smbc->share, 0, SERVICENAME);
- p++; /* count the final null-termination */
- DEBUGASSERT(byte_count == (size_t)(p - msg.bytes));
- msg.byte_count = smb_swap16((unsigned short)byte_count);
-
- return smb_send_message(data, smbc, req, SMB_COM_TREE_CONNECT_ANDX, &msg,
- sizeof(msg) - sizeof(msg.bytes) + byte_count);
-}
-
-static CURLcode smb_send_open(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- struct smb_nt_create msg;
- const size_t byte_count = strlen(req->path) + 1;
-
- if(byte_count > sizeof(msg.bytes))
- return CURLE_FILESIZE_EXCEEDED;
-
- memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes));
- msg.word_count = SMB_WC_NT_CREATE_ANDX;
- msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
- msg.name_length = smb_swap16((unsigned short)(byte_count - 1));
- msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
- if(data->state.upload) {
- msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
- msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
- }
- else {
- msg.access = smb_swap32(SMB_GENERIC_READ);
- msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
- }
- msg.byte_count = smb_swap16((unsigned short)byte_count);
- curlx_strcopy(msg.bytes, sizeof(msg.bytes), req->path, byte_count - 1);
-
- return smb_send_message(data, smbc, req, SMB_COM_NT_CREATE_ANDX, &msg,
- sizeof(msg) - sizeof(msg.bytes) + byte_count);
-}
-
-static CURLcode smb_send_close(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- struct smb_close msg;
-
- memset(&msg, 0, sizeof(msg));
- msg.word_count = SMB_WC_CLOSE;
- msg.fid = smb_swap16(req->fid);
-
- return smb_send_message(data, smbc, req, SMB_COM_CLOSE, &msg, sizeof(msg));
-}
-
-static CURLcode smb_send_tree_disconnect(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- struct smb_tree_disconnect msg;
- memset(&msg, 0, sizeof(msg));
- return smb_send_message(data, smbc, req, SMB_COM_TREE_DISCONNECT,
- &msg, sizeof(msg));
-}
-
-static CURLcode smb_send_read(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- curl_off_t offset = data->req.offset;
- struct smb_read msg;
-
- memset(&msg, 0, sizeof(msg));
- msg.word_count = SMB_WC_READ_ANDX;
- msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
- msg.fid = smb_swap16(req->fid);
- msg.offset = smb_swap32((unsigned int)offset);
- msg.offset_high = smb_swap32((unsigned int)(offset >> 32));
- msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
- msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
-
- return smb_send_message(data, smbc, req, SMB_COM_READ_ANDX,
- &msg, sizeof(msg));
-}
-
-static CURLcode smb_send_write(struct Curl_easy *data,
- struct smb_conn *smbc,
- struct smb_request *req)
-{
- struct smb_write *msg;
- curl_off_t offset = data->req.offset;
- curl_off_t upload_size = data->req.size - data->req.bytecount;
-
- msg = (struct smb_write *)smbc->send_buf;
- if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
- upload_size = MAX_PAYLOAD_SIZE - 1;
-
- memset(msg, 0, sizeof(*msg));
- msg->word_count = SMB_WC_WRITE_ANDX;
- msg->andx.command = SMB_COM_NO_ANDX_COMMAND;
- msg->fid = smb_swap16(req->fid);
- msg->offset = smb_swap32((unsigned int)offset);
- msg->offset_high = smb_swap32((unsigned int)(offset >> 32));
- msg->data_length = smb_swap16((unsigned short)upload_size);
- msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
- msg->byte_count = smb_swap16((unsigned short)(upload_size + 1));
-
- smb_format_message(smbc, req, &msg->h, SMB_COM_WRITE_ANDX,
- sizeof(*msg) - sizeof(msg->h) + (size_t)upload_size);
-
- return smb_send(data, smbc, sizeof(*msg), (size_t)upload_size);
-}
-
-static CURLcode smb_send_and_recv(struct Curl_easy *data,
- struct smb_conn *smbc, void **msg)
-{
- CURLcode result;
- *msg = NULL; /* if it returns early */
-
- /* Check if there is data in the transfer buffer */
- if(!smbc->send_size && smbc->upload_size) {
- size_t nread = smbc->upload_size > (size_t)MAX_MESSAGE_SIZE ?
- (size_t)MAX_MESSAGE_SIZE : smbc->upload_size;
- bool eos;
-
- result = Curl_client_read(data, smbc->send_buf, nread, &nread, &eos);
- if(result && result != CURLE_AGAIN)
- return result;
- if(!nread)
- return CURLE_OK;
-
- smbc->upload_size -= nread;
- smbc->send_size = nread;
- smbc->sent = 0;
- }
-
- /* Check if there is data to send */
- if(smbc->send_size) {
- result = smb_flush(data, smbc);
- if(result)
- return result;
- }
-
- /* Check if there is still data to be sent */
- if(smbc->send_size || smbc->upload_size)
- return CURLE_AGAIN;
-
- return smb_recv_message(data, smbc, msg);
-}
-
-static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
-{
- struct connectdata *conn = data->conn;
- struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
- struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
- struct smb_negotiate_response *nrsp;
- struct smb_header *h;
- CURLcode result;
- void *msg = NULL;
-
- if(!smbc || !req)
- return CURLE_FAILED_INIT;
-
- if(smbc->state == SMB_CONNECTING) {
-#ifdef USE_SSL
- if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) {
- bool ssl_done = FALSE;
- result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssl_done);
- if(result && result != CURLE_AGAIN)
- return result;
- if(!ssl_done)
- return CURLE_OK;
- }
-#endif
-
- result = smb_send_negotiate(data, smbc, req);
- if(result) {
- CURL_TRC_M(data, "SMB: failed to send negotiate message");
- connclose(conn);
- return result;
- }
-
- conn_state(data, smbc, SMB_NEGOTIATE);
- }
-
- /* Send the previous message and check for a response */
- result = smb_send_and_recv(data, smbc, &msg);
- if(result && result != CURLE_AGAIN) {
- CURL_TRC_M(data, "SMB: failed to communicate");
- connclose(conn);
- return result;
- }
-
- if(!msg)
- return CURLE_OK;
-
- h = msg;
-
- switch(smbc->state) {
- case SMB_NEGOTIATE:
- if((smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) ||
- h->status) {
- CURL_TRC_M(data, "SMB: negotiation failed");
- connclose(conn);
- return CURLE_COULDNT_CONNECT;
- }
- nrsp = msg;
-#if defined(__GNUC__) && __GNUC__ >= 13
-#pragma GCC diagnostic push
-/* error: 'memcpy' offset [74, 80] from the object at '<unknown>' is out of
- the bounds of referenced subobject 'bytes' with type 'char[1]' */
-#pragma GCC diagnostic ignored "-Warray-bounds"
-#endif
- memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
-#if defined(__GNUC__) && __GNUC__ >= 13
-#pragma GCC diagnostic pop
-#endif
- smbc->session_key = smb_swap32(nrsp->session_key);
- result = smb_send_setup(data);
- if(result) {
- CURL_TRC_M(data, "SMB: failed to send setup message");
- connclose(conn);
- return result;
- }
- conn_state(data, smbc, SMB_SETUP);
- break;
-
- case SMB_SETUP:
- if(h->status) {
- CURL_TRC_M(data, "SMB: authentication failed");
- connclose(conn);
- return CURLE_LOGIN_DENIED;
- }
- smbc->uid = smb_swap16(h->uid);
- conn_state(data, smbc, SMB_CONNECTED);
- *done = TRUE;
- break;
-
- default:
- smb_pop_message(smbc);
- return CURLE_OK; /* ignore */
- }
-
- smb_pop_message(smbc);
-
- return CURLE_OK;
-}
-
-/*
- * Convert a timestamp from the Windows world (100 nsec units from 1 Jan 1601)
- * to POSIX time. Cap the output to fit within a time_t.
- */
-static void get_posix_time(time_t *out, curl_off_t timestamp)
-{
- if(timestamp >= (curl_off_t)116444736000000000) {
- timestamp -= (curl_off_t)116444736000000000;
- timestamp /= 10000000;
-#if SIZEOF_TIME_T < SIZEOF_CURL_OFF_T
- if(timestamp > TIME_T_MAX)
- *out = TIME_T_MAX;
- else if(timestamp < TIME_T_MIN)
- *out = TIME_T_MIN;
- else
-#endif
- *out = (time_t)timestamp;
- }
- else
- *out = 0;
-}
-
-static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
-{
- struct connectdata *conn = data->conn;
- struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
- struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
- struct smb_header *h;
- enum smb_req_state next_state = SMB_DONE;
- size_t len;
- size_t off;
- CURLcode result;
- void *msg = NULL;
- const struct smb_nt_create_response *smb_m;
-
- if(!smbc || !req)
- return CURLE_FAILED_INIT;
-
- if(data->state.upload && (data->state.infilesize < 0)) {
- failf(data, "SMB upload needs to know the size up front");
- return CURLE_SEND_ERROR;
- }
-
- /* Start the request */
- if(req->state == SMB_REQUESTING) {
- result = smb_send_tree_connect(data, smbc, req);
- if(result) {
- CURL_TRC_M(data, "SMB: failed to send tree connect message");
- connclose(conn);
- return result;
- }
-
- request_state(data, SMB_TREE_CONNECT);
- }
-
- /* Send the previous message and check for a response */
- result = smb_send_and_recv(data, smbc, &msg);
- if(result && result != CURLE_AGAIN) {
- CURL_TRC_M(data, "SMB: failed to communicate");
- connclose(conn);
- return result;
- }
-
- if(!msg)
- return CURLE_OK;
-
- h = msg;
-
- switch(req->state) {
- case SMB_TREE_CONNECT:
- if(h->status) {
- req->result = CURLE_REMOTE_FILE_NOT_FOUND;
- if(h->status == smb_swap32(SMB_ERR_NOACCESS))
- req->result = CURLE_REMOTE_ACCESS_DENIED;
- break;
- }
- req->tid = smb_swap16(h->tid);
- next_state = SMB_OPEN;
- break;
-
- case SMB_OPEN:
- if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) {
- req->result = CURLE_REMOTE_FILE_NOT_FOUND;
- if(h->status == smb_swap32(SMB_ERR_NOACCESS))
- req->result = CURLE_REMOTE_ACCESS_DENIED;
- next_state = SMB_TREE_DISCONNECT;
- break;
- }
- smb_m = (const struct smb_nt_create_response *)msg;
- req->fid = smb_swap16(smb_m->fid);
- data->req.offset = 0;
- if(data->state.upload) {
- data->req.size = data->state.infilesize;
- Curl_pgrsSetUploadSize(data, data->req.size);
- next_state = SMB_UPLOAD;
- }
- else {
- data->req.size = smb_swap64(smb_m->end_of_file);
- if(data->req.size < 0) {
- req->result = CURLE_WEIRD_SERVER_REPLY;
- next_state = SMB_CLOSE;
- }
- else {
- Curl_pgrsSetDownloadSize(data, data->req.size);
- if(data->set.get_filetime)
- get_posix_time(&data->info.filetime, smb_m->last_change_time);
- next_state = SMB_DOWNLOAD;
- }
- }
- break;
-
- case SMB_DOWNLOAD:
- if(h->status || smbc->got < sizeof(struct smb_header) + 15) {
- req->result = CURLE_RECV_ERROR;
- next_state = SMB_CLOSE;
- break;
- }
- len = Curl_read16_le((const unsigned char *)msg +
- sizeof(struct smb_header) + 11);
- off = Curl_read16_le((const unsigned char *)msg +
- sizeof(struct smb_header) + 13);
- if(len > 0) {
- if(off + sizeof(unsigned int) + len > smbc->got) {
- failf(data, "Invalid input packet");
- result = CURLE_RECV_ERROR;
- }
- else
- result = Curl_client_write(data, CLIENTWRITE_BODY,
- (char *)msg + off + sizeof(unsigned int),
- len);
- if(result) {
- req->result = result;
- next_state = SMB_CLOSE;
- break;
- }
- }
- data->req.offset += len;
- next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
- break;
-
- case SMB_UPLOAD:
- if(h->status || smbc->got < sizeof(struct smb_header) + 7) {
- req->result = CURLE_UPLOAD_FAILED;
- next_state = SMB_CLOSE;
- break;
- }
- len = Curl_read16_le((const unsigned char *)msg +
- sizeof(struct smb_header) + 5);
- data->req.bytecount += len;
- data->req.offset += len;
- Curl_pgrs_upload_inc(data, len);
- if(data->req.bytecount >= data->req.size)
- next_state = SMB_CLOSE;
- else
- next_state = SMB_UPLOAD;
- break;
-
- case SMB_CLOSE:
- /* We do not care if the close failed, proceed to tree disconnect anyway */
- next_state = SMB_TREE_DISCONNECT;
- break;
-
- case SMB_TREE_DISCONNECT:
- next_state = SMB_DONE;
- break;
-
- default:
- smb_pop_message(smbc);
- return CURLE_OK; /* ignore */
- }
-
- smb_pop_message(smbc);
-
- switch(next_state) {
- case SMB_OPEN:
- result = smb_send_open(data, smbc, req);
- break;
-
- case SMB_DOWNLOAD:
- result = smb_send_read(data, smbc, req);
- break;
-
- case SMB_UPLOAD:
- result = smb_send_write(data, smbc, req);
- break;
-
- case SMB_CLOSE:
- result = smb_send_close(data, smbc, req);
- break;
-
- case SMB_TREE_DISCONNECT:
- result = smb_send_tree_disconnect(data, smbc, req);
- break;
-
- case SMB_DONE:
- result = req->result;
- *done = TRUE;
- break;
-
- default:
- break;
- }
-
- if(result) {
- CURL_TRC_M(data, "SMB: failed to send message");
- connclose(conn);
- return result;
- }
-
- request_state(data, next_state);
-
- return CURLE_OK;
-}
-
-static CURLcode smb_pollset(struct Curl_easy *data,
- struct easy_pollset *ps)
-{
- return Curl_pollset_add_inout(data, ps, data->conn->sock[FIRSTSOCKET]);
-}
-
-static CURLcode smb_do(struct Curl_easy *data, bool *done)
-{
- struct connectdata *conn = data->conn;
- struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
-
- *done = FALSE;
- if(!smbc)
- return CURLE_FAILED_INIT;
- if(smbc->share)
- return CURLE_OK;
- return CURLE_URL_MALFORMAT;
-}
-
-/*
- * SMB handler interface
- */
-const struct Curl_protocol Curl_protocol_smb = {
- smb_setup_connection, /* setup_connection */
- smb_do, /* do_it */
- ZERO_NULL, /* done */
- ZERO_NULL, /* do_more */
- smb_connect, /* connect_it */
- smb_connection_state, /* connecting */
- smb_request_state, /* doing */
- smb_pollset, /* proto_pollset */
- smb_pollset, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- ZERO_NULL, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_is_dead */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
-};
-
-#endif /* CURL_ENABLE_SMB && USE_CURL_NTLM_CORE */
lib/smb.h+0 -31
@@ -1,31 +0,0 @@
-#ifndef HEADER_CURL_SMB_H
-#define HEADER_CURL_SMB_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Bill Nagel <[email protected]>, Exacq Technologies
- * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE)
-extern const struct Curl_protocol Curl_protocol_smb;
-#endif
-
-#endif /* HEADER_CURL_SMB_H */
lib/urldata.h+0 -1
@@ -93,7 +93,6 @@ typedef CURLcode (Curl_recv)(struct Curl_easy *data, /* transfer */
#include "protocol.h"
#include "ftp.h"
#include "http.h"
-#include "smb.h"
#include "mqtt.h"
#include "ftplistparser.h"
#include "multihandle.h"
lib/version.c+0 -6
@@ -345,12 +345,6 @@ static const char * const supported_protocols[] = {
"scp",
"sftp",
#endif
-#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE)
- "smb",
-# ifdef USE_SSL
- "smbs",
-# endif
-#endif
#ifndef CURL_DISABLE_SMTP
"smtp",
#endif
projects/OS400/README.OS400+0 -1
@@ -257,7 +257,6 @@ _ POP3
_ RTSP
_ SCP if libssh2 is enabled
_ SFTP if libssh2 is enabled
-_ SMB
_ SMTP
_ TELNET
_ TFTP
scripts/cd2nroff+0 -2
@@ -175,8 +175,6 @@ my %knownprotos = (
'RTSP' => 1,
'SCP' => 1,
'SFTP' => 1,
- 'SMB' => 1,
- 'SMBS' => 1,
'SMTP' => 1,
'SMTPS' => 1,
'TELNET' => 1,
tests/Makefile.am+0 -2
@@ -66,14 +66,12 @@ EXTRA_DIST = \
nghttpx.conf \
pathhelp.pm \
processhelp.pm \
- requirements.txt \
rtspserver.pl \
runner.pm \
runtests.pl \
secureserver.pl \
serverhelp.pm \
servers.pm \
- smbserver.py \
sshhelp.pm \
sshserver.pl \
testcurl.pl \
tests/data/Makefile.am+0 -5
@@ -25,9 +25,6 @@ all:
install:
test:
-# The helper script ./scripts/testnum provides a set of available test
-# numbers.
-
# this list is in numerical order
TESTCASES = \
test1 \
@@ -1472,7 +1469,6 @@ TESTCASES = \
test1448 \
test1449 \
test1450 \
- test1451 \
test1452 \
test1453 \
test1454 \
@@ -1740,7 +1736,6 @@ TESTCASES = \
test1847 \
test1848 \
test1849 \
- test1850 \
test1851 \
test1862 \
test1900 \
tests/data/test1451+0 -38
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="US-ASCII"?>
-<testcase>
-<info>
-<keywords>
-SMB
-</keywords>
-</info>
-
-# Server-side
-<reply>
-<data nocheck="yes">
-Basic SMB test complete
-</data>
-</reply>
-
-# Client-side
-<client>
-<server>
-smb
-</server>
-<features>
-smb
-</features>
-<name>
-Basic SMB request
-</name>
-<command>
--u 'curltest:curltest' smb://%HOSTIP:%SMBPORT/TESTS/%TESTNUMBER
-</command>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-<stdout>
-Basic SMB test complete
-</stdout>
-</verify>
-</testcase>
tests/data/test1627+1 -1
@@ -18,7 +18,7 @@ Curl_get_scheme unit test
<verify>
<stdout mode="text">
-547 invokes
+541 invokes
</stdout>
</verify>
</testcase>
tests/data/test1850+0 -39
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="US-ASCII"?>
-<testcase>
-<info>
-<keywords>
-SMB
-</keywords>
-</info>
-
-# Server-side
-<reply>
-<data nocheck="yes">
-Basic SMB test complete
-</data>
-</reply>
-
-# Client-side
-<client>
-<server>
-smb
-</server>
-<features>
-smb
-</features>
-<name>
-Two SMB requests in the same command line
-</name>
-<command>
--u 'curltest:curltest' smb://%HOSTIP:%SMBPORT/TESTS/%TESTNUMBER smb://%HOSTIP:%SMBPORT/TESTS/%TESTNUMBER
-</command>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-<stdout>
-Basic SMB test complete
-Basic SMB test complete
-</stdout>
-</verify>
-</testcase>
tests/requirements.txt+0 -5
@@ -1,5 +0,0 @@
-# Copyright (C) Daniel Stenberg, <[email protected]>, et al.
-#
-# SPDX-License-Identifier: curl
-
-impacket==0.13.1
tests/serverhelp.pm+1 -1
@@ -123,7 +123,7 @@ sub servername_str {
$proto = uc($proto) if($proto);
die "unsupported protocol: '$proto'" unless($proto &&
- ($proto =~ /^(((DNS|FTP|HTTP|HTTP\/2|HTTP\/3|IMAP|POP3|GOPHER|SMTP|HTTPS-MTLS)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|DICT|SMB|SMBS|TELNET|MQTT|MQTTS))$/));
+ ($proto =~ /^(((DNS|FTP|HTTP|HTTP\/2|HTTP\/3|IMAP|POP3|GOPHER|SMTP|HTTPS-MTLS)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|DICT|TELNET|MQTT|MQTTS))$/));
$ipver = (not $ipver) ? 'ipv4' : lc($ipver);
die "unsupported IP version: '$ipver'" unless($ipver &&
tests/servers.pm+1 -135
@@ -235,7 +235,7 @@ sub init_serverpidfile_hash {
}
}
for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp',
- 'dict', 'smb', 'smbs', 'telnet', 'mqtt', 'mqtts',
+ 'dict', 'telnet', 'mqtt', 'mqtts',
'https-mtls', 'dns')) {
for my $ipvnum ((4, 6)) {
for my $idnum ((1, 2)) {
@@ -797,66 +797,6 @@ sub verifypid {
return $pid;
}
-#######################################################################
-# Verify that the server that runs on $ip, $port is our server. This also
-# implies that we can speak with it, as there might be occasions when the
-# server runs fine but we cannot talk to it ("Failed to connect to ::1: Cannot
-# assign requested address")
-#
-sub verifysmb {
- my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
- my $server = servername_id($proto, $ipvnum, $idnum);
- my $time = time();
- my $extra = "";
-
- my $verifylog = "$LOGDIR/".
- servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
- unlink($verifylog) if(-f $verifylog);
-
- my $flags = "--max-time $server_response_maxtime ";
- $flags .= "--silent ";
- $flags .= "--verbose ";
- $flags .= "--globoff ";
- $flags .= "-u 'curltest:curltest' ";
- $flags .= $extra;
- $flags .= "\"$proto://$ip:$port/SERVER/verifiedserver\"";
-
- my $cmd = exerunner() . "$VCURL $flags 2>$verifylog";
-
- # check if this is our server running on this port:
- logmsg "RUN: $cmd\n" if($verbose);
- my @data = runclientoutput($cmd);
-
- my $res = $? >> 8; # rotate the result
- if($res & 128) {
- logmsg "RUN: curl command died with a coredump\n";
- return -1;
- }
-
- my $pid = 0;
- foreach my $line (@data) {
- if($line =~ /WE ROOLZ: (\d+)/) {
- # this is our test server with a known pid!
- $pid = 0+$1;
- last;
- }
- }
- if($pid <= 0 && @data && $data[0]) {
- # this is not a known server
- logmsg "RUN: Unknown server on our $server port: $port\n";
- return 0;
- }
- # we can/should use the time it took to verify the server as a measure
- # on how fast/slow this host is.
- my $took = int(0.5+time()-$time);
-
- if($verbose) {
- logmsg "RUN: Verifying our test $server server took $took seconds\n";
- }
-
- return $pid;
-}
-
#######################################################################
# Verify that the server that runs on $ip, $port is our server. This also
# implies that we can speak with it, as there might be occasions when the
@@ -950,7 +890,6 @@ my %protofunc = ('http' => \&verifyhttp,
'socks5unix' => \&verifypid,
'gopher' => \&verifyhttp,
'dict' => \&verifyftp,
- 'smb' => \&verifysmb,
'telnet' => \&verifytelnet);
#######################################################################
@@ -1973,67 +1912,6 @@ sub rundictserver {
return (0+!$dictpid, $dictpid, $pid2, $port);
}
-#######################################################################
-# start the SMB server
-#
-sub runsmbserver {
- my ($verb, $alt) = @_;
- my $proto = "smb";
- my $ip = $HOSTIP;
- my $ipvnum = 4;
- my $idnum = 1;
-
- if($alt eq "ipv6") {
- # No IPv6
- }
-
- my $server = servername_id($proto, $ipvnum, $idnum);
-
- my $pidfile = $serverpidfile{$server};
-
- # do not retry if the server does not work
- if($doesntrun{$pidfile}) {
- return (2, 0, 0, 0);
- }
-
- my $pid = processexists($pidfile);
- if($pid > 0) {
- stopserver($server, $pid);
- }
- unlink($pidfile) if(-f $pidfile);
-
- my $srvrname = servername_str($proto, $ipvnum, $idnum);
- my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
-
- my $flags = "";
- $flags .= "--verbose 1 " if($debugprotocol);
- $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
- $flags .= "--id $idnum " if($idnum > 1);
- $flags .= "--srcdir \"$srcdir\" ";
- $flags .= "--host $HOSTIP";
-
- my $port = getfreeport($ipvnum);
- my $aflags = "--port $port $flags";
- my $cmd = "$srcdir/smbserver.py $aflags";
- my ($smbpid, $pid2) = startnew($cmd, $pidfile, 15, 0);
-
- if($smbpid <= 0 || !pidexists($smbpid)) {
- # it is NOT alive
- stopserver($server, $pid2);
- $doesntrun{$pidfile} = 1;
- $smbpid = $pid2 = 0;
- logmsg "RUN: failed to start the $srvrname server\n";
- return (3, 0, 0, 0);
- }
- $doesntrun{$pidfile} = 0;
-
- if($verb) {
- logmsg "RUN: $srvrname server PID $smbpid port $port\n";
- }
-
- return (0+!$smbpid, $smbpid, $pid2, $port);
-}
-
#######################################################################
# start the telnet server
#
@@ -2817,17 +2695,6 @@ sub startservers {
$run{'dict'} = "$pid $pid2";
}
}
- elsif($what eq "smb") {
- if(!$run{'smb'}) {
- ($serr, $pid, $pid2, $PORT{"smb"}) = runsmbserver($verbose, "");
- if($pid <= 0) {
- return ("failed starting SMB server", $serr);
- }
- logmsg sprintf ("* pid SMB => %d %d\n", $pid, $pid2)
- if($verbose);
- $run{'smb'} = "$pid $pid2";
- }
- }
elsif($what eq "telnet") {
if(!$run{'telnet'}) {
($serr, $pid, $pid2, $PORT{"telnet"}) =
@@ -2930,7 +2797,6 @@ sub subvariables {
'NOLISTEN',
'POP3', 'POP36', 'POP3S',
'RTSP', 'RTSP6',
- 'SMB', 'SMBS',
'SMTP', 'SMTP6', 'SMTPS',
'SOCKS',
'SSH',
tests/smbserver.py+0 -440
@@ -1,440 +0,0 @@
-#!/usr/bin/env python3
-#
-# Project ___| | | | _ \| |
-# / __| | | | |_) | |
-# | (__| |_| | _ <| |___
-# \___|\___/|_| \_\_____|
-#
-# Copyright (C) Daniel Stenberg, <[email protected]>, et al.
-#
-# This software is licensed as described in the file COPYING, which
-# you should have received as part of this distribution. The terms
-# are also available at https://curl.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-# SPDX-License-Identifier: curl
-#
-"""Server for testing SMB."""
-
-import argparse
-import configparser
-import importlib.util
-import logging
-import os
-import signal
-import sys
-import tempfile
-import threading
-
-# Import our curl test data helper
-from util import ClosingFileHandler, TestData
-
-# impacket needs to be installed in the Python environment
-if importlib.util.find_spec('impacket') is None:
- sys.stderr.write(
- 'Warning: Python package impacket is required for smb testing; '
- 'use pip or your package manager to install it\n')
- sys.exit(1)
-
-from impacket import smb as imp_smb
-from impacket import smbserver as imp_smbserver
-from impacket.nt_errors import STATUS_ACCESS_DENIED, STATUS_NO_SUCH_FILE, STATUS_SUCCESS
-
-log = logging.getLogger(__name__)
-SERVER_MAGIC = "SERVER_MAGIC"
-TESTS_MAGIC = "TESTS_MAGIC"
-VERIFIED_REQ = "verifiedserver"
-VERIFIED_RSP = "WE ROOLZ: {pid}\n"
-
-
-class ShutdownHandler(threading.Thread):
- """
- Cleanly shut down the SMB server.
-
- This can only be done from another thread while the server is in
- serve_forever(), so a thread is spawned here that waits for a shutdown
- signal before doing its thing. Use in a with statement around the
- serve_forever() call.
- """
-
- def __init__(self, server):
- super().__init__()
- self.server = server
- self.shutdown_event = threading.Event()
-
- def __enter__(self):
- self.start()
- signal.signal(signal.SIGINT, self._sighandler)
- signal.signal(signal.SIGTERM, self._sighandler)
-
- def __exit__(self, *_):
- # Call for shutdown in case it was not done already
- self.shutdown_event.set()
- # Wait for thread, and therefore also the server, to finish
- self.join()
- # Uninstall our signal handlers
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- signal.signal(signal.SIGTERM, signal.SIG_DFL)
- # Delete any temporary files created by the server during its run
- log.info("Deleting %d temporary file(s)", len(self.server.tmpfiles))
- for f in self.server.tmpfiles:
- os.unlink(f)
-
- def _sighandler(self, _signum, _frame):
- # Wake up the cleanup task
- self.shutdown_event.set()
-
- def run(self):
- # Wait for shutdown signal
- self.shutdown_event.wait()
- # Notify the server to shut down
- self.server.shutdown()
-
-
-def smbserver(options):
- """Start up a TCP SMB server that serves forever."""
- if options.pidfile:
- pid = os.getpid()
- # see tests/server/util.c function write_pidfile
- if os.name == "nt":
- pid += 4194304
- with open(options.pidfile, "w") as f:
- f.write(str(pid))
-
- # Here we write a mini config for the server
- smb_config = configparser.ConfigParser()
- smb_config.add_section("global")
- smb_config.set("global", "server_name", "SERVICE")
- smb_config.set("global", "server_os", "UNIX")
- smb_config.set("global", "server_domain", "WORKGROUP")
- smb_config.set("global", "log_file", "None")
- smb_config.set("global", "credentials_file", "")
-
- # We need a share which allows us to test that the server is running
- smb_config.add_section("SERVER")
- smb_config.set("SERVER", "comment", "server function")
- smb_config.set("SERVER", "read only", "yes")
- smb_config.set("SERVER", "share type", "0")
- smb_config.set("SERVER", "path", SERVER_MAGIC)
-
- # Have a share for tests. These files are auto-generated from the
- # test input.
- smb_config.add_section("TESTS")
- smb_config.set("TESTS", "comment", "tests")
- smb_config.set("TESTS", "read only", "yes")
- smb_config.set("TESTS", "share type", "0")
- smb_config.set("TESTS", "path", TESTS_MAGIC)
-
- if not options.srcdir or not os.path.isdir(options.srcdir):
- raise ScriptError("--srcdir is mandatory")
-
- test_data_dir = os.path.join(options.srcdir, "data")
-
- smb_server = TestSmbServer((options.host, options.port),
- config_parser=smb_config,
- test_data_directory=test_data_dir)
- log.info("[SMB] setting up SMB server on port %s", options.port)
- smb_server.processConfigFile()
-
- # Start a thread that cleanly shuts down the server on a signal
- with ShutdownHandler(smb_server):
- # This blocks until smb_server.shutdown() is called
- smb_server.serve_forever()
-
- return 0
-
-
-class TestSmbServer(imp_smbserver.SMBSERVER):
- """
- Test server for SMB.
-
- It subclasses the impacket SMBSERVER and provides test functionality.
- """
-
- def __init__(self,
- address,
- config_parser=None,
- test_data_directory=None):
- imp_smbserver.SMBSERVER.__init__(self,
- address,
- config_parser=config_parser)
- self.tmpfiles = []
-
- # Set up a test data object so we can get test data later.
- self.ctd = TestData(test_data_directory)
-
- # Override smbComNtCreateAndX so we can pretend to have files which
- # do not exist.
- self.hookSmbCommand(imp_smb.SMB.SMB_COM_NT_CREATE_ANDX,
- self.create_and_x)
-
- def create_and_x(self, conn_id, smb_server, smb_command, recv_packet):
- """
- Our version of smbComNtCreateAndX.
-
- It looks for special test files and fools the rest of the framework
- into opening them as if they were normal files.
- """
- conn_data = smb_server.getConnectionData(conn_id)
-
- # Wrap processing in a try block which allows us to throw SmbError
- # to control the flow.
- try:
- ncax_params = imp_smb.SMBNtCreateAndX_Parameters(
- smb_command["Parameters"])
-
- path = self.get_share_path(conn_data,
- ncax_params["RootFid"],
- recv_packet["Tid"])
- log.info("[SMB] Requested share path: %s", path)
-
- disposition = ncax_params["Disposition"]
- log.debug("[SMB] Requested disposition: %s", disposition)
-
- # Currently we only support reading files.
- if disposition != imp_smb.FILE_OPEN:
- raise SmbError(STATUS_ACCESS_DENIED, "Only support reading files")
-
- # Check to see if the path we were given is actually a
- # magic path which needs generating on the fly.
- if path not in [SERVER_MAGIC, TESTS_MAGIC]:
- # Pass the command onto the original handler.
- return imp_smbserver.SMBCommands.smbComNtCreateAndX(conn_id,
- smb_server,
- smb_command,
- recv_packet)
-
- flags2 = recv_packet["Flags2"]
- ncax_data = imp_smb.SMBNtCreateAndX_Data(flags=flags2,
- data=smb_command["Data"])
- requested_file = imp_smbserver.decodeSMBString(
- flags2,
- ncax_data["FileName"])
- log.debug("[SMB] User requested file '%s'", requested_file)
-
- if path == SERVER_MAGIC:
- fid, full_path = self.get_server_path(requested_file)
- else:
- assert path == TESTS_MAGIC
- fid, full_path = self.get_test_path(requested_file)
-
- self.tmpfiles.append(full_path)
-
- resp_params = imp_smb.SMBNtCreateAndXResponse_Parameters()
- resp_data = ""
-
- # Simple way to generate a fid
- if len(conn_data["OpenedFiles"]) == 0:
- fakefid = 1
- else:
- fakefid = max(conn_data["OpenedFiles"].keys()) + 1
- resp_params["Fid"] = fakefid
- resp_params["CreateAction"] = disposition
-
- if os.path.isdir(path):
- resp_params[
- "FileAttributes"] = imp_smb.SMB_FILE_ATTRIBUTE_DIRECTORY
- resp_params["IsDirectory"] = 1
- else:
- resp_params["IsDirectory"] = 0
- resp_params["FileAttributes"] = ncax_params["FileAttributes"]
-
- # Get this file's information
- resp_info, error_code = imp_smbserver.queryPathInformation(
- os.path.dirname(full_path), os.path.basename(full_path),
- level=imp_smb.SMB_QUERY_FILE_ALL_INFO)
-
- if error_code != STATUS_SUCCESS:
- raise SmbError(error_code, "Failed to query path info")
-
- resp_params["CreateTime"] = resp_info["CreationTime"]
- resp_params["LastAccessTime"] = resp_info[
- "LastAccessTime"]
- resp_params["LastWriteTime"] = resp_info["LastWriteTime"]
- resp_params["LastChangeTime"] = resp_info[
- "LastChangeTime"]
- resp_params["FileAttributes"] = resp_info[
- "ExtFileAttributes"]
- resp_params["AllocationSize"] = resp_info[
- "AllocationSize"]
- resp_params["EndOfFile"] = resp_info["EndOfFile"]
-
- # Let's store the fid for the connection
- # smbServer.log("Create file %s, mode:0x%x" % (pathName, mode))
- conn_data["OpenedFiles"][fakefid] = {}
- conn_data["OpenedFiles"][fakefid]["FileHandle"] = fid
- conn_data["OpenedFiles"][fakefid]["FileName"] = path
- conn_data["OpenedFiles"][fakefid]["DeleteOnClose"] = False
-
- except SmbError as s:
- log.debug("[SMB] SmbError hit: %s", s)
- error_code = s.error_code
- resp_params = ""
- resp_data = ""
-
- resp_cmd = imp_smb.SMBCommand(imp_smb.SMB.SMB_COM_NT_CREATE_ANDX)
- resp_cmd["Parameters"] = resp_params
- resp_cmd["Data"] = resp_data
- smb_server.setConnectionData(conn_id, conn_data)
-
- return [resp_cmd], None, error_code
-
- def get_share_path(self, conn_data, root_fid, tid):
- conn_shares = conn_data["ConnectedShares"]
-
- if tid in conn_shares:
- if root_fid > 0:
- # If we have a rootFid, the path is relative to that fid
- path = conn_data["OpenedFiles"][root_fid]["FileName"]
- log.debug(f'RootFid present {path}!')
- return path
-
- if "path" in conn_shares[tid]:
- return conn_shares[tid]["path"]
-
- raise SmbError(STATUS_ACCESS_DENIED, "Connection share had no path")
- raise SmbError(imp_smbserver.STATUS_SMB_BAD_TID, "TID was invalid")
-
- def get_server_path(self, requested_filename):
- log.debug("[SMB] Get server path '%s'", requested_filename)
-
- if requested_filename != VERIFIED_REQ:
- raise SmbError(STATUS_NO_SUCH_FILE, "Could not find the file")
-
- fid, filename = tempfile.mkstemp()
- log.debug("[SMB] Created %s (%d) for storing '%s'",
- filename, fid, requested_filename)
-
- contents = b''
-
- if requested_filename == VERIFIED_REQ:
- log.debug("[SMB] Verifying server is alive")
- pid = os.getpid()
- # see tests/server/util.c function write_pidfile
- if os.name == "nt":
- pid += 4194304
- contents = VERIFIED_RSP.format(pid=pid).encode('utf-8')
-
- self.write_to_fid(fid, contents)
- return fid, filename
-
- def write_to_fid(self, fid, contents):
- # Write the contents to file descriptor
- os.write(fid, contents)
- os.fsync(fid)
-
- # Rewind the file to the beginning so a read gets us the contents
- os.lseek(fid, 0, os.SEEK_SET)
-
- def get_test_path(self, requested_filename):
- log.info("[SMB] Get reply data from 'test%s'", requested_filename)
-
- fid, filename = tempfile.mkstemp()
- log.debug("[SMB] Created %s (%d) for storing test '%s'",
- filename, fid, requested_filename)
-
- try:
- contents = self.ctd.get_test_data(requested_filename).encode('utf-8')
- self.write_to_fid(fid, contents)
- return fid, filename
-
- except Exception as e:
- log.exception("Failed to make test file")
- raise SmbError(STATUS_NO_SUCH_FILE, "Failed to make test file") from e
-
-
-class SmbError(Exception):
- def __init__(self, error_code, error_message):
- super().__init__(error_message)
- self.error_code = error_code
-
-
-class ScriptRC:
- """Enum for script return codes."""
-
- SUCCESS = 0
- FAILURE = 1
- EXCEPTION = 2
-
-
-class ScriptError(Exception):
- pass
-
-
-def get_options():
- parser = argparse.ArgumentParser()
-
- parser.add_argument("--port", action="store", default=9017,
- type=int, help="port to listen on")
- parser.add_argument("--host", action="store", default="127.0.0.1",
- help="host to listen on")
- parser.add_argument("--verbose", action="store", type=int, default=0,
- help="verbose output")
- parser.add_argument("--pidfile", action="store",
- help="filename for the PID")
- parser.add_argument("--logfile", action="store",
- help="filename for the log")
- parser.add_argument("--srcdir", action="store", help="test directory")
- parser.add_argument("--id", action="store", help="server ID")
- parser.add_argument("--ipv4", action="store_true", default=0,
- help="IPv4 flag")
-
- return parser.parse_args()
-
-
-def setup_logging(options):
- """Set up logging from the command line options."""
- root_logger = logging.getLogger()
- add_stdout = False
-
- formatter = logging.Formatter("%(asctime)s %(levelname)-5.5s %(message)s")
-
- # Write out to a logfile
- if options.logfile:
- handler = ClosingFileHandler(options.logfile)
- handler.setFormatter(formatter)
- handler.setLevel(logging.DEBUG)
- root_logger.addHandler(handler)
- else:
- # The logfile was not specified. Add a stdout logger.
- add_stdout = True
-
- if options.verbose:
- # Add a stdout logger as well in verbose mode
- root_logger.setLevel(logging.DEBUG)
- add_stdout = True
- else:
- root_logger.setLevel(logging.WARNING)
-
- if add_stdout:
- stdout_handler = logging.StreamHandler(sys.stdout)
- stdout_handler.setFormatter(formatter)
- stdout_handler.setLevel(logging.DEBUG)
- root_logger.addHandler(stdout_handler)
-
-
-if __name__ == '__main__':
- # Get the options from the user.
- options = get_options()
-
- # Setup logging using the user options
- setup_logging(options)
-
- # Run main script.
- try:
- rc = smbserver(options)
- except Exception:
- log.exception('Error in SMB server')
- rc = ScriptRC.EXCEPTION
-
- if options.pidfile and os.path.isfile(options.pidfile):
- os.unlink(options.pidfile)
-
- log.info("[SMB] Returning %d", rc)
- sys.exit(rc)
tests/unit/unit1627.c+3 -6
@@ -38,18 +38,15 @@ static CURLcode test_unit1627(const char *arg)
/* all upper */
"DICT", "FILE", "FTP", "FTPS", "GOPHER", "GOPHERS", "HTTP", "HTTPS",
"IMAP", "IMAPS", "LDAP", "LDAPS", "MQTT", "MQTTS", "POP3", "POP3S",
- "RTSP", "SCP", "SFTP", "SMB", "SMBS", "SMTP", "SMTPS",
- "TELNET", "TFTP", "WS", "WSS",
+ "RTSP", "SCP", "SFTP", "SMTP", "SMTPS", "TELNET", "TFTP", "WS", "WSS",
/* all lower */
"dict", "file", "ftp", "ftps", "gopher", "gophers", "http", "https",
"imap", "imaps", "ldap", "ldaps", "mqtt", "mqtts", "pop3", "pop3s",
- "rtsp", "scp", "sftp", "smb", "smbs", "smtp", "smtps",
- "telnet", "tftp", "ws", "wss",
+ "rtsp", "scp", "sftp", "smtp", "smtps", "telnet", "tftp", "ws", "wss",
/* mixed */
"diCt", "fIle", "Ftp", "ftpS", "Gopher", "gOphers", "htTp", "httPs",
"imAP", "imaPS", "LDap", "LDAps", "mQTT", "mqtTS", "pOP3", "pOP3s",
- "RtsP", "ScP", "SFtP", "Smb", "smBS", "sMTP", "SMTPs",
- "TELNEt", "tFTP", "Ws", "wSS",
+ "RtsP", "ScP", "SFtP", "sMTP", "SMTPs", "TELNEt", "tFTP", "Ws", "wSS",
"SOCKS", "SOCKS4", "SOCKS5", "SOCKS4A", "SOCKS5H",
"socks", "socks4", "socks5", "socks4a", "socks5h",