2020-06-08 17:53:38 +01:00
/*
* ssheven
*
* Copyright ( c ) 2020 by cy384 < cy384 @ cy384 . com >
* See LICENSE file for details
*/
// retro68 stdio/console library
# include <stdio.h>
// open transport
# include <OpenTransport.h>
# include <OpenTptInternet.h>
// mac os threads
# include <Threads.h>
2020-06-14 04:33:25 +01:00
// libssh2
# include <libssh2.h>
2020-06-16 01:51:36 +01:00
const char * libssh2_error_string ( int i )
{
switch ( i )
{
case LIBSSH2_ERROR_NONE :
return " no error (LIBSSH2_ERROR_NONE) " ;
case LIBSSH2_ERROR_BANNER_RECV :
return " LIBSSH2_ERROR_BANNER_RECV " ;
case LIBSSH2_ERROR_BANNER_SEND :
return " LIBSSH2_ERROR_BANNER_SEND " ;
case LIBSSH2_ERROR_INVALID_MAC :
return " LIBSSH2_ERROR_INVALID_MAC " ;
case LIBSSH2_ERROR_KEX_FAILURE :
return " LIBSSH2_ERROR_KEX_FAILURE " ;
case LIBSSH2_ERROR_ALLOC :
return " LIBSSH2_ERROR_ALLOC " ;
case LIBSSH2_ERROR_SOCKET_SEND :
return " LIBSSH2_ERROR_SOCKET_SEND " ;
case LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE :
return " LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE " ;
case LIBSSH2_ERROR_TIMEOUT :
return " LIBSSH2_ERROR_TIMEOUT " ;
case LIBSSH2_ERROR_HOSTKEY_INIT :
return " LIBSSH2_ERROR_HOSTKEY_INIT " ;
case LIBSSH2_ERROR_HOSTKEY_SIGN :
return " LIBSSH2_ERROR_HOSTKEY_SIGN " ;
case LIBSSH2_ERROR_DECRYPT :
return " LIBSSH2_ERROR_DECRYPT " ;
case LIBSSH2_ERROR_SOCKET_DISCONNECT :
return " LIBSSH2_ERROR_SOCKET_DISCONNECT " ;
case LIBSSH2_ERROR_PROTO :
return " LIBSSH2_ERROR_PROTO " ;
case LIBSSH2_ERROR_PASSWORD_EXPIRED :
return " LIBSSH2_ERROR_PASSWORD_EXPIRED " ;
case LIBSSH2_ERROR_FILE :
return " LIBSSH2_ERROR_FILE " ;
case LIBSSH2_ERROR_METHOD_NONE :
return " LIBSSH2_ERROR_METHOD_NONE " ;
case LIBSSH2_ERROR_AUTHENTICATION_FAILED :
return " LIBSSHLIBSSH2_ERROR_AUTHENTICATION_FAILED2_ERROR_NONE " ;
case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED :
return " LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED " ;
case LIBSSH2_ERROR_CHANNEL_OUTOFORDER :
return " LIBSSH2_ERROR_CHANNEL_OUTOFORDER " ;
case LIBSSH2_ERROR_CHANNEL_FAILURE :
return " LIBSSH2_ERROR_CHANNEL_FAILURE " ;
case LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED :
return " LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED " ;
case LIBSSH2_ERROR_CHANNEL_UNKNOWN :
return " LIBSSH2_ERROR_CHANNEL_UNKNOWN " ;
case LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED :
return " LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED " ;
case LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED :
return " LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED " ;
case LIBSSH2_ERROR_CHANNEL_CLOSED :
return " LIBSSH2_ERROR_CHANNEL_CLOSED " ;
case LIBSSH2_ERROR_CHANNEL_EOF_SENT :
return " LIBSSH2_ERROR_CHANNEL_EOF_SENT " ;
case LIBSSH2_ERROR_SCP_PROTOCOL :
return " LIBSSH2_ERROR_SCP_PROTOCOL " ;
case LIBSSH2_ERROR_ZLIB :
return " LIBSSH2_ERROR_ZLIB " ;
case LIBSSH2_ERROR_SOCKET_TIMEOUT :
return " LIBSSH2_ERROR_SOCKET_TIMEOUT " ;
case LIBSSH2_ERROR_SFTP_PROTOCOL :
return " LIBSSH2_ERROR_SFTP_PROTOCOL " ;
case LIBSSH2_ERROR_REQUEST_DENIED :
return " LIBSSH2_ERROR_REQUEST_DENIED " ;
case LIBSSH2_ERROR_METHOD_NOT_SUPPORTED :
return " LIBSSH2_ERROR_METHOD_NOT_SUPPORTED " ;
case LIBSSH2_ERROR_INVAL :
return " LIBSSH2_ERROR_INVAL " ;
case LIBSSH2_ERROR_INVALID_POLL_TYPE :
return " LIBSSH2_ERROR_INVALID_POLL_TYPE " ;
case LIBSSH2_ERROR_PUBLICKEY_PROTOCOL :
return " LIBSSH2_ERROR_PUBLICKEY_PROTOCOL " ;
case LIBSSH2_ERROR_EAGAIN :
return " LIBSSH2_ERROR_EAGAIN " ;
case LIBSSH2_ERROR_BUFFER_TOO_SMALL :
return " LIBSSH2_ERROR_BUFFER_TOO_SMALL " ;
case LIBSSH2_ERROR_BAD_USE :
return " LIBSSH2_ERROR_BAD_USE " ;
case LIBSSH2_ERROR_COMPRESS :
return " LIBSSH2_ERROR_COMPRESS " ;
case LIBSSH2_ERROR_OUT_OF_BOUNDARY :
return " LIBSSH2_ERROR_OUT_OF_BOUNDARY " ;
case LIBSSH2_ERROR_AGENT_PROTOCOL :
return " LIBSSH2_ERROR_SOCKET_RECV " ;
case LIBSSH2_ERROR_SOCKET_RECV :
return " LIBSSH2_ERROR_ENCRYPT " ;
case LIBSSH2_ERROR_ENCRYPT :
return " LIBSSH2_ERROR_ENCRYPT " ;
case LIBSSH2_ERROR_BAD_SOCKET :
return " LIBSSH2_ERROR_BAD_SOCKET " ;
case LIBSSH2_ERROR_KNOWN_HOSTS :
return " LIBSSH2_ERROR_KNOWN_HOSTS " ;
case LIBSSH2_ERROR_CHANNEL_WINDOW_FULL :
return " LIBSSH2_ERROR_CHANNEL_WINDOW_FULL " ;
case LIBSSH2_ERROR_KEYFILE_AUTH_FAILED :
return " LIBSSH2_ERROR_KEYFILE_AUTH_FAILED " ;
default :
return " unknown error number " ;
}
return " what??? " ;
}
2020-06-14 04:33:25 +01:00
enum { buffer_size = 4096 } ;
void assertp ( char * message , int b )
{
2020-06-18 01:49:37 +01:00
if ( ! b ) printf ( " assert fail: %s (%d) \n " , message , b ) ;
2020-06-14 04:33:25 +01:00
}
// event handler to yield whenever we're blocked
static pascal void yield_notifier ( void * contextPtr , OTEventCode code , OTResult result , void * cookie )
{
switch ( code )
{
case kOTSyncIdleEvent :
YieldToAnyThread ( ) ;
break ;
default :
break ;
}
}
void do_ssh_connection ( void )
{
2020-06-18 01:49:37 +01:00
char * hostname = " 10.0.2.2:22 " ;
2020-06-14 04:33:25 +01:00
char * command = " uname " ;
char * username = " ssheven " ;
char * password = " password " ;
LIBSSH2_CHANNEL * channel ;
LIBSSH2_SESSION * session ;
int rc ;
// make and set up OT connection
OSStatus err = noErr ;
Ptr buffer = nil ;
EndpointRef endpoint = kOTInvalidEndpointRef ;
TCall sndCall ;
DNSAddress hostDNSAddress ;
// allocate buffer
buffer = OTAllocMem ( buffer_size ) ;
if ( buffer = = nil )
{
2020-06-18 01:49:37 +01:00
printf ( " could not get memory!!! \n " ) ;
2020-06-16 01:51:36 +01:00
return ;
2020-06-14 04:33:25 +01:00
}
2020-06-16 01:51:36 +01:00
else
2020-06-14 04:33:25 +01:00
{
2020-06-18 01:49:37 +01:00
printf ( " got mem \n " ) ;
2020-06-14 04:33:25 +01:00
}
2020-06-16 01:51:36 +01:00
// open TCP endpoint
endpoint = OTOpenEndpoint ( OTCreateConfiguration ( kTCPName ) , 0 , nil , & err ) ;
assertp ( " endpoint opened " , err = = noErr ) ;
if ( err ! = noErr ) return ;
2020-06-14 04:33:25 +01:00
// configure the endpoint
// synchronous and blocking, and we yield until we get a result
2020-06-16 01:51:36 +01:00
OSStatus result ;
2020-06-14 04:33:25 +01:00
2020-06-16 01:51:36 +01:00
result = OTSetSynchronous ( endpoint ) ;
assertp ( " OTSetSynchronous failed " , result = = noErr ) ;
2020-06-14 04:33:25 +01:00
2020-06-16 01:51:36 +01:00
result = OTSetBlocking ( endpoint ) ;
assertp ( " OTSetBlocking failed " , result = = noErr ) ;
2020-06-14 04:33:25 +01:00
2020-06-16 01:51:36 +01:00
result = OTInstallNotifier ( endpoint , yield_notifier , nil ) ;
assertp ( " OTInstallNotifier failed " , result = = noErr ) ;
2020-06-14 04:33:25 +01:00
2020-06-16 01:51:36 +01:00
result = OTUseSyncIdleEvents ( endpoint , true ) ;
assertp ( " OTUseSyncIdleEvents failed " , result = = noErr ) ;
err = OTBind ( endpoint , nil , nil ) ;
assertp ( " OTBind failed " , err = = noErr ) ;
if ( err ! = noErr ) return ;
2020-06-14 04:33:25 +01:00
// set up address struct and connect
2020-06-16 01:51:36 +01:00
OTMemzero ( & sndCall , sizeof ( TCall ) ) ;
2020-06-14 04:33:25 +01:00
2020-06-16 01:51:36 +01:00
sndCall . addr . buf = ( UInt8 * ) & hostDNSAddress ;
sndCall . addr . len = OTInitDNSAddress ( & hostDNSAddress , ( char * ) hostname ) ;
err = 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 ) ;
2020-06-14 04:33:25 +01:00
// init libssh2
rc = libssh2_init ( 0 ) ;
2020-06-16 01:51:36 +01:00
printf ( " init rc %s \n " , libssh2_error_string ( rc ) ) ;
2020-06-14 04:33:25 +01:00
session = libssh2_session_init ( ) ;
2020-06-16 01:51:36 +01:00
if ( session ! = 0 )
{
printf ( " session ok \n " ) ;
}
else
{
printf ( " session fail \n " ) ;
return ;
}
2020-06-14 04:33:25 +01:00
// I think we stubbed this function out, lol
//libssh2_session_set_blocking(session, endpoint);
// replace 0 with the OT connection
2020-06-16 01:51:36 +01:00
rc = libssh2_session_handshake ( session , endpoint ) ;
printf ( " handshake rc %s \n " , libssh2_error_string ( rc ) ) ;
if ( rc ! = LIBSSH2_ERROR_NONE ) return ;
//while((rc = libssh2_session_handshake(session, endpoint)) == LIBSSH2_ERROR_EAGAIN);
2020-06-14 04:33:25 +01:00
2020-06-18 01:49:37 +01:00
rc = libssh2_userauth_password ( session , username , password ) ;
2020-06-16 01:51:36 +01:00
printf ( " authenticate rc %s \n " , libssh2_error_string ( rc ) ) ;
if ( rc ! = LIBSSH2_ERROR_NONE ) return ;
/*
2020-06-14 04:33:25 +01:00
// are we required to look at the known hosts? see if we can skip for now
while ( ( rc = libssh2_userauth_password ( session , username , password ) ) = = LIBSSH2_ERROR_EAGAIN ) ;
assertp ( " pw login failed " , ! rc ) ;
while ( ( channel = libssh2_channel_open_session ( session ) ) = = NULL & & libssh2_session_last_error ( session , NULL , NULL , 0 ) = = LIBSSH2_ERROR_EAGAIN )
{
; //waitsocket(sock, session); // need this?
}
assertp ( " channel open failed " , channel ! = 0 ) ;
while ( ( rc = libssh2_channel_exec ( channel , command ) ) = = LIBSSH2_ERROR_EAGAIN ) ;
assertp ( " exec channel open failed " , rc = = 0 ) ;
// TODO: do the actual read here!
while ( ( rc = libssh2_channel_close ( channel ) ) = = LIBSSH2_ERROR_EAGAIN ) ;
assertp ( " channel close failed " , rc = = 0 ) ;
// skipping some other stuff here
2020-06-16 01:51:36 +01:00
*/
//libssh2_channel_free(channel);
2020-06-14 04:33:25 +01:00
libssh2_session_disconnect ( session , " Normal Shutdown, Thank you for playing " ) ;
2020-06-16 01:51:36 +01:00
2020-06-14 04:33:25 +01:00
libssh2_session_free ( session ) ;
2020-06-18 01:49:37 +01:00
libssh2_exit ( ) ;
2020-06-14 04:33:25 +01:00
// OT cleanup
2020-06-16 01:51:36 +01:00
result = OTUnbind ( endpoint ) ;
2020-06-14 04:33:25 +01:00
assertp ( " OTUnbind failed " , result = = noErr ) ;
// if we set up an endpoint, close it
if ( endpoint ! = kOTInvalidEndpointRef )
{
OSStatus result = OTCloseProvider ( endpoint ) ;
assertp ( " OTCloseProvider failed " , result = = noErr ) ;
}
// if we got a buffer, release it
if ( buffer ! = nil ) OTFreeMem ( buffer ) ;
return ;
}
2020-06-08 17:53:38 +01:00
int main ( int argc , char * * argv )
{
printf ( " hello, world \n " ) ;
2020-06-14 04:33:25 +01:00
2020-06-16 01:51:36 +01:00
if ( InitOpenTransport ( ) ! = noErr )
{
printf ( " failed to init OT \n " ) ;
return 0 ;
}
2020-06-14 04:33:25 +01:00
do_ssh_connection ( ) ;
2020-06-08 17:53:38 +01:00
2020-06-16 01:51:36 +01:00
CloseOpenTransport ( ) ;
2020-06-18 01:49:37 +01:00
printf ( " \n (a to exit) \n " ) ;
2020-06-16 01:51:36 +01:00
while ( getchar ( ) ! = ' a ' ) ;
2020-06-08 17:53:38 +01:00
return 0 ;
}