diff options
author | AlexSm <alex@ydb.tech> | 2024-01-18 11:28:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-18 11:28:56 +0100 |
commit | 9d0a3761b3201e0d9db879a7adf91876ebdb0564 (patch) | |
tree | 541d11ac878c18efd7ebca81e35112aa0fef995b /contrib/libs/curl/lib/vssh/libssh.c | |
parent | 404ef8886ecc9736bc58ade6da2fbd83b486a408 (diff) | |
download | ydb-9d0a3761b3201e0d9db879a7adf91876ebdb0564.tar.gz |
Library import 8 (#1074)
* Library import 8
* Add contrib/libs/cxxsupp/libcxx/include/__verbose_abort
Diffstat (limited to 'contrib/libs/curl/lib/vssh/libssh.c')
-rw-r--r-- | contrib/libs/curl/lib/vssh/libssh.c | 182 |
1 files changed, 87 insertions, 95 deletions
diff --git a/contrib/libs/curl/lib/vssh/libssh.c b/contrib/libs/curl/lib/vssh/libssh.c index dc98aa0413..88bfd6a409 100644 --- a/contrib/libs/curl/lib/vssh/libssh.c +++ b/contrib/libs/curl/lib/vssh/libssh.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2017 - 2022 Red Hat, Inc. + * Copyright (C) Red Hat, Inc. * * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek, * Robert Kolcun, Andreas Schneider @@ -40,9 +40,6 @@ #ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> #endif -#ifdef HAVE_UTSNAME_H -#include <sys/utsname.h> -#endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif @@ -51,11 +48,6 @@ #include <inet.h> #endif -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - #include <curl/curl.h> #include "urldata.h" #include "sendf.h" @@ -71,6 +63,7 @@ #include "strdup.h" #include "strcase.h" #include "vtls/vtls.h" +#include "cfilters.h" #include "connect.h" #include "inet_ntop.h" #include "parsedate.h" /* for the week day and month names */ @@ -100,6 +93,7 @@ #if defined(__GNUC__) && \ (LIBSSH_VERSION_MINOR >= 10) || \ (LIBSSH_VERSION_MAJOR > 0) +#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif @@ -580,7 +574,7 @@ cleanup: rc = SSH_ERROR; \ } while(0) -#define MOVE_TO_LAST_AUTH do { \ +#define MOVE_TO_PASSWD_AUTH do { \ if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ rc = SSH_OK; \ state(data, SSH_AUTH_PASS_INIT); \ @@ -590,23 +584,23 @@ cleanup: } \ } while(0) -#define MOVE_TO_TERTIARY_AUTH do { \ +#define MOVE_TO_KEY_AUTH do { \ if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ rc = SSH_OK; \ state(data, SSH_AUTH_KEY_INIT); \ } \ else { \ - MOVE_TO_LAST_AUTH; \ + MOVE_TO_PASSWD_AUTH; \ } \ } while(0) -#define MOVE_TO_SECONDARY_AUTH do { \ +#define MOVE_TO_GSSAPI_AUTH do { \ if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ rc = SSH_OK; \ state(data, SSH_AUTH_GSSAPI); \ } \ else { \ - MOVE_TO_TERTIARY_AUTH; \ + MOVE_TO_KEY_AUTH; \ } \ } while(0) @@ -689,7 +683,6 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) struct ssh_conn *sshc = &conn->proto.sshc; curl_socket_t sock = conn->sock[FIRSTSOCKET]; int rc = SSH_NO_ERROR, err; - char *new_readdir_line; int seekerr = CURL_SEEKFUNC_OK; const char *err_msg; *block = 0; /* we're not blocking by default */ @@ -758,6 +751,16 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); + if(sshc->auth_methods) + infof(data, "SSH authentication methods available: %s%s%s%s", + sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY ? + "public key, ": "", + sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC ? + "GSSAPI, " : "", + sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE ? + "keyboard-interactive, " : "", + sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD ? + "password": ""); if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { state(data, SSH_AUTH_PKEY_INIT); infof(data, "Authentication using SSH public key file"); @@ -780,7 +783,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } case SSH_AUTH_PKEY_INIT: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; break; } @@ -796,7 +799,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } if(rc != SSH_OK) { - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; break; } } @@ -831,7 +834,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; } break; case SSH_AUTH_PKEY: @@ -849,13 +852,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else { infof(data, "Failed public key authentication (rc: %d)", rc); - MOVE_TO_SECONDARY_AUTH; + MOVE_TO_GSSAPI_AUTH; } break; case SSH_AUTH_GSSAPI: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { - MOVE_TO_TERTIARY_AUTH; + MOVE_TO_KEY_AUTH; break; } @@ -873,7 +876,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } - MOVE_TO_TERTIARY_AUTH; + MOVE_TO_KEY_AUTH; break; case SSH_AUTH_KEY_INIT: @@ -881,13 +884,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_AUTH_KEY); } else { - MOVE_TO_LAST_AUTH; + MOVE_TO_PASSWD_AUTH; } break; case SSH_AUTH_KEY: - - /* Authentication failed. Continue with keyboard-interactive now. */ + /* keyboard-interactive authentication */ rc = myssh_auth_interactive(conn); if(rc == SSH_AGAIN) { break; @@ -895,13 +897,15 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == SSH_OK) { sshc->authed = TRUE; infof(data, "completed keyboard interactive authentication"); + state(data, SSH_AUTH_DONE); + } + else { + MOVE_TO_PASSWD_AUTH; } - state(data, SSH_AUTH_DONE); break; case SSH_AUTH_PASS_INIT: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { - /* Host key authentication is intentionally not implemented */ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); break; } @@ -1156,13 +1160,23 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } else if(statvfs) { + #ifdef _MSC_VER + #define LIBSSH_VFS_SIZE_MASK "I64u" + #else + #define LIBSSH_VFS_SIZE_MASK PRIu64 + #endif char *tmp = aprintf("statvfs:\n" - "f_bsize: %llu\n" "f_frsize: %llu\n" - "f_blocks: %llu\n" "f_bfree: %llu\n" - "f_bavail: %llu\n" "f_files: %llu\n" - "f_ffree: %llu\n" "f_favail: %llu\n" - "f_fsid: %llu\n" "f_flag: %llu\n" - "f_namemax: %llu\n", + "f_bsize: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_frsize: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_blocks: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_bfree: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_bavail: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_files: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_ffree: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_favail: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_fsid: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_flag: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_namemax: %" LIBSSH_VFS_SIZE_MASK "\n", statvfs->f_bsize, statvfs->f_frsize, statvfs->f_blocks, statvfs->f_bfree, statvfs->f_bavail, statvfs->f_files, @@ -1214,7 +1228,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } case SSH_SFTP_TRANS_INIT: - if(data->set.upload) + if(data->state.upload) state(data, SSH_SFTP_UPLOAD_INIT); else { if(protop->path[strlen(protop->path)-1] == '/') @@ -1415,7 +1429,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_READDIR_INIT: Curl_pgrsSetDownloadSize(data, -1); - if(data->set.opt_no_body) { + if(data->req.no_body) { state(data, SSH_STOP); break; } @@ -1436,7 +1450,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; case SSH_SFTP_READDIR: - + Curl_dyn_reset(&sshc->readdir_buf); if(sshc->readdir_attrs) sftp_attributes_free(sshc->readdir_attrs); @@ -1463,26 +1477,15 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_STOP); break; } - /* since this counts what we send to the client, we include the - newline in this counter */ - data->req.bytecount += sshc->readdir_len + 1; - /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_DATA_OUT, (char *)sshc->readdir_filename, - sshc->readdir_len); } else { - sshc->readdir_currLen = strlen(sshc->readdir_longentry); - sshc->readdir_totalLen = 80 + sshc->readdir_currLen; - sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); - if(!sshc->readdir_line) { - state(data, SSH_SFTP_CLOSE); + if(Curl_dyn_add(&sshc->readdir_buf, sshc->readdir_longentry)) { sshc->actualcode = CURLE_OUT_OF_MEMORY; + state(data, SSH_STOP); break; } - memcpy(sshc->readdir_line, sshc->readdir_longentry, - sshc->readdir_currLen); if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && ((sshc->readdir_attrs->permissions & SSH_S_IFMT) == SSH_S_IFLNK)) { @@ -1545,24 +1548,11 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) Curl_safefree(sshc->readdir_linkPath); - /* get room for the filename and extra output */ - sshc->readdir_totalLen += 4 + sshc->readdir_len; - new_readdir_line = Curl_saferealloc(sshc->readdir_line, - sshc->readdir_totalLen); - if(!new_readdir_line) { - sshc->readdir_line = NULL; - state(data, SSH_SFTP_CLOSE); + if(Curl_dyn_addf(&sshc->readdir_buf, " -> %s", + sshc->readdir_filename)) { sshc->actualcode = CURLE_OUT_OF_MEMORY; break; } - sshc->readdir_line = new_readdir_line; - - sshc->readdir_currLen += msnprintf(sshc->readdir_line + - sshc->readdir_currLen, - sshc->readdir_totalLen - - sshc->readdir_currLen, - " -> %s", - sshc->readdir_filename); sftp_attributes_free(sshc->readdir_link_attrs); sshc->readdir_link_attrs = NULL; @@ -1572,21 +1562,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_SFTP_READDIR_BOTTOM); /* FALLTHROUGH */ case SSH_SFTP_READDIR_BOTTOM: - sshc->readdir_currLen += msnprintf(sshc->readdir_line + - sshc->readdir_currLen, - sshc->readdir_totalLen - - sshc->readdir_currLen, "\n"); - result = Curl_client_write(data, CLIENTWRITE_BODY, - sshc->readdir_line, - sshc->readdir_currLen); - - if(!result) { - /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line, - sshc->readdir_currLen); - data->req.bytecount += sshc->readdir_currLen; - } - Curl_safefree(sshc->readdir_line); + if(Curl_dyn_addn(&sshc->readdir_buf, "\n", 1)) + result = CURLE_OUT_OF_MEMORY; + else + result = Curl_client_write(data, CLIENTWRITE_BODY, + Curl_dyn_ptr(&sshc->readdir_buf), + Curl_dyn_len(&sshc->readdir_buf)); + ssh_string_free_char(sshc->readdir_tmp); sshc->readdir_tmp = NULL; @@ -1622,7 +1604,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) MOVE_TO_SFTP_CLOSE_STATE(); break; } - + sftp_file_set_nonblocking(sshc->sftp_file); state(data, SSH_SFTP_DOWNLOAD_STAT); break; @@ -1662,13 +1644,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) CURLofft to_t; CURLofft from_t; - from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); + from_t = curlx_strtoofft(data->state.range, &ptr, 10, &from); if(from_t == CURL_OFFT_FLOW) { return CURLE_RANGE_ERROR; } while(*ptr && (ISBLANK(*ptr) || (*ptr == '-'))) ptr++; - to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + to_t = curlx_strtoofft(ptr, &ptr2, 10, &to); if(to_t == CURL_OFFT_FLOW) { return CURLE_RANGE_ERROR; } @@ -1827,7 +1809,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ ssh_set_blocking(sshc->ssh_session, 1); - if(data->set.upload) { + if(data->state.upload) { if(data->state.infilesize < 0) { failf(data, "SCP requires a known file size for upload"); sshc->actualcode = CURLE_UPLOAD_FAILED; @@ -1932,7 +1914,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } case SSH_SCP_DONE: - if(data->set.upload) + if(data->state.upload) state(data, SSH_SCP_SEND_EOF); else state(data, SSH_SCP_CHANNEL_FREE); @@ -1980,10 +1962,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) ssh_disconnect(sshc->ssh_session); if(!ssh_version(SSH_VERSION_INT(0, 10, 0))) { /* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back, - explicitly mark it as closed with the memdebug macro. This libssh + tell the connection to forget about it. This libssh bug is fixed in 0.10.0. */ - fake_sclose(conn->sock[FIRSTSOCKET]); - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; + Curl_conn_forget_socket(data, FIRSTSOCKET); } SSH_STRING_FREE_CHAR(sshc->homedir); @@ -2025,7 +2006,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) Curl_safefree(sshc->rsa); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); - Curl_safefree(sshc->readdir_line); + Curl_dyn_free(&sshc->readdir_buf); Curl_safefree(sshc->readdir_linkPath); SSH_STRING_FREE_CHAR(sshc->homedir); @@ -2170,11 +2151,12 @@ static CURLcode myssh_setup_connection(struct Curl_easy *data, struct connectdata *conn) { struct SSHPROTO *ssh; - (void)conn; + struct ssh_conn *sshc = &conn->proto.sshc; data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO)); if(!ssh) return CURLE_OUT_OF_MEMORY; + Curl_dyn_init(&sshc->readdir_buf, PATH_MAX * 2); return CURLE_OK; } @@ -2199,7 +2181,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done) myssh_setup_connection(data, conn); /* We default to persistent connections. We set this already in this connect - function to make the re-use checks properly be able to check this bit. */ + function to make the reuse checks properly be able to check this bit. */ connkeep(conn, "SSH default"); if(conn->handler->protocol & CURLPROTO_SCP) { @@ -2323,7 +2305,6 @@ CURLcode scp_perform(struct Curl_easy *data, bool *connected, bool *dophase_done) { CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; DEBUGF(infof(data, "DO phase starts")); @@ -2334,7 +2315,7 @@ CURLcode scp_perform(struct Curl_easy *data, result = myssh_multi_statemach(data, dophase_done); - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); if(*dophase_done) { DEBUGF(infof(data, "DO phase is complete")); @@ -2504,7 +2485,6 @@ CURLcode sftp_perform(struct Curl_easy *data, bool *dophase_done) { CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; DEBUGF(infof(data, "DO phase starts")); @@ -2516,7 +2496,7 @@ CURLcode sftp_perform(struct Curl_easy *data, /* run the state-machine */ result = myssh_multi_statemach(data, dophase_done); - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); if(*dophase_done) { DEBUGF(infof(data, "DO phase is complete")); @@ -2585,6 +2565,12 @@ static ssize_t sftp_send(struct Curl_easy *data, int sockindex, struct connectdata *conn = data->conn; (void)sockindex; + /* limit the writes to the maximum specified in Section 3 of + * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02 + */ + if(len > 32768) + len = 32768; + nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len); myssh_block2waitfor(conn, FALSE); @@ -2672,7 +2658,7 @@ static void sftp_quote(struct Curl_easy *data) /* if a command starts with an asterisk, which a legal SFTP command never can, the command will be allowed to fail without it causing any aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ + is successful, whatever the server responds. */ if(cmd[0] == '*') { cmd++; @@ -2846,7 +2832,7 @@ static void sftp_quote_stat(struct Curl_easy *data) /* if a command starts with an asterisk, which a legal SFTP command never can, the command will be allowed to fail without it causing any aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ + is successful, whatever the server responds. */ if(cmd[0] == '*') { cmd++; @@ -2971,4 +2957,10 @@ void Curl_ssh_version(char *buffer, size_t buflen) (void)msnprintf(buffer, buflen, "libssh/%s", ssh_version(0)); } +#if defined(__GNUC__) && \ + (LIBSSH_VERSION_MINOR >= 10) || \ + (LIBSSH_VERSION_MAJOR > 0) +#pragma GCC diagnostic pop +#endif + #endif /* USE_LIBSSH */ |