mirror of https://github.com/cy384/ssheven.git
improve error handling, allow user to input stuff
This commit is contained in:
parent
3893ca8d62
commit
98e3bf2d57
|
@ -7,7 +7,7 @@ set_target_properties(ssheven PROPERTIES COMPILE_OPTIONS -ffunction-sections)
|
||||||
IF(CMAKE_SYSTEM_NAME MATCHES Retro68)
|
IF(CMAKE_SYSTEM_NAME MATCHES Retro68)
|
||||||
# for 68k
|
# for 68k
|
||||||
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-strip-macsbug -Wl,--mac-segments -Wl,${CMAKE_CURRENT_SOURCE_DIR}/ssheven.segmap")
|
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections -Wl,--mac-strip-macsbug -Wl,--mac-segments -Wl,${CMAKE_CURRENT_SOURCE_DIR}/ssheven.segmap")
|
||||||
target_link_libraries(ssheven RetroConsole ThreadsLib ssh2 mbedtls mbedx509 mbedcrypto OpenTransportApp OpenTransport OpenTptInet)
|
target_link_libraries(ssheven RetroConsole ssh2 mbedtls mbedx509 mbedcrypto OpenTransportApp OpenTransport OpenTptInet)
|
||||||
ELSE()
|
ELSE()
|
||||||
# for PPC
|
# for PPC
|
||||||
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
|
set_target_properties(ssheven PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
|
||||||
|
|
185
ssheven.c
185
ssheven.c
|
@ -18,6 +18,12 @@
|
||||||
// libssh2
|
// libssh2
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
// network buffer size
|
||||||
|
enum { buffer_size = 4096 };
|
||||||
|
|
||||||
|
// text input buffer size
|
||||||
|
enum { input_buffer_size = 128 };
|
||||||
|
|
||||||
const char* libssh2_error_string(int i)
|
const char* libssh2_error_string(int i)
|
||||||
{
|
{
|
||||||
switch (i)
|
switch (i)
|
||||||
|
@ -123,14 +129,7 @@ const char* libssh2_error_string(int i)
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "what???";
|
return "should never return from here?";
|
||||||
}
|
|
||||||
|
|
||||||
enum { buffer_size = 4096 };
|
|
||||||
|
|
||||||
void assertp(char* message, int b)
|
|
||||||
{
|
|
||||||
if (!b) printf("assert fail: %s (%d)\n", message, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// event handler to yield whenever we're blocked
|
// event handler to yield whenever we're blocked
|
||||||
|
@ -147,107 +146,94 @@ static pascal void yield_notifier(void* contextPtr, OTEventCode code, OTResult r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_ssh_connection(void)
|
void get_line(char* buffer)
|
||||||
{
|
{
|
||||||
char* hostname = "10.0.2.2:22";
|
int i = 0;
|
||||||
char* username = "ssheven";
|
char c;
|
||||||
char* password = "password";
|
|
||||||
char* command = "uname -a";
|
|
||||||
|
|
||||||
|
while (i < input_buffer_size - 1)
|
||||||
|
{
|
||||||
|
c = getc(stdin);
|
||||||
|
if (c != '\n') buffer[i++] = c; else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_ssh_connection(char* hostname, char* username, char* password, char* command)
|
||||||
|
{
|
||||||
|
// libssh2 vars
|
||||||
LIBSSH2_CHANNEL* channel;
|
LIBSSH2_CHANNEL* channel;
|
||||||
LIBSSH2_SESSION* session;
|
LIBSSH2_SESSION* session;
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
// make and set up OT connection
|
// OT vars
|
||||||
OSStatus err = noErr;
|
OSStatus err = noErr;
|
||||||
Ptr buffer = nil;
|
char* buffer = NULL;
|
||||||
EndpointRef endpoint = kOTInvalidEndpointRef;
|
EndpointRef endpoint = kOTInvalidEndpointRef;
|
||||||
TCall sndCall;
|
TCall sndCall;
|
||||||
DNSAddress hostDNSAddress;
|
DNSAddress hostDNSAddress;
|
||||||
|
OSStatus result;
|
||||||
|
OTFlags ot_flags;
|
||||||
|
|
||||||
// allocate buffer
|
// allocate buffer
|
||||||
buffer = OTAllocMem(buffer_size);
|
buffer = OTAllocMem(buffer_size);
|
||||||
if (buffer == nil)
|
if (buffer == NULL)
|
||||||
{
|
{
|
||||||
printf("could not get memory!!!\n");
|
printf("failed to allocate OT buffer\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("got OT buffer\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// open TCP endpoint
|
// open TCP endpoint
|
||||||
endpoint = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
|
endpoint = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
|
||||||
assertp("endpoint opened", err == noErr);
|
if (err != noErr)
|
||||||
if (err != noErr) return;
|
{
|
||||||
|
printf("failed to open TCP endpoint\n");
|
||||||
|
if (buffer != NULL) OTFreeMem(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// configure the endpoint
|
#define OT_CHECK(X) err = (X); if (err != noErr) { printf("" #X " failed: %d\n", err); goto OT_cleanup; };
|
||||||
// synchronous and blocking, and we yield until we get a result
|
|
||||||
|
|
||||||
OSStatus result;
|
OT_CHECK(OTSetSynchronous(endpoint));
|
||||||
|
OT_CHECK(OTSetBlocking(endpoint));
|
||||||
result = OTSetSynchronous(endpoint);
|
OT_CHECK(OTInstallNotifier(endpoint, yield_notifier, nil));
|
||||||
assertp("OTSetSynchronous failed", result == noErr);
|
OT_CHECK(OTUseSyncIdleEvents(endpoint, true));
|
||||||
|
OT_CHECK(OTBind(endpoint, nil, nil));
|
||||||
result = OTSetBlocking(endpoint);
|
|
||||||
assertp("OTSetBlocking failed", result == noErr);
|
|
||||||
|
|
||||||
result = OTInstallNotifier(endpoint, yield_notifier, nil);
|
|
||||||
assertp("OTInstallNotifier failed", result == noErr);
|
|
||||||
|
|
||||||
result = OTUseSyncIdleEvents(endpoint, true);
|
|
||||||
assertp("OTUseSyncIdleEvents failed", result == noErr);
|
|
||||||
|
|
||||||
err = OTBind(endpoint, nil, nil);
|
|
||||||
assertp("OTBind failed", err == noErr);
|
|
||||||
|
|
||||||
if (err != noErr) return;
|
|
||||||
|
|
||||||
// set up address struct and connect
|
|
||||||
|
|
||||||
|
// set up address struct, do the DNS lookup, and connect
|
||||||
OTMemzero(&sndCall, sizeof(TCall));
|
OTMemzero(&sndCall, sizeof(TCall));
|
||||||
|
|
||||||
sndCall.addr.buf = (UInt8 *) &hostDNSAddress;
|
sndCall.addr.buf = (UInt8 *) &hostDNSAddress;
|
||||||
sndCall.addr.len = OTInitDNSAddress(&hostDNSAddress, (char *) hostname);
|
sndCall.addr.len = OTInitDNSAddress(&hostDNSAddress, (char *) hostname);
|
||||||
|
|
||||||
err = OTConnect(endpoint, &sndCall, nil);
|
OT_CHECK(OTConnect(endpoint, &sndCall, nil));
|
||||||
assertp("OTConnect failed", err == noErr);
|
|
||||||
|
|
||||||
if (err != noErr) return;
|
printf("OT setup done, endpoint: %d, (should not be %d for libssh2,"
|
||||||
|
" should not be %d for OT)\n", (int) endpoint,
|
||||||
|
(int) LIBSSH2_INVALID_SOCKET, (int) kOTInvalidEndpointRef);
|
||||||
|
|
||||||
printf("OT setup done, endpoint: %d, (should not be %d for libssh2, should not be %d for OT)\n", (int) endpoint, (int) LIBSSH2_INVALID_SOCKET, (int) kOTInvalidEndpointRef);
|
#define SSH_CHECK(X) rc = (X); if (rc != LIBSSH2_ERROR_NONE) { printf("" #X "failed: %s\n", libssh2_error_string(rc)); goto libssh2_cleanup; };
|
||||||
|
|
||||||
// init libssh2
|
// init libssh2
|
||||||
rc = libssh2_init(0);
|
SSH_CHECK(libssh2_init(0));
|
||||||
printf("init rc %s\n", libssh2_error_string(rc));
|
|
||||||
|
|
||||||
session = libssh2_session_init();
|
session = libssh2_session_init();
|
||||||
if (session != 0)
|
if (session == 0)
|
||||||
{
|
{
|
||||||
printf("session ok\n");
|
printf("failed to open SSH session\n");
|
||||||
}
|
goto libssh2_cleanup;
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("session fail\n");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_session_handshake(session, endpoint);
|
SSH_CHECK(libssh2_session_handshake(session, endpoint));
|
||||||
printf("handshake rc %s\n", libssh2_error_string(rc));
|
|
||||||
if (rc != LIBSSH2_ERROR_NONE) return;
|
|
||||||
|
|
||||||
rc = libssh2_userauth_password(session, username, password);
|
SSH_CHECK(libssh2_userauth_password(session, username, password));
|
||||||
printf("authenticate rc %s\n", libssh2_error_string(rc));
|
|
||||||
if (rc != LIBSSH2_ERROR_NONE) return;
|
|
||||||
|
|
||||||
channel = libssh2_channel_open_session(session);
|
channel = libssh2_channel_open_session(session);
|
||||||
printf("channel open: %d\n", channel);
|
printf("channel open: %d\n", channel);
|
||||||
|
|
||||||
printf("sending command \"%s\"\n", command);
|
SSH_CHECK(libssh2_channel_exec(channel, command));
|
||||||
rc = libssh2_channel_exec(channel, command);
|
|
||||||
printf("libssh2_channel_exec rc %s\n", libssh2_error_string(rc));
|
|
||||||
|
|
||||||
// read from the channel
|
// read from the channel
|
||||||
rc = libssh2_channel_read(channel, buffer, buffer_size);
|
rc = libssh2_channel_read(channel, buffer, buffer_size);
|
||||||
|
@ -262,23 +248,18 @@ void do_ssh_connection(void)
|
||||||
printf("channel read error: %s\n", libssh2_error_string(rc));
|
printf("channel read error: %s\n", libssh2_error_string(rc));
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_channel_close(channel);
|
libssh2_cleanup:
|
||||||
printf("libssh2_channel_close rc %s\n", libssh2_error_string(rc));
|
|
||||||
|
|
||||||
|
libssh2_channel_close(channel);
|
||||||
libssh2_channel_free(channel);
|
libssh2_channel_free(channel);
|
||||||
|
|
||||||
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
||||||
|
|
||||||
libssh2_session_free(session);
|
libssh2_session_free(session);
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
// request to close the TCP connection
|
// request to close the TCP connection
|
||||||
rc = OTSndOrderlyDisconnect(endpoint);
|
OT_CHECK(OTSndOrderlyDisconnect(endpoint));
|
||||||
assertp("OTSndOrderlyDisconnect failed", rc == noErr);
|
|
||||||
|
|
||||||
// get any remaining data so we can finish closing the connection
|
// get and discard remaining data so we can finish closing the connection
|
||||||
OTFlags ot_flags;
|
|
||||||
rc = 1;
|
rc = 1;
|
||||||
while (rc != kOTLookErr)
|
while (rc != kOTLookErr)
|
||||||
{
|
{
|
||||||
|
@ -286,26 +267,28 @@ void do_ssh_connection(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish closing the TCP connection
|
// finish closing the TCP connection
|
||||||
OTResult look_result = OTLook(endpoint);
|
result = OTLook(endpoint);
|
||||||
switch (look_result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case T_DISCONNECT:
|
case T_DISCONNECT:
|
||||||
err = OTRcvDisconnect(endpoint, nil);
|
OTRcvDisconnect(endpoint, nil);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("other connection error: %d\n", look_result);
|
printf("unexpected OTLook result while closing: %d\n", result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OT_cleanup:
|
||||||
|
|
||||||
// release endpoint
|
// release endpoint
|
||||||
result = OTUnbind(endpoint);
|
err = OTUnbind(endpoint);
|
||||||
assertp("OTUnbind failed", result == noErr);
|
if (err != noErr) printf("OTUnbind failed: %d\n", err);
|
||||||
|
|
||||||
result = OTCloseProvider(endpoint);
|
err = OTCloseProvider(endpoint);
|
||||||
assertp("OTCloseProvider failed", result == noErr);
|
if (err != noErr) printf("OTCloseProvider failed: %d\n", err);
|
||||||
|
|
||||||
// if we got a buffer, release it
|
// if we have a buffer, release it
|
||||||
if (buffer != nil) OTFreeMem(buffer);
|
if (buffer != nil) OTFreeMem(buffer);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -313,20 +296,40 @@ void do_ssh_connection(void)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
printf("starting up\n");
|
char hostname[input_buffer_size] = {0};
|
||||||
|
char username[input_buffer_size] = {0};
|
||||||
|
char password[input_buffer_size] = {0};
|
||||||
|
char command[input_buffer_size] = {0};
|
||||||
|
|
||||||
|
printf("WARNING: this is a prototype with a bad RNG and no host key checks,"
|
||||||
|
" do not use over untrusted networks or with untrusted SSH servers!\n\n");
|
||||||
|
|
||||||
|
printf("ssheven by cy384 version 0.0.0\n\n");
|
||||||
|
|
||||||
|
printf("enter a host:port >"); fflush(stdout);
|
||||||
|
get_line(hostname);
|
||||||
|
|
||||||
|
printf("enter a username >"); fflush(stdout);
|
||||||
|
get_line(username);
|
||||||
|
|
||||||
|
printf("enter a password >"); fflush(stdout);
|
||||||
|
get_line(password);
|
||||||
|
|
||||||
|
printf("enter a command >"); fflush(stdout);
|
||||||
|
get_line(command);
|
||||||
|
|
||||||
if (InitOpenTransport() != noErr)
|
if (InitOpenTransport() != noErr)
|
||||||
{
|
{
|
||||||
printf("failed to init OT \n");
|
printf("failed to initialize OT\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_ssh_connection();
|
do_ssh_connection(hostname, username, password, command);
|
||||||
|
|
||||||
CloseOpenTransport();
|
CloseOpenTransport();
|
||||||
|
|
||||||
printf("\n(a to exit)\n");
|
printf("\n(enter to exit)\n");
|
||||||
while (getchar() != 'a');
|
getchar();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue