#include "url.h"
#include "speedcheck.h"
#include "getinfo.h"
-
-#include "strequal.h"
+#include "strdup.h"
+#include "strcase.h"
#include "vtls/vtls.h"
#include "connect.h"
#include "strerror.h"
static CURLcode sftp_libssh2_error_to_CURLE(int err)
{
- switch (err) {
+ switch(err) {
case LIBSSH2_FX_OK:
return CURLE_OK;
static CURLcode libssh2_session_error_to_CURLE(int err)
{
- switch (err) {
+ switch(err) {
/* Ordered by order of appearance in libssh2.h */
case LIBSSH2_ERROR_NONE:
return CURLE_OK;
struct Curl_easy *data = conn->data;
char *real_path = NULL;
char *working_path;
- int working_path_len;
-
- working_path = curl_easy_unescape(data, data->state.path, 0,
- &working_path_len);
- if(!working_path)
- return CURLE_OUT_OF_MEMORY;
+ size_t working_path_len;
+ CURLcode result =
+ Curl_urldecode(data, data->state.path, 0, &working_path,
+ &working_path_len, FALSE);
+ if(result)
+ return result;
/* Check for /~/, indicating relative to the user's home directory */
if(conn->handler->protocol & CURLPROTO_SCP) {
* against a known fingerprint, if available.
*/
if(pubkey_md5 && strlen(pubkey_md5) == 32) {
- if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
+ if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
if(fingerprint)
failf(data,
"Denied establishing ssh session: mismatch md5 fingerprint. "
state(conn, SSH_AUTH_DONE);
break;
}
- else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
- LIBSSH2_ERROR_EAGAIN) {
- rc = LIBSSH2_ERROR_EAGAIN;
- break;
- }
else {
- state(conn, SSH_SESSION_FREE);
- sshc->actualcode = libssh2_session_error_to_CURLE(err);
+ err = libssh2_session_last_errno(sshc->ssh_session);
+ if(err == LIBSSH2_ERROR_EAGAIN)
+ rc = LIBSSH2_ERROR_EAGAIN;
+ else {
+ state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = libssh2_session_error_to_CURLE(err);
+ }
break;
}
}
break;
}
- sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
+ sshc->passphrase = data->set.ssl.key_passwd;
if(!sshc->passphrase)
sshc->passphrase = "";
&err_msg, NULL, 0);
infof(data, "SSH public key authentication failed: %s\n", err_msg);
state(conn, SSH_AUTH_PASS_INIT);
+ rc = 0; /* clear rc and continue */
}
break;
}
else {
state(conn, SSH_AUTH_HOST_INIT);
+ rc = 0; /* clear rc and continue */
}
break;
if(rc < 0) {
infof(data, "Failure connecting to agent\n");
state(conn, SSH_AUTH_KEY_INIT);
+ rc = 0; /* clear rc and continue */
}
else {
state(conn, SSH_AUTH_AGENT_LIST);
if(rc < 0) {
infof(data, "Failure requesting identities to agent\n");
state(conn, SSH_AUTH_KEY_INIT);
+ rc = 0; /* clear rc and continue */
}
else {
state(conn, SSH_AUTH_AGENT);
sshc->acceptfail = TRUE;
}
- if(curl_strequal("pwd", cmd)) {
+ if(strcasecompare("pwd", cmd)) {
/* output debug output if that is requested */
char *tmp = aprintf("257 \"%s\" is current directory.\n",
sftp_scp->path);
* OpenSSH's sftp program and call the appropriate libssh2
* functions.
*/
- if(curl_strnequal(cmd, "chgrp ", 6) ||
- curl_strnequal(cmd, "chmod ", 6) ||
- curl_strnequal(cmd, "chown ", 6) ) {
+ if(strncasecompare(cmd, "chgrp ", 6) ||
+ strncasecompare(cmd, "chmod ", 6) ||
+ strncasecompare(cmd, "chown ", 6) ) {
/* attribute change */
/* sshc->quote_path1 contains the mode to set */
state(conn, SSH_SFTP_QUOTE_STAT);
break;
}
- else if(curl_strnequal(cmd, "ln ", 3) ||
- curl_strnequal(cmd, "symlink ", 8)) {
+ else if(strncasecompare(cmd, "ln ", 3) ||
+ strncasecompare(cmd, "symlink ", 8)) {
/* symbolic linking */
/* sshc->quote_path1 is the source */
/* get the destination */
state(conn, SSH_SFTP_QUOTE_SYMLINK);
break;
}
- else if(curl_strnequal(cmd, "mkdir ", 6)) {
+ else if(strncasecompare(cmd, "mkdir ", 6)) {
/* create dir */
state(conn, SSH_SFTP_QUOTE_MKDIR);
break;
}
- else if(curl_strnequal(cmd, "rename ", 7)) {
+ else if(strncasecompare(cmd, "rename ", 7)) {
/* rename file */
/* first param is the source path */
/* second param is the dest. path */
state(conn, SSH_SFTP_QUOTE_RENAME);
break;
}
- else if(curl_strnequal(cmd, "rmdir ", 6)) {
+ else if(strncasecompare(cmd, "rmdir ", 6)) {
/* delete dir */
state(conn, SSH_SFTP_QUOTE_RMDIR);
break;
}
- else if(curl_strnequal(cmd, "rm ", 3)) {
+ else if(strncasecompare(cmd, "rm ", 3)) {
state(conn, SSH_SFTP_QUOTE_UNLINK);
break;
}
#ifdef HAS_STATVFS_SUPPORT
- else if(curl_strnequal(cmd, "statvfs ", 8)) {
+ else if(strncasecompare(cmd, "statvfs ", 8)) {
state(conn, SSH_SFTP_QUOTE_STATVFS);
break;
}
sshc->acceptfail = TRUE;
}
- if(!curl_strnequal(cmd, "chmod", 5)) {
+ if(!strncasecompare(cmd, "chmod", 5)) {
/* Since chown and chgrp only set owner OR group but libssh2 wants to
* set them both at once, we need to obtain the current ownership
* first. This takes an extra protocol round trip.
}
/* Now set the new attributes... */
- if(curl_strnequal(cmd, "chgrp", 5)) {
+ if(strncasecompare(cmd, "chgrp", 5)) {
sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
break;
}
}
- else if(curl_strnequal(cmd, "chmod", 5)) {
+ else if(strncasecompare(cmd, "chmod", 5)) {
sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
/* permissions are octal */
break;
}
}
- else if(curl_strnequal(cmd, "chown", 5)) {
+ else if(strncasecompare(cmd, "chown", 5)) {
sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
(data->set.ftp_create_missing_dirs &&
(strlen(sftp_scp->path) > 1))) {
/* try to create the path remotely */
+ rc = 0; /* clear rc and continue */
sshc->secondCreateDirs = 1;
state(conn, SSH_SFTP_CREATE_DIRS_INIT);
break;
}
*sshc->slash_pos = '/';
++sshc->slash_pos;
- if(rc == -1) {
+ if(rc < 0) {
/*
* Abort if failure wasn't that the dir already exists or the
* permission was denied (creation might succeed further down the
sshc->actualcode = result?result:CURLE_SSH;
break;
}
+ else {
+ rc = 0; /* clear rc and continue */
+ }
}
state(conn, SSH_SFTP_CREATE_DIRS);
break;
break;
}
}
- if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
+ sshc->readdir_filename = malloc(PATH_MAX+1);
+ if(!sshc->readdir_filename) {
state(conn, SSH_SFTP_CLOSE);
sshc->actualcode = CURLE_OUT_OF_MEMORY;
break;
}
- if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
+ sshc->readdir_longentry = malloc(PATH_MAX+1);
+ if(!sshc->readdir_longentry) {
Curl_safefree(sshc->readdir_filename);
state(conn, SSH_SFTP_CLOSE);
sshc->actualcode = CURLE_OUT_OF_MEMORY;
/* get room for the filename and extra output */
sshc->readdir_totalLen += 4 + sshc->readdir_len;
- new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
+ new_readdir_line = Curl_saferealloc(sshc->readdir_line,
+ sshc->readdir_totalLen);
if(!new_readdir_line) {
- Curl_safefree(sshc->readdir_line);
+ sshc->readdir_line = NULL;
Curl_safefree(sshc->readdir_filename);
Curl_safefree(sshc->readdir_longentry);
state(conn, SSH_SFTP_CLOSE);
else if(rc < 0) {
infof(data, "Failed to disconnect from libssh2 agent\n");
}
- libssh2_agent_free (sshc->ssh_agent);
+ libssh2_agent_free(sshc->ssh_agent);
sshc->ssh_agent = NULL;
/* NB: there is no need to free identities, they are part of internal
static void ssh_block2waitfor(struct connectdata *conn, bool block)
{
struct ssh_conn *sshc = &conn->proto.sshc;
- int dir;
- if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
- /* translate the libssh2 define bits into our own bit defines */
- conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
- ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
+ int dir = 0;
+ if(block) {
+ dir = libssh2_session_block_directions(sshc->ssh_session);
+ if(dir) {
+ /* translate the libssh2 define bits into our own bit defines */
+ conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
+ ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
+ }
}
- else
+ if(!dir)
/* It didn't block or libssh2 didn't reveal in which direction, put back
the original set */
conn->waitfor = sshc->orig_waitfor;
if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
fd_write = sock;
/* wait for the socket to become ready */
- Curl_socket_ready(fd_read, fd_write,
- left>1000?1000:left); /* ignore result */
+ (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
+ left>1000?1000:left); /* ignore result */
}
#endif
static const char *sftp_libssh2_strerror(int err)
{
- switch (err) {
+ switch(err) {
case LIBSSH2_FX_NO_SUCH_FILE:
return "No such file or directory";