Skip to content
Snippets Groups Projects
Commit 0c5a796c authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Somewhat working now... still some issues getting the second channel

working reliably though.
parent ab866866
No related branches found
No related tags found
No related merge requests found
Pipeline #5115 failed
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
/* $Id: ssh.c,v 1.31 2020/05/28 22:58:26 deuce Exp $ */ /* $Id: ssh.c,v 1.31 2020/05/28 22:58:26 deuce Exp $ */
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include "bbslist.h" #include "bbslist.h"
#include "ciolib.h" #include "ciolib.h"
#include "conn.h" #include "conn.h"
#include "eventwrap.h"
#include "gen_defs.h" #include "gen_defs.h"
#include "genwrap.h" #include "genwrap.h"
#include "sftp.h" #include "sftp.h"
...@@ -51,60 +53,95 @@ cryptlib_error_message(int status, const char *msg) ...@@ -51,60 +53,95 @@ cryptlib_error_message(int status, const char *msg)
static void static void
close_sftp_channel(void) close_sftp_channel(void)
{ {
if (sftp_state == NULL)
return;
pthread_mutex_lock(&ssh_mutex); pthread_mutex_lock(&ssh_mutex);
if (sftp_channel != -1) { if (sftp_channel != -1) {
cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, sftp_channel); if (cryptStatusOK(cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, sftp_channel)))
cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, 0); cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, 0);
sftp_channel = -1; sftp_channel = -1;
} }
pthread_mutex_unlock(&ssh_mutex); pthread_mutex_unlock(&ssh_mutex);
sftpc_finish(sftp_state); sftpc_finish(sftp_state);
sftp_state = NULL;
}
static void
close_ssh_channel(void)
{
pthread_mutex_lock(&ssh_mutex);
if (ssh_channel != -1) {
if (cryptStatusOK(cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, ssh_channel)))
cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, 0);
ssh_channel = -1;
}
pthread_mutex_unlock(&ssh_mutex);
} }
void void
ssh_input_thread(void *args) ssh_input_thread(void *args)
{ {
int status; int popstatus, gchstatus, status;
int rd; int rd;
size_t buffered; size_t buffered;
size_t buffer; size_t buffer;
int chan; int chan;
SetThreadName("SSH Input"); SetThreadName("SSH Input");
conn_api.input_thread_running = 1;
while (ssh_active && !conn_api.terminate) { while (ssh_active && !conn_api.terminate) {
if (!socket_readable(ssh_sock, 100)) if (!socket_readable(ssh_sock, 100))
continue; continue;
pthread_mutex_lock(&ssh_mutex); pthread_mutex_lock(&ssh_mutex);
status = cl.FlushData(ssh_session); conn_api.input_thread_running = 1;
status = cl.PopData(ssh_session, conn_api.rd_buf, conn_api.rd_buf_size, &rd); cl.FlushData(ssh_session);
if (cryptStatusOK(status)) popstatus = cl.PopData(ssh_session, conn_api.rd_buf, conn_api.rd_buf_size, &rd);
status = cl.GetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, &chan); gchstatus = cl.GetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, &chan);
pthread_mutex_unlock(&ssh_mutex); pthread_mutex_unlock(&ssh_mutex);
// Handle case where there was socket activity without readable data (ie: rekey) // Handle case where there was socket activity without readable data (ie: rekey)
if (status == CRYPT_ERROR_TIMEOUT) if (popstatus == CRYPT_ERROR_TIMEOUT)
continue; continue;
if (cryptStatusError(status)) { // A final read on a channel just occured... figure out which is missing...
if ((status == CRYPT_ERROR_COMPLETE) || (status == CRYPT_ERROR_READ) || (status == CRYPT_ERROR_NOTFOUND)) { /* connection closed */ if (gchstatus == CRYPT_ERROR_NOTFOUND) {
ssh_active = true; if (ssh_channel != -1) {
status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, ssh_channel);
if (status == CRYPT_ERROR_NOTFOUND) {
chan = ssh_channel;
}
}
if (chan == -1) {
if (sftp_channel != -1) {
status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, ssh_channel);
if (status == CRYPT_ERROR_NOTFOUND) {
chan = sftp_channel;
}
}
}
}
if (cryptStatusError(popstatus)) {
if ((popstatus == CRYPT_ERROR_COMPLETE) || (popstatus == CRYPT_ERROR_READ)) { /* connection closed */
if (chan == ssh_channel)
break;
}
else {
cryptlib_error_message(popstatus, "recieving data");
break; break;
} }
cryptlib_error_message(status, "recieving data");
ssh_active = true;
break;
} }
else { else {
if (chan == sftp_channel) { if (chan == sftp_channel) {
if (!sftpc_recv(sftp_state, conn_api.rd_buf, rd)) { if (!sftpc_recv(sftp_state, conn_api.rd_buf, rd)) {
ssh_active = true;
close_sftp_channel(); close_sftp_channel();
continue; continue;
} }
if (gchstatus == CRYPT_ERROR_NOTFOUND) {
sftp_channel = -1;
}
} }
else { else if (chan == ssh_channel) {
buffered = 0; buffered = 0;
while (buffered < rd) { while (buffered < rd) {
pthread_mutex_lock(&(conn_inbuf.mutex)); pthread_mutex_lock(&(conn_inbuf.mutex));
...@@ -112,6 +149,13 @@ ssh_input_thread(void *args) ...@@ -112,6 +149,13 @@ ssh_input_thread(void *args)
buffered += conn_buf_put(&conn_inbuf, conn_api.rd_buf + buffered, buffer); buffered += conn_buf_put(&conn_inbuf, conn_api.rd_buf + buffered, buffer);
pthread_mutex_unlock(&(conn_inbuf.mutex)); pthread_mutex_unlock(&(conn_inbuf.mutex));
} }
if (gchstatus == CRYPT_ERROR_NOTFOUND) {
ssh_channel = -1;
}
}
else {
assert(true);
cryptlib_error_message(gchstatus, "unknown channel");
} }
} }
} }
...@@ -128,7 +172,7 @@ ssh_output_thread(void *args) ...@@ -128,7 +172,7 @@ ssh_output_thread(void *args)
SetThreadName("SSH Output"); SetThreadName("SSH Output");
conn_api.output_thread_running = 1; conn_api.output_thread_running = 1;
while (ssh_active && !conn_api.terminate) { while (ssh_active && !conn_api.terminate && ssh_channel != -1) {
pthread_mutex_lock(&(conn_outbuf.mutex)); pthread_mutex_lock(&(conn_outbuf.mutex));
wr = conn_buf_wait_bytes(&conn_outbuf, 1, 100); wr = conn_buf_wait_bytes(&conn_outbuf, 1, 100);
if (wr) { if (wr) {
...@@ -138,17 +182,19 @@ ssh_output_thread(void *args) ...@@ -138,17 +182,19 @@ ssh_output_thread(void *args)
while (ssh_active && sent < wr) { while (ssh_active && sent < wr) {
ret = 0; ret = 0;
pthread_mutex_lock(&ssh_mutex); pthread_mutex_lock(&ssh_mutex);
if (ssh_channel == -1) {
pthread_mutex_unlock(&ssh_mutex);
break;
}
status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, ssh_channel); status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, ssh_channel);
if (cryptStatusOK(status)) if (cryptStatusOK(status))
status = cl.PushData(ssh_session, conn_api.wr_buf + sent, wr - sent, &ret); status = cl.PushData(ssh_session, conn_api.wr_buf + sent, wr - sent, &ret);
pthread_mutex_unlock(&ssh_mutex); pthread_mutex_unlock(&ssh_mutex);
if (cryptStatusError(status)) { if (cryptStatusError(status)) {
if ((status == CRYPT_ERROR_COMPLETE) || (status == CRYPT_ERROR_NOTFOUND)) { /* connection closed */ if ((status == CRYPT_ERROR_COMPLETE) || (status == CRYPT_ERROR_NOTFOUND)) { /* connection closed */
ssh_active = true;
break; break;
} }
cryptlib_error_message(status, "sending data"); cryptlib_error_message(status, "sending data");
ssh_active = true;
break; break;
} }
sent += ret; sent += ret;
...@@ -187,11 +233,9 @@ sftp_send(uint8_t *buf, size_t sz, void *cb_data) ...@@ -187,11 +233,9 @@ sftp_send(uint8_t *buf, size_t sz, void *cb_data)
cryptlib_error_message(status, "sending sftp data"); cryptlib_error_message(status, "sending sftp data");
if (cryptStatusError(status)) { if (cryptStatusError(status)) {
if (status == CRYPT_ERROR_COMPLETE) { /* connection closed */ if (status == CRYPT_ERROR_COMPLETE) { /* connection closed */
ssh_active = true; // TODO: Why are we doing this?
break; break;
} }
cryptlib_error_message(status, "sending sftp data"); cryptlib_error_message(status, "sending sftp data");
ssh_active = true;
break; break;
} }
sent += ret; sent += ret;
...@@ -380,6 +424,7 @@ ssh_connect(struct bbslist *bbs) ...@@ -380,6 +424,7 @@ ssh_connect(struct bbslist *bbs)
uifc.pop(NULL); uifc.pop(NULL);
return -1; return -1;
} }
cl.FlushData(ssh_session);
ssh_active = true; ssh_active = true;
if (!bbs->hidepopups) { if (!bbs->hidepopups) {
...@@ -426,57 +471,47 @@ ssh_connect(struct bbslist *bbs) ...@@ -426,57 +471,47 @@ ssh_connect(struct bbslist *bbs)
#if NOTYET #if NOTYET
// TODO: Without this sleep, all is woe. // TODO: Without this sleep, all is woe.
SLEEP(10); //SLEEP(10);
while (!conn_api.input_thread_running)
SLEEP(1);
if (cryptStatusOK(status)) { if (cryptStatusOK(status)) {
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
if (!bbs->hidepopups) { if (!bbs->hidepopups) {
/* Clear ownership */ /* Clear ownership */
uifc.pop(NULL); uifc.pop(NULL);
uifc.pop("Creating SFTP Channel"); uifc.pop("Creating SFTP Channel");
} }
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
pthread_mutex_lock(&ssh_mutex); pthread_mutex_lock(&ssh_mutex);
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, CRYPT_UNUSED); status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, CRYPT_UNUSED);
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
if (cryptStatusError(status)) if (cryptStatusError(status))
cryptlib_error_message(status, "setting new channel"); cryptlib_error_message(status, "setting new channel");
if (cryptStatusOK(status)) { if (cryptStatusOK(status)) {
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
status = cl.SetAttributeString(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_TYPE, "subsystem", 9); status = cl.SetAttributeString(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_TYPE, "subsystem", 9);
if (cryptStatusError(status)) if (cryptStatusError(status))
cryptlib_error_message(status, "setting channel type"); cryptlib_error_message(status, "setting channel type");
if (cryptStatusOK(status)) { if (cryptStatusOK(status)) {
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
status = cl.SetAttributeString(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_ARG1, "sftp", 4); status = cl.SetAttributeString(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_ARG1, "sftp", 4);
if (cryptStatusError(status)) if (cryptStatusError(status))
cryptlib_error_message(status, "setting subsystem"); cryptlib_error_message(status, "setting subsystem");
if (cryptStatusOK(status)) { if (cryptStatusOK(status)) {
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
status = cl.GetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, &sftp_channel); status = cl.GetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, &sftp_channel);
if (cryptStatusError(status)) if (cryptStatusError(status))
cryptlib_error_message(status, "getting new channel"); cryptlib_error_message(status, "getting new channel");
if (cryptStatusOK(status)) { if (cryptStatusOK(status)) {
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
// TODO: Do something... // TODO: Do something...
} }
} }
} }
} }
pthread_mutex_unlock(&ssh_mutex);
} }
if (sftp_channel != -1) { if (sftp_channel != -1) {
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
pthread_mutex_lock(&ssh_mutex); pthread_mutex_lock(&ssh_mutex);
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__); cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, sftp_channel);
status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, 1); status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE, 1);
pthread_mutex_unlock(&ssh_mutex); pthread_mutex_unlock(&ssh_mutex);
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__); if (cryptStatusError(status)) {
if (cryptStatusError(status))
cryptlib_error_message(status, "activating sftp session"); cryptlib_error_message(status, "activating sftp session");
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__); }
if (cryptStatusOK(status)) { if (cryptStatusOK(status)) {
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__);
sftp_state = sftpc_begin(sftp_send, NULL); sftp_state = sftpc_begin(sftp_send, NULL);
if (sftp_state == NULL) if (sftp_state == NULL)
fprintf(stderr, "Failure!\n"); fprintf(stderr, "Failure!\n");
...@@ -498,7 +533,8 @@ ssh_close(void) ...@@ -498,7 +533,8 @@ ssh_close(void)
char garbage[1024]; char garbage[1024];
conn_api.terminate = 1; conn_api.terminate = 1;
cl.SetAttribute(ssh_session, CRYPT_SESSINFO_ACTIVE, 0); close_sftp_channel();
close_ssh_channel();
ssh_active = false; ssh_active = false;
while (conn_api.input_thread_running == 1 || conn_api.output_thread_running == 1) { while (conn_api.input_thread_running == 1 || conn_api.output_thread_running == 1) {
conn_recv_upto(garbage, sizeof(garbage), 0); conn_recv_upto(garbage, sizeof(garbage), 0);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment