mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Move connection-oriented variables from the SessionHandle struct to the
connectdata struct. This will in theory enable us to do persistent connections with SCP+SFTP, but currently the state machine always (and wrongly) cleanup everything in the 'done' action instead of in 'disconnect'. Also did a bunch of indent fixes, if () => if() and a few other source cleanups like added comments etc.
This commit is contained in:
parent
51009a40b4
commit
b9a7f4e502
304
lib/ssh.c
304
lib/ssh.c
@ -377,7 +377,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
sshc->nextState = SSH_NO_STATE;
|
||||
sshc->actualCode = CURLE_OK;
|
||||
|
||||
rc = libssh2_session_startup(sftp_scp->ssh_session, sock);
|
||||
rc = libssh2_session_startup(sshc->ssh_session, sock);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
@ -389,7 +389,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* Set libssh2 to non-blocking, since cURL is all non-blocking */
|
||||
libssh2_session_set_blocking(sftp_scp->ssh_session, 0);
|
||||
libssh2_session_set_blocking(sshc->ssh_session, 0);
|
||||
|
||||
#ifdef CURL_LIBSSH2_DEBUG
|
||||
/*
|
||||
@ -398,7 +398,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
* whatever) is up to us. As for know not much is implemented, besides
|
||||
* showing how to get the fingerprint.
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(sftp_scp->ssh_session,
|
||||
fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
|
||||
LIBSSH2_HOSTKEY_HASH_MD5);
|
||||
|
||||
/* The fingerprint points to static storage (!), don't free() it. */
|
||||
@ -417,7 +417,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32)
|
||||
{
|
||||
char buf[33];
|
||||
host_public_key_md5 = libssh2_hostkey_hash(sftp_scp->ssh_session,
|
||||
host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
|
||||
LIBSSH2_HOSTKEY_HASH_MD5);
|
||||
for (i = 0; i < 16; i++)
|
||||
snprintf(&buf[i*2], 3, "%02x",
|
||||
@ -449,15 +449,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
* experience.
|
||||
* So always specify it here.
|
||||
*/
|
||||
sshc->authlist = libssh2_userauth_list(sftp_scp->ssh_session,
|
||||
sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
|
||||
sftp_scp->user,
|
||||
strlen(sftp_scp->user));
|
||||
|
||||
if(!sshc->authlist) {
|
||||
if ((err = libssh2_session_last_errno(sftp_scp->ssh_session)) ==
|
||||
if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualCode = libssh2_session_error_to_CURLE(err);
|
||||
break;
|
||||
@ -538,7 +539,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
case SSH_AUTH_PKEY:
|
||||
/* The function below checks if the files exists, no need to stat() here.
|
||||
*/
|
||||
rc = libssh2_userauth_publickey_fromfile(sftp_scp->ssh_session,
|
||||
rc = libssh2_userauth_publickey_fromfile(sshc->ssh_session,
|
||||
sftp_scp->user, sshc->rsa_pub,
|
||||
sshc->rsa, sshc->passphrase);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
@ -554,7 +555,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
sshc->authed = TRUE;
|
||||
infof(data, "Initialized SSH public key authentication\n");
|
||||
state(conn, SSH_AUTH_DONE);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_PASS_INIT);
|
||||
}
|
||||
break;
|
||||
@ -569,7 +571,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_AUTH_PASS:
|
||||
rc = libssh2_userauth_password(sftp_scp->ssh_session, sftp_scp->user,
|
||||
rc = libssh2_userauth_password(sshc->ssh_session, sftp_scp->user,
|
||||
sftp_scp->passwd);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
@ -578,7 +580,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
sshc->authed = TRUE;
|
||||
infof(data, "Initialized password authentication\n");
|
||||
state(conn, SSH_AUTH_DONE);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_HOST_INIT);
|
||||
}
|
||||
break;
|
||||
@ -587,7 +590,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
|
||||
(strstr(sshc->authlist, "hostbased") != NULL)) {
|
||||
state(conn, SSH_AUTH_HOST);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
}
|
||||
break;
|
||||
@ -600,14 +604,15 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
|
||||
&& (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
|
||||
state(conn, SSH_AUTH_KEY);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_DONE);
|
||||
}
|
||||
break;
|
||||
|
||||
case SSH_AUTH_KEY:
|
||||
/* Authentication failed. Continue with keyboard-interactive now. */
|
||||
rc = libssh2_userauth_keyboard_interactive_ex(sftp_scp->ssh_session,
|
||||
rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
|
||||
sftp_scp->user,
|
||||
strlen(sftp_scp->user),
|
||||
&kbd_callback);
|
||||
@ -648,12 +653,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
/*
|
||||
* Start the libssh2 sftp session
|
||||
*/
|
||||
sftp_scp->sftp_session = libssh2_sftp_init(sftp_scp->ssh_session);
|
||||
if (!sftp_scp->sftp_session) {
|
||||
if (libssh2_session_last_errno(sftp_scp->ssh_session) ==
|
||||
sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
|
||||
if(!sshc->sftp_session) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
failf(data, "Failure initialising sftp session\n");
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualCode = CURLE_FAILED_INIT;
|
||||
@ -670,7 +676,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
/*
|
||||
* Get the "home" directory
|
||||
*/
|
||||
rc = libssh2_sftp_realpath(sftp_scp->sftp_session, ".",
|
||||
rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
|
||||
tempHome, PATH_MAX-1);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
@ -684,9 +690,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
sshc->actualCode = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* Return the error type */
|
||||
result = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
result = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
DEBUGF(infof(data, "error = %d\n", result));
|
||||
state(conn, SSH_STOP);
|
||||
break;
|
||||
@ -785,7 +792,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
infof(data, "Sending quote commands\n");
|
||||
sshc->quote_item = data->set.quote;
|
||||
state(conn, SSH_SFTP_QUOTE);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_SFTP_TRANS_INIT);
|
||||
}
|
||||
break;
|
||||
@ -795,7 +803,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
infof(data, "Sending quote commands\n");
|
||||
sshc->quote_item = data->set.postquote;
|
||||
state(conn, SSH_SFTP_QUOTE);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_STOP);
|
||||
}
|
||||
break;
|
||||
@ -975,13 +984,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_STAT:
|
||||
rc = libssh2_sftp_stat(sftp_scp->sftp_session, sshc->quote_path2,
|
||||
rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2,
|
||||
&sshc->quote_attrs);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0) { /* get those attributes */
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@ -1041,12 +1050,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_SETSTAT:
|
||||
rc = libssh2_sftp_setstat(sftp_scp->sftp_session, sshc->quote_path2,
|
||||
rc = libssh2_sftp_setstat(sshc->sftp_session, sshc->quote_path2,
|
||||
&sshc->quote_attrs);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else if(rc != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@ -1061,13 +1070,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_SYMLINK:
|
||||
rc = libssh2_sftp_symlink(sftp_scp->sftp_session, sshc->quote_path1,
|
||||
rc = libssh2_sftp_symlink(sshc->sftp_session, sshc->quote_path1,
|
||||
sshc->quote_path2);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@ -1082,12 +1091,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_MKDIR:
|
||||
rc = libssh2_sftp_mkdir(sftp_scp->sftp_session, sshc->quote_path1, 0755);
|
||||
rc = libssh2_sftp_mkdir(sshc->sftp_session, sshc->quote_path1, 0755);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
|
||||
@ -1099,12 +1108,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_RENAME:
|
||||
rc = libssh2_sftp_rename(sftp_scp->sftp_session, sshc->quote_path1,
|
||||
rc = libssh2_sftp_rename(sshc->sftp_session, sshc->quote_path1,
|
||||
sshc->quote_path2);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else if (rc != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
}
|
||||
else if(rc != 0) {
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@ -1118,12 +1128,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_RMDIR:
|
||||
rc = libssh2_sftp_rmdir(sftp_scp->sftp_session, sshc->quote_path1);
|
||||
rc = libssh2_sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
|
||||
@ -1135,12 +1145,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_UNLINK:
|
||||
rc = libssh2_sftp_unlink(sftp_scp->sftp_session, sshc->quote_path1);
|
||||
rc = libssh2_sftp_unlink(sshc->sftp_session, sshc->quote_path1);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
|
||||
@ -1152,17 +1162,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_TRANS_INIT:
|
||||
if (data->set.upload) {
|
||||
if(data->set.upload)
|
||||
state(conn, SSH_SFTP_UPLOAD_INIT);
|
||||
break;
|
||||
} else {
|
||||
if (sftp_scp->path[strlen(sftp_scp->path)-1] == '/') {
|
||||
else {
|
||||
if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
|
||||
state(conn, SSH_SFTP_READDIR_INIT);
|
||||
break;
|
||||
} else {
|
||||
else
|
||||
state(conn, SSH_SFTP_DOWNLOAD_INIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1173,16 +1179,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
* If this is not done the destination file will be named the
|
||||
* same name as the last directory in the path.
|
||||
*/
|
||||
sftp_scp->sftp_handle =
|
||||
libssh2_sftp_open(sftp_scp->sftp_session, sftp_scp->path,
|
||||
sshc->sftp_handle =
|
||||
libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
|
||||
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
|
||||
data->set.new_file_perms);
|
||||
if (!sftp_scp->sftp_handle) {
|
||||
if (libssh2_session_last_errno(sftp_scp->ssh_session) ==
|
||||
if(!sshc->sftp_handle) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
}
|
||||
else {
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
failf(data, "Upload failed: %s", sftp_libssh2_strerror(err));
|
||||
if(sshc->secondCreateDirs) {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
@ -1240,7 +1247,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
|
||||
case SSH_SFTP_CREATE_DIRS_MKDIR:
|
||||
/* 'mode' - parameter is preliminary - default to 0644 */
|
||||
rc = libssh2_sftp_mkdir(sftp_scp->sftp_session, sftp_scp->path,
|
||||
rc = libssh2_sftp_mkdir(sshc->sftp_session, sftp_scp->path,
|
||||
data->set.new_directory_perms);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
@ -1254,7 +1261,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
* permission was denied (creation might succeed further
|
||||
* down the path) - retry on unspecific FAILURE also
|
||||
*/
|
||||
sftp_err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
sftp_err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
|
||||
(sftp_err != LIBSSH2_FX_FAILURE) &&
|
||||
(sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
|
||||
@ -1272,14 +1279,15 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
* This is a directory that we are trying to get, so produce a
|
||||
* directory listing
|
||||
*/
|
||||
sftp_scp->sftp_handle = libssh2_sftp_opendir(sftp_scp->sftp_session,
|
||||
sshc->sftp_handle = libssh2_sftp_opendir(sshc->sftp_session,
|
||||
sftp_scp->path);
|
||||
if (!sftp_scp->sftp_handle) {
|
||||
if (libssh2_session_last_errno(sftp_scp->ssh_session) ==
|
||||
if(!sshc->sftp_handle) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
}
|
||||
else {
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
failf(data, "Could not open directory for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
@ -1303,7 +1311,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_READDIR:
|
||||
sshc->readdir_len = libssh2_sftp_readdir_ex(sftp_scp->sftp_handle,
|
||||
sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
|
||||
sshc->readdir_filename,
|
||||
PATH_MAX,
|
||||
sshc->readdir_longentry,
|
||||
@ -1380,11 +1388,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
}
|
||||
else if(sshc->readdir_len <= 0) {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
sshc->actualCode = err;
|
||||
failf(data, "Could not open remote file for reading: %s :: %d",
|
||||
sftp_libssh2_strerror(err),
|
||||
libssh2_session_last_errno(sftp_scp->ssh_session));
|
||||
libssh2_session_last_errno(sshc->ssh_session));
|
||||
Curl_safefree(sshc->readdir_filename);
|
||||
sshc->readdir_filename = NULL;
|
||||
Curl_safefree(sshc->readdir_longentry);
|
||||
@ -1395,7 +1403,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_READDIR_LINK:
|
||||
sshc->readdir_len = libssh2_sftp_readlink(sftp_scp->sftp_session,
|
||||
sshc->readdir_len = libssh2_sftp_readlink(sshc->sftp_session,
|
||||
sshc->readdir_linkPath,
|
||||
sshc->readdir_filename,
|
||||
PATH_MAX);
|
||||
@ -1446,11 +1454,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_READDIR_DONE:
|
||||
if (libssh2_sftp_closedir(sftp_scp->sftp_handle) ==
|
||||
if(libssh2_sftp_closedir(sshc->sftp_handle) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
sftp_scp->sftp_handle = NULL;
|
||||
sshc->sftp_handle = NULL;
|
||||
Curl_safefree(sshc->readdir_filename);
|
||||
sshc->readdir_filename = NULL;
|
||||
Curl_safefree(sshc->readdir_longentry);
|
||||
@ -1465,15 +1473,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
/*
|
||||
* Work on getting the specified file
|
||||
*/
|
||||
sftp_scp->sftp_handle =
|
||||
libssh2_sftp_open(sftp_scp->sftp_session, sftp_scp->path,
|
||||
sshc->sftp_handle =
|
||||
libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
|
||||
LIBSSH2_FXF_READ, data->set.new_file_perms);
|
||||
if (!sftp_scp->sftp_handle) {
|
||||
if (libssh2_session_last_errno(sftp_scp->ssh_session) ==
|
||||
if(!sshc->sftp_handle) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
err = libssh2_sftp_last_error(sftp_scp->sftp_session);
|
||||
}
|
||||
else {
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
failf(data, "Could not open remote file for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
@ -1488,7 +1497,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
{
|
||||
LIBSSH2_SFTP_ATTRIBUTES attrs;
|
||||
|
||||
rc = libssh2_sftp_stat(sftp_scp->sftp_session, sftp_scp->path, &attrs);
|
||||
rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
@ -1518,29 +1527,29 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SFTP_CLOSE:
|
||||
if (sftp_scp->sftp_handle) {
|
||||
rc = libssh2_sftp_close(sftp_scp->sftp_handle);
|
||||
if(sshc->sftp_handle) {
|
||||
rc = libssh2_sftp_close(sshc->sftp_handle);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
infof(data, "Failed to close libssh2 file\n");
|
||||
}
|
||||
sftp_scp->sftp_handle = NULL;
|
||||
sshc->sftp_handle = NULL;
|
||||
}
|
||||
state(conn, SSH_SFTP_SHUTDOWN);
|
||||
break;
|
||||
|
||||
case SSH_SFTP_SHUTDOWN:
|
||||
if (sftp_scp->sftp_session) {
|
||||
rc = libssh2_sftp_shutdown(sftp_scp->sftp_session);
|
||||
if(sshc->sftp_session) {
|
||||
rc = libssh2_sftp_shutdown(sshc->sftp_session);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
infof(data, "Failed to stop libssh2 sftp subsystem\n");
|
||||
}
|
||||
sftp_scp->sftp_session = NULL;
|
||||
sshc->sftp_session = NULL;
|
||||
}
|
||||
|
||||
Curl_safefree(sftp_scp->path);
|
||||
@ -1573,19 +1582,19 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
* not done the destination file will be named the same name as the last
|
||||
* directory in the path.
|
||||
*/
|
||||
sftp_scp->ssh_channel =
|
||||
libssh2_scp_send_ex(sftp_scp->ssh_session, sftp_scp->path,
|
||||
sshc->ssh_channel =
|
||||
libssh2_scp_send_ex(sshc->ssh_session, sftp_scp->path,
|
||||
data->set.new_file_perms,
|
||||
data->set.infilesize, 0, 0);
|
||||
if (!sftp_scp->ssh_channel) {
|
||||
if (libssh2_session_last_errno(sftp_scp->ssh_session) ==
|
||||
if(!sshc->ssh_channel) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
int ssh_err;
|
||||
char *err_msg;
|
||||
|
||||
ssh_err = libssh2_session_last_error(sftp_scp->ssh_session,
|
||||
ssh_err = libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0);
|
||||
err = libssh2_session_error_to_CURLE(ssh_err);
|
||||
failf(conn->data, "%s", err_msg);
|
||||
@ -1617,17 +1626,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
curl_off_t bytecount;
|
||||
|
||||
memset(&sb, 0, sizeof(struct stat));
|
||||
sftp_scp->ssh_channel = libssh2_scp_recv(sftp_scp->ssh_session,
|
||||
sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
|
||||
sftp_scp->path, &sb);
|
||||
if (!sftp_scp->ssh_channel) {
|
||||
if (libssh2_session_last_errno(sftp_scp->ssh_session) ==
|
||||
if(!sshc->ssh_channel) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
} else {
|
||||
int ssh_err;
|
||||
char *err_msg;
|
||||
|
||||
ssh_err = libssh2_session_last_error(sftp_scp->ssh_session,
|
||||
ssh_err = libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0);
|
||||
err = libssh2_session_error_to_CURLE(ssh_err);
|
||||
failf(conn->data, "%s", err_msg);
|
||||
@ -1661,8 +1670,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SCP_SEND_EOF:
|
||||
if (sftp_scp->ssh_channel) {
|
||||
rc = libssh2_channel_send_eof(sftp_scp->ssh_channel);
|
||||
if(sshc->ssh_channel) {
|
||||
rc = libssh2_channel_send_eof(sshc->ssh_channel);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
@ -1674,8 +1683,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SCP_WAIT_EOF:
|
||||
if (sftp_scp->ssh_channel) {
|
||||
rc = libssh2_channel_wait_eof(sftp_scp->ssh_channel);
|
||||
if(sshc->ssh_channel) {
|
||||
rc = libssh2_channel_wait_eof(sshc->ssh_channel);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
@ -1687,8 +1696,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SCP_WAIT_CLOSE:
|
||||
if (sftp_scp->ssh_channel) {
|
||||
rc = libssh2_channel_wait_closed(sftp_scp->ssh_channel);
|
||||
if(sshc->ssh_channel) {
|
||||
rc = libssh2_channel_wait_closed(sshc->ssh_channel);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
@ -1700,36 +1709,36 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SCP_CHANNEL_FREE:
|
||||
if (sftp_scp->ssh_channel) {
|
||||
rc = libssh2_channel_free(sftp_scp->ssh_channel);
|
||||
if(sshc->ssh_channel) {
|
||||
rc = libssh2_channel_free(sshc->ssh_channel);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
infof(data, "Failed to free libssh2 scp subsystem\n");
|
||||
}
|
||||
sftp_scp->ssh_channel = NULL;
|
||||
sshc->ssh_channel = NULL;
|
||||
}
|
||||
state(conn, SSH_SESSION_DISCONECT);
|
||||
break;
|
||||
|
||||
case SSH_CHANNEL_CLOSE:
|
||||
if (sftp_scp->ssh_channel) {
|
||||
rc = libssh2_channel_close(sftp_scp->ssh_channel);
|
||||
if(sshc->ssh_channel) {
|
||||
rc = libssh2_channel_close(sshc->ssh_channel);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
infof(data, "Failed to stop libssh2 channel subsystem\n");
|
||||
}
|
||||
sftp_scp->ssh_channel = NULL;
|
||||
sshc->ssh_channel = NULL;
|
||||
}
|
||||
state(conn, SSH_SESSION_DISCONECT);
|
||||
break;
|
||||
|
||||
case SSH_SESSION_DISCONECT:
|
||||
if (sftp_scp->ssh_session) {
|
||||
rc = libssh2_session_disconnect(sftp_scp->ssh_session, "Shutdown");
|
||||
if(sshc->ssh_session) {
|
||||
rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
@ -1748,15 +1757,15 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case SSH_SESSION_FREE:
|
||||
if (sftp_scp->ssh_session) {
|
||||
rc = libssh2_session_free(sftp_scp->ssh_session);
|
||||
if(sshc->ssh_session) {
|
||||
rc = libssh2_session_free(sshc->ssh_session);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
infof(data, "Failed to free libssh2 session\n");
|
||||
}
|
||||
sftp_scp->ssh_session = NULL;
|
||||
sshc->ssh_session = NULL;
|
||||
}
|
||||
sshc->nextState = SSH_NO_STATE;
|
||||
state(conn, SSH_STOP);
|
||||
@ -1827,11 +1836,6 @@ static CURLcode ssh_init(struct connectdata *conn)
|
||||
|
||||
ssh->errorstr = NULL;
|
||||
|
||||
ssh->ssh_session = NULL;
|
||||
ssh->ssh_channel = NULL;
|
||||
ssh->sftp_session = NULL;
|
||||
ssh->sftp_handle = NULL;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -1841,11 +1845,20 @@ static CURLcode ssh_init(struct connectdata *conn)
|
||||
*/
|
||||
static CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SSHPROTO *ssh;
|
||||
struct ssh_conn *ssh;
|
||||
curl_socket_t sock;
|
||||
CURLcode result;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#if 0
|
||||
/* Due to the fact that the state machine always cleans up and kills all
|
||||
handles, we cannot currently re-use SCP or SFTP connections... */
|
||||
|
||||
/* 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. */
|
||||
conn->bits.close = FALSE;
|
||||
#endif
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
@ -1854,7 +1867,7 @@ static CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
ssh = data->reqdata.proto.ssh;
|
||||
ssh = &conn->proto.sshc;
|
||||
|
||||
#ifdef CURL_LIBSSH2_DEBUG
|
||||
if(ssh->user) {
|
||||
@ -1975,14 +1988,6 @@ static CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
res = scp_perform(conn, &connected, done);
|
||||
|
||||
if (CURLE_OK == res) {
|
||||
|
||||
if (!done) {
|
||||
/* the DO phase has not completed yet */
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1999,11 +2004,13 @@ static CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
|
||||
/* run the state-machine */
|
||||
if(conn->data->state.used_interface == Curl_if_multi) {
|
||||
result = Curl_ssh_multi_statemach(conn, &done);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
result = ssh_easy_statemach(conn);
|
||||
done = TRUE;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
result = status;
|
||||
done = TRUE;
|
||||
}
|
||||
@ -2023,18 +2030,14 @@ ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
|
||||
void *mem, size_t len)
|
||||
{
|
||||
ssize_t nwrite;
|
||||
(void)sockindex; /* we only support SCP on the fixed known primary socket */
|
||||
|
||||
/* libssh2_channel_write() returns int
|
||||
*
|
||||
* NOTE: we should not store nor rely on connection-related data to be
|
||||
* in the SessionHandle struct
|
||||
*/
|
||||
/* libssh2_channel_write() returns int! */
|
||||
nwrite = (ssize_t)
|
||||
libssh2_channel_write(conn->data->reqdata.proto.ssh->ssh_channel,
|
||||
mem, len);
|
||||
libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
|
||||
if(nwrite == LIBSSH2_ERROR_EAGAIN)
|
||||
return 0;
|
||||
(void)sockindex;
|
||||
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
@ -2048,14 +2051,9 @@ ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
|
||||
ssize_t nread;
|
||||
(void)sockindex; /* we only support SCP on the fixed known primary socket */
|
||||
|
||||
/* libssh2_channel_read() returns int
|
||||
*
|
||||
* NOTE: we should not store nor rely on connection-related data to be
|
||||
* in the SessionHandle struct
|
||||
*/
|
||||
/* libssh2_channel_read() returns int */
|
||||
nread = (ssize_t)
|
||||
libssh2_channel_read(conn->data->reqdata.proto.ssh->ssh_channel,
|
||||
mem, len);
|
||||
libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
|
||||
return nread;
|
||||
}
|
||||
|
||||
@ -2089,7 +2087,8 @@ CURLcode sftp_perform(struct connectdata *conn,
|
||||
/* run the state-machine */
|
||||
if(conn->data->state.used_interface == Curl_if_multi) {
|
||||
result = Curl_ssh_multi_statemach(conn, dophase_done);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
result = ssh_easy_statemach(conn);
|
||||
*dophase_done = TRUE; /* with the easy interface we are done here */
|
||||
}
|
||||
@ -2131,9 +2130,8 @@ static CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
* Curl_ssh_connect() function.
|
||||
*/
|
||||
res = ssh_init(conn);
|
||||
if (res) {
|
||||
if(res)
|
||||
return res;
|
||||
}
|
||||
|
||||
data->reqdata.size = -1; /* make sure this is unknown at this point */
|
||||
|
||||
@ -2169,18 +2167,19 @@ static CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
|
||||
if(!status && !premature && conn->data->set.postquote) {
|
||||
sshc->nextState = SSH_SFTP_CLOSE;
|
||||
state(conn, SSH_SFTP_POSTQUOTE_INIT);
|
||||
} else {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
}
|
||||
else
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
|
||||
/* run the state-machine */
|
||||
if (conn->data->state.used_interface == Curl_if_multi) {
|
||||
if(conn->data->state.used_interface == Curl_if_multi)
|
||||
result = Curl_ssh_multi_statemach(conn, &done);
|
||||
} else {
|
||||
else {
|
||||
result = ssh_easy_statemach(conn);
|
||||
done = TRUE;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
result = status;
|
||||
done = TRUE;
|
||||
}
|
||||
@ -2194,25 +2193,24 @@ static CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* return number of received (decrypted) bytes */
|
||||
/* return number of sent bytes */
|
||||
ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
|
||||
void *mem, size_t len)
|
||||
{
|
||||
ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
|
||||
but is changed to ssize_t in 0.15! */
|
||||
but is changed to ssize_t in 0.15. These days we don't
|
||||
support libssh2 0.15*/
|
||||
(void)sockindex;
|
||||
|
||||
nwrite = (ssize_t)
|
||||
libssh2_sftp_write(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
|
||||
nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
|
||||
if(nwrite == LIBSSH2_ERROR_EAGAIN)
|
||||
return 0;
|
||||
|
||||
(void)sockindex;
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
|
||||
* a regular CURLcode value.
|
||||
* Return number of received (decrypted) bytes
|
||||
*/
|
||||
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
|
||||
char *mem, size_t len)
|
||||
@ -2220,9 +2218,7 @@ ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
|
||||
ssize_t nread;
|
||||
(void)sockindex;
|
||||
|
||||
/* libssh2_sftp_read() returns size_t !*/
|
||||
nread = (ssize_t)
|
||||
libssh2_sftp_read(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
|
||||
nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
@ -485,6 +485,10 @@ typedef enum {
|
||||
SSH_LAST /* never used */
|
||||
} sshstate;
|
||||
|
||||
/* this struct is used in the HandleData struct which is part of the
|
||||
SessionHandle, which means this is used on a per-easy handle basis.
|
||||
Everything that is strictly related to a connection is banned from this
|
||||
struct. */
|
||||
struct SSHPROTO {
|
||||
curl_off_t *bytecountp;
|
||||
char *user;
|
||||
@ -492,12 +496,6 @@ struct SSHPROTO {
|
||||
char *path; /* the path we operate on */
|
||||
char *homedir;
|
||||
char *errorstr;
|
||||
#ifdef USE_LIBSSH2
|
||||
LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
|
||||
LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
|
||||
LIBSSH2_SFTP *sftp_session; /* SFTP handle */
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
#endif /* USE_LIBSSH2 */
|
||||
};
|
||||
|
||||
/* ssh_conn is used for struct connection-oriented data in the connectdata
|
||||
@ -505,25 +503,35 @@ struct SSHPROTO {
|
||||
struct ssh_conn {
|
||||
const char *authlist; /* List of auth. methods, managed by libssh2 */
|
||||
#ifdef USE_LIBSSH2
|
||||
const char *passphrase;
|
||||
char *rsa_pub;
|
||||
char *rsa;
|
||||
bool authed;
|
||||
const char *passphrase; /* passphrase to use */
|
||||
char *rsa_pub; /* path name */
|
||||
char *rsa; /* path name */
|
||||
bool authed; /* the connection has been authenticated fine */
|
||||
sshstate state; /* always use ssh.c:state() to change state! */
|
||||
sshstate nextState; /* the state to goto after stopping */
|
||||
CURLcode actualCode; /* the actual error code */
|
||||
struct curl_slist *quote_item;
|
||||
char *quote_path1;
|
||||
struct curl_slist *quote_item; /* for the quote option */
|
||||
char *quote_path1; /* two generic pointers for the QUOTE stuff */
|
||||
char *quote_path2;
|
||||
LIBSSH2_SFTP_ATTRIBUTES quote_attrs;
|
||||
LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
|
||||
|
||||
/* Here's a set of struct members used by the SFTP_READDIR state */
|
||||
LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
|
||||
char *readdir_filename;
|
||||
char *readdir_longentry;
|
||||
int readdir_len, readdir_totalLen, readdir_currLen;
|
||||
char *readdir_line;
|
||||
char *readdir_linkPath;
|
||||
int secondCreateDirs;
|
||||
char *slash_pos;
|
||||
/* end of READDIR stuff */
|
||||
|
||||
int secondCreateDirs; /* counter use by the code to see if the
|
||||
second attempt has been made to change
|
||||
to/create a directory */
|
||||
char *slash_pos; /* used by the SFTP_CREATE_DIRS state */
|
||||
LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
|
||||
LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
|
||||
LIBSSH2_SFTP *sftp_session; /* SFTP handle */
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
#endif /* USE_LIBSSH2 */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user