From 0c6d04259ac11abe30cbdbbbcbc2e3943e3be251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Tue, 16 Mar 2021 08:15:25 -0400 Subject: [PATCH] Add support for the SSH "none" auth method. This is used by some BBSs to enable encryption without needing to integrate the BBS user base into their SSH server (and presumably so they don't need to run multiple SSH servers). All users log in with the same username (ie: "bbs") and no password is requested or required. Once the BBS starts, it prompts for the BBS user name and password as normal. In SyncTERM, the user/password/syspass fields are redefined as SSHuser/BBSuser/BBSpassword and they are moved around when you change the connection type. This means that if you change a listing that has a syspass to SSH (no auth) and back, the syspass is lost. I'm not sure if I plan to fix this or not. --- 3rdp/build/GNUmakefile | 3 +- 3rdp/build/cl-allow-none-auth.patch | 158 ++++++++++++++++++++++++++++ src/syncterm/bbslist.c | 68 +++++++++--- src/syncterm/conn.c | 7 +- src/syncterm/conn.h | 1 + src/syncterm/ssh.c | 49 ++++++--- src/syncterm/st_crypt.c | 5 + src/syncterm/st_crypt.h | 2 + src/syncterm/term.c | 10 +- 9 files changed, 263 insertions(+), 40 deletions(-) create mode 100644 3rdp/build/cl-allow-none-auth.patch diff --git a/3rdp/build/GNUmakefile b/3rdp/build/GNUmakefile index 8e615d93a1..8f21d156b1 100644 --- a/3rdp/build/GNUmakefile +++ b/3rdp/build/GNUmakefile @@ -81,7 +81,7 @@ $(CRYPT_SRC): | $(3RDPSRCDIR) $(CRYPT_IDIR): | $(3RDPODIR) $(QUIET)$(IFNOTEXIST) mkdir $(CRYPT_IDIR) -$(CRYPTLIB_BUILD): $(3RDP_ROOT)$(DIRSEP)dist/cryptlib.zip $(3RDP_ROOT)$(DIRSEP)build/terminal-params.patch $(3RDP_ROOT)$(DIRSEP)build/cl-mingw32-static.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ranlib.patch $(3RDP_ROOT)$(DIRSEP)build/cl-win32-noasm.patch $(3RDP_ROOT)$(DIRSEP)build/cl-zz-country.patch $(3RDP_ROOT)$(DIRSEP)build/cl-algorithms.patch $(3RDP_ROOT)$(DIRSEP)build/cl-allow-duplicate-ext.patch $(3RDP_ROOT)$(DIRSEP)build/cl-macosx-minver.patch $(3RDP_ROOT)$(DIRSEP)build/cl-endian.patch $(3RDP_ROOT)$(DIRSEP)build/cl-cryptodev.patch $(3RDP_ROOT)$(DIRSEP)build/cl-posix-me-gently.patch $(3RDP_ROOT)$(DIRSEP)build/cl-tpm-linux.patch $(3RDP_ROOT)$(DIRSEP)build/cl-PAM-noprompts.patch $(3RDP_ROOT)$(DIRSEP)build/cl-zlib.patch $(3RDP_ROOT)$(DIRSEP)build/Dynamic-linked-static-lib.patch $(3RDP_ROOT)$(DIRSEP)build/SSL-fix.patch $(3RDP_ROOT)$(DIRSEP)build/cl-bigger-maxattribute.patch $(3RDP_ROOT)$(DIRSEP)build/cl-vcxproj.patch $(3RDP_ROOT)$(DIRSEP)build/cl-mingw-vcver.patch $(3RDP_ROOT)$(DIRSEP)build/cl-win32-build-fix.patch $(3RDP_ROOT)$(DIRSEP)build/cl-gcc-non-const-time-val.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-odbc.patch $(3RDP_ROOT)$(DIRSEP)build/cl-noasm-defines.patch $(3RDP_ROOT)$(DIRSEP)build/cl-bn-noasm64-fix.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-RSA-suites.patch $(3RDP_ROOT)$(DIRSEP)build/cl-fix-ECC-RSA.patch $(3RDP_ROOT)$(DIRSEP)build/cl-prefer-ECC.patch $(3RDP_ROOT)$(DIRSEP)build/cl-prefer-ECC-harder.patch $(3RDP_ROOT)$(DIRSEP)build/cl-more-RSA-ECC-fixes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-DH-key-init.patch $(3RDP_ROOT)$(DIRSEP)build/cl-clear-GCM-flag.patch $(3RDP_ROOT)$(DIRSEP)build/cl-use-ssh-ctr.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ssh-list-ctr-modes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ssh-incCtr.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ssl-suite-blocksizes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-tpm.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-via-aes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-fix-ssh-ecc-ephemeral.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-just-use-cc.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-learn-numbers.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-no-safe-stack.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-allow-pkcs12.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-uint64_t-redefine.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-random-openbsd.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-openbsd-threads.patch | $(CRYPT_SRC) $(CRYPT_IDIR) +$(CRYPTLIB_BUILD): $(3RDP_ROOT)$(DIRSEP)dist/cryptlib.zip $(3RDP_ROOT)$(DIRSEP)build/terminal-params.patch $(3RDP_ROOT)$(DIRSEP)build/cl-mingw32-static.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ranlib.patch $(3RDP_ROOT)$(DIRSEP)build/cl-win32-noasm.patch $(3RDP_ROOT)$(DIRSEP)build/cl-zz-country.patch $(3RDP_ROOT)$(DIRSEP)build/cl-algorithms.patch $(3RDP_ROOT)$(DIRSEP)build/cl-allow-duplicate-ext.patch $(3RDP_ROOT)$(DIRSEP)build/cl-macosx-minver.patch $(3RDP_ROOT)$(DIRSEP)build/cl-endian.patch $(3RDP_ROOT)$(DIRSEP)build/cl-cryptodev.patch $(3RDP_ROOT)$(DIRSEP)build/cl-posix-me-gently.patch $(3RDP_ROOT)$(DIRSEP)build/cl-tpm-linux.patch $(3RDP_ROOT)$(DIRSEP)build/cl-PAM-noprompts.patch $(3RDP_ROOT)$(DIRSEP)build/cl-zlib.patch $(3RDP_ROOT)$(DIRSEP)build/Dynamic-linked-static-lib.patch $(3RDP_ROOT)$(DIRSEP)build/SSL-fix.patch $(3RDP_ROOT)$(DIRSEP)build/cl-bigger-maxattribute.patch $(3RDP_ROOT)$(DIRSEP)build/cl-vcxproj.patch $(3RDP_ROOT)$(DIRSEP)build/cl-mingw-vcver.patch $(3RDP_ROOT)$(DIRSEP)build/cl-win32-build-fix.patch $(3RDP_ROOT)$(DIRSEP)build/cl-gcc-non-const-time-val.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-odbc.patch $(3RDP_ROOT)$(DIRSEP)build/cl-noasm-defines.patch $(3RDP_ROOT)$(DIRSEP)build/cl-bn-noasm64-fix.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-RSA-suites.patch $(3RDP_ROOT)$(DIRSEP)build/cl-fix-ECC-RSA.patch $(3RDP_ROOT)$(DIRSEP)build/cl-prefer-ECC.patch $(3RDP_ROOT)$(DIRSEP)build/cl-prefer-ECC-harder.patch $(3RDP_ROOT)$(DIRSEP)build/cl-more-RSA-ECC-fixes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-DH-key-init.patch $(3RDP_ROOT)$(DIRSEP)build/cl-clear-GCM-flag.patch $(3RDP_ROOT)$(DIRSEP)build/cl-use-ssh-ctr.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ssh-list-ctr-modes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ssh-incCtr.patch $(3RDP_ROOT)$(DIRSEP)build/cl-ssl-suite-blocksizes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-tpm.patch $(3RDP_ROOT)$(DIRSEP)build/cl-no-via-aes.patch $(3RDP_ROOT)$(DIRSEP)build/cl-fix-ssh-ecc-ephemeral.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-just-use-cc.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-learn-numbers.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-no-safe-stack.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-allow-pkcs12.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-uint64_t-redefine.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-random-openbsd.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-openbsd-threads.patch $(3RDP_ROOT)$(DIRSEP)/build/cl-allow-none-auth.patch | $(CRYPT_SRC) $(CRYPT_IDIR) @echo Creating $@ ... $(QUIET)-rm -rf $(CRYPT_SRC)/* $(QUIET)unzip -oa $(3RDPDISTDIR)$(DIRSEP)cryptlib.zip -d $(CRYPT_SRC) @@ -131,6 +131,7 @@ $(CRYPTLIB_BUILD): $(3RDP_ROOT)$(DIRSEP)dist/cryptlib.zip $(3RDP_ROOT)$(DIRSEP)b $(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-uint64_t-redefine.patch $(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-random-openbsd.patch $(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-openbsd-threads.patch + $(QUIET)patch -b -p0 -d $(CRYPT_SRC) < cl-allow-none-auth.patch ifeq ($(CC),mingw32-gcc) $(QUIET)cd $(CRYPT_SRC) && env - PATH="$(PATH)" CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)" make directories $(QUIET)cd $(CRYPT_SRC) && env - PATH="$(PATH)" CC="$(CC)" AR="$(AR)" RANLIB="$(RANLIB)" make toolscripts diff --git a/3rdp/build/cl-allow-none-auth.patch b/3rdp/build/cl-allow-none-auth.patch new file mode 100644 index 0000000000..95ab0fd698 --- /dev/null +++ b/3rdp/build/cl-allow-none-auth.patch @@ -0,0 +1,158 @@ +--- ../cl-old/cryptlib.h 2021-03-16 04:15:50.265534000 -0400 ++++ ./cryptlib.h 2021-03-16 06:53:47.582168000 -0400 +@@ -1215,6 +1215,7 @@ + CRYPT_SESSINFO_SSH_CHANNEL_ARG1,/* SSH channel argument 1 */ + CRYPT_SESSINFO_SSH_CHANNEL_ARG2,/* SSH channel argument 2 */ + CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE,/* SSH channel active */ ++ CRYPT_SESSINFO_SSH_OPTIONS, /* SSH protocol options */ + CRYPT_SESSINFO_SSL_OPTIONS, /* SSL/TLS protocol options */ + CRYPT_SESSINFO_SSL_SUBPROTOCOL, /* SSL/TLS additional sub-protocol */ + CRYPT_SESSINFO_SSL_WSPROTOCOL, /* SSL/TLS WebSockets sub-protocol */ +@@ -1680,6 +1681,14 @@ + #define CRYPT_SSLOPTION_SUITEB_256 0x200 /* vanish in future releases) */ + #ifdef _CRYPT_DEFINED + #define CRYPT_SSLOPTION_MAX 0x7F /* Defines for range checking */ ++#endif /* _CRYPT_DEFINED */ ++ ++/* SSH protocol options. */ ++ ++#define CRYPT_SSHOPTION_NONE 0x000 ++#define CRYPT_SSHOPTION_NONE_AUTH 0x001 /* Try none authentication */ ++#ifdef _CRYPT_DEFINED ++#define CRYPT_SSHOPTION_MAX 0x01 /* Defines for range checking */ + #endif /* _CRYPT_DEFINED */ + + /**************************************************************************** +diff -ur ../cl-old/kernel/attr_acl.c ./kernel/attr_acl.c +--- ../cl-old/kernel/attr_acl.c 2021-03-16 04:15:50.398060000 -0400 ++++ ./kernel/attr_acl.c 2021-03-16 06:53:47.606473000 -0400 +@@ -3731,6 +3731,12 @@ + ST_NONE, ST_NONE, ST_SESS_SSH | ST_SESS_SSH_SVR, + MKPERM_SSH_EXT( RWx_xxx ), + ROUTE( OBJECT_TYPE_SESSION ) ), ++ MKACL_N( /* SSH protocol options */ ++ CRYPT_SESSINFO_SSH_OPTIONS, ++ ST_NONE, ST_NONE, ST_SESS_SSH, ++ MKPERM_SSH_EXT( Rxx_RWx ), ++ ROUTE( OBJECT_TYPE_SESSION ), ++ RANGE( CRYPT_SSHOPTION_NONE, CRYPT_SSHOPTION_MAX ) ), + + MKACL_N( /* SSL/TLS protocol options */ + CRYPT_SESSINFO_SSL_OPTIONS, +@@ -4653,7 +4659,7 @@ + static_assert( CRYPT_CERTINFO_FIRST_EXTENSION == 2200, "Attribute value" ); + static_assert( CRYPT_CERTINFO_FIRST_CMS == 2500, "Attribute value" ); + static_assert( CRYPT_SESSINFO_FIRST_SPECIFIC == 6016, "Attribute value" ); +- static_assert( CRYPT_SESSINFO_LAST_SPECIFIC == 6031, "Attribute value" ); ++ static_assert( CRYPT_SESSINFO_LAST_SPECIFIC == 6032, "Attribute value" ); + static_assert( CRYPT_CERTFORMAT_LAST == 12, "Attribute value" ); + + /* Perform a consistency check on the attribute ACLs. The ACLs are +diff -ur ../cl-old/session/ssh.c ./session/ssh.c +--- ../cl-old/session/ssh.c 2021-03-16 04:15:50.257467000 -0400 ++++ ./session/ssh.c 2021-03-16 06:53:47.638940000 -0400 +@@ -980,6 +980,18 @@ + type == CRYPT_SESSINFO_SSH_CHANNEL_ARG2 || \ + type == CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE ); + ++ if( type == CRYPT_SESSINFO_SSH_OPTIONS ) ++ { ++ int *valuePtr = ( int * ) data; ++ ++ *valuePtr = CRYPT_SSHOPTION_NONE; ++ if( TEST_FLAG( sessionInfoPtr->protocolFlags, ++ SSH_PFLAG_DUMMYUSERAUTH ) ) ++ *valuePtr |= CRYPT_SSHOPTION_NONE_AUTH; ++ ++ return( CRYPT_OK ); ++ } ++ + if( type == CRYPT_SESSINFO_SSH_CHANNEL || \ + type == CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE ) + { +@@ -1010,11 +1022,13 @@ + type == CRYPT_SESSINFO_SSH_CHANNEL_TYPE || \ + type == CRYPT_SESSINFO_SSH_CHANNEL_ARG1 || \ + type == CRYPT_SESSINFO_SSH_CHANNEL_ARG2 || \ ++ type == CRYPT_SESSINFO_SSH_OPTIONS || \ + type == CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE ); + + /* Get the data value if it's an integer parameter */ + if( type == CRYPT_SESSINFO_SSH_CHANNEL || \ +- type == CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE ) ++ type == CRYPT_SESSINFO_SSH_CHANNEL_ACTIVE || \ ++ type == CRYPT_SESSINFO_SSH_OPTIONS) + value = *( ( int * ) data ); + + /* If we're selecting a channel and there's unwritten data from a +@@ -1038,6 +1052,13 @@ + return( createChannel( sessionInfoPtr ) ); + } + ++ if( type == CRYPT_SESSINFO_SSH_OPTIONS ) ++ { ++ if (value & CRYPT_SSHOPTION_NONE_AUTH) ++ SET_FLAG( sessionInfoPtr->protocolFlags, SSH_PFLAG_DUMMYUSERAUTH ); ++ return( CRYPT_OK ); ++ } ++ + /* If we 're setting the channel-active attribute, this implicitly + activates or deactivates the channel rather than setting any + attribute value */ +@@ -1165,8 +1186,6 @@ + SESSION_FLAG_NONE, /* Flags */ + SSH_PORT, /* SSH port */ + SESSION_NEEDS_USERID | /* Client attributes */ +- SESSION_NEEDS_PASSWORD | \ +- SESSION_NEEDS_KEYORPASSWORD | \ + SESSION_NEEDS_PRIVKEYSIGN, + /* The client private key is optional, but if present it has + to be signature-capable */ +diff -ur ../cl-old/session/ssh2_authc.c ./session/ssh2_authc.c +--- ../cl-old/session/ssh2_authc.c 2021-03-16 04:15:50.264206000 -0400 ++++ ./session/ssh2_authc.c 2021-03-16 07:46:47.873769000 -0400 +@@ -315,13 +315,22 @@ + assert( isWritePtr( authAlgo, sizeof( CRYPT_ALGO_TYPE ) ) ); + assert( isWritePtr( furtherAuthRequired, sizeof( BOOLEAN ) ) ); + +- REQUIRES( isShortIntegerRangeNZ( length ) ); + REQUIRES( usedPasswordAuth == TRUE || usedPasswordAuth == FALSE ); + + /* Clear return values */ + *authAlgo = CRYPT_ALGO_NONE; + *furtherAuthRequired = FALSE; + ++ if (length == 0 && GET_FLAG( sessionInfoPtr->protocolFlags, SSH_PFLAG_DUMMYUSERAUTH ) && !usedPasswordAuth) ++ { ++ CLEAR_FLAG( sessionInfoPtr->protocolFlags, SSH_PFLAG_DUMMYUSERAUTH ); ++ *furtherAuthRequired = TRUE; ++ *authAlgo = CRYPT_PSEUDOALGO_PASSWORD; ++ return( CRYPT_OK ); ++ } ++ ++ REQUIRES( isShortIntegerRangeNZ( length ) ); ++ + /* Before we can try and interpret the response, we have to check for an + empty response */ + if( length >= LENGTH_SIZE && \ +@@ -647,6 +656,8 @@ + SSH_MSG_USERAUTH_REQUEST ); + if( cryptStatusError( status ) ) + return( status ); ++ if (passwordPtr == NULL && GET_FLAG( sessionInfoPtr->protocolFlags, SSH_PFLAG_DUMMYUSERAUTH )) ++ return( OK_SPECIAL ); + if( usePasswordAuth ) + { + /* byte type = SSH_MSG_USERAUTH_REQUEST +@@ -1220,6 +1231,11 @@ + auth required */ + if( !hasPassword ) + { ++ if (length == 0) ++ { ++ return( reportAuthFailure( sessionInfoPtr, CRYPT_PSEUDOALGO_PASSWORD, ++ requiredAuthAlgo, TRUE ) ); ++ } + return( reportAuthFailure( sessionInfoPtr, CRYPT_ALGO_RSA, + requiredAuthAlgo, TRUE ) ); + } diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c index 17695425cb..4fe5b12f30 100644 --- a/src/syncterm/bbslist.c +++ b/src/syncterm/bbslist.c @@ -966,10 +966,18 @@ int edit_list(struct bbslist **list, struct bbslist *item,char *listpath,int isd fc_str(opt[i++], item->flow_control); else if (item->conn_type != CONN_TYPE_SHELL) sprintf(opt[i++], "TCP Port %hu",item->port); - printf_trunc(opt[i], sizeof(opt[i]), "Username %s",item->user); - i++; - sprintf(opt[i++], "Password %s",item->password[0]?"********":"<none>"); - sprintf(opt[i++], "System Password %s",item->syspass[0]?"********":"<none>"); + if (item->conn_type == CONN_TYPE_SSHNA) { + printf_trunc(opt[i], sizeof(opt[i]), "SSH Username %s",item->user); + i++; + sprintf(opt[i++], "BBS Username %s",item->password); + sprintf(opt[i++], "BBS Password %s",item->syspass[0]?"********":"<none>"); + } + else { + printf_trunc(opt[i], sizeof(opt[i]), "Username %s",item->user); + i++; + sprintf(opt[i++], "Password %s",item->password[0]?"********":"<none>"); + sprintf(opt[i++], "System Password %s",item->syspass[0]?"********":"<none>"); + } sprintf(opt[i++], "Screen Mode %s",screen_modes[item->screen_mode]); sprintf(opt[i++], "Hide Status Line %s",item->nostatus?"Yes":"No"); printf_trunc(opt[i], sizeof(opt[i]), "Download Path %s", item->dldir); @@ -1179,27 +1187,45 @@ int edit_list(struct bbslist **list, struct bbslist *item,char *listpath,int isd } break; case 4: - uifc.helpbuf= "`Username`\n\n" - "Enter the username to attempt auto-login to the remote with.\n" - "For SSH, this must be the SSH user name."; + if (item->conn_type == CONN_TYPE_SSHNA) { + uifc.helpbuf= "`SSH Username`\n\n" + "Enter the username for passwordless SSH authentication."; + } + else { + uifc.helpbuf= "`Username`\n\n" + "Enter the username to attempt auto-login to the remote with.\n" + "For SSH, this must be the SSH user name."; + } uifc.input(WIN_MID|WIN_SAV,0,0,"Username",item->user,MAX_USER_LEN,K_EDIT); check_exit(FALSE); iniSetString(&inifile,itemname,"UserName",item->user,&ini_style); break; case 5: - uifc.helpbuf= "`Password`\n\n" - "Enter your password for auto-login.\n" - "For SSH, this must be the SSH password if it exists.\n"; + if (item->conn_type == CONN_TYPE_SSHNA) { + uifc.helpbuf= "`BBS Username`\n\n" + "Enter the username to be sent for auto-login (ALT-L)."; + } + else { + uifc.helpbuf= "`Password`\n\n" + "Enter your password for auto-login.\n" + "For SSH, this must be the SSH password if it exists.\n"; + } uifc.input(WIN_MID|WIN_SAV,0,0,"Password",item->password,MAX_PASSWD_LEN,K_EDIT); check_exit(FALSE); iniSetString(&inifile,itemname,"Password",item->password,&ini_style); break; case 6: - uifc.helpbuf= "`System Password`\n\n" - "Enter your System password for auto-login.\n" - "This password is sent after the username and password, so for non-\n" - "Synchronet, or non-sysop accounts, this can be used for simple\n" - "scripting."; + if (item->conn_type == CONN_TYPE_SSHNA) { + uifc.helpbuf= "`BBS Password`\n\n" + "Enter your password for auto-login. (ALT-L)\n"; + } + else { + uifc.helpbuf= "`System Password`\n\n" + "Enter your System password for auto-login.\n" + "This password is sent after the username and password, so for non-\n" + "Synchronet, or non-sysop accounts, this can be used for simple\n" + "scripting."; + } uifc.input(WIN_MID|WIN_SAV,0,0,"System Password",item->syspass,MAX_SYSPASS_LEN,K_EDIT); check_exit(FALSE); iniSetString(&inifile,itemname,"SystemPassword",item->syspass,&ini_style); @@ -1217,6 +1243,18 @@ int edit_list(struct bbslist **list, struct bbslist *item,char *listpath,int isd item->conn_type++; iniSetEnum(&inifile,itemname,"ConnectionType",conn_types_enum,item->conn_type,&ini_style); + // TODO: NOTE: This is destructive! Beware! Ooooooo.... + if (i == CONN_TYPE_SSHNA && item->conn_type != CONN_TYPE_SSHNA) { + SAFECOPY(item->user, item->password); + SAFECOPY(item->password, item->syspass); + item->syspass[0] = 0; + } + if (i != CONN_TYPE_SSHNA && item->conn_type == CONN_TYPE_SSHNA) { + SAFECOPY(item->syspass, item->password); + SAFECOPY(item->password, item->user); + item->user[0] = 0; + } + if(item->conn_type!=CONN_TYPE_MODEM && item->conn_type!=CONN_TYPE_SERIAL && item->conn_type!=CONN_TYPE_SHELL ) { diff --git a/src/syncterm/conn.c b/src/syncterm/conn.c index 6a04211ebd..572dab1c3e 100644 --- a/src/syncterm/conn.c +++ b/src/syncterm/conn.c @@ -45,9 +45,9 @@ #include "conn_telnet.h" struct conn_api conn_api; -char *conn_types_enum[]={"Unknown","RLogin","RLoginReversed","Telnet","Raw","SSH","Modem","Serial","Shell","MBBSGhost","TelnetS", NULL}; -char *conn_types[]={"Unknown","RLogin","RLogin Reversed","Telnet","Raw","SSH","Modem","Serial","Shell","MBBS GHost","TelnetS",NULL}; -short unsigned int conn_ports[]={0,513,513,23,0,22,0,0,0,65535,992,0}; +char *conn_types_enum[]={"Unknown","RLogin","RLoginReversed","Telnet","Raw","SSH","SSHNA","Modem","Serial","Shell","MBBSGhost","TelnetS", NULL}; +char *conn_types[]={"Unknown","RLogin","RLogin Reversed","Telnet","Raw","SSH","SSH (no auth)","Modem","Serial","Shell","MBBS GHost","TelnetS",NULL}; +short unsigned int conn_ports[]={0,513,513,23,0,22,22,0,0,0,65535,992,0}; struct conn_buffer conn_inbuf; struct conn_buffer conn_outbuf; @@ -367,6 +367,7 @@ int conn_connect(struct bbslist *bbs) conn_api.binary_mode_on=telnet_binary_mode_on; conn_api.binary_mode_off=telnet_binary_mode_off; break; + case CONN_TYPE_SSHNA: case CONN_TYPE_SSH: conn_api.connect=ssh_connect; conn_api.close=ssh_close; diff --git a/src/syncterm/conn.h b/src/syncterm/conn.h index 0356e15fa7..2178e3708f 100644 --- a/src/syncterm/conn.h +++ b/src/syncterm/conn.h @@ -21,6 +21,7 @@ enum { ,CONN_TYPE_TELNET ,CONN_TYPE_RAW ,CONN_TYPE_SSH + ,CONN_TYPE_SSHNA ,CONN_TYPE_MODEM ,CONN_TYPE_SERIAL ,CONN_TYPE_SHELL diff --git a/src/syncterm/ssh.c b/src/syncterm/ssh.c index ad9ad0bb44..1dcaae8b8e 100644 --- a/src/syncterm/ssh.c +++ b/src/syncterm/ssh.c @@ -229,26 +229,41 @@ int ssh_connect(struct bbslist *bbs) if (!bbs->hidepopups) uifc.pop(NULL); - if(!password[0]) { - if (bbs->hidepopups) - init_uifc(FALSE, FALSE); - uifcinput("Password",MAX_PASSWD_LEN,password,K_PASSWORD,"Incorrect password. Try again."); - if (bbs->hidepopups) - uifcbail(); + if (bbs->conn_type == CONN_TYPE_SSHNA) { + status = cl.SetAttribute(ssh_session, CRYPT_SESSINFO_SSH_OPTIONS, CRYPT_SSHOPTION_NONE_AUTH); + if(cryptStatusError(status)) { + char str[1024]; + sprintf(str,"Error %d disabling password auth",status); + if (!bbs->hidepopups) + uifcmsg("Error disabling password auth",str); + conn_api.terminate=1; + if (!bbs->hidepopups) + uifc.pop(NULL); + return(-1); + } } + else { + if(!password[0]) { + if (bbs->hidepopups) + init_uifc(FALSE, FALSE); + uifcinput("Password",MAX_PASSWD_LEN,password,K_PASSWORD,"Incorrect password. Try again."); + if (bbs->hidepopups) + uifcbail(); + } - if (!bbs->hidepopups) - uifc.pop("Setting Password"); - status=cl.SetAttributeString(ssh_session, CRYPT_SESSINFO_PASSWORD, password, strlen(password)); - if(cryptStatusError(status)) { - char str[1024]; - sprintf(str,"Error %d setting password",status); - if (!bbs->hidepopups) - uifcmsg("Error setting password",str); - conn_api.terminate=1; if (!bbs->hidepopups) - uifc.pop(NULL); - return(-1); + uifc.pop("Setting Password"); + status=cl.SetAttributeString(ssh_session, CRYPT_SESSINFO_PASSWORD, password, strlen(password)); + if(cryptStatusError(status)) { + char str[1024]; + sprintf(str,"Error %d setting password",status); + if (!bbs->hidepopups) + uifcmsg("Error setting password",str); + conn_api.terminate=1; + if (!bbs->hidepopups) + uifc.pop(NULL); + return(-1); + } } if (!bbs->hidepopups) { diff --git a/src/syncterm/st_crypt.c b/src/syncterm/st_crypt.c index 90cdc7f634..e46c51373b 100644 --- a/src/syncterm/st_crypt.c +++ b/src/syncterm/st_crypt.c @@ -49,6 +49,7 @@ int init_crypt(void) cl.SetAttributeString=cryptSetAttributeString; cl.DestroySession=cryptDestroySession; cl.AddRandom=cryptAddRandom; + cl.DeleteAttribute=cryptDeleteAttribute; #else cryptlib=xp_dlopen(libnames,RTLD_LAZY, CRYPTLIB_VERSION/1000); if(cryptlib==NULL) @@ -101,6 +102,10 @@ int init_crypt(void) xp_dlclose(cryptlib); return(-1); } + if((cl.DeleteAttribute=xp_dlsym(cryptlib,cryptDeleteAttribute))==NULL) { + xp_dlclose(cryptlib); + return(-1); + } #endif if(cryptStatusOK(cl.Init())) { if(cryptStatusOK(cl.AddRandom(NULL, CRYPT_RANDOM_SLOWPOLL))) { diff --git a/src/syncterm/st_crypt.h b/src/syncterm/st_crypt.h index d9a704fecd..323b9a1f23 100644 --- a/src/syncterm/st_crypt.h +++ b/src/syncterm/st_crypt.h @@ -37,6 +37,8 @@ struct crypt_funcs { C_IN void C_PTR value, C_IN int valueLength ); int (*DestroySession)( C_IN CRYPT_SESSION session ); int (*AddRandom)( C_IN void C_PTR randomData, C_IN int randomDataLength ); + int (*DeleteAttribute)( C_IN CRYPT_HANDLE cryptHandle, + C_IN CRYPT_ATTRIBUTE_TYPE attributeType); }; #endif diff --git a/src/syncterm/term.c b/src/syncterm/term.c index bbb608a014..6e5db091b2 100644 --- a/src/syncterm/term.c +++ b/src/syncterm/term.c @@ -2824,10 +2824,12 @@ BOOL doterm(struct bbslist *bbs) break; case 0x2600: /* ALT-L */ if(bbs->conn_type != CONN_TYPE_RLOGIN && bbs->conn_type != CONN_TYPE_RLOGIN_REVERSED && bbs->conn_type != CONN_TYPE_SSH) { - if(bbs->user[0]) { - conn_send(bbs->user,strlen(bbs->user),0); - conn_send(cterm->emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0); - SLEEP(10); + if (bbs->conn_type != CONN_TYPE_SSHNA) { + if(bbs->user[0]) { + conn_send(bbs->user,strlen(bbs->user),0); + conn_send(cterm->emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0); + SLEEP(10); + } } if(bbs->password[0]) { conn_send(bbs->password,strlen(bbs->password),0); -- GitLab