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:
Daniel Stenberg 2007-11-05 09:30:45 +00:00
parent 51009a40b4
commit b9a7f4e502
2 changed files with 347 additions and 343 deletions

304
lib/ssh.c
View File

@ -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;
}

View File

@ -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 */
};