home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / k95source / ckossh.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  354KB  |  11,282 lines

  1. char *cksshv = "SSH support, 8.0.051,  26 Sep 2005";
  2. /*
  3.   C K O S S H . C --  OpenSSH Interface for Kermit 95
  4.  
  5.   Copyright (C) 2001-2005,
  6.     Trustees of Columbia University in the City of New York.
  7.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  8.     copyright text in the ckcmai.c module for disclaimer and permissions.
  9.  
  10.   Portions Copyright (c) 2000-2002 Markus Friedl.
  11.   Portions Copyright (c) 1999 Niels Provos.
  12.   Portions Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  13.     All rights reserved
  14.  
  15.   Includes work by Niels Provos <provos@citi.umich.edu> to work with OpenSSL.
  16.  
  17. */
  18.  
  19. #ifdef TO_DO_LIST
  20.   . Kerberos 4 and 5 Auto-get/auto-destroy support
  21.  
  22.   . listen to SET TCP REVERSE-DNS-LOOKUPS
  23.  
  24.   . listen to SET TCP DNS-SRV-RECORDS
  25.  
  26.   . make SET TELNET ENV DISPLAY more portable or SSH equivalent
  27.  
  28.   . Implement service name processing in apply_kermit_settings()
  29.  
  30.   . add \f...()'s to process the .ssh\... key files (pub, priv, host)
  31.  
  32.   . document using Kermit file transfer to upload a public key identity
  33.     file and append it to the authorized_keys file on the host
  34.  
  35.   . all strings are to be tranmitted as UTF-8. (username, passphrase, ...)
  36.     need to examine what conversions are necessary.
  37.  
  38.   . do not close the SSH connection when the terminal session stops
  39.     leave it open until an SSH CLOSE command is given.  This will allow
  40.     port forwarding and additional terminal sessions to be created on top
  41.     of the SSH connection.
  42.  
  43.   . Incoming SSH connections SET HOST *
  44. #endif /* TO_DO_LIST */
  45.  
  46. #include "ckcdeb.h"
  47.  
  48. #ifdef CK_SSL
  49. #ifdef SSHBUILTIN
  50. #ifndef OPENSSL_NO_KRB5
  51. #define OPENSSL_NO_KRB5
  52. #endif
  53.  
  54. #include "ckuusr.h"
  55. #include "ckcnet.h"
  56. #ifdef OS2                              /* OS/2 with TCP/IP */
  57. #ifdef NT
  58. #define BSDSELECT
  59. #else /* NT */
  60. #define IBMSELECT
  61. #endif /* NT */
  62. #endif /* OS2 */
  63.  
  64. #include "ssh/includes.h"
  65. #include <fcntl.h>
  66. #include <stdio.h>
  67. #ifdef KRB4
  68. #define  des_cblock Block
  69. #define  const_des_cblock const Block
  70. #define  des_key_schedule Schedule
  71. #ifdef KRB524
  72. #ifdef NT
  73. #define _WINDOWS
  74. #endif /* NT */
  75. #include "kerberosIV/krb.h"
  76. #ifndef OS2
  77. _PROTOTYP(const char * krb_get_err_text_entry, (int));
  78. #endif /* OS2 */
  79. #else /* KRB524 */
  80. #ifdef SOLARIS
  81. #ifndef sun
  82. /* for some reason the Makefile entries for the Solaris systems have -Usun */
  83. #define sun
  84. #endif /* sun */
  85. #endif /* SOLARIS */
  86. #include "krb.h"
  87. #define krb_get_err_text_entry krb_get_err_text
  88. #endif /* KRB524 */
  89. #else /* KRB4 */
  90. #ifdef CK_SSL
  91. #define  des_cblock Block
  92. #define  const_des_cblock const Block
  93. #define  des_key_schedule Schedule
  94. #endif /* CK_SSL */
  95. #endif /* KRB4 */
  96. #ifdef KRB5
  97. #include <krb5.h>
  98. #define GSSAPI
  99. #endif /* KRB5 */
  100. #ifdef AFS
  101. #include <kafs.h>
  102. #include "ssh/radix.h"
  103. #endif
  104. #ifndef HEADER_DES_H
  105. #define HEADER_DES_H
  106. #endif /* HEADER_DES_H */
  107. #include "ck_ssl.h"
  108. #include "ssh/ssh.h"
  109. #include "ssh/ssh1.h"
  110. #include "ssh/ssh2.h"
  111. #include "ssh/compat.h"
  112. #include "ssh/cipher.h"
  113. #include "ssh/packet.h"
  114. #include "ssh/buffer.h"
  115. #include "ssh/bufaux.h"
  116. #include "ssh/uidswap.h"
  117. #include "ssh/channels.h"
  118. #include "ssh/key.h"
  119. #include "ssh/authfd.h"
  120. #include "ssh/authfile.h"
  121. #include "ssh/pathnames.h"
  122. #include "ssh/clientloop.h"
  123. #include "ssh/log.h"
  124. #include "ssh/readconf.h"
  125. #include "ssh/sshconnect.h"
  126. #include "ssh/tildexpand.h"
  127. #include "ssh/dispatch.h"
  128. #include "ssh/misc.h"
  129. #include "ssh/kex.h"
  130. #include "ssh/mac.h"
  131. #include "ssh/match.h"
  132. #ifndef OS2
  133. #include "ssh/sshtty.h"
  134. #endif /* OS2 */
  135. #include "ssh/version.h"
  136. #include "ssh/myproposal.h"
  137. #include "ssh/hostfile.h"
  138.  
  139. #include "ssh/rsa.h"
  140. #include "ssh/mpaux.h"
  141. #include "ssh/uidswap.h"
  142. #include "ssh/authfile.h"
  143. #include "ssh/canohost.h"
  144. #ifdef GSSAPI
  145. #include "ssh/ssh-gss.h"
  146. #endif /* GSSAPI */
  147. #ifdef CK_SRP
  148. #include "ssh/srp.h"
  149. #endif /* CK_SRP */
  150. #ifdef SMARTCARD
  151. #include <sectok.h>
  152. #include <openssl/engine.h>
  153. #include "ssh/scard.h"
  154. #endif
  155.  
  156. #include "ckcker.h"
  157. #include "ckocon.h"
  158. #include "ckctel.h"
  159. #ifndef NO_KERBEROS
  160. #define MAP_KRB4
  161. #define MAP_KRB5
  162. #define MAP_GSSAPI
  163. #ifdef CK_ENCRYPTION
  164. #define MAP_DES
  165. #endif /* CK_ENCRYPTION */
  166. #endif /* NO_KERBEROS */
  167. #include "ckoath.h"
  168. #include "ckossh.h"
  169.  
  170. #ifdef CK_SOCKS                         /* SOCKS Internet relay package */
  171. #ifdef CK_SOCKS5                        /* SOCKS 5 */
  172. #define accept  SOCKSaccept
  173. #define bind    SOCKSbind
  174. #define connect SOCKSconnect
  175. #define getsockname SOCKSgetsockname
  176. #define listen SOCKSlisten
  177. #else  /* Not SOCKS 5 */
  178. #define accept  Raccept
  179. #define bind    Rbind
  180. #define connect Rconnect
  181. #define getsockname Rgetsockname
  182. #define listen Rlisten
  183. #endif /* CK_SOCKS5 */
  184. #endif /* CK_SOCKS */
  185.  
  186. #ifndef NOHTTP
  187. extern char * tcp_http_proxy;           /* Name[:port] of http proxy server */
  188. extern int    tcp_http_proxy_errno;
  189. extern char * tcp_http_proxy_user;
  190. extern char * tcp_http_proxy_pwd;
  191. extern char * tcp_http_proxy_agent;
  192. #define HTTPCPYL 1024
  193. static char proxyhost[HTTPCPYL];
  194. #endif /* NOHTTP */
  195. #define ERRBUFSZ 1024
  196. static char errbuf[ERRBUFSZ];
  197.  
  198. #ifdef NT
  199. extern int WSASafeToCancel;
  200. extern int win95selectbug;             /* For TCP/IP stacks whose select() */
  201. /* always fails on write requests such as Cisco and Quarterdeck */
  202. #define stricmp _stricmp
  203. #endif /* NT */
  204.  
  205. extern int quiet, filecase;
  206.  
  207. /* Flag indicating whether IPv4 or IPv6.  This can be set on the command line.
  208.    Default value is AF_UNSPEC means both IPv4 and IPv6. */
  209. #ifdef IPV4_DEFAULT
  210. int IPv4or6 = AF_INET;
  211. #else
  212. int IPv4or6 = AF_UNSPEC;
  213. #endif
  214.  
  215. /* Save the socket handle */
  216. int ssh_sock = -1;
  217.  
  218. /* Flag indicating whether debug mode is on.  This can be set on the command line. */
  219. int debug_flag = 0;
  220.  
  221. /* Flag indicating whether a tty should be allocated */
  222. int tty_flag = 0;
  223. int no_tty_flag = 0;
  224. int force_tty_flag = 0;
  225.  
  226. /* don't exec a shell */
  227. int no_shell_flag = 0;
  228.  
  229. /*
  230.  * Flag indicating that nothing should be read from stdin.  This can be set
  231.  * on the command line.
  232.  */
  233. int stdin_null_flag = 0;
  234.  
  235. /*
  236.  * Flag indicating that ssh should fork after authentication.  This is useful
  237.  * so that the passphrase can be entered manually, and then ssh goes to the
  238.  * background.
  239.  */
  240. int fork_after_authentication_flag = 0;
  241.  
  242. /*
  243.  * General data structure for command line options and options configurable
  244.  * in configuration files.  See readconf.h.
  245.  */
  246. static Options options;
  247. static int opt_init = 0;
  248.  
  249. /*
  250.  * Name of the host we are connecting to.  This is the name given on the
  251.  * command line, or the HostName specified for the user-supplied name in a
  252.  * configuration file.
  253.  */
  254. static char *host = 0;
  255.  
  256. /* socket address the host resolves to */
  257. struct sockaddr_storage hostaddr;
  258.  
  259. /*
  260.  * Flag to indicate that we have received a window change signal which has
  261.  * not yet been processed.  This will cause a message indicating the new
  262.  * window size to be sent to the server a little later.  This is volatile
  263.  * because this is updated in a signal handler.
  264.  */
  265. static volatile int received_window_change_signal = 0;
  266. static volatile int received_signal = 0;
  267. static int sent_initial_ws = 0;
  268. static int ssh_height = 0;
  269. static int ssh_width = 0;
  270.  
  271. /* Private host keys. */
  272. Sensitive sensitive_data;
  273.  
  274. /* command to be executed */
  275. static Buffer command;
  276. static int buf_init = 0;
  277.  
  278. /* Should we execute a command or invoke a subsystem? */
  279. static int subsystem_flag = 0;
  280.  
  281. /* Number of replies received for global requests */
  282. static int client_global_request_id = 0;
  283.  
  284. /* Flag indicating whether the user\'s terminal is in non-blocking mode. */
  285. static int in_non_blocking_mode = 0;
  286.  
  287. /* Common data for the client loop code. */
  288. static int quit_pending = 0;    /* Set to non-zero to quit the client loop. */
  289. static int escape_char  = 0;    /* Escape character. */
  290. static int escape_pending = 0;  /* Last character was the escape character */
  291. static int last_was_cr  = 0;    /* Last character was a newline. */
  292. static int exit_status  = 0;    /* Used to store the exit status of the command. */
  293. static int stdin_eof = 0;       /* EOF has been encountered on standard error. */
  294. static Buffer stdin_buffer;     /* Buffer for stdin data. */
  295. static Buffer stdout_buffer;    /* Buffer for stdout data. */
  296. static Buffer stderr_buffer;    /* Buffer for stderr data. */
  297. static u_long stdin_bytes = 0, stdout_bytes = 0, stderr_bytes = 0;
  298. static u_int buffer_high= 0;    /* Soft max buffer size. */
  299. static int connection_in = 0;   /* Connection to server (input). */
  300. static int connection_out = 0;  /* Connection to server (output). */
  301. static int need_rekeying = 0;   /* Set to non-zero if rekeying is requested. */
  302. static int session_closed = 0;  /* In SSH2: login session closed. */
  303.  
  304. static void     client_init_dispatch(void);
  305. int     session_ident = -1;
  306.  
  307. char *client_version_string = NULL;
  308. char *server_version_string = NULL;
  309.  
  310. #ifndef NOTCPOPTS
  311. #ifdef SOL_SOCKET
  312. #ifdef TCP_NODELAY
  313. extern int tcp_nodelay;                    /* Nagle algorithm TCP_NODELAY */
  314. #endif /* TCP_NODELAY */
  315.  
  316. #ifdef SO_DONTROUTE
  317. extern int tcp_dontroute;
  318. #endif /* SO_DONTROUTE */
  319.  
  320. #ifdef SO_LINGER
  321. extern int tcp_linger;                     /* SO_LINGER */
  322. extern int tcp_linger_tmo;                 /* SO_LINGER timeout */
  323. #endif /* SO_LINGER */
  324.  
  325. #ifdef SO_SNDBUF
  326. extern int tcp_sendbuf;
  327. #endif /* SO_SNDBUF */
  328.  
  329. #ifdef SO_RCVBUF
  330. extern int tcp_recvbuf;
  331. #endif /* SO_RCVBUF */
  332.  
  333. #ifdef SO_KEEPALIVE
  334. extern int tcp_keepalive;
  335. #endif /* SO_KEEPALIVE */
  336. #endif /* SOL_SOCKET */
  337. #endif /* NOTCPOPTS */
  338.  
  339. #ifdef CK_DNS_SRV
  340. static struct sockaddr * ssh_dns_addrs = NULL;
  341. static int ssh_dns_naddrs = 0;
  342. #endif /* CK_DNS_SRV */
  343.  
  344. extern char pwbuf[];
  345. extern int  pwflg, pwcrypt;
  346.  
  347. /*
  348.  * SSH2 key exchange
  349.  */
  350.  
  351. u_char *session_id2 = NULL;
  352. int session_id2_len = 0;
  353.  
  354. char *xxx_host;
  355. struct sockaddr *xxx_hostaddr;
  356.  
  357. Kex *xxx_kex = NULL;
  358.  
  359. #ifdef OS2
  360. extern int CreateSocketPair(SOCKET *pair);
  361. SOCKET inPair[2] = { INVALID_SOCKET, INVALID_SOCKET };
  362. SOCKET outPair[2] = { INVALID_SOCKET, INVALID_SOCKET };
  363. SOCKET sock_stdin = INVALID_SOCKET;
  364. SOCKET sock_stdout = INVALID_SOCKET;
  365. SOCKET sock_stderr = INVALID_SOCKET;
  366. #define SOCK_OUT inPair[1]
  367. #define SOCK_IN  outPair[0]
  368.  
  369. /* BEGIN SSHDLL.C */
  370. static int open_connection=0;
  371. extern char uidbuf[];
  372.  
  373. static HANDLE hClientLoopThread=NULL;
  374. static DWORD  ClientLoopThreadID=0;
  375. static int    clientloopID = 0;
  376.  
  377. static DWORD WINAPI
  378. ClientLoopThread(void * dummy) {
  379.     int rc, id = *((int *)dummy);
  380.     rc = client_loop(1, options.escape_char, id);
  381.  
  382.     /* WaitForSingleObject(hClientLoopThread,INFINITE); */
  383.     if ( hClientLoopThread ) {
  384.         CloseHandle(hClientLoopThread);
  385.         hClientLoopThread = NULL;
  386.         ClientLoopThreadID = 0;
  387.     }
  388.     return(rc);
  389. }
  390. #endif /* OS2 */
  391.  
  392. char *
  393. getterm()
  394. {
  395.     static char ttn[64];
  396.     int i;
  397. #ifndef NOTERM
  398.     extern char * tn_term;
  399. #ifdef OS2
  400.     extern int tt_type;
  401.     extern int tt_type, max_tt;
  402.     extern struct tt_info_rec tt_info[];
  403.     extern char ttname[];
  404.  
  405.     if (!tn_term) {
  406.         if (tt_type >= 0 && tt_type <= max_tt) {
  407.             ckstrncpy(ttn,tt_info[tt_type].x_name,sizeof(ttn));
  408.         } else
  409.           ttn[0] = '\0';
  410.     }
  411. #endif /* OS2 */
  412.  
  413.     if (tn_term) {                      /* Terminal type override? */
  414.         debug(F110,"ssh_getterm",tn_term,0);
  415.         if (*tn_term)
  416.             ckstrncpy(ttn,tn_term,sizeof(ttn));
  417.     } else
  418.         debug(F100,"ssh_getterm no term override","",0);
  419. #endif /* NOTERM */
  420.  
  421. #ifndef OS2
  422. #ifndef datageneral
  423.     if (!ttn[0]) {                         /* If no override, */
  424.         char * env = getenv("TERM");      /* get it from the environment. */
  425.         if ( env )
  426.             ckstrncpy(ttn,env,sizeof(ttn));
  427.     }
  428. #endif /* datageneral */
  429. #endif /* OS2 */
  430.     if (!ttn[0])
  431.       ckstrncpy(ttn,"UNKNOWN",sizeof(ttn));
  432.     cklower(ttn);
  433.     return(ttn);
  434. }
  435.  
  436. /* _getwinsize() -- Get console size (like ioctl() with TIOCGWINSZ)
  437.  
  438.    /// LIMITATION ///
  439.    xxx, x and y pixels of returned structure are not correct
  440.    (calculated as fixed size 8x16 dot font).
  441.  */
  442. int
  443. _getwinsize( struct winsize *winsize )
  444. {
  445.     extern int tt_status[];
  446.     winsize->ws_col = VscrnGetWidth(VTERM);
  447.     winsize->ws_row = VscrnGetHeight(VTERM) - (tt_status[VTERM]?1:0);
  448.     winsize->ws_xpixel = winsize->ws_col * 8; /* xxx */
  449.     winsize->ws_ypixel = winsize->ws_row * 16; /* xxx */
  450.     return 0;
  451. }
  452.  
  453. /*
  454.  * Expands tildes in the file name.  Returns data allocated by malloc.
  455.  * Warning: this calls getpw*.
  456.  */
  457. static char *
  458. tilde_expand_filename(const char *filename, uid_t my_uid)
  459. {
  460.     const char *cp;
  461.     const char *home;
  462.     u_int userlen;
  463.     char *expanded;
  464.     char user[100];
  465.     char userdir[MAXPATHLEN+1];
  466.     int len;
  467.  
  468.     /* Return immediately if no tilde. */
  469.     if (filename[0] != '~')
  470.         return strdup(filename);
  471.  
  472.     /* Skip the tilde. */
  473.     filename++;
  474.  
  475.     /* Find where the username ends. */
  476.     cp = strchr(filename, '/');
  477.     if (cp)
  478.         userlen = cp - filename;        /* Something after username. */
  479.     else
  480.         userlen = strlen(filename);     /* Nothing after username. */
  481.  
  482.     if (userlen > sizeof(user) - 1) {
  483.         fatal("User name after tilde too long.");
  484.         return NULL;
  485.     }
  486.  
  487.     if (userlen)
  488.         memcpy(user, filename, userlen);
  489.     user[userlen] = 0;
  490.  
  491.     if (userlen == 0 || !ckstrcmp(user,(char *)GetLocalUser(),-1,filecase))
  492.         home = zhome();
  493.     else {
  494.         char * homedrive = (char *)GetHomeDrive();
  495.         /* Tilde refers to someone elses home directory. */
  496.  
  497.         snprintf(userdir,MAXPATHLEN+1, "%s:/Documents and Settings/%s/",
  498.                   homedrive[0]?homedrive:"C:",(char *)GetLocalUser());
  499.         home = userdir;
  500.     }
  501.  
  502.     /* If referring to someones home directory, return it now. */
  503.     if (!cp) {
  504.         /* Only home directory specified */
  505.         return strdup(home);
  506.     }
  507.     /* Build a path combining the specified directory and path. */
  508.     len = strlen(home) + strlen(cp + 1) + 2;
  509.     if (len > MAXPATHLEN) {
  510.         fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1);
  511.         return NULL;
  512.     }
  513.     expanded = malloc(len);
  514.     snprintf(expanded, len, "%s%s", home, cp + 1);
  515.     return expanded;
  516. }
  517.  
  518.  
  519. static int passwd_attempt = 0;
  520. static int kbdint_attempt = 0;
  521. static int srp_attempt = 0;
  522. static int external_attempt = 0;
  523. static int gssapi_attempt = 0;
  524. static int pubkey_agent_called = 0;
  525. static int pubkey_idx = 0;
  526. static int gssapi_mech = 0;
  527.  
  528. void
  529. userauth_reset(void)
  530. {
  531.     passwd_attempt = 0;
  532.     kbdint_attempt = 0;
  533.     srp_attempt = 0;
  534.     external_attempt = 0;
  535.     gssapi_attempt = 0;
  536.     gssapi_mech = 0;
  537.     pubkey_agent_called = 0;
  538.     pubkey_idx = 0;
  539. }
  540.  
  541. static int      ssh_session(void);
  542. static int      ssh_session2(void);
  543. static void     load_public_identity_files(void);
  544.  
  545. static void
  546. apply_kermit_settings(Options * options)
  547. {
  548.     extern int tcp_dns_srv;
  549.     int i, x;
  550.  
  551.     switch (ssh_ver) {
  552.     case 1:
  553.         options->protocol = SSH_PROTO_1;
  554.         break;
  555.     case 2:
  556.         options->protocol = SSH_PROTO_2;
  557.         break;
  558.     default:
  559.         options->protocol = SSH_PROTO_1|SSH_PROTO_2;
  560.     }
  561.  
  562.     options->use_privileged_port = ssh_prp;
  563.     options->forward_x11 = ssh_xfw;
  564.     options->forward_agent = ssh_afw;
  565.     options->gateway_ports = ssh_gwp;
  566.     options->check_host_ip = ssh_chkip;
  567.     options->strict_host_key_checking = ssh_shk;
  568.     options->keepalives = tcp_keepalive;
  569.     options->heartbeat_interval = ssh_hbt;
  570.  
  571.     if ( ssh_xal && *ssh_xal )
  572.         makestr(&options->xauth_location,ssh_xal);
  573.     else
  574.         makestr(&options->xauth_location,NULL);
  575.  
  576.     if ( ssh1_gnh && *ssh1_gnh )
  577.         makestr(&options->system_hostfile,ssh1_gnh);
  578.     else
  579.         makestr(&options->system_hostfile,NULL);
  580.  
  581.     if ( ssh1_unh && *ssh1_unh )
  582.         makestr(&options->user_hostfile,ssh1_unh);
  583.     else
  584.         makestr(&options->user_hostfile,NULL);
  585.  
  586.     if ( ssh2_gnh && *ssh2_gnh )
  587.         makestr(&options->system_hostfile2,ssh2_gnh);
  588.     else
  589.         makestr(&options->system_hostfile2,NULL);
  590.  
  591.     if ( ssh2_unh && *ssh2_unh )
  592.         makestr(&options->user_hostfile2,ssh2_unh);
  593.     else
  594.         makestr(&options->user_hostfile2,NULL);
  595.  
  596.     if ( ssh_idf_n > 0) {
  597.         int i;
  598.         for ( i=0; i < SSH_MAX_IDENTITY_FILES && i < ssh_idf_n ; i++ )
  599.             makestr(&options->identity_files[i],ssh_idf[i]);
  600.         options->num_identity_files = i;
  601.     } else
  602.         options->num_identity_files = 0;
  603.  
  604.     options->rhosts_authentication = 1;
  605.     options->rsa_authentication = 1;
  606.     options->pubkey_authentication = 1;
  607.     options->challenge_response_authentication = 1;
  608.     options->password_authentication = 1;
  609.     options->kbd_interactive_authentication = 1;
  610.     options->rhosts_rsa_authentication = 1;
  611.     options->hostbased_authentication = 1;
  612.  
  613. #ifdef CK_SRP
  614.     if ( ck_srp_is_installed() )
  615.         options->srp_authentication = 1;
  616.     else
  617.         options->srp_authentication = 0;
  618. #endif /* CK_SRP */
  619. #ifdef KRB5
  620.     if ( ck_krb5_is_installed() ) {
  621.         options->kerberos_tgt_passing = ssh_k5tgt;
  622.         options->krb5_authentication = 1;
  623.     } else {
  624.         options->kerberos_tgt_passing = 0;
  625.         options->krb5_authentication = 0;
  626.     }
  627. #endif /* KRB5 */
  628. #ifdef GSSAPI
  629.     if ( ck_gssapi_is_installed() ) {
  630.         options->gss_authentication = 1;
  631.         options->gss_deleg_creds = ssh_gsd;
  632.     } else {
  633.         options->gss_deleg_creds = 0;
  634.         options->gss_authentication = 1;
  635.     }
  636. #endif /* GSSAPI */
  637. #ifdef KRB4
  638.     if ( ck_krb4_is_installed() ) {
  639.         options->krb4_authentication = 1;
  640.         options->kerberos_tgt_passing = ssh_k4tgt;
  641.     } else {
  642.         options->krb4_authentication = 1;
  643.         options->kerberos_tgt_passing = 0;
  644.     }
  645. #endif /* KRB4 */
  646. #ifdef AFS
  647.     options->afs_token_passing = -1;
  648. #endif /* AFS */
  649.  
  650.     /* options.log_level = SYSLOG_LEVEL_DEBUG[123], SYSLOG_LEVEL_QUIET */
  651.     options->log_level = ssh_vrb;
  652.  
  653.     /* Currently no escape character. Would be any ascii value. */
  654.     options->escape_char = SSH_ESCAPECHAR_NONE;
  655.  
  656.     if (ssh2_cif && *ssh2_cif) {
  657.         makestr(&options->ciphers,ssh2_cif);
  658.         options->cipher = SSH_CIPHER_ILLEGAL;
  659.     } else
  660.         makestr(&options->ciphers,NULL);
  661.  
  662.     if (ssh1_cif && *ssh1_cif) {
  663.         /* SSH1 only */
  664.         options->cipher = cipher_number(ssh1_cif);
  665.         if (options->cipher == -1) {
  666.             fprintf(stderr, "Unknown cipher type '%s'\n", ssh1_cif);
  667.         } else if (options->ciphers == NULL) {
  668.             if (options->cipher == SSH_CIPHER_3DES) {
  669.                 options->ciphers= "3des-cbc";
  670.             } else if (options->cipher == SSH_CIPHER_BLOWFISH) {
  671.                 options->ciphers = "blowfish-cbc";
  672.             } else {
  673.                 options->ciphers = (char *)-1;
  674.             }
  675.         }
  676.     } else
  677.         options->cipher = -1;
  678.  
  679.     if ( ssh2_mac && *ssh2_mac )
  680.         makestr(&options->macs,ssh2_mac);
  681.         else
  682.             makestr(&options->macs,NULL);
  683.  
  684.     if ( ssh2_hka && *ssh2_hka ) {
  685.         if ( key_names_valid2(ssh2_hka) )
  686.             makestr(&options->hostkeyalgorithms,ssh2_hka);
  687.         else {
  688.             printf("Invalid v2 host key algorithms: %s\n",ssh2_hka);
  689.             makestr(&options->hostkeyalgorithms,NULL);
  690.         }
  691.     } else
  692.         makestr(&options->hostkeyalgorithms,NULL);
  693.  
  694.     if ( ssh2_auth && *ssh2_auth )
  695.         makestr(&options->preferred_authentications,ssh2_auth);
  696.     else
  697.         makestr(&options->preferred_authentications,NULL);
  698.  
  699.     if (ssh_prt == NULL)
  700.     ssh_prt = SSH_SERVICE_NAME;
  701.  
  702.     x = atoi(ssh_prt);
  703.     if (x > 0)
  704.     options->port = x;
  705.     else {
  706.     struct servent * service = NULL;
  707. #ifdef CK_DNS_SRV
  708.     if (ssh_dns_addrs) {
  709.         free(ssh_dns_addrs);
  710.         ssh_dns_addrs = NULL;
  711.         ssh_dns_naddrs = 0;
  712.     }
  713.     if (tcp_dns_srv && !quiet) {
  714.         printf(" DNS SRV Lookup... ");
  715.         fflush(stdout);
  716.     }
  717.     if (tcp_dns_srv &&
  718.          locate_srv_dns(ssh_hst,
  719.                  ssh_prt,
  720.                  "tcp",
  721.                  &ssh_dns_addrs,
  722.                  &ssh_dns_naddrs
  723.                  )
  724.          )
  725.     {
  726.         /* Use the first one.  Eventually we should cycle through all */
  727.         /* the returned IP addresses and port numbers. */
  728.         struct sockaddr_in *sin = NULL;
  729. #ifdef BETADEBUG
  730.         int i;
  731.         printf("\r\n");
  732.         for ( i=0;i<ssh_dns_naddrs;i++ ) {
  733.         sin = (struct sockaddr_in *) &ssh_dns_addrs[i];
  734.         printf("ssh_dns_addrs[%d] = %s %d\r\n", i,
  735.             (char *)inet_ntoa(sin->sin_addr),
  736.             ntohs(sin->sin_port));
  737.         }
  738. #endif /* BETADEBUG */
  739.         sin = (struct sockaddr_in *) &ssh_dns_addrs[0];
  740.         options->port = ntohs(sin->sin_port);
  741.     } else
  742. #endif /* CK_DNS_SRV */
  743.     {
  744.         service = getservbyname(ssh_prt, "tcp");
  745.         if (service)
  746.         options->port = ntohs(service->s_port);
  747.     }
  748.     }
  749.     
  750.     if (uidbuf[0])
  751.         makestr(&options->user,uidbuf);
  752.     else {
  753.         char tmp[BUFSIZ], prompt[256];
  754.         char *user;
  755.         char *myname;
  756.         int ok;
  757.  
  758.         myname = whoami();
  759.         if (!myname) myname = "";
  760.         if (myname[0])
  761.           ckmakxmsg(prompt,sizeof(prompt)," Name (",myname,"): ",
  762.                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  763.         else
  764.           strcpy(prompt," Name: ");
  765.         tmp[0] = '\0';
  766.         ok = uq_txt("Username required for SSH\n",prompt,1,NULL,tmp,sizeof(tmp),
  767.                     NULL,DEFAULT_UQ_TIMEOUT);
  768.         if (!ok || (*tmp == '\0'))
  769.           user = myname;
  770.         else
  771.           user = tmp;
  772.         makestr(&options->user,user);
  773.     }
  774.  
  775.     for ( i=0 ; i < ssh_pf_lcl_n ; i++ )
  776.         add_local_forward(options, ssh_pf_lcl[i].p1,
  777.                            ssh_pf_lcl[i].host, ssh_pf_lcl[i].p2);
  778.     for ( i=0 ; i < ssh_pf_rmt_n ; i++ )
  779.         add_remote_forward(options, ssh_pf_rmt[i].p1,
  780.                             ssh_pf_rmt[i].host, ssh_pf_rmt[i].p2);
  781.  
  782.     if ( ssh_dyf )
  783.         add_local_forward(options, 1080, "socks4", 0);
  784.  
  785.     options->compression = ck_zlib_is_installed() ? ssh_cmp : 0;
  786.  
  787.     subsystem_flag = ssh_cas;
  788. }
  789.  
  790. int
  791. ssh_open(VOID)
  792. {
  793.     int i, opt, optind, type, cerr, fwd_port=0, fwd_host_port=0, authfd;
  794.     char *optarg=NULL, *cp=NULL, buf[256];
  795.     struct _stat st;
  796.     int interactive = 0, dummy;
  797.     char *pw_dir=NULL, *pw_name=NULL;
  798.     struct passwd *pw=NULL;
  799.     Sensitive sensitive_data;
  800.  
  801.     if (!ck_ssleay_is_installed()) {
  802.         printf("? SSH not available\r\n");
  803.         return -1;
  804.     }
  805.  
  806.     /* Check that we got a host name. */
  807.     if (!ssh_hst)
  808.         return(-114);
  809.  
  810.     myproposal[0] = KEX_DEFAULT_KEX;
  811.     myproposal[1] = KEX_DEFAULT_PK_ALG;
  812.     myproposal[2] = KEX_DEFAULT_ENCRYPT;
  813.     myproposal[3] = KEX_DEFAULT_ENCRYPT;
  814.     myproposal[4] = KEX_DEFAULT_MAC;
  815.     myproposal[5] = KEX_DEFAULT_MAC;
  816.     myproposal[6] = KEX_DEFAULT_COMP;
  817.     myproposal[7] = KEX_DEFAULT_COMP;
  818.     myproposal[8] = KEX_DEFAULT_LANG;
  819.     myproposal[9] = KEX_DEFAULT_LANG;
  820.  
  821.     debug(F100,"ssh_open starting resets","",0);
  822.     reset_compat();
  823.     channel_reset();
  824.     packet_reset();
  825.     authmethod_reset();
  826.     userauth_reset();
  827.     buffer_compress_uninit();
  828.     sent_initial_ws = 0;
  829.     received_window_change_signal = 0;
  830.     session_closed = 0;
  831.     debug(F100,"ssh_open finished resets","",0);
  832.  
  833.     /* Initialize option structure to indicate that no values have been set. */
  834.     if ( !opt_init ) {
  835.         initialize_options(&options);
  836.         opt_init = 1;
  837.     }
  838.  
  839.     /* Set options. */
  840.     host = ssh_hst;
  841.     debug(F100,"ssh_open applying kermit settings","",0);
  842.     apply_kermit_settings(&options);
  843.  
  844.     /* Initialize the command to execute on remote host. */
  845.     if ( buf_init )
  846.         buffer_clear(&command);
  847.     else {
  848.         buffer_init(&command);
  849.         buf_init = 1;
  850.     }
  851.  
  852.     /* Save the command to execute on the remote host in a buffer.  There is
  853.     no limit on the length of the command, except by the maximum packet
  854.     size.  Also sets the tty flag if there is no command. */
  855.     if ( ssh_cmd && *ssh_cmd )
  856.     {
  857.         /* A command has been specified.  Store it into the buffer. */
  858.         buffer_append(&command, ssh_cmd, strlen(ssh_cmd));
  859.     }
  860.  
  861.     /* Allocate a tty by default if no command specified. */
  862.     tty_flag = (buffer_len(&command) == 0);
  863.  
  864.     debug(F100,"ssh_open initalizing pw","",0);
  865.     /* Get home directory and initialize struct passwd */
  866.     makestr(&pw_dir,zhome());
  867.     makestr(&pw_name, uidbuf);
  868.  
  869.     pw = malloc(sizeof(struct passwd));
  870.     if ( pw ) {
  871.         pw->pw_name = pw_name;
  872.         pw->pw_dir = pw_dir;
  873.         pw->pw_passwd = NULL;
  874.         pw->pw_shell = NULL;
  875.         pw->pw_uid = 1;                 /* meaningless on windows */
  876.         pw->pw_gid = 1;                 /* ditto */
  877.     }
  878.  
  879.     debug(F100,"ssh_open log_init() 1","",0);
  880.     /* Initialize "log" output.  Since we are the client all output actually
  881.     goes to the terminal. */
  882.     log_init("Kermit Builtin SSH", 1, SYSLOG_FACILITY_USER, 1);
  883.  
  884.     if (ssh_cfg) {
  885.     /* Read per-user configuration file. pw_dir contains trailing slash */
  886.         sprintf(buf, "%.100s%s", pw_dir, (char *)_PATH_SSH_USER_CONFFILE);
  887.         read_config_file(buf, host, &options);
  888.  
  889.         /* Read systemwide configuration file. */
  890.         read_config_file((char *)_PATH_HOST_CONFIG_FILE, host, &options);
  891.     }
  892.  
  893.     debug(F100,"ssh_open calling fill_default_options()","",0);
  894.     /* Fill configuration defaults. */
  895.     fill_default_options(&options);
  896.  
  897.     debug(F100,"ssh_open calling log_init() 2","",0);
  898.     /* reinit */
  899.     log_init("Kermit Builtin SSH", options.log_level, SYSLOG_FACILITY_USER, 1);
  900.  
  901.     debug(F100,"ssh_open calling seed_rng()","",0);
  902.     seed_rng();
  903.  
  904.     if (options.user == NULL)
  905.         options.user = strdup(pw_name);
  906.  
  907.     if (options.hostname != NULL)
  908.         host = options.hostname;
  909.  
  910.     /* Disable rhosts authentication if not running as root. */
  911.     if (!options.use_privileged_port)
  912.         options.rhosts_authentication = 0;
  913.  
  914.     /* Open a connection to the remote host.  This needs root privileges if
  915.     rhosts_authentication is true.  Note that the random_state is not
  916.     yet used by this call, although a pointer to it is stored, and thus it
  917.     need not be initialized. */
  918.     cerr = ssh_connect(host, &hostaddr, options.port, IPv4or6,
  919.                      options.connection_attempts,
  920.                      options.use_privileged_port,
  921.                      NULL);
  922.     if ( cerr ) {
  923.         if (!quiet) {
  924.             error("Could not connect to %s.",host);
  925. #ifdef COMMENT
  926. #ifdef KUI
  927.             ckmakmsg(errbuf,ERRBUFSZ,"Could not connect to ",host,NULL,NULL);
  928.             uq_ok(NULL, errbuf, 1, NULL, 0);
  929. #endif /* KUI */
  930. #endif /* COMMENT */
  931.         }
  932.         return -116;
  933.     }
  934.     /* Successful connection. */
  935.  
  936.     /*
  937.     * If we successfully made the connection, load the host private key
  938.     * in case we will need it later for combined rsa-rhosts
  939.     * authentication. This must be done before releasing extra
  940.     * privileges, because the file is only readable by root.
  941.     * If we cannot access the private keys, load the public keys
  942.     * instead and try to execute the ssh-keysign helper instead.
  943.     */
  944.     sensitive_data.nkeys = 0;
  945.     sensitive_data.keys = NULL;
  946.     sensitive_data.external_keysign = 0;
  947.     if (options.rhosts_rsa_authentication ||
  948.         options.hostbased_authentication) {
  949.         sensitive_data.nkeys = 3;
  950.         sensitive_data.keys = malloc(sensitive_data.nkeys*sizeof(Key));
  951.         sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
  952.                                                         (char *)_PATH_HOST_KEY_FILE, "", NULL);
  953.         sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
  954.                                                         (char *)_PATH_HOST_DSA_KEY_FILE, "", NULL);
  955.         sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
  956.                                                         (char *)_PATH_HOST_RSA_KEY_FILE, "", NULL);
  957.  
  958.         if (options.hostbased_authentication == 1 &&
  959.              sensitive_data.keys[0] == NULL &&
  960.              sensitive_data.keys[1] == NULL &&
  961.              sensitive_data.keys[2] == NULL) {
  962.  
  963.             sensitive_data.keys[1] = key_load_public(
  964.                                                       (char *)_PATH_HOST_DSA_KEY_FILE, NULL);
  965.             sensitive_data.keys[2] = key_load_public(
  966.                                                       (char *)_PATH_HOST_RSA_KEY_FILE, NULL);
  967.             sensitive_data.external_keysign = 1;
  968.         }
  969.     }
  970.  
  971.     /*
  972.     * Create ~/.ssh directory if it doesn\'t already exist.
  973.     */
  974.     snprintf(buf, sizeof buf, "%s", (char *)_PATH_SSH_USER_DIR);
  975.     if (stat(buf, &st) < 0)
  976.         if (mkdir(buf, 0700) < 0) {
  977.             error("Could not create directory '%.256s'.", buf);
  978. #ifdef KUI
  979.             ckmakmsg(errbuf,ERRBUFSZ,"Could not create directory: \"",
  980.                       buf,"\"",NULL);
  981.             uq_ok(NULL, errbuf, 1, NULL, 0);
  982. #endif /* KUI */
  983.         }
  984.  
  985.     /* load options.identity_files */
  986.     load_public_identity_files();
  987.  
  988.     /* Expand ~ in known host file names. */
  989.     /* XXX mem-leaks: */
  990.     options.system_hostfile =
  991.         tilde_expand_filename(options.system_hostfile, -1);
  992.     options.user_hostfile =
  993.         tilde_expand_filename(options.user_hostfile, -1);
  994.     options.system_hostfile2 =
  995.         tilde_expand_filename(options.system_hostfile2, -1);
  996.     options.user_hostfile2 =
  997.         tilde_expand_filename(options.user_hostfile2, -1);
  998.  
  999. #ifdef SIGPIPE
  1000.     signal(SIGPIPE, SIG_IGN);
  1001. #endif /* SIGPIPE */
  1002.  
  1003.     /* Log into the remote system.  This never returns if the login fails. */
  1004.     cerr = ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw);
  1005.  
  1006.     /* We no longer need the private host keys.  Clear them now. */
  1007.     if (sensitive_data.nkeys != 0) {
  1008.         for (i = 0; i < sensitive_data.nkeys; i++) {
  1009.             if (sensitive_data.keys[i] != NULL) {
  1010.                 /* Destroys contents safely */
  1011.                 debug3("clear hostkey %d", i);
  1012.                 key_free(sensitive_data.keys[i]);
  1013.                 sensitive_data.keys[i] = NULL;
  1014.             }
  1015.         }
  1016.         free(sensitive_data.keys);
  1017.     }
  1018.     for (i = 0; i < options.num_identity_files; i++) {
  1019.         if (options.identity_files[i]) {
  1020.                 free(options.identity_files[i]);
  1021.                 options.identity_files[i] = NULL;
  1022.         }
  1023.         if (options.identity_keys[i]) {
  1024.                 key_free(options.identity_keys[i]);
  1025.                 options.identity_keys[i] = NULL;
  1026.         }
  1027.     }
  1028.     free(pw);
  1029.  
  1030.     /* If ssh_login() failed, return. */
  1031.     if (cerr) {
  1032.         if ( !quiet )
  1033.             error("login failed");
  1034. #ifdef COMMENT
  1035. #ifdef KUI
  1036.         uq_ok(NULL, "login failed", 1, NULL, 1);
  1037. #endif /* KUI */
  1038. #endif /* COMMENT */
  1039.         ssh_clos();
  1040.         return(-122);
  1041.     }
  1042.  
  1043. #ifdef OS2
  1044.     CreateSocketPair(inPair);
  1045.     CreateSocketPair(outPair);
  1046.     sock_stdin = inPair[0];
  1047.     sock_stdout = outPair[1];
  1048.     sock_stderr = outPair[1];
  1049. #endif /* OS2 */
  1050.  
  1051.     /* Enable Window Size reporting */
  1052.     TELOPT_ME(TELOPT_NAWS) = 1;
  1053.  
  1054.     exit_status = compat20 ? ssh_session2() : ssh_session();
  1055.     
  1056.     return exit_status;
  1057. }
  1058.  
  1059. #ifndef NOLOCAL
  1060. _PROTOTYP(VOID slrestor,(VOID));
  1061. #endif /* NOLOCAL */
  1062. int
  1063. ssh_clos() {
  1064.  
  1065.     if (quit_pending) {
  1066.         while (quit_pending)
  1067.             msleep(50);
  1068.         return(0);
  1069.     }
  1070.  
  1071.     if (hClientLoopThread) {
  1072.         quit_pending = 1;           /* Instruct Client Loop to end */
  1073.         ssh_toc(0);
  1074.         while (quit_pending && hClientLoopThread)
  1075.             msleep(50);
  1076.         open_connection = 0;
  1077.         quit_pending = 0;
  1078.     }
  1079.  
  1080.     packet_close();
  1081.  
  1082.     if ( SOCK_IN != INVALID_SOCKET ) {
  1083.         closesocket(SOCK_IN);
  1084.         SOCK_IN = INVALID_SOCKET;
  1085.     }
  1086.     if ( SOCK_OUT != INVALID_SOCKET ) {
  1087.         closesocket(SOCK_OUT);
  1088.         SOCK_OUT = INVALID_SOCKET;
  1089.     }
  1090.  
  1091. #ifndef NOLOCAL
  1092.     slrestor();
  1093. #endif /* NOLOCAL */
  1094.  
  1095.     ssh_sock = -1;
  1096.  
  1097.     /* Exit with the status returned by the program on the remote side. */
  1098.     return(0);
  1099. }
  1100.  
  1101. #ifndef NOBUF
  1102. #ifdef OS2
  1103. #ifdef NT
  1104. #define SSHIBUFL 64240                   /* 44 * 1460 (MSS) */
  1105. #else
  1106. #define SSHIBUFL 32120                   /* 22 * 1460 (MSS) */
  1107. #endif /* NT */
  1108. #else /* OS2 */
  1109. #define SSHIBUFL 8191                    /* Let's use 8K. */
  1110. #endif /* OS2 */
  1111.  
  1112. static CHAR sshibuf[SSHIBUFL+1];
  1113. static int sshibp = 0, sshibn = 0;
  1114. #endif /* NOBUF */
  1115.  
  1116. int
  1117. ssh_tchk(void) {
  1118.     long count = 0;
  1119.     int x = 0;
  1120.     long y;
  1121.     char c;
  1122.  
  1123.     if ( !open_connection )
  1124.         return(-1);
  1125.  
  1126.     if (ioctlsocket(SOCK_IN,FIONREAD,&count) < 0) {
  1127. #ifdef NT
  1128.         int s_errno = WSAGetLastError();
  1129.         debug3("ssh_tchk socket = %u s_errno = %d",SOCK_IN, s_errno);
  1130. #endif /* NT */ 
  1131.  
  1132. #ifndef NOBUF
  1133.         if ( sshibn > 0 ) {
  1134.             return(sshibn);
  1135.         } else 
  1136. #endif /* NOBUF */
  1137.         {
  1138.             ttclos(0);
  1139.             return(-1);
  1140.         }
  1141.     }
  1142. #ifndef NOBUF
  1143.     return(count+sshibn);
  1144. #else
  1145.     return(count);
  1146. #endif /* NOBUF */
  1147. }
  1148.  
  1149. int
  1150. ssh_flui(void) {
  1151.     char c;
  1152.     if ( !open_connection )
  1153.         return(-1);
  1154.  
  1155.     /* Not safe to flush encrypted/compressed connections */
  1156.     return(0);
  1157. }
  1158.  
  1159. int
  1160. ssh_break(void) {
  1161.     if ( !open_connection )
  1162.         return(-1);
  1163.  
  1164.     /* No equivalent to Telnet Break */
  1165.     return(0);
  1166. }
  1167.  
  1168. static int
  1169. sshbufr(void) {                              /* TT Buffer Read */
  1170.     int count;
  1171.  
  1172. #ifdef OS2
  1173.     RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
  1174. #endif /* OS2 */
  1175.  
  1176.     if (sshibn > 0) {                    /* Our internal buffer is not empty, */
  1177. #ifdef OS2
  1178.         ReleaseTCPIPMutex();
  1179. #endif /* OS2 */
  1180.         return(sshibn);                  /* so keep using it. */
  1181.     }
  1182.  
  1183.     if ( !open_connection ) {
  1184. #ifdef OS2
  1185.         ReleaseTCPIPMutex();
  1186. #endif /* OS2 */
  1187.         return(-2);
  1188.     }
  1189.  
  1190.     sshibp = 0;                          /* Else reset pointer to beginning */
  1191.  
  1192. #ifdef OS2
  1193.     count = SSHIBUFL;
  1194. #else                                   /* Multinet, etc. */
  1195.     count = ttchk();                    /* Check network input buffer, */
  1196.     if (sshibn > 0) {                    /* which can put a char there! */
  1197.         debug(F111,"sshbufr","ttchk() returns",count);
  1198. #ifdef OS2
  1199.         ReleaseTCPIPMutex();
  1200. #endif /* OS2 */
  1201.         return(sshibn);
  1202.     }
  1203.     if (count < 0) {                     /* Read error - connection closed */
  1204. #ifdef OS2
  1205.         ReleaseTCPIPMutex();
  1206. #endif /* OS2 */
  1207.         return(-2);
  1208.     }
  1209.     else if (count > SSHIBUFL)           /* Too many to read */
  1210.       count = SSHIBUFL;
  1211.     else if (count == 0)                /* None, so force blocking read */
  1212.       count = 1;
  1213. #endif /* OS2 */
  1214.     debug(F101,"sshbufr count 1","",count);
  1215.  
  1216.  
  1217. /* This is for blocking reads */
  1218.  
  1219. #ifndef VMS
  1220. #ifdef SO_OOBINLINE
  1221.     {
  1222.         int outofband = 0;
  1223. #ifdef BELLSELECT
  1224.         if (select(128, NULL, NULL, efds, 0) > 0 && FD_ISSET(SOCK_IN, efds))
  1225.           outofband = 1;
  1226. #else
  1227. #ifdef BSDSELECT
  1228.         fd_set efds;
  1229.         struct timeval tv;
  1230.         FD_ZERO(&efds);
  1231.         FD_SET(SOCK_IN, &efds);
  1232.         tv.tv_sec  = tv.tv_usec = 0L;
  1233.         debug(F100,"Out-of-Band BSDSELECT","",0);
  1234. #ifdef NT
  1235.         WSASafeToCancel = 1;
  1236. #endif /* NT */
  1237.         if (select(FD_SETSIZE, NULL, NULL, &efds, &tv) > 0 &&
  1238.             FD_ISSET(SOCK_IN, &efds))
  1239.           outofband = 1;
  1240. #ifdef NT
  1241.         WSASafeToCancel = 0;
  1242. #endif /* NT */
  1243. #else /* !BSDSELECT */
  1244. #ifdef IBMSELECT
  1245. /* Is used by OS/2 ... */
  1246. /* ... and it came in handy!  For our TCP/IP layer, it avoids all the fd_set */
  1247. /* and timeval stuff since this is the only place where it is used. */
  1248.         int socket = SOCK_IN;
  1249.         debug(F100,"Out-of-Band IBMSELECT","",0);
  1250.         if ((select(&socket, 0, 0, 1, 0L) == 1) && (socket == SOCK_IN))
  1251.           outofband = 1;
  1252. #else /* !IBMSELECT */
  1253. /*
  1254.   If we can't use select(), then we use the regular alarm()/signal()
  1255.   timeout mechanism.
  1256. */
  1257.       debug(F101,"Out-of-Band data not supported","",0);
  1258.       outofband = 0;
  1259.  
  1260. #endif /* IBMSELECT */
  1261. #endif /* BSDSELECT */
  1262. #endif /* BELLSELECT */
  1263.       if (outofband) {
  1264.          /* Get the Urgent Data */
  1265.          /* if OOBINLINE is disabled this should be only a single byte      */
  1266.          /* MS Winsock has a bug in Windows 95.  Extra bytes are delivered  */
  1267.          /* That were never sent.                                           */
  1268. #ifdef OS2
  1269.           RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
  1270. #endif /* OS2 */
  1271.           count = socket_recv(SOCK_IN,&sshibuf[sshibp+sshibn],count,MSG_OOB);
  1272. #ifdef OS2
  1273.           ReleaseTCPIPMutex();
  1274. #endif /* OS2 */
  1275.           if (count <= 0) {
  1276.               int s_errno = socket_errno;
  1277.               debug(F101, "sshbufr socket_recv MSG_OOB","",count);
  1278.               debug(F101, "sshbufr socket_errno","",s_errno);
  1279. #ifdef OS2ONLY
  1280.               if (count < 0 && (s_errno == 0 || s_errno == 23)) {
  1281.                   /* These appear in OS/2 - don't know why   */
  1282.                   /* ignore it and read as normal data       */
  1283.                   /* and break, then we will attempt to read */
  1284.                   /* the port using normal read() techniques */
  1285.                   debug(F100,"sshbufr handing as in-band data","",0);
  1286.                   count = 1;
  1287.               } else {
  1288.                   ttclos(0);                    /* *** *** */
  1289. #ifdef OS2
  1290.                   ReleaseTCPIPMutex();
  1291. #endif /* OS2 */
  1292.                   return(-2);
  1293.               }
  1294. #else /* OS2ONLY */
  1295.               ttclos(0);                        /* *** *** */
  1296. #ifdef OS2
  1297.               ReleaseTCPIPMutex();
  1298. #endif /* OS2 */
  1299.               return(-2);
  1300. #endif /* OS2ONLY */
  1301.           } else {                      /* we got out-of-band data */
  1302.               hexdump("sshbufr out-of-band chars",&sshibuf[sshibp+sshibn],count);
  1303. #ifdef BETADEBUG
  1304.               bleep(BP_NOTE);
  1305. #endif /* BETADEBUG */
  1306.               {
  1307.                   /* For any protocols we don't have a special out-of-band  */
  1308.                   /* handler for, just put the bytes in the normal buffer   */
  1309.                   /* and return                                             */
  1310.  
  1311.                   sshibp += 0;       /* Reset buffer pointer. */
  1312.                   sshibn += count;
  1313. #ifdef DEBUG
  1314.                   /* Got some bytes. */
  1315.                   debug(F101,"sshbufr count 2","",count);
  1316.                   if (count > 0)
  1317.                       sshibuf[sshibp+sshibn] = '\0';
  1318.                   debug(F111,"sshbufr sshibuf",sshibuf,sshibp);
  1319. #endif /* DEBUG */
  1320. #ifdef OS2
  1321.                   ReleaseTCPIPMutex();
  1322. #endif /* OS2 */
  1323.                   return(sshibn);    /* Return buffer count. */
  1324.               }
  1325.           }
  1326.       }
  1327.     }
  1328. #endif /* SO_OOBINLINE */
  1329. #endif /* VMS */
  1330.  
  1331.     count = socket_read(SOCK_IN,&sshibuf[sshibp+sshibn],count);
  1332.     if (count <= 0) {
  1333.         int s_errno = socket_errno;
  1334.         debug(F101,"sshbufr socket_read","",count);
  1335.         debug(F101,"sshbufr socket_errno","",s_errno);
  1336. #ifdef OS2
  1337.         if (count == 0 || os2socketerror(s_errno) < 0) {
  1338.             ttclos(0);
  1339.             ReleaseTCPIPMutex();
  1340.             return(-2);
  1341.         }
  1342.         ReleaseTCPIPMutex();
  1343.         return(-1);
  1344. #else /* OS2 */
  1345.         ttclos(0);                      /* *** *** */
  1346.         return(-2);
  1347. #endif /* OS2 */
  1348.     } else {
  1349.         sshibp = 0;                      /* Reset buffer pointer. */
  1350.         sshibn += count;
  1351. #ifdef DEBUG
  1352.         debug(F101,"sshbufr count 2","",count); /* Got some bytes. */
  1353.         if (count > 0)
  1354.           sshibuf[sshibp+sshibn] = '\0';
  1355.         debug(F111,"sshbufr sshibuf",&sshibuf[sshibp],sshibn);
  1356. #endif /* DEBUG */
  1357. #ifdef OS2
  1358.         ReleaseTCPIPMutex();
  1359. #endif /* OS2 */
  1360.         return(sshibn);                  /* Return buffer count. */
  1361.     }
  1362. }
  1363.  
  1364. int
  1365. ssh_inc(int timo)  {
  1366. #ifdef NOBUF
  1367.     char c=0;
  1368.     fd_set rfds;
  1369.     struct timeval tv;
  1370.     int count;
  1371.  
  1372.     if ( !open_connection )
  1373.         return(-1);
  1374.  
  1375.   begin:
  1376.     FD_ZERO(&rfds);
  1377.     FD_SET(SOCK_IN, &rfds);
  1378.     tv.tv_sec  = tv.tv_usec = 0L;
  1379.     if (timo < 0)
  1380.         tv.tv_usec = (long) -timo * 1000L;
  1381.     else
  1382.         tv.tv_sec = timo;
  1383.     if (select(FD_SETSIZE, (fd_set *) &rfds,
  1384.                 NULL, NULL, &tv) > 0 &&
  1385.          FD_ISSET(SOCK_IN, &rfds)) {
  1386.  
  1387.         if ((count = recv(SOCK_IN,&c,1,0)) <= 0) {
  1388.             int s_errno = WSAGetLastError();
  1389.             if (count == 0) {
  1390.                 ttclos(0);              /* if the connection was  */
  1391.                 return -3;              /* return a hard error    */
  1392.             } else {
  1393.                 switch (s_errno) {
  1394.                 case WSAETIMEDOUT:
  1395.                     if ( timo == 0 )
  1396.                         goto begin;
  1397.                     return(-1);
  1398.                 case WSAECONNRESET:
  1399.                     ttclos(0);                  /* *** *** */
  1400.                     return(-2);                 /* Connection is broken. */
  1401.                 case WSAECONNABORTED:
  1402.                     ttclos(0);                  /* *** *** */
  1403.                     return(-2);                 /* Connection is broken. */
  1404.                 case WSAENETRESET:
  1405.                     ttclos(0);                  /* *** *** */
  1406.                     return(-2);                 /* Connection is broken. */
  1407.                 case WSAENOTCONN:
  1408.                     ttclos(0);                  /* *** *** */
  1409.                     return(-2);                 /* Connection is broken. */
  1410.                 case WSAEWOULDBLOCK:
  1411.                     break;
  1412.                 }
  1413.                 if ( timo == 0 )
  1414.                     goto begin;
  1415.                 return -1;                      /* Return a timeout */
  1416.             }
  1417.         }
  1418.         return(c);                              /* Return char read */
  1419.     }
  1420.     if ( timo == 0 )
  1421.         goto begin;
  1422.     return(-1);                                 /* Return a timeout */
  1423. #else /* NOBUF */
  1424.     int x, c;
  1425. #ifdef OS2
  1426.     RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
  1427. #endif /* OS2 */
  1428.     if (sshibn > 0) {                    /* Something in internal buffer? */
  1429. #ifdef COMMENT
  1430.         debug(F100,"ssh_inc char in buf","",0); /* Yes. */
  1431. #endif /* COMMENT */
  1432.         x = 0;                          /* Success. */
  1433.     } else {                            /* Else must read from network. */
  1434.         x = -1;                         /* Assume failure. */
  1435. #ifdef DEBUG
  1436.         debug(F101,"ssh_inc goes to net, timo","",timo);
  1437. #endif /* DEBUG */
  1438.         {
  1439. #ifdef BSDSELECT
  1440.             fd_set rfds;
  1441.             struct timeval tv;
  1442.             int timeout = timo < 0 ? -timo : 1000 * timo;
  1443.             debug(F101,"ssh_inc BSDSELECT","",timo);
  1444.  
  1445.             for ( ; timeout >= 0; timeout -= (timo ? 100 : 0)) {
  1446.                 int rc;
  1447.                 debug(F111,"ssh_inc","timeout",timeout);
  1448.                 /* Don't move select() initialization out of the loop. */
  1449.                 FD_ZERO(&rfds);
  1450.                 FD_SET(SOCK_IN, &rfds);
  1451.                 tv.tv_sec  = tv.tv_usec = 0L;
  1452.                 if (timo)
  1453.                   tv.tv_usec = (long) 100000L;
  1454.                 else
  1455.                   tv.tv_sec = 30;
  1456. #ifdef NT
  1457.                 WSASafeToCancel = 1;
  1458. #endif /* NT */
  1459.                 rc = select(FD_SETSIZE,
  1460. #ifndef __DECC
  1461.                             (fd_set *)
  1462. #endif /* __DECC */
  1463.                             &rfds, NULL, NULL, &tv);
  1464.                 if (rc < 0) {
  1465.                     int s_errno = socket_errno;
  1466.                     debug(F111,"ssh_inc","select",rc);
  1467.                     debug(F111,"ssh_inc","socket_errno",s_errno);
  1468.                     if (s_errno) {
  1469. #ifdef OS2
  1470.                         ReleaseTCPIPMutex();
  1471. #endif /* OS2 */
  1472.                         return(-1);
  1473.                     }
  1474.                 }
  1475.                 debug(F111,"ssh_inc","select",rc);
  1476. #ifdef NT
  1477.                 WSASafeToCancel = 0;
  1478. #endif /* NT */
  1479.                 if (!FD_ISSET(SOCK_IN, &rfds)) {
  1480. #ifdef LEBUF
  1481.                     if (le_inbuf() > 0) {
  1482.                         timeout = -1;
  1483.                         break;
  1484.                     }
  1485. #endif /* LEBUF */
  1486.                     /* If waiting forever we have no way of knowing if the */
  1487.                     /* socket closed so try writing a 0-length TCP packet  */
  1488.                     /* which should force an error if the socket is closed */
  1489.                     if (!timo) {
  1490.                         if ((rc = socket_write(SOCK_IN,"",0)) < 0) {
  1491.                             int s_errno = socket_errno;
  1492.                             debug(F101,"ssh_inc socket_write error","",s_errno);
  1493. #ifdef OS2
  1494.                             if (os2socketerror(s_errno) < 0) {
  1495.                               ReleaseTCPIPMutex();
  1496.                               return(-2);
  1497.                             }
  1498.                             ReleaseTCPIPMutex();
  1499. #endif /* OS2 */
  1500.                             return(-1); /* Call it an i/o error */
  1501.                         }
  1502.                     }
  1503.                     continue;
  1504.                 }
  1505.                 while (1) {
  1506.                     if (sshbufr() < 0) { /* Keep trying to refill it. */
  1507.                         timeout = -1;
  1508.                         break;          /* Till we get an error. */
  1509.                     }
  1510.                     if (sshibn > 0) {    /* Or we get a character. */
  1511.                         x = 0;
  1512.                         timeout = -1;
  1513.                         break;
  1514.                     }
  1515.                 }
  1516.             }
  1517. #ifdef NT
  1518.             WSASafeToCancel = 0;
  1519. #endif /* NT */
  1520. #else /* !BSDSELECT */
  1521. #ifdef IBMSELECT
  1522. /*
  1523.   Was used by OS/2, currently not used, but might come in handy some day...
  1524.   ... and it came in handy!  For our TCP/IP layer, it avoids all the fd_set
  1525.   and timeval stuff since this is the only place where it is used.
  1526. */
  1527.             int socket = SOCK_IN;
  1528.             int timeout = timo < 0 ? -timo : 1000 * timo;
  1529.  
  1530.             debug(F101,"ssh_inc IBMSELECT","",timo);
  1531.             for ( ; timeout >= 0; timeout -= (timo ? 100 : 0)) {
  1532.                 if (select(&socket, 1, 0, 0, 100L) == 1) {
  1533.                     while (1) {
  1534.                         if (sshbufr() < 0) { /* Keep trying to refill it. */
  1535.                             timeout = -1;
  1536.                             break;      /* Till we get an error. */
  1537.                         }
  1538.                         if (sshibn > 0) { /* Or we get a character. */
  1539.                             x = 0;
  1540.                             timeout = -1;
  1541.                             break;
  1542.                         }
  1543.                     }
  1544.                 }
  1545. #ifdef LEBUF
  1546.                 else if (le_inbuf() > 0)  {
  1547.                     timeout = -1;
  1548.                     break;
  1549.                 }
  1550. #endif /* LEBUF */
  1551.             }
  1552. #else /* !IBMSELECT */
  1553. #ifdef WINSOCK
  1554.        /* Actually, under WinSock we have a better mechanism than select() */
  1555.        /* for setting timeouts (SO_RCVTIMEO, SO_SNDTIMEO) */
  1556.             SOCKET socket = SOCK_IN;
  1557.             debug(F101,"ssh_inc NTSELECT","",timo);
  1558.             if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timo,
  1559.                             sizeof(timo))  == NO_ERROR)
  1560.               while (1) {
  1561.                   if (sshbufr() < 0)     /* Keep trying to refill it. */
  1562.                     break;              /* Till we get an error. */
  1563.                   if (sshibn > 0) {      /* Or we get a character. */
  1564.                       x = 0;
  1565.                       break;
  1566.                   }
  1567.               }
  1568. #else /* WINSOCK */
  1569. /*
  1570.   If we can't use select(), then we use the regular alarm()/signal()
  1571.   timeout mechanism.
  1572. */
  1573.             debug(F101,"ssh_inc alarm","",timo);
  1574.             x = alrm_execute(ckjaddr(njbuf),timo,nettout,dossh_inc,failssh_inc);
  1575.             sshimoff();                  /* Timer off. */
  1576. #endif /* WINSOCK */
  1577. #endif /* IBMSELECT */
  1578. #endif /* BSDSELECT */
  1579.         }
  1580.     }
  1581.  
  1582. #ifdef LEBUF
  1583.     if (le_inbuf() > 0) {               /* If data was inserted into the */
  1584.         if (le_getchar((CHAR *)&c) > 0) {/* Local Echo buffer while the   */
  1585. #ifdef OS2                               /* was taking place do not mix   */
  1586.           ReleaseTCPIPMutex();           /* the le data with the net data */
  1587. #endif /* OS2 */
  1588.           return(c);
  1589.         }
  1590.     }
  1591. #endif /* LEBUF */
  1592.     if (x < 0) {                        /* Return -1 if we failed. */
  1593.         debug(F100,"ssh_inc timed out","",0);
  1594. #ifdef OS2
  1595.         ReleaseTCPIPMutex();
  1596. #endif /* OS2 */
  1597.         return(-1);
  1598.     } else {                            /* Otherwise */
  1599.         c = sshibuf[sshibp];              /* Return the first char in sshibuf[] */
  1600.         if (deblog) {
  1601. #ifndef COMMENT
  1602.             debug(F101,"ssh_inc returning","",c);
  1603. #endif /* COMMENT */
  1604.             if (c == 0) {
  1605.                 debug(F101,"ssh_inc 0 sshibn","",sshibn);
  1606.                 debug(F101,"ssh_inc 0 sshibp","",sshibp);
  1607. #ifdef BETADEBUG
  1608.                 {
  1609. #ifdef OS2
  1610.                     extern int tt_type_mode;
  1611.                     if ( !ISVTNT(tt_type_mode) )
  1612. #endif /* OS2 */
  1613.                     hexdump("ssh_inc &ttbuf[sshibp]",&sshibuf[sshibp],sshibn);
  1614.                 }
  1615. #endif /* BETADEBUG */
  1616.             }
  1617.         }
  1618.         sshibp++;
  1619.         sshibn--;
  1620. #ifdef OS2
  1621.         ReleaseTCPIPMutex();
  1622. #endif /* OS2 */
  1623.         return(c);
  1624.     }
  1625. #endif /* NOBUF */
  1626. }
  1627.  
  1628.  
  1629. int
  1630. ssh_xin(int n, char * buf) {
  1631. #ifdef NOBUF
  1632.     int count;
  1633.     char c=0;
  1634.     fd_set rfds;
  1635.     struct timeval tv;
  1636.  
  1637.     if ( !open_connection )
  1638.         return(-1);
  1639.  
  1640.   begin:
  1641.     FD_ZERO(&rfds);
  1642.     FD_SET(SOCK_IN, &rfds);
  1643.     tv.tv_sec  = tv.tv_usec = 0L;       /* No timeout */
  1644.  
  1645.     if (select(FD_SETSIZE, (fd_set *) &rfds,
  1646.                 NULL, NULL, &tv) > 0 &&
  1647.          FD_ISSET(SOCK_IN, &rfds)) {
  1648.  
  1649.         if ((count = recv(SOCK_IN,buf,n,0)) <= 0) {
  1650.             int s_errno = WSAGetLastError();
  1651.             if (count == 0) {
  1652.                 ttclos(0);              /* if the connection was  */
  1653.                 return -3;              /* return a hard error    */
  1654.             } else {
  1655.                 switch (s_errno) {
  1656.                 case WSAETIMEDOUT:
  1657.                     return(-1);
  1658.                 case WSAECONNRESET:
  1659.                     ttclos(0);                  /* *** *** */
  1660.                     return(-2);                 /* Connection is broken. */
  1661.                 case WSAECONNABORTED:
  1662.                     ttclos(0);                  /* *** *** */
  1663.                     return(-2);                 /* Connection is broken. */
  1664.                 case WSAENETRESET:
  1665.                     ttclos(0);                  /* *** *** */
  1666.                     return(-2);                 /* Connection is broken. */
  1667.                 case WSAENOTCONN:
  1668.                     ttclos(0);                  /* *** *** */
  1669.                     return(-2);                 /* Connection is broken. */
  1670.                 case WSAEWOULDBLOCK:
  1671.                     break;
  1672.                 }
  1673.                 return 0;                       /* Return a timeout */
  1674.             }
  1675.         }
  1676.         return(count);
  1677.     }
  1678.     return(0);
  1679. #else /* NOBUF */
  1680.     int len, i, j;
  1681.     int rc;
  1682.  
  1683.     if ( !open_connection ) {
  1684.         debug(F100,"ssh_xin socket is closed","",0);
  1685.         return(-2);
  1686.     }
  1687. #ifdef OS2
  1688.     RequestTCPIPMutex(SEM_INDEFINITE_WAIT);
  1689. #endif /* OS2 */
  1690.     if (sshibn == 0)
  1691.       if ((rc = sshbufr()) <= 0) {
  1692. #ifdef OS2
  1693.         ReleaseTCPIPMutex();
  1694. #endif /* OS2 */
  1695.         return(rc);
  1696.       }
  1697.  
  1698.     if (sshibn <= n) {
  1699.         len = sshibn;
  1700.         memcpy(buf,&sshibuf[sshibp],len);         /* safe */
  1701.         sshibp += len;
  1702.         sshibn = 0;
  1703.     } else {
  1704.         memcpy(buf,&sshibuf[sshibp],n);           /* safe */
  1705.         sshibp += n;
  1706.         sshibn -= n;
  1707.         len = n;
  1708.     }
  1709. #ifdef OS2
  1710.     ReleaseTCPIPMutex();
  1711. #endif /* OS2 */
  1712.  
  1713.     return(len);
  1714. #endif /* NOBUF */
  1715. }
  1716.  
  1717.  
  1718. int
  1719. ssh_toc(int c) {
  1720.     char ch = c;
  1721.     fd_set wfds;
  1722.     struct timeval tv;
  1723.  
  1724.     if ( !open_connection )
  1725.         return(-1);
  1726.  
  1727.     FD_ZERO(&wfds);
  1728.     FD_SET(SOCK_OUT, &wfds);
  1729.     tv.tv_sec  = tv.tv_usec = 0L;
  1730.     tv.tv_sec = 60;
  1731.     if (!(select(FD_SETSIZE, NULL, &wfds, NULL, &tv) > 0 &&
  1732.            FD_ISSET(SOCK_OUT, &wfds))) {
  1733.               return(-1);
  1734.     }
  1735.  
  1736.     if (send(SOCK_OUT,&ch,1,0) < 1) {
  1737.         int s_errno = WSAGetLastError();
  1738.         switch (s_errno) {
  1739.         case WSAETIMEDOUT:
  1740.             return(-1);
  1741.         case WSAECONNRESET:
  1742.             ttclos(0);                  /* *** *** */
  1743.             return(-2);                 /* Connection is broken. */
  1744.         case WSAECONNABORTED:
  1745.             ttclos(0);                  /* *** *** */
  1746.             return(-2);                 /* Connection is broken. */
  1747.         case WSAENETRESET:
  1748.             ttclos(0);                  /* *** *** */
  1749.             return(-2);                 /* Connection is broken. */
  1750.         case WSAENOTCONN:
  1751.             ttclos(0);                  /* *** *** */
  1752.             return(-2);                 /* Connection is broken. */
  1753.         case WSAEWOULDBLOCK:
  1754.             break;
  1755.         }
  1756.         return(-1);
  1757.     }
  1758.     return(0);
  1759. }
  1760.  
  1761. int
  1762. ssh_tol(char * buffer, int count) {
  1763.     fd_set wfds;
  1764.     struct timeval tv;
  1765.  
  1766.     if ( !open_connection )
  1767.         return(-1);
  1768.  
  1769.     FD_ZERO(&wfds);
  1770.     FD_SET(SOCK_OUT, &wfds);
  1771.     tv.tv_sec  = tv.tv_usec = 0L;
  1772.     tv.tv_sec = 60;
  1773.     if (!(select(FD_SETSIZE, NULL, &wfds, NULL, &tv) > 0 &&
  1774.            FD_ISSET(SOCK_OUT, &wfds))) {
  1775.               return(-1);
  1776.     }
  1777.  
  1778.     if ((count = send(SOCK_OUT,buffer,count,0)) < 1) {
  1779.         int s_errno = WSAGetLastError();         /* maybe a function */
  1780.         switch (s_errno) {
  1781.         case WSAETIMEDOUT:
  1782.             return(-1);
  1783.         case WSAECONNRESET:
  1784.             ttclos(0);                  /* *** *** */
  1785.             return(-2);                 /* Connection is broken. */
  1786.         case WSAECONNABORTED:
  1787.             ttclos(0);                  /* *** *** */
  1788.             return(-2);                 /* Connection is broken. */
  1789.         case WSAENETRESET:
  1790.             ttclos(0);                  /* *** *** */
  1791.             return(-2);                 /* Connection is broken. */
  1792.         case WSAENOTCONN:
  1793.             ttclos(0);                  /* *** *** */
  1794.             return(-2);                 /* Connection is broken. */
  1795.         case WSAEWOULDBLOCK:
  1796.             break;
  1797.         }
  1798.         return(-1);
  1799.     }
  1800.     return(count);
  1801. }
  1802.  
  1803. VOID
  1804. ssh_terminfo(char * ttype, int h, int w) {
  1805.     static int height=0, width=0;
  1806.     if ( h != height || w != width ) {
  1807.         height = h;
  1808.         width = w;
  1809.         packet_start(SSH_CMSG_WINDOW_SIZE);
  1810.         packet_put_int(h);
  1811.         packet_put_int(w);
  1812.         packet_put_int(0);
  1813.         packet_put_int(0);
  1814.         packet_send();
  1815.     }
  1816. }
  1817.  
  1818.  
  1819.  
  1820. const char *
  1821. ssh_version(void) {
  1822.     static char msg[256];
  1823.     sprintf(msg,
  1824.              "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n",
  1825.              SSH_VERSION,
  1826.              PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
  1827.              PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
  1828.              SSLeay());
  1829.     return(msg);
  1830. }
  1831.  
  1832. const char *
  1833. ssh_errorstr(int error) {
  1834.     switch ( error ) {
  1835.     case 0:
  1836.         return("success");
  1837.         break;
  1838.     case -1:
  1839.         return("timeout");
  1840.         break;
  1841.     case -2:
  1842.         return("connection closed");
  1843.     case -100:
  1844.         return("usage error: matching parenthese not found");
  1845.     case -101:
  1846.         return("usage error: missing operand");
  1847.     case -102:
  1848.         return("usage error: option missing argument");
  1849.         break;
  1850.     case -103:
  1851.         return("usage error: switch specified is more than one letter");
  1852.     case -104:
  1853.         return("usage error: identity file does not exist");
  1854.     case -105:
  1855.         return("usage error: too many identity files specified");
  1856.     case -106:
  1857.         return(ssh_version());
  1858.     case -107:
  1859.         return("usage error: Bad escape character");
  1860.     case -108:
  1861.         return("usage error: unknown cipher type");
  1862.     case -109:
  1863.         return("usage error: bad port");
  1864.     case -110:
  1865.         return("usage error: bad remote forwarding specification");
  1866.     case -111:
  1867.         return("usage error: bad local forwarding specification");
  1868.     case -112:
  1869.         return("usage error: privileged ports can only be forwarded by root");
  1870.     case -113:
  1871.         return("usage error: unknown switch");
  1872.     case -114:
  1873.         return("usage error: missing host");
  1874.     case -115:
  1875.         return("cannot fork into background without a command to execute");
  1876.     case -116:
  1877.         return("connection failed");
  1878.     case -117:
  1879.         return("unable to create directory $(HOME)/.ssh");
  1880.     case -118:
  1881.         return("Compression level must be from 1 (fast) to 9 (slow, best)");
  1882.     case -119:
  1883.         return("fork after authentication not implemented on Windows NT");
  1884.     case -120:
  1885.         return("authentication failed");
  1886.     case -121:
  1887.         return("unable to create socket pair");
  1888.     case -122:
  1889.         return("login failure");
  1890.     default:
  1891.         return("unknown");
  1892.     }
  1893. }
  1894.  
  1895. int
  1896. ssh_ttvt(void)
  1897. {
  1898.     if ( !open_connection )
  1899.         return(-1);
  1900.     return(0);
  1901. }
  1902.  
  1903. int
  1904. ssh_ttpkt(void)
  1905. {
  1906.     if ( !open_connection )
  1907.         return(-1);
  1908.     return(0);
  1909. }
  1910.  
  1911. int
  1912. ssh_ttres(void)
  1913. {
  1914.     if ( !open_connection )
  1915.         return(-1);
  1916.     return(0);
  1917. }
  1918. /* END SSHDLL.C */
  1919.  
  1920. #ifdef COMMENT
  1921. /* Keep so we know what the SSH personality command line should look like */
  1922. VOID
  1923. ssh_usage(void)
  1924. {
  1925.         fprintf(stderr, "Usage: %s [options] host [command]\n", __progname);
  1926.         fprintf(stderr, "Options:\n");
  1927.         fprintf(stderr, "  -l user     Log in using this user name.\n");
  1928.         fprintf(stderr, "  -n          Redirect input from " _PATH_DEVNULL ".\n");
  1929.         fprintf(stderr, "  -A          Enable authentication agent forwarding.\n");
  1930.         fprintf(stderr, "  -a          Disable authentication agent forwarding.\n");
  1931. #ifdef AFS
  1932.         fprintf(stderr, "  -k          Disable Kerberos ticket and AFS token forwarding.\n");
  1933. #endif                          /* AFS */
  1934.         fprintf(stderr, "  -X          Enable X11 connection forwarding.\n");
  1935.         fprintf(stderr, "  -x          Disable X11 connection forwarding.\n");
  1936.         fprintf(stderr, "  -i file     Identity for public key authentication "
  1937.             "(default: ~/.ssh/identity)\n");
  1938.         fprintf(stderr, "  -t          Tty; allocate a tty even if command is given.\n");
  1939.         fprintf(stderr, "  -T          Do not allocate a tty.\n");
  1940.         fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");
  1941.         fprintf(stderr, "              Multiple -v increases verbosity.\n");
  1942.         fprintf(stderr, "  -V          Display version number only.\n");
  1943.         fprintf(stderr, "  -q          Quiet; don't display any warning messages.\n");
  1944.         fprintf(stderr, "  -f          Fork into background after authentication.\n");
  1945.         fprintf(stderr, "  -e char     Set escape character; ``none'' = disable (default: ~).\n");
  1946.  
  1947.         fprintf(stderr, "  -c cipher   Select encryption algorithm: "
  1948.             "``3des'', ``blowfish''\n");
  1949.         fprintf(stderr, "  -m macs     Specify MAC algorithms for protocol version 2.\n");
  1950.         fprintf(stderr, "  -p port     Connect to this port.  Server must be on the same port.\n");
  1951.         fprintf(stderr, "  -L listen-port:host:port   Forward local port to remote address\n");
  1952.         fprintf(stderr, "  -R listen-port:host:port   Forward remote port to local address\n");
  1953.         fprintf(stderr, "              These cause %s to listen for connections on a port, and\n", __progname);
  1954.         fprintf(stderr, "              forward them to the other side by connecting to host:port.\n");
  1955.         fprintf(stderr, "  -C          Enable compression.\n");
  1956.         fprintf(stderr, "  -N          Do not execute a shell or command.\n");
  1957.         fprintf(stderr, "  -g          Allow remote hosts to connect to forwarded ports.\n");
  1958.         fprintf(stderr, "  -1          Force protocol version 1.\n");
  1959.         fprintf(stderr, "  -2          Force protocol version 2.\n");
  1960.         fprintf(stderr, "  -4          Use IPv4 only.\n");
  1961.         fprintf(stderr, "  -6          Use IPv6 only.\n");
  1962.         fprintf(stderr, "  -o 'option' Process the option as if it was read from a configuration file.\n");
  1963.         fprintf(stderr, "  -s          Invoke command (mandatory) as SSH2 subsystem.\n");
  1964.         exit(1);
  1965. }
  1966. #endif /* COMMENT */
  1967.  
  1968. static void
  1969. x11_get_proto(char ** _proto, char **_data)
  1970. {
  1971.     char line[512];
  1972.     static char proto[512], data[512];
  1973.     FILE *f;
  1974.     int got_data = 0, i;
  1975.     char *display;
  1976.     struct _stat st;
  1977.  
  1978.     *_proto = proto;
  1979.     *_data  = data;
  1980.     proto[0] = data[0] = '\0';
  1981.  
  1982. #ifndef OS2
  1983.     if (options.xauth_location ||
  1984.         (stat(options.xauth_location, &st) == -1)) 
  1985.     {
  1986.         debug("No xauth program.");
  1987.     } else {
  1988.         if ((display = tn_get_display()) == NULL) {
  1989.             debug("x11_get_proto: DISPLAY not set");
  1990.             return;
  1991.         }
  1992.  
  1993.         /* Try to get Xauthority information for the display. */
  1994.         if (strncmp(display, "localhost:", 10) == 0)
  1995.             snprintf(line, sizeof line, "%.100s list %.200s 2>" _PATH_DEVNULL,
  1996.                       options.xauth_location, display+10);
  1997.         else
  1998.             snprintf(line, sizeof line, "%.100s list %.200s 2>" _PATH_DEVNULL,
  1999.                   options.xauth_location, display);
  2000.         debug2("x11_get_proto: %s", line);
  2001.         f = _popen(line, "r");
  2002.         if (f && fgets(line, sizeof(line), f) &&
  2003.              sscanf(line, "%*s %511s %511s", proto, data) == 2)
  2004.             got_data = 1;
  2005.         if (f)
  2006.             _pclose(f);
  2007.     }
  2008. #endif /* OS2 */
  2009.     /*
  2010.      * If we didn't get authentication data, just make up some
  2011.      * data.  The forwarding code will check the validity of the
  2012.      * response anyway, and substitute this data.  The X11
  2013.      * server, however, will ignore this fake data and use
  2014.      * whatever authentication mechanisms it was using otherwise
  2015.      * for the local connection.
  2016.      */
  2017.     if (!got_data) {
  2018.         u_int32_t rand = 0;
  2019.  
  2020.         log("Warning: No xauth data; using fake authentication data for X11 forwarding");
  2021.         strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof(proto));
  2022.         for (i = 0; i < 16; i++) {
  2023.             if (i % 4 == 0)
  2024.                 rand = arc4random();
  2025.             snprintf(data + 2 * i, sizeof(data) - 2 * i, "%02x", rand & 0xff);
  2026.             rand >>= 8;
  2027.         }
  2028.     }
  2029. }
  2030.  
  2031. void
  2032. ssh_v2_rekey(void)
  2033. {
  2034.     if (compat20 && !(datafellows & SSH_BUG_NOREKEY))
  2035.         need_rekeying = 1;
  2036. }
  2037.  
  2038. int
  2039. ssh_fwd_local_port(int port, char * host, int host_port)
  2040. {
  2041.     return channel_setup_local_fwd_listener(port,host,host_port,ssh_gwp);
  2042. }
  2043.  
  2044. int
  2045. ssh_fwd_remote_port(int port, char * host, int host_port)
  2046. {
  2047.     return channel_request_remote_forwarding(port,host,host_port);
  2048. }
  2049.  
  2050. static void
  2051. ssh_init_forwarding(void)
  2052. {
  2053.     int success = 0;
  2054.     int i;
  2055.  
  2056.     /* Initiate local TCP/IP port forwardings. */
  2057.     for (i = 0; i < options.num_local_forwards; i++) {
  2058.         debug(F111,"SSH: Connections to","local port",
  2059.                options.local_forwards[i].port);
  2060.         debug(F111,"SSH: Forwarded to",
  2061.                options.local_forwards[i].host,
  2062.                options.local_forwards[i].host_port);
  2063.         success += channel_setup_local_fwd_listener(
  2064.                options.local_forwards[i].port,
  2065.                options.local_forwards[i].host,
  2066.                options.local_forwards[i].host_port,
  2067.                options.gateway_ports);
  2068.     }
  2069.     if (i > 0 && success == 0) {
  2070.         error("Could not request local forwarding.");
  2071. #ifdef KUI
  2072.         uq_ok(NULL, "Could not request local forwarding", 1, NULL, 0);
  2073. #endif /* KUI */
  2074.     }
  2075.     /* Initiate remote TCP/IP port forwardings. */
  2076.     for (i = 0; i < options.num_remote_forwards; i++) {
  2077.         debug(F111,"SSH: Connections to","remote port",
  2078.                options.remote_forwards[i].port);
  2079.         debug(F111,"SSH: Forwarded to local address",
  2080.                options.remote_forwards[i].host,
  2081.                options.remote_forwards[i].host_port);
  2082.         channel_request_remote_forwarding(options.remote_forwards[i].port,
  2083.                                            options.remote_forwards[i].host,
  2084.                                            options.remote_forwards[i].host_port);
  2085.     }
  2086. }
  2087.  
  2088. static void
  2089. check_agent_present(void)
  2090. {
  2091.     if (options.forward_agent) {
  2092.         /* Clear agent forwarding if we don\'t have an agent. */
  2093.         if (!ssh_agent_present())
  2094.             options.forward_agent = 0;
  2095.     }
  2096. }
  2097.  
  2098. static int
  2099. ssh_session(void)
  2100. {
  2101.     int type;
  2102.     int interactive = 0;
  2103.     int have_tty = 0;
  2104.     struct winsize ws;
  2105.     char *cp;
  2106.  
  2107.     /* Enable compression if requested. */
  2108.     if (options.compression) {
  2109.         debug(F111,"SSH","Requesting compression at level", options.compression_level);
  2110.  
  2111.         if (options.compression_level < 1 || options.compression_level > 9) {
  2112.             ssh_fatal("Compression level must be from 1 (fast) to 9 (slow, best).");
  2113.             return -1;
  2114.         }
  2115.         /* Send the request. */
  2116.         packet_start(SSH_CMSG_REQUEST_COMPRESSION);
  2117.         packet_put_int(options.compression_level);
  2118.         packet_send();
  2119.         packet_write_wait();
  2120.         type = packet_read();
  2121.         if (type == SSH_SMSG_SUCCESS)
  2122.             packet_start_compression(options.compression_level);
  2123.         else if (type == SSH_SMSG_FAILURE)
  2124.             log("Warning: Remote host refused compression.");
  2125.         else {
  2126.             packet_disconnect("Protocol error waiting for compression response.");
  2127.             return(-1);
  2128.         }
  2129.     }
  2130.     /* Allocate a pseudo tty if appropriate. */
  2131.     if (tty_flag) {
  2132.         debug(F110,"SSH","Requesting pty.",0);
  2133.  
  2134.         /* Start the packet. */
  2135.         packet_start(SSH_CMSG_REQUEST_PTY);
  2136.  
  2137.         /* Store TERM in the packet.  There is no limit on the
  2138.            length of the string. */
  2139.         cp = getterm();
  2140.         if (!cp)
  2141.             cp = "";
  2142.         packet_put_cstring(cp);
  2143.  
  2144.         /* Store window size in the packet. */
  2145. #ifdef OS2
  2146.         if (_getwinsize( &ws ) == -1)
  2147.             memset(&ws,0,sizeof(ws));
  2148. #else
  2149.         if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
  2150.             memset(&ws, 0, sizeof(ws));
  2151. #endif
  2152.         received_window_change_signal = 0;
  2153.         sent_initial_ws = 1;
  2154.         ssh_width = ws.ws_col;
  2155.         ssh_height = ws.ws_row;
  2156.         packet_put_int(ws.ws_row);
  2157.         packet_put_int(ws.ws_col);
  2158.         packet_put_int(ws.ws_xpixel);
  2159.         packet_put_int(ws.ws_ypixel);
  2160.  
  2161.         /* Store tty modes in the packet. */
  2162.         tty_make_modes(fileno(stdin), NULL);
  2163.  
  2164.         /* Send the packet, and wait for it to leave. */
  2165.         packet_send();
  2166.         packet_write_wait();
  2167.  
  2168.         /* Read response from the server. */
  2169.         type = packet_read();
  2170.         if (type == SSH_SMSG_SUCCESS) {
  2171.             interactive = 1;
  2172.             have_tty = 1;
  2173.         } else if (type == SSH_SMSG_FAILURE)
  2174.             log("Warning: Remote host failed or refused to allocate a pseudo tty.");
  2175.         else {
  2176.             packet_disconnect("Protocol error waiting for pty request response.");
  2177.             return -1;
  2178.         }
  2179.     }
  2180.     /* Request X11 forwarding if enabled. (display is checked in x11_get_proto) */
  2181.     if (options.forward_x11) 
  2182.     {
  2183.         char *proto, *data;
  2184.         /* Get reasonable local authentication information. */
  2185.         x11_get_proto(&proto, &data);
  2186.         /* Request forwarding with authentication spoofing. */
  2187.         debug(F110,"SSH","Requesting X11 forwarding with authentication spoofing.",0);
  2188.         x11_request_forwarding_with_spoofing(0, proto, data);
  2189.  
  2190.         /* Read response from the server. */
  2191.         type = packet_read();
  2192.         if (type == SSH_SMSG_SUCCESS) {
  2193.             interactive = 1;
  2194.         } else if (type == SSH_SMSG_FAILURE) {
  2195.             log("Warning: Remote host denied X11 forwarding.");
  2196.         } else {
  2197.             packet_disconnect("Protocol error waiting for X11 forwarding");
  2198.             return -1;
  2199.         }
  2200.     }
  2201.     /* Tell the packet module whether this is an interactive session. */
  2202.     packet_set_interactive(interactive);
  2203.  
  2204.     /* Request authentication agent forwarding if appropriate. */
  2205.     check_agent_present();
  2206.  
  2207.     if (options.forward_agent) {
  2208.         debug(F110,"SSH","Requesting authentication agent forwarding.",0);
  2209.         auth_request_forwarding();
  2210.  
  2211.         /* Read response from the server. */
  2212.         type = packet_read();
  2213.         packet_check_eom();
  2214.         if (type != SSH_SMSG_SUCCESS)
  2215.             log("Warning: Remote host denied authentication agent forwarding.");
  2216.     }
  2217.  
  2218.     /* Initiate port forwardings. */
  2219.     ssh_init_forwarding();
  2220.  
  2221.     /* If requested, let ssh continue in the background. */
  2222.     if (fork_after_authentication_flag)
  2223.     {
  2224. #ifdef OS2
  2225.         fprintf(stderr,
  2226.                  "fork after authentication is not implemented on Win32 environment\n");
  2227.         exit(1);
  2228. #else
  2229.         if (daemon(1, 1) < 0)
  2230.             fatal("daemon() failed: %.200s", strerror(errno));
  2231. #endif /* OS2 */
  2232.     }
  2233.  
  2234.     /*
  2235.      * If a command was specified on the command line, execute the
  2236.      * command now. Otherwise request the server to start a shell.
  2237.      */
  2238.     if (buffer_len(&command) > 0) {
  2239.         int len = buffer_len(&command);
  2240.         if (len > 900)
  2241.             len = 900;
  2242.         debug1("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));
  2243.         packet_start(SSH_CMSG_EXEC_CMD);
  2244.         packet_put_string(buffer_ptr(&command), buffer_len(&command));
  2245.         packet_send();
  2246.         packet_write_wait();
  2247.     } else {
  2248.         debug1("Requesting shell.");
  2249.         packet_start(SSH_CMSG_EXEC_SHELL);
  2250.         packet_send();
  2251.         packet_write_wait();
  2252.     }
  2253.  
  2254.     /* Enter the interactive session. */
  2255. #ifdef OS2
  2256.     /* Start the Client Loop Thread */
  2257.     clientloopID = 0;
  2258.     hClientLoopThread = CreateThread(NULL, 0, ClientLoopThread,
  2259.                                       &clientloopID, 0, &ClientLoopThreadID);
  2260.     msleep(100);
  2261.     open_connection = 1;
  2262.     return(0);
  2263. #else
  2264.     return client_loop(have_tty, tty_flag ? options.escape_char : SSH_ESCAPECHAR_NONE, 0);
  2265. #endif /* OS2 */
  2266. }
  2267.  
  2268. static int
  2269. client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
  2270. {
  2271.     int id, len;
  2272.  
  2273.     id = packet_get_int();
  2274.     len = buffer_len(&command);
  2275.     if (len > 900)
  2276.         len = 900;
  2277.     packet_check_eom();
  2278.     if (type == SSH2_MSG_CHANNEL_FAILURE) {
  2279.         fatal("Request for subsystem '%.*s' failed on channel %d",
  2280.                len, (u_char *)buffer_ptr(&command), id);
  2281.         quit_pending = 1;
  2282.         return(-1);
  2283.     }
  2284.     return(0);
  2285. }
  2286.  
  2287. static int
  2288. client_global_request_reply(int type, u_int32_t seq, void *ctxt)
  2289. {
  2290.     int i;
  2291.  
  2292.     i = client_global_request_id++;
  2293.     if (i >= options.num_remote_forwards) {
  2294.         debug1("client_global_request_reply: too many replies %d > %d",
  2295.                i, options.num_remote_forwards);
  2296.         return 0;
  2297.     }
  2298.     debug1("remote forward %s for: listen %d, connect %s:%d",
  2299.            type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
  2300.            options.remote_forwards[i].port,
  2301.            options.remote_forwards[i].host,
  2302.            options.remote_forwards[i].host_port);
  2303.     if (type == SSH2_MSG_REQUEST_FAILURE)
  2304.         log("Warning: remote port forwarding failed for listen port %d",
  2305.              options.remote_forwards[i].port);
  2306.     return 0;
  2307. }
  2308.  
  2309. /* request pty/x11/agent/tcpfwd/shell for channel */
  2310. static void
  2311. ssh_session2_setup(int id, void *arg)
  2312. {
  2313.     int len;
  2314.     int interactive = 0;
  2315. #ifndef OS2
  2316.     struct termios tio;
  2317. #endif /* OS2 */
  2318.  
  2319.     debug2("ssh_session2_setup: id: %d arg: ",id);
  2320.  
  2321.     if (tty_flag) {
  2322.         struct winsize ws;
  2323.         char *cp;
  2324.         cp = getterm();
  2325.         if (!cp)
  2326.             cp = "";
  2327.         /* Store window size in the packet. */
  2328. #ifdef OS2
  2329.         if (_getwinsize( &ws ) == -1)
  2330.             memset(&ws,0,sizeof(ws));
  2331. #else
  2332.         if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
  2333.             memset(&ws, 0, sizeof(ws));
  2334. #endif
  2335.         received_window_change_signal = 0;
  2336.         sent_initial_ws = 1;
  2337.         ssh_width = ws.ws_col;
  2338.         ssh_height = ws.ws_row;
  2339.         channel_request_start(id, "pty-req", 0);
  2340.         packet_put_cstring(cp);
  2341.         packet_put_int(ws.ws_col);
  2342.         packet_put_int(ws.ws_row);
  2343.         packet_put_int(ws.ws_xpixel);
  2344.         packet_put_int(ws.ws_ypixel);
  2345.  
  2346. #ifdef OS2
  2347.         tty_make_modes(0,0);
  2348. #else
  2349.         tio = get_saved_tio();
  2350.         tty_make_modes(/*ignored*/ 0, &tio);
  2351. #endif /* OS2 */
  2352.         packet_send();
  2353.         interactive = 1;
  2354.         /* XXX wait for reply */
  2355.     }
  2356.     if (options.forward_x11) {
  2357.         char *proto, *data;
  2358.         /* Get reasonable local authentication information. */
  2359.         x11_get_proto(&proto, &data);
  2360.         /* Request forwarding with authentication spoofing. */
  2361.         debug1("Requesting X11 forwarding with authentication spoofing.");
  2362.         x11_request_forwarding_with_spoofing(id, proto, data);
  2363.         interactive = 1;
  2364.         /* XXX wait for reply */
  2365.     }
  2366.  
  2367.     check_agent_present();
  2368.     if (options.forward_agent) {
  2369.         debug1("Requesting authentication agent forwarding.");
  2370.         channel_request_start(id, "auth-agent-req@openssh.com", 0);
  2371.         packet_send();
  2372.     }
  2373.  
  2374.     len = buffer_len(&command);
  2375.     if (len > 0) {
  2376.         if (len > 900)
  2377.             len = 900;
  2378.         if (subsystem_flag) {
  2379.             debug1("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command));
  2380.             channel_request_start(id, "subsystem", /*want reply*/ 1);
  2381.             /* register callback for reply */
  2382.             /* XXX we assume that client_loop has already been called */
  2383.             dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply);
  2384.             dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply);
  2385.         } else {
  2386.             debug1("Sending command: %.*s",len, (u_char *)buffer_ptr(&command));
  2387.             channel_request_start(id, "exec", 0);
  2388.         }
  2389.         packet_put_string(buffer_ptr(&command), buffer_len(&command));
  2390.         packet_send();
  2391.     } else {
  2392.         channel_request_start(id, "shell", 0);
  2393.         packet_send();
  2394.     }
  2395.     packet_set_interactive(interactive);
  2396. }
  2397.  
  2398. int
  2399. ssh_session2_open(void)
  2400. {
  2401.     Channel *c;
  2402.     int window, packetmax;
  2403.     int in, out, err;
  2404.  
  2405. #ifdef OS2
  2406.     in = sock_stdin;
  2407.     out = sock_stdout;
  2408.     err = sock_stderr;
  2409. #else
  2410.     if (stdin_null_flag) {
  2411.         in = open(_PATH_DEVNULL, O_RDONLY);
  2412.     } else {
  2413.         in = dup(STDIN_FILENO);
  2414.     }
  2415.     out = dup(STDOUT_FILENO);
  2416.     err = dup(STDERR_FILENO);
  2417.  
  2418.     if (in < 0 || out < 0 || err < 0) {
  2419.         fatal("dup() in/out/err failed");
  2420.         return(-1);
  2421.     }
  2422.  
  2423.     /* enable nonblocking unless tty */
  2424.     if (!isatty(in))
  2425.         set_nonblock(in);
  2426.     if (!isatty(out))
  2427.         set_nonblock(out);
  2428.     if (!isatty(err))
  2429.         set_nonblock(err);
  2430. #endif /* OS2 */
  2431.  
  2432.     window = CHAN_SES_WINDOW_DEFAULT;
  2433.     packetmax = CHAN_SES_PACKET_DEFAULT;
  2434.     if (!tty_flag) {
  2435.         window >>= 1;
  2436.         packetmax >>= 1;
  2437.     }
  2438.     c = channel_new("session", SSH_CHANNEL_OPENING, in, out, err,
  2439.                       window, packetmax, CHAN_EXTENDED_WRITE,
  2440.                       strdup("client-session"), /*nonblock*/0);
  2441.     if ( c == NULL ) {
  2442.         debug1("ssh_session2_open: channel_new failed");
  2443.         return -1;
  2444.     }
  2445.     debug3("ssh_session2_open: channel_new: %d", c->self);
  2446.  
  2447.     channel_send_open(c->self);
  2448.     if ( !no_shell_flag )
  2449.         channel_register_confirm(c->self, ssh_session2_setup);
  2450.  
  2451.     return c->self;
  2452. }
  2453.  
  2454. static int
  2455. ssh_session2(void)
  2456. {
  2457.     int id = -1;
  2458.  
  2459.     /* XXX should be pre-session */
  2460.     ssh_init_forwarding();
  2461.  
  2462.     if ( !no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN) )
  2463.         id = ssh_session2_open();
  2464.  
  2465.     /* If requested, let ssh continue in the background. */
  2466.     if (fork_after_authentication_flag) {
  2467. #ifdef OS2
  2468.         fprintf(stderr,
  2469.                  "fork after authentication is not implemented on Win32 environment\n");
  2470.         return(-1);
  2471. #else
  2472.         if (daemon(1, 1) < 0) {
  2473.             fatal("daemon() failed: %.200s", strerror(errno));
  2474.             return(-1);
  2475.         }
  2476. #endif /* OS2 */
  2477.     }
  2478. #ifdef OS2
  2479.     /* Start the Client Loop Thread */
  2480.     clientloopID = id;
  2481.     hClientLoopThread = CreateThread(NULL, 0, ClientLoopThread,
  2482.                                       &clientloopID, 0, &ClientLoopThreadID);
  2483.  
  2484.     open_connection = 1;
  2485.     return(0);
  2486. #else
  2487.     return client_loop(tty_flag, tty_flag ? options.escape_char : SSH_ESCAPECHAR_NONE, id);
  2488. #endif /* OS2 */
  2489. }
  2490.  
  2491. static void
  2492. load_public_identity_files(void)
  2493. {
  2494.     char *filename;
  2495.     int i = 0;
  2496.     Key *public;
  2497.  
  2498. #ifdef SMARTCARD
  2499.     Key **keys;
  2500.  
  2501.     if (options.smartcard_device != NULL &&
  2502.          options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
  2503.          (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL ) {
  2504.         int count = 0;
  2505.         for (i = 0; keys[i] != NULL; i++) {
  2506.                 count++;
  2507.                 memmove(&options.identity_files[1], &options.identity_files[0],
  2508.                     sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
  2509.                 memmove(&options.identity_keys[1], &options.identity_keys[0],
  2510.                     sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
  2511.                 options.num_identity_files++;
  2512.                 options.identity_keys[0] = keys[i];
  2513.                 options.identity_files[0] = strdup("smartcard key");;
  2514.         }
  2515.         if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
  2516.                 options.num_identity_files = SSH_MAX_IDENTITY_FILES;
  2517.         i = count;
  2518.         free(keys);
  2519.     }
  2520. #endif /* SMARTCARD */
  2521.     for (; i < options.num_identity_files; i++) {
  2522.         filename = tilde_expand_filename(options.identity_files[i], -1);
  2523.         public = key_load_public(filename, NULL);
  2524.         debug1("identity file: \"%s\" type: %d", filename,
  2525.                public ? public->type : -1);
  2526.         free(options.identity_files[i]);
  2527.         options.identity_files[i] = filename;
  2528.         options.identity_keys[i] = public;
  2529.     }
  2530. }
  2531.  
  2532. /*
  2533.  * Creates a (possibly privileged) socket for use as the ssh connection.
  2534.  */
  2535. int
  2536. ssh_create_socket(int privileged, int family)
  2537. {
  2538.     extern char * tcp_address;
  2539.     SOCKET sock;
  2540.  
  2541.     /*
  2542.      * If we are running as root and want to connect to a privileged
  2543.      * port, bind our own socket to a privileged port.
  2544.      */
  2545.     if (privileged) {
  2546.         int p = IPPORT_RESERVED - 1;
  2547.         sock = rresvport_af(&p, family);
  2548.         if (sock < 0)
  2549.             error("rresvport: af=%d %.100s", family, strerror(errno));
  2550.         else
  2551.             debug1("Allocated local port: %d", p);
  2552.     } else {
  2553.         sock = socket(family, SOCK_STREAM, 0);
  2554. #ifdef OS2
  2555.         if (sock == SOCKET_ERROR)
  2556.             error("socket: %.100s", sock_strerror(sock_lasterror()));
  2557. #else
  2558.         if (sock < 0)
  2559.             error("socket: %.100s", strerror(errno));
  2560. #endif /* OS2 */
  2561.     }
  2562.  
  2563. #ifndef datageneral
  2564.     if (tcp_address && family == AF_INET) {
  2565.         struct sockaddr_in sin;
  2566. #ifdef INADDRX
  2567.         struct in_addr inaddrx;
  2568. #endif /* INADDRX */
  2569.         int s_errno;
  2570.  
  2571.         debug1("ssh_create_socket binding socket to: %s",tcp_address);
  2572.         memset((char *)&sin,0,sizeof(sin));
  2573.         sin.sin_family = family;
  2574. #ifdef INADDRX
  2575.         inaddrx = inet_addr(tcp_address);
  2576.         sin.sin_addr.s_addr = *(unsigned long *)&inaddrx;
  2577. #else
  2578.         sin.sin_addr.s_addr = inet_addr(tcp_address);
  2579. #endif /* INADDRX */
  2580.         sin.sin_port = 0;
  2581.         if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
  2582.             s_errno = WSAGetLastError(); /* Save error code */
  2583. #ifdef TCPIPLIB
  2584.             socket_close(sock);
  2585. #else /* TCPIPLIB */
  2586.             close(sock);
  2587. #endif /* TCPIPLIB */
  2588.             sock = -1;
  2589.             errno = s_errno;       /* and report this error */
  2590.             debug1("ssh_create_socket bind errno: %d",errno);
  2591.             return(-1);
  2592.         }
  2593.     }
  2594. #endif /* datageneral */
  2595.  
  2596.     return sock;
  2597. }
  2598.  
  2599. #ifndef INET6_ADDRSTRLEN                /* for non IPv6 machines */
  2600. #define INET6_ADDRSTRLEN 46
  2601. #endif
  2602.  
  2603. static const char *
  2604. sockaddr_ntop(struct sockaddr *sa)
  2605. {
  2606.     void *addr;
  2607.     static char addrbuf[INET6_ADDRSTRLEN];
  2608.  
  2609.     switch (sa->sa_family) {
  2610.     case AF_INET:
  2611.         addr = &((struct sockaddr_in *)sa)->sin_addr;
  2612.         break;
  2613.     case AF_INET6:
  2614.         addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
  2615.         break;
  2616.     default:
  2617.         /* This case should be protected against elsewhere */
  2618.         abort();
  2619.     }
  2620.     inet_ntop(sa->sa_family, addr, addrbuf, sizeof(addrbuf));
  2621.     return addrbuf;
  2622. }
  2623.  
  2624. static int show_other_keys(const char *, Key *);
  2625.  
  2626. /*
  2627.  * Opens a TCP/IP connection to the remote server on the given host.
  2628.  * The address of the remote host will be returned in hostaddr.
  2629.  * If port is 0, the default port will be used.  If needpriv is true,
  2630.  * a privileged port will be allocated to make the connection.
  2631.  * This requires super-user privileges if needpriv is true.
  2632.  * Connection_attempts specifies the maximum number of tries (one per
  2633.  * second).  If proxy_command is non-NULL, it specifies the command (with %h
  2634.  * and %p substituted for host and port, respectively) to use to contact
  2635.  * the daemon.
  2636.  * Return values:
  2637.  *    0 for OK
  2638.  *    ECONNREFUSED if we got a "Connection Refused" by the peer on any address
  2639.  *    ECONNABORTED if we failed without a "Connection refused"
  2640.  * Suitable error messages for the connection failure will already have been
  2641.  * printed.
  2642.  */
  2643. int
  2644. ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
  2645.             u_short port, int family, int connection_attempts,
  2646.             int needpriv, const char *proxy_command)
  2647. {
  2648.     int gaierr;
  2649.     int on = 1;
  2650.     int attempt, i;
  2651.     char ntop[NI_MAXHOST], strport[NI_MAXSERV];
  2652.     struct addrinfo hints, *ai = NULL, *aitop = NULL;
  2653.     struct servent *sp = NULL;
  2654.     /*
  2655.     * Did we get only other errors than "Connection refused" (which
  2656.     * should block fallback to rsh and similar), or did we get at least
  2657.     * one "Connection refused"?
  2658.     */
  2659.     int full_failure = 1;
  2660. #ifndef NOHTTP
  2661.     char * proxy_user=NULL, * proxy_pwd=NULL;
  2662.     char uid[UIDBUFLEN];
  2663.     char pwd[256];
  2664. #endif /* NOHTTP */
  2665.  
  2666. #ifdef UNIX
  2667.     debug2("ssh_connect: needpriv %d", needpriv);
  2668. #endif /* UNIX */
  2669.  
  2670.     /* Get default port if port has not been set. */
  2671.     if (port == 0) {
  2672.         sp = getservbyname(SSH_SERVICE_NAME, "tcp");
  2673.         if (sp)
  2674.             port = ntohs(sp->s_port);
  2675.         else
  2676.             port = SSH_DEFAULT_PORT;
  2677.     }
  2678.  
  2679.     memset(&hints, 0, sizeof(hints));
  2680.     hints.ai_family = family;
  2681.     hints.ai_socktype = SOCK_STREAM;
  2682.     snprintf(strport, sizeof strport, "%d", port);
  2683.     if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
  2684.         fatal("ssh: %.100s: %s", host, gai_strerror(gaierr));
  2685.         return -1;
  2686.     }
  2687.  
  2688.     /*
  2689.      * Try to connect several times.  On some machines, the first time
  2690.      * will sometimes fail.  In general socket code appears to behave
  2691.      * quite magically on many machines.
  2692.      */
  2693.     for (attempt = 0;;) {
  2694.         if (attempt > 0 && !quiet)
  2695.             printf("Trying again...");
  2696.  
  2697.         /* Loop through addresses for this host, and try each one in
  2698.            sequence until the connection succeeds. */
  2699.         for (ai = aitop; ai; ai = ai->ai_next) {
  2700.             if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
  2701.                 continue;
  2702.             if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
  2703.                              ntop, sizeof(ntop), strport, sizeof(strport),
  2704.                              NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
  2705.                 error("ssh_connect: getnameinfo failed");
  2706.                 continue;
  2707.             }
  2708.             debug1("Connecting to %s:%s %s",host,strport,ntop);
  2709.  
  2710. #ifndef NOHTTP
  2711.             if (tcp_http_proxy) {
  2712.                 struct   sockaddr_in sa_proxy;
  2713. #ifdef OS2
  2714.                 char * agent = "Kermit 95"; /* Default user agent */
  2715. #else
  2716.                 char * agent = "C-Kermit";
  2717. #endif /* OS2 */
  2718.                 register struct hostent *hp = 0;
  2719.                 struct servent *destsp;
  2720.                 char proxyhost[128], *p, *q;
  2721.                 char proxyto[128];
  2722. #ifdef IP_TOS
  2723. #ifdef IPTOS_THROUGHPUT
  2724.                 int tos;
  2725. #endif /* IPTOS_THROUGHPUT */
  2726. #endif /* IP_TOS */
  2727.                 int s;
  2728. #ifdef DEBUG
  2729.                 extern int debtim;
  2730.                 int xdebtim;
  2731.                 xdebtim = debtim;
  2732.                 debtim = 1;
  2733. #endif /* DEBUG */
  2734.  
  2735.                 ckmakmsg(proxyto,512,(char*)host,":",strport,NULL);
  2736.  
  2737.                 memset((char *)&sa_proxy, 0, sizeof (sa_proxy));
  2738.                 for (p = tcp_http_proxy, q=proxyhost; *p != '\0' && *p != ':'; p++, q++)
  2739.                     *q = *p;
  2740.                 *q = '\0';
  2741.  
  2742.                 sa_proxy.sin_addr.s_addr = inet_addr(proxyhost);
  2743.                 if (sa_proxy.sin_addr.s_addr != -1) {
  2744.                     debug(F110,"ssh_connect A",proxyhost,0);
  2745.                     sa_proxy.sin_family = AF_INET;
  2746.                 } else {
  2747.                     debug(F110,"ssh_connect B",proxyhost,0);
  2748.                     hp = gethostbyname(proxyhost);
  2749. #ifdef HADDRLIST
  2750.                     hp = ck_copyhostent(hp); /* make safe copy that won't change */
  2751. #endif /* HADDRLIST */
  2752.                     if (hp == NULL) {
  2753.                         fprintf(stderr, "ssh: %s: Unknown host", proxyhost);
  2754. #ifdef DEBUG
  2755.                         debtim = xdebtim;
  2756. #endif /* DEBUG */
  2757.                         goto next_ai;
  2758.                     }
  2759.                     sa_proxy.sin_family = hp->h_addrtype;
  2760. #ifdef HADDRLIST
  2761.                     memcpy((char *)&sa_proxy.sin_addr, hp->h_addr_list[0],
  2762.                             sizeof(sa_proxy.sin_addr));
  2763. #else /* HADDRLIST */
  2764.                     memcpy((char *)&sa_proxy.sin_addr, hp->h_addr,
  2765.                             sizeof(sa_proxy.sin_addr));
  2766. #endif /* HADDRLIST */
  2767.                 }
  2768.  
  2769.               http_restart:
  2770.                 ssh_sock = ssh_create_socket(needpriv, ai->ai_family);
  2771.                 debug(F101,"ssh_connect socket","",ssh_sock);
  2772.                 if (ssh_sock < 0) {
  2773.                     perror("ssh: socket");
  2774. #ifdef DEBUG
  2775.                     debtim = xdebtim;
  2776. #endif /* DEBUG */
  2777.                     goto next_ai;
  2778.                 }
  2779.                 if (*p == ':')
  2780.                     p++;
  2781.                 else
  2782.                     p = "http";
  2783.  
  2784.                 destsp = getservbyname(p,"tcp");
  2785.                 if (destsp)
  2786.                     sa_proxy.sin_port = destsp->s_port;
  2787.                 else if (p)
  2788.                     sa_proxy.sin_port = htons(atoi(p));
  2789.                 else
  2790.                     sa_proxy.sin_port = htons(80);
  2791.                 errno = 0;
  2792. #ifdef HADDRLIST
  2793.                 debug(F100,"ssh_connect HADDRLIST","",0);
  2794.                 while
  2795. #else
  2796.                 debug(F100,"ssh_connect no HADDRLIST","",0);
  2797.                 if
  2798. #endif /* HADDRLIST */
  2799.                     (connect(ssh_sock, (struct sockaddr *)&sa_proxy,
  2800.                               sizeof (sa_proxy)) < 0) 
  2801.                 {
  2802.                     debug(F101,"ssh_connect connect failed","",errno);
  2803. #ifdef HADDRLIST
  2804.                     if (hp && hp->h_addr_list[1]) 
  2805.                     {
  2806.                         int oerrno = errno;
  2807.  
  2808.                         fprintf(stderr,
  2809.                                  "ssh: connect to address %s: ",
  2810.                                  inet_ntoa(sa_proxy.sin_addr)
  2811.                                  );
  2812.                         errno = oerrno;
  2813.                         perror((char *)0);
  2814.                         hp->h_addr_list++;
  2815.                         memcpy((char *)&sa_proxy.sin_addr,
  2816.                                 hp->h_addr_list[0],
  2817.                                 sizeof(sa_proxy.sin_addr));
  2818.                         if ( !quiet )
  2819.                             fprintf(stdout, "Trying %s...\n",
  2820.                                  inet_ntoa(sa_proxy.sin_addr));
  2821.                         shutdown(ssh_sock, SHUT_RDWR);
  2822. #ifdef TCPIPLIB
  2823.                         socket_close(ssh_sock);
  2824. #else /* TCPIPLIB */
  2825.                         close(ssh_sock);
  2826. #endif /* TCPIPLIB */
  2827.                         ssh_sock = ssh_create_socket(needpriv, ai->ai_family);
  2828.                         if (ssh_sock < 0) {
  2829.                             perror("ssh: socket");
  2830. #ifdef DEBUG
  2831.                             debtim = xdebtim;
  2832. #endif /* DEBUG */
  2833.                             goto next_ai;
  2834.                         }
  2835.                         continue;
  2836.                     }
  2837. #endif /* HADDRLIST */
  2838.                     perror("ssh: connect");
  2839.                     goto next_attempt;
  2840.                 }
  2841.                 if (http_connect(ssh_sock,
  2842.                                  tcp_http_proxy_agent ? tcp_http_proxy_agent : agent,
  2843.                                  NULL,
  2844.                                  tcp_http_proxy_user,
  2845.                                  tcp_http_proxy_pwd,
  2846.                                  0,
  2847.                                  proxyto
  2848.                                  ) < 0) 
  2849.                 {
  2850.  
  2851.                     shutdown(ssh_sock, SHUT_RDWR);
  2852. #ifdef TCPIPLIB
  2853.                     socket_close(ssh_sock);
  2854. #else /* TCPIPLIB */
  2855.                     close(ssh_sock);
  2856. #endif /* TCPIPLIB */
  2857.                     
  2858.                     if (tcp_http_proxy_errno == 401 ||
  2859.                          tcp_http_proxy_errno == 407 ) 
  2860.                     {
  2861.                         struct txtbox tb[2];
  2862.                         int ok;
  2863.  
  2864.                         tb[0].t_buf = uid;
  2865.                         tb[0].t_len = UIDBUFLEN;
  2866.                         tb[0].t_lbl = "Proxy Userid: ";
  2867.                         tb[0].t_dflt = NULL;
  2868.                         tb[0].t_echo = 1;
  2869.                         tb[1].t_buf = pwd;
  2870.                         tb[1].t_len = 256;
  2871.                         tb[1].t_lbl = "Proxy Passphrase: ";
  2872.                         tb[1].t_dflt = NULL;
  2873.                         tb[1].t_echo = 2;
  2874.  
  2875.                         ok = uq_mtxt("Proxy Server Authentication Required\n",
  2876.                                       NULL, 2, tb);
  2877.  
  2878.                         if (ok && uid[0]) {
  2879.                             if ( !proxy_user ) {
  2880.                                 proxy_user = tcp_http_proxy_user;
  2881.                                 tcp_http_proxy_user = uid;
  2882.                             }
  2883.                             if ( !proxy_user ) {
  2884.                                 proxy_pwd  = tcp_http_proxy_pwd;
  2885.                                 tcp_http_proxy_pwd = pwd;
  2886.                             }
  2887.                             goto http_restart;
  2888.                         }
  2889.                     }
  2890.                     perror("ssh: connect");
  2891.                     goto next_attempt;
  2892.                 } else {
  2893.                     /* Successful connection. */
  2894.                     memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
  2895.                     break;
  2896.                 }
  2897.             } else
  2898. #endif /* NOHTTP */
  2899.             {
  2900.                 /* Create a socket for connecting. */
  2901.                 ssh_sock = ssh_create_socket(needpriv, ai->ai_family);
  2902.                 if (ssh_sock < 0)
  2903.                     continue;
  2904.  
  2905.                 if (connect(ssh_sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
  2906.                     /* Successful connection. */
  2907.                     memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
  2908.                     break;
  2909.                 } else {
  2910.                     if (sock_lasterror() == WSAECONNREFUSED)
  2911.                         full_failure = 0;
  2912.                     log("ssh: connect to address %s port %s: %s",
  2913.                          sockaddr_ntop(ai->ai_addr), strport,
  2914. #ifdef OS2
  2915.                          sock_strerror(sock_lasterror())
  2916. #else
  2917.                          strerror(errno)
  2918. #endif /* OS2 */
  2919.                          );
  2920.                     /*
  2921.                     * Close the failed socket; there appear to
  2922.                     * be some problems when reusing a socket for
  2923.                     * which connect() has already returned an
  2924.                     * error.
  2925.                     */
  2926.                     shutdown(ssh_sock, SHUT_RDWR);
  2927. #ifdef OS2
  2928.                     closesocket(ssh_sock);
  2929. #else
  2930.                     close(ssh_sock);
  2931. #endif /* OS2 */
  2932.                 }
  2933.             }
  2934.           next_ai:
  2935.             ;
  2936.         }
  2937.         if (ai)
  2938.             break;      /* Successful connection. */
  2939.  
  2940.       next_attempt:
  2941.         if ( ++attempt >= connection_attempts )
  2942.             break;
  2943.  
  2944.         /* Sleep a moment before retrying. */
  2945.         sleep(1);
  2946.     }
  2947.  
  2948. #ifndef NOHTTP
  2949.     if ( proxy_user )
  2950.         tcp_http_proxy_user = proxy_user;
  2951.     if ( proxy_pwd ) {
  2952.         memset(pwd,0,sizeof(pwd));
  2953.         tcp_http_proxy_pwd = proxy_pwd;
  2954.     }
  2955. #endif /* NOHTTP */
  2956.  
  2957.     freeaddrinfo(aitop);
  2958.  
  2959.     /* Return failure if we didn't get a successful connection. */
  2960.     if (attempt >= connection_attempts) {
  2961.         log("ssh: connect to host %s port %s: %s",
  2962.              host, strport, sock_strerror(sock_lasterror()));
  2963.         return full_failure ? WSAECONNABORTED : WSAECONNREFUSED;
  2964.     }
  2965.     debug1("Connection established.");
  2966.  
  2967. #ifndef NOTCPOPTS
  2968. #ifndef datageneral
  2969. #ifdef SOL_SOCKET
  2970. #ifdef TCP_NODELAY
  2971.     no_delay(ssh_sock,tcp_nodelay);
  2972. #endif /* TCP_NODELAY */
  2973. #ifdef SO_KEEPALIVE
  2974.     keepalive(ssh_sock,tcp_keepalive);
  2975. #endif /* SO_KEEPALIVE */
  2976. #ifdef SO_LINGER
  2977.     ck_linger(ssh_sock,tcp_linger, tcp_linger_tmo);
  2978. #endif /* SO_LINGER */
  2979. #ifdef SO_SNDBUF
  2980.     sendbuf(ssh_sock,tcp_sendbuf);
  2981. #endif /* SO_SNDBUF */
  2982. #ifdef SO_RCVBUF
  2983.     recvbuf(ssh_sock,tcp_recvbuf);
  2984. #endif /* SO_RCVBUF */
  2985. #endif /* SOL_SOCKET */
  2986. #endif /* datageneral */
  2987. #endif /* NOTCPOPTS */
  2988.  
  2989.     /* Set the connection. */
  2990.     packet_set_connection(ssh_sock, ssh_sock);
  2991.     return 0;
  2992. }
  2993.  
  2994. static int minor1 = PROTOCOL_MINOR_1;
  2995. char *
  2996. ssh_proto_ver(void)
  2997. {
  2998.     static char buf[16];
  2999.     snprintf(buf, sizeof buf, "SSH-%d.%d",
  3000.               compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
  3001.               compat20 ? PROTOCOL_MINOR_2 : minor1);
  3002.     return buf;
  3003. }
  3004.  
  3005. /*
  3006.  * Waits for the server identification string, and sends our own
  3007.  * identification string.
  3008.  */
  3009. static int
  3010. ssh_exchange_identification(void)
  3011. {
  3012.     char buf[256], remote_version[256]; /* must be same size! */
  3013.     int remote_major, remote_minor, i, mismatch;
  3014.     int connection_in = packet_get_connection_in();
  3015.     int connection_out = packet_get_connection_out();
  3016.  
  3017.     minor1 = PROTOCOL_MINOR_1;
  3018.  
  3019.     /* Read other side\'s version identification. */
  3020.     for (;;) {
  3021.         for (i = 0; i < sizeof(buf) - 1; i++) {
  3022. #ifdef OS2
  3023.             int len;
  3024. #ifdef BSDSELECT
  3025.             fd_set rfds;
  3026.             struct timeval tv;
  3027.             int ready;
  3028.  
  3029.             FD_ZERO(&rfds);
  3030.             FD_SET(connection_in, &rfds);
  3031.             tv.tv_sec = 30;
  3032.             tv.tv_usec = 0L;
  3033.  
  3034.             ready = ((select(FD_SETSIZE, &rfds, NULL, NULL, &tv) > 0) &&
  3035.                FD_ISSET(connection_in, &rfds));
  3036.             if ( !ready ) {
  3037.                 fatal("ssh_exchange_identification: select: 30 second timeout");
  3038.                 return -1;
  3039.             }
  3040. #endif /* BSDSELECT */
  3041.  
  3042.             len = recv(connection_in, &buf[i], 1, 0);
  3043.             if (len < 0) {
  3044.                 fatal("ssh_exchange_identification: read: %.100s",
  3045.                        sock_strerror(sock_lasterror()));
  3046.                 return -1;
  3047.             }
  3048. #else
  3049.             int len = atomicio(read, connection_in, &buf[i], 1);
  3050.             if (len < 0) {
  3051.                 fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
  3052.                 return -1;
  3053.             }
  3054. #endif /* OS2 */
  3055.             if (len != 1) {
  3056.                 fatal("ssh_exchange_identification: Connection closed by remote host");
  3057.                 return -1;
  3058.             }
  3059.             if (buf[i] == '\r') {
  3060.                 buf[i] = '\n';
  3061.                 buf[i + 1] = 0;
  3062.                 continue;               /**XXX wait for \n */
  3063.             }
  3064.             if (buf[i] == '\n') {
  3065.                 buf[i + 1] = 0;
  3066.                 break;
  3067.             }
  3068.         }
  3069.         buf[sizeof(buf) - 1] = 0;
  3070.         if (strncmp(buf, "SSH-", 4) == 0)
  3071.             break;
  3072.         debug1("ssh_exchange_identification: %s", buf);
  3073.     }
  3074.     server_version_string = strdup(buf);
  3075.  
  3076.     /*
  3077.      * Check that the versions match.  In future this might accept
  3078.      * several versions and set appropriate flags to handle them.
  3079.      */
  3080.     if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n",
  3081.                 &remote_major, &remote_minor, remote_version) != 3) {
  3082.         fatal("Bad remote protocol version identification: '%.100s'", buf);
  3083.         return -1;
  3084.     }
  3085.     debug1("Remote protocol version (major) %d (minor) %d",
  3086.             remote_major, remote_minor);
  3087.     debug1("Remote software version: %s",remote_version);
  3088.  
  3089.     compat_datafellows(remote_version);
  3090.     mismatch = 0;
  3091.  
  3092.     switch(remote_major) {
  3093.     case 1:
  3094.         if (remote_minor == 99 &&
  3095.              (options.protocol & SSH_PROTO_2) &&
  3096.              !(options.protocol & SSH_PROTO_1_PREFERRED)) {
  3097.             enable_compat20();
  3098.             break;
  3099.         }
  3100.         if (!(options.protocol & SSH_PROTO_1)) {
  3101.             mismatch = 1;
  3102.             break;
  3103.         }
  3104.         if (remote_minor < 3) {
  3105.             fatal("Remote machine has too old SSH software version.");
  3106.             return -1;
  3107.         } else if (remote_minor == 3 || remote_minor == 4) {
  3108.             /* We speak 1.3, too. */
  3109.             enable_compat13();
  3110.             minor1 = 3;
  3111.             if (options.forward_agent) {
  3112.                 log("Agent forwarding disabled for protocol 1.3");
  3113.                 options.forward_agent = 0;
  3114.             }
  3115.         }
  3116.         break;
  3117.     case 2:
  3118.         if (options.protocol & SSH_PROTO_2) {
  3119.             enable_compat20();
  3120.             break;
  3121.         }
  3122.         /* FALLTHROUGH */
  3123.     default:
  3124.         mismatch = 1;
  3125.         break;
  3126.     }
  3127.     if (mismatch)
  3128.         fatal("Protocol major versions differ: %d vs. %d",
  3129.                (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
  3130.                remote_major);
  3131.     /* Send our own protocol version identification. */
  3132.     snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
  3133.               compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
  3134.               compat20 ? PROTOCOL_MINOR_2 : minor1,
  3135.               SSH_VERSION);
  3136. #ifdef OS2
  3137.     if (send(connection_out, buf, strlen(buf), 0) != strlen(buf)) {
  3138.         fatal("write: %.100s", sock_strerror(sock_lasterror()));
  3139.         return -1;
  3140.     }
  3141. #else
  3142.     if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) {
  3143.         fatal("write: %.100s", strerror(errno));
  3144.         return -1;
  3145.     }
  3146. #endif /* OS2 */
  3147.     client_version_string = strdup(buf);
  3148.     chop(client_version_string);
  3149.     chop(server_version_string);
  3150.     debug1("Local version string: %s", client_version_string);
  3151.     return 0;
  3152. }
  3153.  
  3154. /* defaults to 'no' */
  3155. static int
  3156. confirm(const char *preface, const char *prompt, int defval)
  3157. {
  3158.     char buf[1024];
  3159.     FILE *f;
  3160.     int retval = -1;
  3161.  
  3162.     if (options.batch_mode)
  3163.         return 0;
  3164.     retval = uq_ok((char *)preface, (char *)prompt, 3, NULL, defval);
  3165.     if ( retval < 0 )
  3166.         retval = defval;
  3167.     return(retval);
  3168. }
  3169.  
  3170. /*
  3171.  * check whether the supplied host key is valid, return -1 if the key
  3172.  * is not valid. the user_hostfile will not be updated if 'readonly' is true.
  3173.  */
  3174.  
  3175. int
  3176. check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
  3177.         int readonly, const char *user_hostfile, const char *system_hostfile)
  3178. {
  3179.     Key *file_key;
  3180.     char *type = key_type(host_key);
  3181.     char *ip = NULL;
  3182.     char hostline[1000], *hostp, *fp;
  3183.     HostStatus host_status;
  3184.     HostStatus ip_status;
  3185.     int local = 0, host_ip_differ = 0;
  3186.     int salen;
  3187.     char ntop[NI_MAXHOST];
  3188.     char msg[1024];
  3189.     int len, host_line, ip_line, has_keys;
  3190.     const char *host_file = NULL, *ip_file = NULL;
  3191.  
  3192.     /*
  3193.      * Force accepting of the host key for loopback/localhost. The
  3194.      * problem is that if the home directory is NFS-mounted to multiple
  3195.      * machines, localhost will refer to a different machine in each of
  3196.      * them, and the user will get bogus HOST_CHANGED warnings.  This
  3197.      * essentially disables host authentication for localhost; however,
  3198.      * this is probably not a real problem.
  3199.      */
  3200.     /**  hostaddr == 0! */
  3201.     switch (hostaddr->sa_family) {
  3202.     case AF_INET:
  3203.         local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
  3204.         salen = sizeof(struct sockaddr_in);
  3205.         break;
  3206.     case AF_INET6:
  3207.         local = IN6_IS_ADDR_LOOPBACK(&(((struct sockaddr_in6 *)hostaddr)->sin6_addr));
  3208.         salen = sizeof(struct sockaddr_in6);
  3209.         break;
  3210.     default:
  3211.         local = 0;
  3212.         salen = sizeof(struct sockaddr_storage);
  3213.         break;
  3214.     }
  3215.     if (options.no_host_authentication_for_localhost == 1 &&
  3216.         local && options.host_key_alias == NULL) {
  3217.         debug1("Forcing accepting of host key for "
  3218.                "loopback/localhost.");
  3219.         return 0;
  3220.     }
  3221.  
  3222.     /*
  3223.      * We don't have the remote ip-address for connections
  3224.      * using a proxy command
  3225.      */
  3226.     if (!tcp_http_proxy) {
  3227.         if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
  3228.                          NULL, 0, NI_NUMERICHOST) != 0) {
  3229.             fatal("check_host_key: getnameinfo failed");
  3230.             return -1;
  3231.         }
  3232.         ip = strdup(ntop);
  3233.     } else {
  3234.         ip = strdup("<no hostip for proxy command>");
  3235.     }
  3236.     /*
  3237.      * Turn off check_host_ip if the connection is to localhost, via proxy
  3238.      * command or if we don't have a hostname to compare with
  3239.      */
  3240.     if (options.check_host_ip &&
  3241.          (local || strcmp(host, ip) == 0 || tcp_http_proxy))
  3242.         options.check_host_ip = 0;
  3243.  
  3244.     /*
  3245.      * Allow the user to record the key under a different name. This is
  3246.      * useful for ssh tunneling over forwarded connections or if you run
  3247.      * multiple sshd's on different ports on the same machine.
  3248.      */
  3249.     if (options.host_key_alias != NULL) {
  3250.         host = options.host_key_alias;
  3251.         debug1("using hostkeyalias: %s", host);
  3252.     }
  3253.  
  3254.     /*
  3255.      * Store the host key from the known host file in here so that we can
  3256.      * compare it with the key for the IP address.
  3257.      */
  3258.     file_key = key_new(host_key->type);
  3259.  
  3260.     /*
  3261.      * Check if the host key is present in the user\'s list of known
  3262.      * hosts or in the systemwide list.
  3263.      */
  3264.     host_file = user_hostfile;
  3265.     host_status = check_host_in_hostfile(host_file, host, host_key, file_key, &host_line);
  3266.     if (host_status == HOST_NEW) {
  3267.         host_file = system_hostfile;
  3268.         host_status = check_host_in_hostfile(host_file, host, host_key, file_key, &host_line);
  3269.     }
  3270.     /*
  3271.      * Also perform check for the ip address, skip the check if we are
  3272.      * localhost or the hostname was an ip address to begin with
  3273.      */
  3274.     if (options.check_host_ip) {
  3275.         Key *ip_key = key_new(host_key->type);
  3276.  
  3277.         ip_file = user_hostfile;
  3278.         ip_status = check_host_in_hostfile(ip_file, ip, host_key, ip_key, &ip_line);
  3279.         if (ip_status == HOST_NEW) {
  3280.             ip_file = system_hostfile;
  3281.             ip_status = check_host_in_hostfile(ip_file, ip, host_key, ip_key, &ip_line);
  3282.         }
  3283.         if (host_status == HOST_CHANGED &&
  3284.              (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
  3285.             host_ip_differ = 1;
  3286.  
  3287.         key_free(ip_key);
  3288.     } else
  3289.         ip_status = host_status;
  3290.  
  3291.     key_free(file_key);
  3292.  
  3293.     switch (host_status) {
  3294.     case HOST_OK:
  3295.         /* The host is known and the key matches. */
  3296.         debug1("Host is known: %s and matches the host key: %s found in %s (%d)",
  3297.                 host,type,host_file,host_line);
  3298.         if (options.check_host_ip && ip_status == HOST_NEW) {
  3299.             if (readonly)
  3300.                 log("%s host key for IP address "
  3301.                      "'%.128s' not in list of known hosts.",
  3302.                      type, ip);
  3303.             else if (!add_host_to_hostfile(user_hostfile, ip, host_key))
  3304.                 log("Failed to add the %s host key for IP address '%.128s' to the list of known hosts (%.30s).",
  3305.                      type, ip, user_hostfile);
  3306.             else
  3307.                 log("Warning: Permanently added the %s host key for IP address '%.128s' to the list of known hosts.",
  3308.                      type, ip);
  3309.         }
  3310.         break;
  3311.     case HOST_NEW:
  3312.         /* The host is new. */
  3313.         if ( readonly )
  3314.             goto fail;
  3315.         if (options.strict_host_key_checking == 1) {
  3316.             /* User has requested strict host key checking.  We will not add the host key
  3317.             automatically.  The only alternative left is to abort. */
  3318.             ckmakxmsg(errbuf,ERRBUFSZ,
  3319.                        "No ",type," host key is known for ",host,
  3320.                        " and\n"
  3321.                        "you have requested strict host checking.\n"
  3322.                        "If you wish to make an untrusted connection,\n"
  3323.                        "SET SSH STRICT-HOST-KEY-CHECK OFF and try again.",
  3324.                        NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  3325.             error(errbuf);
  3326. #ifdef KUI
  3327.             uq_ok(NULL, errbuf, 1, NULL, 0);
  3328. #endif /* KUI */
  3329.             goto fail;
  3330.         } else if (options.strict_host_key_checking == 2) {
  3331.             has_keys = show_other_keys(host, host_key);
  3332.             /* The default */
  3333.             fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
  3334.             snprintf(msg, sizeof(msg),
  3335.                       "The authenticity of host '%.200s (%s)' can't be established%s\n"
  3336.                       "%s key fingerprint is %s.\n",
  3337.                       host, ip, 
  3338.                       has_keys ? ",\nbut keys of different type are already known for this host." : ".",
  3339.                       type, fp);
  3340.             free(fp);
  3341.             if (!confirm(msg, 
  3342.                          "Are you sure you want to continue connecting (yes/no)? ",
  3343.                          -1)) {
  3344.                 error("Aborted by user!");
  3345.                 goto fail;
  3346.             }
  3347.         } else if (options.strict_host_key_checking != 0) {
  3348.             error("Invalid Strict Host Key Check value!");
  3349.             goto fail;
  3350.         }
  3351.         if (options.check_host_ip && ip_status == HOST_NEW) {
  3352.             snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
  3353.             hostp = hostline;
  3354.         } else
  3355.             hostp = host;
  3356.  
  3357.         /* If not in strict mode, add the key automatically to the local known_hosts file. */
  3358.         if (!add_host_to_hostfile(user_hostfile, hostp, host_key))
  3359.             log("Failed to add the host to the list of known hosts (%.500s).",
  3360.                  user_hostfile);
  3361.         else
  3362.             log("Warning: Permanently added '%.200s' (%s) to the list of known hosts.",
  3363.                  hostp, type);
  3364.         break;
  3365.     case HOST_CHANGED:
  3366.         if (options.check_host_ip && host_ip_differ) {
  3367.             char *msg;
  3368.             if (ip_status == HOST_NEW)
  3369.                 msg = "is unknown";
  3370.             else if (ip_status == HOST_OK)
  3371.                 msg = "is unchanged";
  3372.             else
  3373.                 msg = "has a different value";
  3374.             ckmakxmsg(errbuf,ERRBUFSZ,
  3375.                        "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  3376.                        "@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @\n"
  3377.                        "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  3378.                        "The ", type, " host key for ", host, " has changed,\n"
  3379.                        "and the key for the according IP address ", ip, "\n",
  3380.                        msg, ". This could either mean that\n",
  3381.                        "DNS SPOOFING is happening or the IP address for the host\n"
  3382.                        "and its host key have changed at the same time.\n",
  3383.                        NULL, NULL);
  3384.             if ( ip_status != HOST_NEW ) {
  3385.                 ckstrncat(errbuf, "Offending key for IP in ", ERRBUFSZ);
  3386.                 ckstrncat(errbuf, ip_file, ERRBUFSZ);
  3387.                 ckstrncat(errbuf, ":", ERRBUFSZ);
  3388.                 ckstrncat(errbuf, ckitoa(ip_line), ERRBUFSZ);
  3389.             }
  3390.             error(errbuf);
  3391. #ifdef KUI
  3392.             uq_ok(NULL, errbuf, 1, NULL, 0);
  3393. #endif /* KUI */
  3394.  
  3395.         }
  3396.         /* The host key has changed. */
  3397.         fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
  3398.         ckmakxmsg(errbuf,ERRBUFSZ,
  3399.         "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  3400.         "@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @\n"
  3401.         "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  3402.         "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"
  3403.         "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"
  3404.         "It is also possible that the ", type, " host key has just been changed.\n"
  3405.         "The fingerprint for the ", type, " key sent by the remote host is\n",
  3406.         fp, "\nPlease contact your system administrator.\n"
  3407.         "Add correct host key in ", (char*)user_hostfile, " to get rid of this message.\n"
  3408.         "Offending key in ", (char *)host_file, ":", ckitoa(host_line));
  3409.         free(fp);
  3410.         error(errbuf);
  3411. #ifdef KUI
  3412.         uq_ok(NULL, errbuf, 1, NULL, 0);
  3413. #endif /* KUI */
  3414.  
  3415.         /*
  3416.          * If strict host key checking is in use, the user will have
  3417.          * to edit the key manually and we can only abort.
  3418.          */
  3419.         if (options.strict_host_key_checking == 1) {
  3420.             ckmakmsg(errbuf,ERRBUFSZ, type, " host key for ", host,
  3421.                       "has changed and you have requested strict checking.");
  3422.             error(errbuf);
  3423. #ifdef KUI
  3424.             uq_ok(NULL, errbuf, 1, NULL, 0);
  3425. #endif /* KUI */
  3426.             goto fail;
  3427.         } else if (options.strict_host_key_checking == 2) {
  3428.             /* The default */
  3429.             char prompt[1024];
  3430.             fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
  3431.             snprintf(prompt, sizeof(prompt),
  3432.                       "The authenticity of host '%.200s (%s)' can't be established.\n"
  3433.                       "%s key fingerprint is %s.\n",
  3434.                       host, ip, type, fp);
  3435.             free(fp);
  3436.             if (!confirm(prompt, 
  3437.                          "Are you sure you want to continue connecting (yes/no)? ",
  3438.                          -1)) {
  3439.                 error("Aborted by user!");
  3440.                 goto fail;
  3441.             }
  3442.         } else if (options.strict_host_key_checking != 0) {
  3443.             error("Invalid Strict Host Key Check value!");
  3444.             goto fail;
  3445.         }
  3446.  
  3447.         /*
  3448.          * If strict host key checking has not been requested, allow
  3449.          * the connection but without password authentication or
  3450.          * agent forwarding.
  3451.          */
  3452.         if (options.password_authentication) {
  3453.             error("Password authentication is disabled to avoid trojan horses.");
  3454.             options.password_authentication = 0;
  3455.         }
  3456.         if (options.forward_agent) {
  3457.             error("Agent forwarding is disabled to avoid trojan horses.");
  3458.             options.forward_agent = 0;
  3459.         }
  3460.         if (options.forward_x11) {
  3461.             error("X11 forwarding is disabled to avoid trojan horses.");
  3462.             options.forward_x11 = 0;
  3463.         }
  3464.         if (options.num_local_forwards > 0 || options.num_remote_forwards > 0) {
  3465.             error("Port forwarding is disabled to avoid trojan horses.");
  3466.             options.num_local_forwards = options.num_remote_forwards = 0;
  3467.         }
  3468.         /*
  3469.          * XXX Should permit the user to change to use the new id.
  3470.          * This could be done by converting the host key to an
  3471.          * identifying sentence, tell that the host identifies itself
  3472.          * by that sentence, and ask the user if he/she whishes to
  3473.          * accept the authentication.
  3474.          */
  3475.         break;
  3476.     case HOST_FOUND:
  3477.         error("Internal Error!");
  3478.         goto fail;
  3479.     }
  3480.  
  3481.     if (options.check_host_ip && host_status != HOST_CHANGED &&
  3482.          ip_status == HOST_CHANGED) {
  3483.         ckmakxmsg(errbuf,ERRBUFSZ,"Warning: the ",
  3484.                   type, " host key for '", host, "' differs from the key for the IP address '",
  3485.                   ip, "'\nOffending key for IP in ", (char *)ip_file, ":", ckitoa(ip_line), NULL, NULL);
  3486.         if (host_status == HOST_OK) {
  3487.             ckstrncat(errbuf, "\nMatching host key in ", ERRBUFSZ);
  3488.             ckstrncat(errbuf, host_file, ERRBUFSZ);
  3489.             ckstrncat(errbuf, ":", ERRBUFSZ);
  3490.             ckstrncat(errbuf, ckitoa(host_line), ERRBUFSZ);
  3491.         }
  3492.  
  3493.         if (options.strict_host_key_checking == 1) {
  3494.             log(errbuf);
  3495.             ckstrncat(errbuf, "\nConnection Failure: Strict Host Key Checking enabled.", ERRBUFSZ);
  3496.             error(errbuf);
  3497. #ifdef KUI
  3498.             uq_ok(NULL, errbuf, 1, NULL, 0);
  3499. #endif /* KUI */
  3500.             goto fail;
  3501.         } else if (options.strict_host_key_checking == 2) {
  3502.             ckstrncat(errbuf,"\n",
  3503.                       ERRBUFSZ);
  3504.             if (!confirm(errbuf, 
  3505.                           "Are you sure you want to continue connecting (yes/no)? ",
  3506.                           -1)) {
  3507.                 error("Aborted by user!");
  3508.                 goto fail;
  3509.             }
  3510.         } else if (options.strict_host_key_checking != 0) {
  3511.             log(errbuf);
  3512.             error("Invalid Strict Host Key Check value!");
  3513.             goto fail;
  3514.         } else {
  3515.             log(errbuf);
  3516.         }
  3517.     }
  3518.  
  3519.     free(ip);
  3520.     return(0);
  3521.  
  3522.   fail:
  3523.     free(ip);
  3524.     return(-1);
  3525. }
  3526.  
  3527. int
  3528. verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
  3529. {
  3530.         struct _stat st;
  3531.  
  3532.         /* return ok if the key can be found in an old keyfile */
  3533.         if (stat(options.system_hostfile2, &st) == 0 ||
  3534.             stat(options.user_hostfile2, &st) == 0) {
  3535.                 if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1,
  3536.                     options.user_hostfile2, options.system_hostfile2) == 0)
  3537.                         return 0;
  3538.         }
  3539.         return check_host_key(host, hostaddr, host_key, /*readonly*/ 0,
  3540.             options.user_hostfile, options.system_hostfile);
  3541. }
  3542.  
  3543. /*
  3544.  * Starts a dialog with the server, and authenticates the current user on the
  3545.  * server.  This does not need any extra privileges.  The basic connection
  3546.  * to the server must already have been established before this is called.
  3547.  * If login fails, this function prints an error and never returns.
  3548.  * This function does not require super-user privileges.
  3549.  */
  3550. int
  3551. ssh_login(Sensitive *sensitive, const char *orighost,
  3552.     struct sockaddr *hostaddr, struct passwd *pw)
  3553. {
  3554.     char *host, *cp;
  3555.     char *server_user, *local_user;
  3556.  
  3557.     local_user = strdup(pw->pw_name);
  3558.     server_user = options.user ? options.user : local_user;
  3559.  
  3560.     /* Convert the user-supplied hostname into all lowercase. */
  3561.     host = strdup(orighost);
  3562.     for (cp = host; *cp; cp++)
  3563.         if (isupper(*cp))
  3564.             *cp = tolower(*cp);
  3565.  
  3566.     /* Exchange protocol version identification strings with the server. */
  3567.     if (ssh_exchange_identification() < 0)
  3568.         return(-1);
  3569.  
  3570.     /* Put the connection into non-blocking mode. */
  3571.     packet_set_nonblocking();
  3572.  
  3573.     /* key exchange */
  3574.     /* authenticate user */
  3575.     if (compat20) {
  3576.         if (ssh_kex2(host, hostaddr) < 0)
  3577.             return -1;
  3578.         if (ssh_userauth2(local_user, server_user, host, sensitive) < 0)
  3579.             return -1;
  3580.     } else {
  3581.         if (ssh_kex(host, hostaddr) < 0)
  3582.             return -1;
  3583.         if (ssh_userauth1(local_user, server_user, host, sensitive) < 0)
  3584.             return -1;
  3585.     }
  3586.     return(0);
  3587. }
  3588.  
  3589. static int
  3590. show_key_from_file(const char *file, const char *host, int keytype)
  3591. {
  3592.     Key *found;
  3593.     char *fp;
  3594.     int line, ret;
  3595.  
  3596.     found = key_new(keytype);
  3597.     if ((ret = lookup_key_in_hostfile_by_type(file, host,
  3598.                                                keytype, found, &line))) {
  3599.         fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
  3600.         log("WARNING: %s key found for host %s\n"
  3601.              "in %s:%d\n"
  3602.              "%s key fingerprint %s.",
  3603.              key_type(found), host, file, line,
  3604.              key_type(found), fp);
  3605.         free(fp);
  3606.     }
  3607.     key_free(found);
  3608.     return (ret);
  3609. }
  3610.  
  3611. /* print all known host keys for a given host, but skip keys of given type */
  3612. static int
  3613. show_other_keys(const char *host, Key *key)
  3614. {
  3615.     int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, -1};
  3616.     int i, found = 0;
  3617.  
  3618.     for (i = 0; type[i] != -1; i++) {
  3619.         if (type[i] == key->type)
  3620.             continue;
  3621.         if (type[i] != KEY_RSA1 &&
  3622.              show_key_from_file(options.user_hostfile2, host, type[i])) {
  3623.             found = 1;
  3624.             continue;
  3625.         }
  3626.         if (type[i] != KEY_RSA1 &&
  3627.              show_key_from_file(options.system_hostfile2, host, type[i])) {
  3628.             found = 1;
  3629.             continue;
  3630.         }
  3631.         if (show_key_from_file(options.user_hostfile, host, type[i])) {
  3632.             found = 1;
  3633.             continue;
  3634.         }
  3635.         if (show_key_from_file(options.system_hostfile, host, type[i])) {
  3636.             found = 1;
  3637.             continue;
  3638.         }
  3639.         debug2("no key of type %d for host %s", type[i], host);
  3640.     }
  3641.     return (found);
  3642. }
  3643.  
  3644. void
  3645. ssh_put_password(char *password)
  3646. {
  3647.     int size;
  3648.     char *padded;
  3649.  
  3650.     if (datafellows & SSH_BUG_PASSWORDPAD) {
  3651.         packet_put_cstring(password);
  3652.         return;
  3653.     }
  3654.     size = roundup(strlen(password) + 1, 32);
  3655.     padded = malloc(size);
  3656.     memset(padded, 0, size);
  3657.     strlcpy(padded, password, size);
  3658.     packet_put_string(padded, size);
  3659.     memset(padded, 0, size);
  3660.     free(padded);
  3661. }
  3662.  
  3663.  
  3664. /* Session id for the current session. */
  3665. u_char session_id[16];
  3666. u_int supported_authentications = 0;
  3667.  
  3668. #ifdef KRB5
  3669. krb5_context ssh_context = NULL;
  3670. krb5_auth_context auth_context = NULL;
  3671. #endif /* KRB5 */
  3672.  
  3673. /*
  3674.  * Checks if the user has an authentication agent, and if so, tries to
  3675.  * authenticate using the agent.
  3676.  */
  3677. static int
  3678. try_agent_authentication(void)
  3679. {
  3680.     int type;
  3681.     char *comment;
  3682.     AuthenticationConnection *auth;
  3683.     u_char response[16];
  3684.     u_int i;
  3685.     Key *key;
  3686.     BIGNUM *challenge;
  3687.  
  3688.     /* Get connection to the agent. */
  3689.     auth = ssh_get_authentication_connection();
  3690.     if (!auth)
  3691.         return 0;
  3692.  
  3693.     challenge = BN_new();
  3694.     if (challenge == NULL) {
  3695.         fatal("try_agent_authentication: BN_new_failed");
  3696.         return(0);
  3697.     }
  3698.  
  3699.     /* Loop through identities served by the agent. */
  3700.     for (key = ssh_get_first_identity(auth, &comment, 1);
  3701.           key != NULL;
  3702.           key = ssh_get_next_identity(auth, &comment, 1)) {
  3703.  
  3704.         /* Try this identity. */
  3705.         debug1("Trying RSA authentication via agent with: %s", comment);
  3706.         free(comment);
  3707.  
  3708.         /* Tell the server that we are willing to authenticate using this key. */
  3709.         packet_start(SSH_CMSG_AUTH_RSA);
  3710.         packet_put_bignum(key->rsa->n);
  3711.         packet_send();
  3712.         packet_write_wait();
  3713.  
  3714.         /* Wait for server's response. */
  3715.         type = packet_read();
  3716.  
  3717.         /* The server sends failure if it doesn\'t like our key or
  3718.            does not support RSA authentication. */
  3719.         if (type == SSH_SMSG_FAILURE) {
  3720.             debug1("Server refused our key.");
  3721.             key_free(key);
  3722.             continue;
  3723.         }
  3724.         /* Otherwise it should have sent a challenge. */
  3725.         if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) {
  3726.             packet_disconnect("Protocol error during RSA authentication: %d",
  3727.                                type);
  3728.             return 0;
  3729.         }
  3730.         packet_get_bignum(challenge);
  3731.         packet_check_eom();
  3732.  
  3733.         debug1("Received RSA challenge from server.");
  3734.  
  3735.         /* Ask the agent to decrypt the challenge. */
  3736.         if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) {
  3737.             /*
  3738.              * The agent failed to authenticate this identifier
  3739.              * although it advertised it supports this.  Just
  3740.              * return a wrong value.
  3741.              */
  3742.             log("Authentication agent failed to decrypt challenge.");
  3743.             memset(response, 0, sizeof(response));
  3744.         }
  3745.         key_free(key);
  3746.         debug1("Sending response to RSA challenge.");
  3747.  
  3748.         /* Send the decrypted challenge back to the server. */
  3749.         packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
  3750.         for (i = 0; i < 16; i++)
  3751.             packet_put_char(response[i]);
  3752.         packet_send();
  3753.         packet_write_wait();
  3754.  
  3755.         /* Wait for response from the server. */
  3756.         type = packet_read();
  3757.  
  3758.         /* The server returns success if it accepted the authentication. */
  3759.         if (type == SSH_SMSG_SUCCESS) {
  3760.             ssh_close_authentication_connection(auth);
  3761.             BN_clear_free(challenge);
  3762.             debug1("RSA authentication accepted by server.");
  3763.             return 1;
  3764.         }
  3765.         /* Otherwise it should return failure. */
  3766.         if (type != SSH_SMSG_FAILURE) {
  3767.             packet_disconnect("Protocol error waiting RSA auth response: %d",
  3768.                                type);
  3769.             return 0;
  3770.         }
  3771.     }
  3772.     ssh_close_authentication_connection(auth);
  3773.     BN_clear_free(challenge);
  3774.     debug1("RSA authentication using agent refused.");
  3775.     return 0;
  3776. }
  3777.  
  3778. /*
  3779.  * Computes the proper response to a RSA challenge, and sends the response to
  3780.  * the server.
  3781.  */
  3782. static void
  3783. respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
  3784. {
  3785.     u_char buf[32], response[16];
  3786.     MD5_CTX md;
  3787.     int i, len;
  3788.  
  3789.     /* Decrypt the challenge using the private key. */
  3790.     /* XXX think about Bleichenbacher, too */
  3791.     if (rsa_private_decrypt(challenge, challenge, prv) <= 0) {
  3792.         packet_disconnect("respond_to_rsa_challenge: rsa_private_decrypt failed");
  3793.         return;
  3794.     }
  3795.     /* Compute the response. */
  3796.     /* The response is MD5 of decrypted challenge plus session id. */
  3797.     len = BN_num_bytes(challenge);
  3798.     if (len <= 0 || len > sizeof(buf)) {
  3799.         packet_disconnect("respond_to_rsa_challenge: bad challenge length %d", len);
  3800.         return;
  3801.     }
  3802.     memset(buf, 0, sizeof(buf));
  3803.     BN_bn2bin(challenge, buf + sizeof(buf) - len);
  3804.     MD5_Init(&md);
  3805.     MD5_Update(&md, buf, 32);
  3806.     MD5_Update(&md, session_id, 16);
  3807.     MD5_Final(response, &md);
  3808.  
  3809.     debug1("Sending response to host key RSA challenge.");
  3810.  
  3811.     /* Send the response back to the server. */
  3812.     packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
  3813.     for (i = 0; i < 16; i++)
  3814.         packet_put_char(response[i]);
  3815.     packet_send();
  3816.     packet_write_wait();
  3817.  
  3818.     memset(buf, 0, sizeof(buf));
  3819.     memset(response, 0, sizeof(response));
  3820.     memset(&md, 0, sizeof(md));
  3821. }
  3822.  
  3823. /*
  3824.  * Checks if the user has authentication file, and if so, tries to authenticate
  3825.  * the user using it.
  3826.  */
  3827. int
  3828. try_rsa_authentication(int idx)
  3829. {
  3830.     BIGNUM *challenge;
  3831.     Key *public, *private;
  3832.     char buf[300], passphrase[300]="", *comment, *authfile;
  3833.     int type, i, quit;
  3834.  
  3835.     public = options.identity_keys[idx];
  3836.     authfile = options.identity_files[idx];
  3837.     comment = strdup(authfile);
  3838.  
  3839.     debug1("Trying RSA authentication with key: %s", comment);
  3840.  
  3841.     /* Tell the server that we are willing to authenticate using this key. */
  3842.     packet_start(SSH_CMSG_AUTH_RSA);
  3843.     packet_put_bignum(public->rsa->n);
  3844.     packet_send();
  3845.     packet_write_wait();
  3846.  
  3847.     /* Wait for server's response. */
  3848.     type = packet_read();
  3849.  
  3850.     /*
  3851.      * The server responds with failure if it doesn\'t like our key or
  3852.      * doesn\'t support RSA authentication.
  3853.      */
  3854.     if (type == SSH_SMSG_FAILURE) {
  3855.         debug1("Server refused our key.");
  3856.         free(comment);
  3857.         return 0;
  3858.     }
  3859.     /* Otherwise, the server should respond with a challenge. */
  3860.     if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) {
  3861.         packet_disconnect("Protocol error during RSA authentication: %d", type);
  3862.         return 0;
  3863.     }
  3864.     /* Get the challenge from the packet. */
  3865.     challenge = BN_new();
  3866.     if (challenge == NULL) {
  3867.         fatal("try_rsa_authentication: BN_new_failed");
  3868.         return(0);
  3869.     }
  3870.     packet_get_bignum(challenge);
  3871.     packet_check_eom();
  3872.  
  3873.     debug1("Received RSA challenge from server.");
  3874.  
  3875.     /*
  3876.      * If the key is not stored in external hardware, we have to
  3877.      * load the private key.  Try first with empty passphrase; if it
  3878.      * fails, ask for a passphrase.
  3879.      */
  3880.     if (public->flags & KEY_FLAG_EXT)
  3881.         private = public;
  3882.     else
  3883.         private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
  3884.  
  3885.     if (private == NULL && !options.batch_mode) {
  3886.         int ok;
  3887.         snprintf(buf, sizeof(buf),
  3888.                   "Enter passphrase for RSA key '%.100s': ", comment);
  3889.         for (i = 0; i < options.number_of_password_prompts; i++) {
  3890.             if ( i == 0 && pwbuf[0] && pwflg ) {
  3891.                 ckstrncpy(passphrase,pwbuf,sizeof(passphrase));
  3892. #ifdef OS2
  3893.                 if ( pwcrypt )
  3894.                     ck_encrypt((char *)passphrase);
  3895. #endif /* OS2 */
  3896.             } else {
  3897.                 ok = uq_txt(buf,"Passphrase: ",2,NULL,passphrase,
  3898.                             sizeof(passphrase),NULL,DEFAULT_UQ_TIMEOUT);
  3899.                 if ( !ok ) {
  3900.                     quit = 1;
  3901.                     break;
  3902.                 }
  3903.             }
  3904.             if (strcmp(passphrase, "") != 0) {
  3905.                 private = key_load_private_type(KEY_RSA1,
  3906.                                                  authfile, passphrase, NULL);
  3907.                 quit = 0;
  3908.             } else {
  3909.                 debug2("no passphrase given, try next key");
  3910.                 quit = 1;
  3911.             }
  3912.             memset(passphrase, 0, strlen(passphrase));
  3913.             if (private != NULL || quit)
  3914.                 break;
  3915.             debug2("bad passphrase given, try again...");
  3916.         }
  3917.     }
  3918.     /* We no longer need the comment. */
  3919.     free(comment);
  3920.  
  3921.     if (private == NULL) {
  3922.         if (!options.batch_mode)
  3923.             error("Bad passphrase.");
  3924. #ifdef KUI
  3925.         uq_ok(NULL, "Bad passphrase.", 1, NULL, 0);
  3926. #endif /* KUI */
  3927.  
  3928.             /* Send a dummy response packet to avoid protocol error. */
  3929.             packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
  3930.             for (i = 0; i < 16; i++)
  3931.                 packet_put_char(0);
  3932.             packet_send();
  3933.             packet_write_wait();
  3934.  
  3935.             /* Expect the server to reject it... */
  3936.             packet_read_expect(SSH_SMSG_FAILURE);
  3937.             BN_clear_free(challenge);
  3938.             return 0;
  3939.     }
  3940.  
  3941.     /* Compute and send a response to the challenge. */
  3942.     respond_to_rsa_challenge(challenge, private->rsa);
  3943.  
  3944.     /* Destroy the private key unless it in external hardware. */
  3945.     if (!(private->flags & KEY_FLAG_EXT))
  3946.         key_free(private);
  3947.  
  3948.     /* We no longer need the challenge. */
  3949.     BN_clear_free(challenge);
  3950.  
  3951.     /* Wait for response from the server. */
  3952.     type = packet_read();
  3953.     if (type == SSH_SMSG_SUCCESS) {
  3954.         debug1("RSA authentication accepted by server.");
  3955.         return 1;
  3956.     }
  3957.     if (type != SSH_SMSG_FAILURE) {
  3958.         packet_disconnect("Protocol error waiting RSA auth response: %d", type);
  3959.         return 0;
  3960.     }
  3961.     debug1("RSA authentication refused.");
  3962.     return 0;
  3963. }
  3964.  
  3965. /*
  3966.  * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
  3967.  * authentication and RSA host authentication.
  3968.  */
  3969. static int
  3970. try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
  3971. {
  3972.     int type;
  3973.     BIGNUM *challenge;
  3974.  
  3975.     debug1("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
  3976.  
  3977.     /* Tell the server that we are willing to authenticate using this key. */
  3978.     packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
  3979.     packet_put_cstring(local_user);
  3980.     packet_put_int(BN_num_bits(host_key->rsa->n));
  3981.     packet_put_bignum(host_key->rsa->e);
  3982.     packet_put_bignum(host_key->rsa->n);
  3983.     packet_send();
  3984.     packet_write_wait();
  3985.  
  3986.     /* Wait for server's response. */
  3987.     type = packet_read();
  3988.  
  3989.     /* The server responds with failure if it doesn't admit our
  3990.        .rhosts authentication or doesn't know our host key. */
  3991.     if (type == SSH_SMSG_FAILURE) {
  3992.         debug1("Server refused our rhosts authentication or host key.");
  3993.         return 0;
  3994.     }
  3995.     /* Otherwise, the server should respond with a challenge. */
  3996.     if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) {
  3997.         packet_disconnect("Protocol error during RSA authentication: %d", type);
  3998.         return 0;
  3999.     }
  4000.     /* Get the challenge from the packet. */
  4001.     challenge = BN_new();
  4002.     if (challenge == NULL) {
  4003.         fatal("try_rhosts_rsa_authentication: BN_new_failed");
  4004.         return(0);
  4005.     }
  4006.     packet_get_bignum(challenge);
  4007.     packet_check_eom();
  4008.  
  4009.     debug1("Received RSA challenge for host key from server.");
  4010.  
  4011.     /* Compute a response to the challenge. */
  4012.     respond_to_rsa_challenge(challenge, host_key->rsa);
  4013.  
  4014.     /* We no longer need the challenge. */
  4015.     BN_clear_free(challenge);
  4016.  
  4017.     /* Wait for response from the server. */
  4018.     type = packet_read();
  4019.     if (type == SSH_SMSG_SUCCESS) {
  4020.         debug1("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
  4021.         return 1;
  4022.     }
  4023.     if (type != SSH_SMSG_FAILURE) {
  4024.         packet_disconnect("Protocol error waiting RSA auth response: %d", type);
  4025.         return 0;
  4026.     }
  4027.     debug1("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
  4028.     return 0;
  4029. }
  4030.  
  4031. #ifdef KRB5
  4032. static void
  4033. krb5_cleanup(void *ignore)
  4034. {
  4035.     if (auth_context) {
  4036.         krb5_auth_con_free(ssh_context, auth_context);
  4037.         auth_context = NULL;
  4038.     }
  4039.     if (ssh_context) {
  4040.         krb5_free_context(ssh_context);
  4041.         ssh_context = NULL;
  4042.     }
  4043. }
  4044.  
  4045. static int
  4046. try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
  4047. {
  4048.     krb5_error_code problem;
  4049.     const char *tkfile;
  4050.     struct _stat buf;
  4051.     krb5_ccache ccache = NULL;
  4052.     const char *remotehost;
  4053.     krb5_data ap;
  4054.     int type;
  4055.     krb5_ap_rep_enc_part *reply = NULL;
  4056.     int ret;
  4057.  
  4058.     memset(&ap, 0, sizeof(ap));
  4059.  
  4060.     problem = krb5_init_context(context);
  4061.     if (problem) {
  4062.         debug1("try_krb5_authentication: krb5_init_context() returns: %s",
  4063.                krb5_get_err_text(*context,problem));
  4064.         ret = 0;
  4065.         goto out;
  4066.     }
  4067.  
  4068.     problem = krb5_auth_con_init(*context, auth_context);
  4069.     if ( problem ) {
  4070.         debug1("Kerberos V5: krb5_auth_con_init failed");
  4071.         ret = 0;
  4072.         goto out;
  4073.     }
  4074. #ifndef HEIMDAL
  4075.         problem = krb5_auth_con_setflags(*context, *auth_context,
  4076.                                          KRB5_AUTH_CONTEXT_RET_TIME);
  4077.         if (problem) {
  4078.                 debug1("Kerberos v5: krb5_auth_con_setflags failed");
  4079.                 ret = 0;
  4080.                 goto out;
  4081.         }
  4082. #endif
  4083.  
  4084.     tkfile = krb5_cc_default_name(*context);
  4085.     if (strncmp(tkfile, "FILE:", 5) == 0) {
  4086.         tkfile += 5;
  4087.  
  4088.         /* XXX ssh should not be suid root here but ...*/
  4089.         if (stat(tkfile, &buf) == 0
  4090. #ifndef OS2
  4091.              && getuid() != buf.st_uid
  4092. #endif /* OS2 */
  4093.              ) {
  4094.             debug1("Kerberos V5: could not get default ccache (permission denied): %s",
  4095.                    tkfile);
  4096.             ret = 0;
  4097.             goto out;
  4098.         }
  4099.     }
  4100.  
  4101.     problem = krb5_cc_default(*context, &ccache);
  4102.     if (problem) {
  4103.         debug1("Kerberos v5: krb5_cc_default failed: %s",
  4104.                krb5_get_err_text(*context, problem));
  4105.         ret = 0;
  4106.         goto out;
  4107.     }
  4108.  
  4109.     remotehost = get_canonical_hostname(1);
  4110.  
  4111.     problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
  4112.                            "host", (char *)remotehost, NULL, ccache, &ap);
  4113.     if (problem) {
  4114.         debug1("Kerberos v5: krb5_mk_req failed: %s",
  4115.                krb5_get_err_text(*context, problem));
  4116.         ret = 0;
  4117.         goto out;
  4118.     }
  4119.  
  4120.     packet_start(ssh_k5_is_k4 ? SSH_CMSG_AUTH_KRB4 : SSH_CMSG_AUTH_KRB5);
  4121.     packet_put_string((char *) ap.data, ap.length);
  4122.     packet_send();
  4123.     packet_write_wait();
  4124.  
  4125.     free(ap.data);
  4126.     ap.length = 0;
  4127.  
  4128.     type = packet_read();
  4129.     switch (type) {
  4130.     case SSH_SMSG_FAILURE:
  4131.         /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
  4132.         debug1("Kerberos v5 authentication failed.");
  4133.         ret = 0;
  4134.         break;
  4135.  
  4136.     case SSH_SMSG_AUTH_KRB4_RESPONSE:
  4137.         /* for compatibility versions of OpenSSH which reuse the K4 message codes */
  4138.         /* fallthrough */
  4139.     case SSH_SMSG_AUTH_KRB5_RESPONSE:
  4140.         debug1("Kerberos v5 authentication accepted.");
  4141.  
  4142.         /* Get server's response. */
  4143.         ap.data = packet_get_string((unsigned int *) &ap.length);
  4144.  
  4145.         packet_check_eom();
  4146.  
  4147.         problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
  4148.         if (problem) {
  4149.             ret = 0;
  4150.         }
  4151.         ret = 1;
  4152.         break;
  4153.  
  4154.     default:
  4155.         packet_disconnect("Protocol error on Kerberos v5 response: %d",
  4156.                            type);
  4157.         ret = 0;
  4158.         break;
  4159.  
  4160.     }
  4161.  
  4162.   out:
  4163.     if (ccache != NULL)
  4164.         krb5_cc_close(*context, ccache);
  4165.     if (reply != NULL)
  4166.         krb5_free_ap_rep_enc_part(*context, reply);
  4167.     if (ap.length > 0) {
  4168. #ifdef HEIMDAL
  4169.         krb5_data_free(&ap);
  4170. #else
  4171.         krb5_free_data_contents(*context, &ap);
  4172. #endif
  4173.     }
  4174.     return (ret);
  4175. }
  4176.  
  4177. static void
  4178. send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
  4179. {
  4180.     int fd, type;
  4181.     krb5_error_code problem;
  4182.     krb5_data outbuf;
  4183.     krb5_ccache ccache = NULL;
  4184.     krb5_creds creds;
  4185. #ifdef HEIMDAL
  4186.     krb5_kdc_flags flags;
  4187. #else
  4188.     int forwardable;
  4189. #endif
  4190.     const char *remotehost;
  4191.  
  4192.     memset(&creds, 0, sizeof(creds));
  4193.     memset(&outbuf, 0, sizeof(outbuf));
  4194.  
  4195.     fd = packet_get_connection_in();
  4196.  
  4197. #ifdef HEIMDAL
  4198.     problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
  4199.     if (problem)
  4200.         goto out;
  4201. #else
  4202.     problem = krb5_auth_con_genaddrs(context, auth_context, fd,
  4203.                         KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
  4204.                         KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
  4205.     if (problem) {
  4206.         debug1("krb5_auth_con_genaddrs: %.100s", error_message(problem));
  4207.         goto out;
  4208.     }
  4209. #endif
  4210.  
  4211.     problem = krb5_cc_default(context, &ccache);
  4212.     if (problem)
  4213.         goto out;
  4214.  
  4215.     problem = krb5_cc_get_principal(context, ccache, &creds.client);
  4216.     if (problem)
  4217.         goto out;
  4218.  
  4219.     remotehost = get_canonical_hostname(1);
  4220.  
  4221. #ifdef HEIMDAL
  4222.     problem = krb5_build_principal(context, &creds.server,
  4223.             strlen(creds.client->realm), creds.client->realm,
  4224.             "krbtgt", creds.client->realm, NULL);
  4225. #else
  4226.         problem = krb5_build_principal(context, &creds.server,
  4227.             creds.client->realm.length, creds.client->realm.data,
  4228.             "krbtgt", creds.client->realm.data, NULL);
  4229. #endif
  4230.  
  4231.     if (problem)
  4232.         goto out;
  4233.  
  4234.     creds.times.endtime = 0;
  4235.  
  4236. #ifdef HEIMDAL
  4237.     flags.i = 0;
  4238.     flags.b.forwarded = 1;
  4239.     flags.b.forwardable = krb5_config_get_bool(context,  NULL,
  4240.                                 "libdefaults", "forwardable", NULL);
  4241.  
  4242.     problem = krb5_get_forwarded_creds(context, auth_context,
  4243.                       ccache, flags.i, remotehost, &creds, &outbuf);
  4244.     if (problem)
  4245.         goto out;
  4246. #else
  4247.     forwardable = 1;
  4248.     problem = krb5_fwd_tgt_creds (context, auth_context,
  4249.                                    (char *)remotehost, creds.client, creds.server, ccache, forwardable,
  4250.                                    &outbuf);
  4251.     if (problem)
  4252.         goto out;
  4253. #endif
  4254.  
  4255.     packet_start(ssh_k5_is_k4 ? SSH_CMSG_HAVE_KRB4_TGT : SSH_CMSG_HAVE_KRB5_TGT);
  4256.     packet_put_string((char *)outbuf.data, outbuf.length);
  4257.     packet_send();
  4258.     packet_write_wait();
  4259.  
  4260.     type = packet_read();
  4261.  
  4262.     if (type == SSH_SMSG_SUCCESS) {
  4263.         char *pname;
  4264.  
  4265.         krb5_unparse_name(context, creds.client, &pname);
  4266.         debug1("Kerberos v5 TGT forwarded (%s).", pname);
  4267.         free(pname);
  4268.     } else
  4269.         debug1("Kerberos v5 TGT forwarding failed.");
  4270.  
  4271.     return;
  4272.  
  4273.  out:
  4274.     if (problem)
  4275.         debug1("Kerberos v5 TGT forwarding failed: %s",
  4276.                krb5_get_err_text(context, problem));
  4277.     if (creds.client)
  4278.         krb5_free_principal(context, creds.client);
  4279.     if (creds.server)
  4280.         krb5_free_principal(context, creds.server);
  4281.     if (ccache)
  4282.         krb5_cc_close(context, ccache);
  4283.     if (outbuf.data)
  4284.         free(outbuf.data);
  4285. }
  4286. #endif /* KRB5 */
  4287.  
  4288. #ifdef KRB4
  4289. static int
  4290. try_krb4_authentication(void)
  4291. {
  4292.     KTEXT_ST auth;              /* Kerberos data */
  4293.     char *reply;
  4294.     char inst[INST_SZ];
  4295.     char *realm;
  4296. #ifdef OS2
  4297.     LEASH_CREDENTIALS cred;
  4298. #else /* OS2 */
  4299.     CREDENTIALS cred;
  4300. #endif /* OS2 */
  4301.     int r, type;
  4302.     socklen_t slen;
  4303.     Schedule schedule;
  4304.     u_long checksum, cksum;
  4305.     MSG_DAT msg_data;
  4306.     struct sockaddr_in local, foreign;
  4307.  
  4308.     /* Don't do anything if we don't have any tickets. */
  4309.     if (ck_krb4_get_tkts() < 1)
  4310.         return 0;
  4311.  
  4312.     ckstrncpy(inst, (char *) krb_get_phost((char *)get_canonical_hostname(1)), INST_SZ);
  4313.  
  4314.     realm = (char *) krb_realmofhost((char *)get_canonical_hostname(1));
  4315.     if (!realm) {
  4316.         debug1("Kerberos V4: no realm for: %s", (char *)get_canonical_hostname(1));
  4317.         return 0;
  4318.     }
  4319.     /* This can really be anything. */
  4320.     checksum = (u_long) getpid();
  4321.  
  4322.     r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
  4323.     if (r != KSUCCESS) {
  4324.         debug1("Kerberos V4 krb_mk_req failed: %s (%d)", krb_get_err_text_entry(r), r);
  4325.         return 0;
  4326.     }
  4327.     /* Get session key to decrypt the server's reply with. */
  4328.     r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
  4329.     if (r != KSUCCESS) {
  4330.         debug1("Kerberos V4: get_cred failed: %s (%d)", krb_get_err_text_entry(r), r);
  4331.         return 0;
  4332.     }
  4333.     des_key_sched(cred.session, schedule);
  4334.  
  4335.     /* Send authentication info to server. */
  4336.     packet_start(SSH_CMSG_AUTH_KRB4);
  4337.     packet_put_string((char *) auth.dat, auth.length);
  4338.     packet_send();
  4339.     packet_write_wait();
  4340.  
  4341.     /* Zero the buffer. */
  4342.     (void) memset(auth.dat, 0, MAX_KTXT_LEN);
  4343.  
  4344.     slen = sizeof(local);
  4345.     memset(&local, 0, sizeof(local));
  4346.     if (getsockname(packet_get_connection_in(),
  4347.                      (struct sockaddr *) & local, &slen) < 0)
  4348.         debug1("getsockname failed: %s",
  4349. #ifdef NT
  4350.                 sock_strerror(sock_lasterror())
  4351. #else
  4352.                 strerror(errno)
  4353. #endif
  4354.                 );
  4355.  
  4356.     slen = sizeof(foreign);
  4357.     memset(&foreign, 0, sizeof(foreign));
  4358.     if (getpeername(packet_get_connection_in(),
  4359.                      (struct sockaddr *) & foreign, &slen) < 0) {
  4360.         debug1("getpeername failed: %s",
  4361. #ifdef NT
  4362.                 sock_strerror(sock_lasterror())
  4363. #else
  4364.                 strerror(errno)
  4365. #endif
  4366.                 );
  4367.         fatal_cleanup();
  4368.         return(-1);
  4369.     }
  4370.     /* Get server reply. */
  4371.     type = packet_read();
  4372.     switch (type) {
  4373.     case SSH_SMSG_FAILURE:
  4374.         /* Should really be SSH_SMSG_AUTH_KRB4_FAILURE */
  4375.         debug1("Kerberos V4 authentication failed.");
  4376.         return 0;
  4377.         break;
  4378.  
  4379.     case SSH_SMSG_AUTH_KRB4_RESPONSE:
  4380.         /* SSH_SMSG_AUTH_KRB4_SUCCESS */
  4381.         debug1("Kerberos V4 authentication accepted.");
  4382.  
  4383.         /* Get server's response. */
  4384.         reply = packet_get_string((u_int *) &auth.length);
  4385.         if ( auth.length >= MAX_KTXT_LEN ) {
  4386.             fatal("Keberos V4: Malformed response from server.");
  4387.             return -1;
  4388.         }
  4389.         memcpy(auth.dat, reply, auth.length);
  4390.         free(reply);
  4391.  
  4392.         packet_check_eom();
  4393.  
  4394.         /*
  4395.          * If his response isn't properly encrypted with the session
  4396.          * key, and the decrypted checksum fails to match, he's
  4397.          * bogus. Bail out.
  4398.          */
  4399.         r = krb_rd_priv(auth.dat, auth.length, schedule,
  4400. #ifdef KRB524
  4401.                          cred.session,
  4402. #else /* KRB524 */
  4403.                          &cred.session,
  4404. #endif /* KRB524 */
  4405.                          &foreign, &local, &msg_data);
  4406.         if (r != KSUCCESS) {
  4407.             debug1("Kerberos V4 krb_rd_priv failed: %s (%d)", krb_get_err_text_entry(r),r);
  4408.             packet_disconnect("Kerberos V4 challenge failed!");
  4409.             return 0;
  4410.         }
  4411.         /* Fetch the (incremented) checksum that we supplied in the request. */
  4412.         (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum));
  4413.         cksum = ntohl(cksum);
  4414.  
  4415.         /* If it matches, we're golden. */
  4416.         if (cksum == checksum + 1) {
  4417.             debug1("Kerberos V4 challenge successful.");
  4418.             return 1;
  4419.         } else {
  4420.             packet_disconnect("Kerberos V4 challenge failed!");
  4421.             return 0;
  4422.         }
  4423.         break;
  4424.  
  4425.     default:
  4426.         packet_disconnect("Protocol error on Kerberos V4 response: %d", type);
  4427.         return 0;
  4428.     }
  4429.     return 0;
  4430. }
  4431. #endif /* KRB4 */
  4432.  
  4433. #ifdef AFS
  4434. static void
  4435. send_krb4_tgt(void)
  4436. {
  4437. #ifdef OS2
  4438.     LEASH_CREDENTIALS *creds;
  4439. #else
  4440.     CREDENTIALS *creds;
  4441. #endif
  4442.     char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
  4443.     int problem, type;
  4444.     char buffer[8192];
  4445.     struct _stat st;
  4446.  
  4447.     /* Don't do anything if we don't have any tickets. */
  4448.     if (stat(tkt_string(), &st) < 0)
  4449.         return;
  4450.  
  4451.     creds = malloc(sizeof(*creds));
  4452.  
  4453.     problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
  4454.     if (problem)
  4455.         goto out;
  4456.  
  4457.     problem = krb_get_cred("krbtgt", prealm, prealm, creds);
  4458.     if (problem)
  4459.         goto out;
  4460.  
  4461.     if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
  4462.         problem = RD_AP_EXP;
  4463.         goto out;
  4464.     }
  4465.     creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
  4466.  
  4467.     packet_start(SSH_CMSG_HAVE_KRB4_TGT);
  4468.     packet_put_cstring(buffer);
  4469.     packet_send();
  4470.     packet_write_wait();
  4471.  
  4472.     type = packet_read();
  4473.  
  4474.     if (type == SSH_SMSG_SUCCESS)
  4475.         debug1("Kerberos v4 TGT forwarded (%s%s%s@%s).",
  4476.                creds->pname, creds->pinst[0] ? "." : "",
  4477.                creds->pinst, creds->realm);
  4478.     else
  4479.         debug1("Kerberos v4 TGT rejected.");
  4480.  
  4481.     free(creds);
  4482.     return;
  4483.  
  4484.   out:
  4485.     debug1("Kerberos v4 TGT passing failed: %s", get_krb_err_txt_entry(problem));
  4486.     free(creds);
  4487. }
  4488.  
  4489. static void
  4490. send_afs_tokens(void)
  4491. {
  4492. #ifdef OS2
  4493.     LEASH_CREDENTIALS creds;
  4494. #else
  4495.     CREDENTIALS creds;
  4496. #endif /* OS2 */
  4497.     struct ViceIoctl parms;
  4498.     struct ClearToken ct;
  4499.     int i, type, len;
  4500.     char buf[2048], *p, *server_cell;
  4501.     char buffer[8192];
  4502.  
  4503.     /* Move over ktc_GetToken, here's something leaner. */
  4504.     for (i = 0; i < 100; i++) { /* just in case */
  4505.         parms.in = (char *) &i;
  4506.         parms.in_size = sizeof(i);
  4507.         parms.out = buf;
  4508.         parms.out_size = sizeof(buf);
  4509.         if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
  4510.             break;
  4511.         p = buf;
  4512.  
  4513.         /* Get secret token. */
  4514.         memcpy(&creds.ticket_st.length, p, sizeof(u_int));
  4515.         if (creds.ticket_st.length > MAX_KTXT_LEN)
  4516.             break;
  4517.         p += sizeof(u_int);
  4518.         memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
  4519.         p += creds.ticket_st.length;
  4520.  
  4521.         /* Get clear token. */
  4522.         memcpy(&len, p, sizeof(len));
  4523.         if (len != sizeof(struct ClearToken))
  4524.             break;
  4525.         p += sizeof(len);
  4526.         memcpy(&ct, p, len);
  4527.         p += len;
  4528.         p += sizeof(len);       /* primary flag */
  4529.         server_cell = p;
  4530.  
  4531.         /* Flesh out our credentials. */
  4532.         strlcpy(creds.service, "afs", sizeof creds.service);
  4533.         creds.instance[0] = '\0';
  4534.         strlcpy(creds.realm, server_cell, REALM_SZ);
  4535.         memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
  4536.         creds.issue_date = ct.BeginTimestamp;
  4537.         creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp);
  4538.         creds.kvno = ct.AuthHandle;
  4539.         snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
  4540.         creds.pinst[0] = '\0';
  4541.  
  4542.         /* Encode token, ship it off. */
  4543.         if (creds_to_radix(&creds, (u_char *) buffer, sizeof buffer) <= 0)
  4544.             break;
  4545.         packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
  4546.         packet_put_cstring(buffer);
  4547.         packet_send();
  4548.         packet_write_wait();
  4549.  
  4550.         /* Roger, Roger. Clearance, Clarence. What's your vector,
  4551.         Victor? */
  4552.         type = packet_read();
  4553.  
  4554.         if (type == SSH_SMSG_FAILURE)
  4555.             debug1("AFS token for cell rejected: %s", server_cell);
  4556.                 else if (type != SSH_SMSG_SUCCESS) {
  4557.                     packet_disconnect("Protocol error on AFS token response: %d", type);
  4558.                     return 0;
  4559.                 }
  4560.     }
  4561. }
  4562.  
  4563. #endif /* AFS */
  4564.  
  4565. /*
  4566.  * Tries to authenticate with any string-based challenge/response system.
  4567.  * Note that the client code is not tied to s/key or TIS.
  4568.  */
  4569. static int
  4570. try_challenge_response_authentication(void)
  4571. {
  4572.     int type, i;
  4573.     u_int clen;
  4574.     char prompt[1024], response[256]="";
  4575.     char *challenge;
  4576.  
  4577.     debug1("Doing challenge response authentication.");
  4578.  
  4579.     for (i = 0; i < options.number_of_password_prompts; i++) {
  4580.         int ok;
  4581.  
  4582.         /* request a challenge */
  4583.         packet_start(SSH_CMSG_AUTH_TIS);
  4584.         packet_send();
  4585.         packet_write_wait();
  4586.  
  4587.         type = packet_read();
  4588.         if (type != SSH_SMSG_FAILURE &&
  4589.             type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
  4590.             packet_disconnect("Protocol error: got %d in response "
  4591.                                "to SSH_CMSG_AUTH_TIS", type);
  4592.             return 0;
  4593.         }
  4594.         if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
  4595.             debug1("No challenge.");
  4596.             return 0;
  4597.         }
  4598.         challenge = packet_get_string(&clen);
  4599.         packet_check_eom();
  4600.         snprintf(prompt, sizeof prompt, "%s%s%s",
  4601.                   i == 0 ? "" : "Permission denied, please try again.\n",
  4602.                   challenge,
  4603.                  strchr(challenge, '\n') ? "" : "\n");
  4604.         free(challenge);
  4605.         if (i != 0)
  4606.             bleep(BP_FAIL);
  4607.         if ( i == 0 && pwbuf[0] && pwflg ) {
  4608.             if (options.cipher == SSH_CIPHER_NONE)
  4609.                 log("WARNING: Encryption is disabled! "
  4610.                     "Response will be transmitted in clear text.");
  4611.             ckstrncpy(response,pwbuf,sizeof(response));
  4612. #ifdef OS2
  4613.             if ( pwcrypt )
  4614.                 ck_encrypt((char *)response);
  4615. #endif /* OS2 */
  4616.             ok = 1;
  4617.         } else { 
  4618.             if (options.cipher == SSH_CIPHER_NONE)
  4619.                 ckstrncat(prompt,"WARNING: Encryption is disabled! "
  4620.                           "Response will be transmitted in clear text.\n",1024);
  4621.             ok = uq_txt(prompt,"Response: ",2,NULL,response, sizeof(response),
  4622.                         NULL,DEFAULT_UQ_TIMEOUT);
  4623.         }
  4624.         if (!ok || strcmp(response, "") == 0)
  4625.             break;
  4626.         packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
  4627.         ssh_put_password(response);
  4628.         memset(response, 0, strlen(response));
  4629.         packet_send();
  4630.         packet_write_wait();
  4631.         type = packet_read();
  4632.         if (type == SSH_SMSG_SUCCESS)
  4633.             return 1;
  4634.         if (type != SSH_SMSG_FAILURE) {
  4635.             packet_disconnect("Protocol error: got %d in response "
  4636.                                "to SSH_CMSG_AUTH_TIS_RESPONSE", type);
  4637.             return 0;
  4638.         }
  4639.     }
  4640.     /* failure */
  4641.     return 0;
  4642. }
  4643.  
  4644. /*
  4645.  * Tries to authenticate with plain passwd authentication.
  4646.  */
  4647. static int
  4648. try_password_authentication(const char *server_user, char *host)
  4649. {
  4650.     int type, i, ok;
  4651.     char password[256]="";
  4652.     char prompt[1024];
  4653.  
  4654.     debug1("Doing password authentication.");
  4655.     for (i = 0; i < options.number_of_password_prompts; i++) {
  4656.         if (i != 0)
  4657.             bleep(BP_FAIL);
  4658.         snprintf(prompt, sizeof(prompt), "%s%.30s@%.128s's password: ",
  4659.                   i == 0 ? "" : "Permission denied, please try again.\n",
  4660.                   server_user, host);
  4661.         if ( i == 0 && pwbuf[0] && pwflg ) {
  4662.             if (options.cipher == SSH_CIPHER_NONE)
  4663.                 log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
  4664.             ckstrncpy(password,pwbuf,sizeof(password));
  4665. #ifdef OS2
  4666.             if ( pwcrypt )
  4667.                 ck_encrypt((char *)password);
  4668. #endif /* OS2 */
  4669.             ok = 1;
  4670.         } else {
  4671.             if (options.cipher == SSH_CIPHER_NONE)
  4672.                 ckstrncat(prompt,
  4673.                 "WARNING: Encryption is disabled! "
  4674.                 "Password will be transmitted in clear text.\n",1024);
  4675.             ok = uq_txt(prompt,"Response: ",2,NULL,password, sizeof(password),NULL,
  4676.                         DEFAULT_UQ_TIMEOUT);
  4677.         }
  4678.         packet_start(SSH_CMSG_AUTH_PASSWORD);
  4679.         if (ok)
  4680.             ssh_put_password(password);
  4681.         memset(password, 0, strlen(password));
  4682.         packet_send();
  4683.         packet_write_wait();
  4684.  
  4685.         type = packet_read();
  4686.         if (type == SSH_SMSG_SUCCESS)
  4687.             return 1;
  4688.         if (type != SSH_SMSG_FAILURE) {
  4689.             packet_disconnect("Protocol error: got %d in response to passwd auth", type);
  4690.             return 0;
  4691.         }
  4692.     }
  4693.     /* failure */
  4694.     return 0;
  4695. }
  4696.  
  4697. /*
  4698.  * SSH1 key exchange
  4699.  */
  4700. int
  4701. ssh_kex(char *host, struct sockaddr *hostaddr)
  4702. {
  4703.     int i;
  4704.     BIGNUM *key;
  4705.     Key *host_key, *server_key;
  4706.     int bits, rbits;
  4707.     int ssh_cipher_default = SSH_CIPHER_3DES;
  4708.     u_char session_key[SSH_SESSION_KEY_LENGTH];
  4709.     u_char cookie[8];
  4710.     u_int supported_ciphers;
  4711.     u_int server_flags, client_flags;
  4712.     u_int32_t rand = 0;
  4713.  
  4714.     debug1("Waiting for server public key.");
  4715.  
  4716.     /* Wait for a public key packet from the server. */
  4717.     packet_read_expect(SSH_SMSG_PUBLIC_KEY);
  4718.  
  4719.     /* Get cookie from the packet. */
  4720.     for (i = 0; i < 8; i++)
  4721.         cookie[i] = packet_get_char();
  4722.  
  4723.     /* Get the public key. */
  4724.     server_key = key_new(KEY_RSA1);
  4725.     bits = packet_get_int();
  4726.     packet_get_bignum(server_key->rsa->e);
  4727.     packet_get_bignum(server_key->rsa->n);
  4728.  
  4729.     rbits = BN_num_bits(server_key->rsa->n);
  4730.     if (bits != rbits) {
  4731.         log("Warning: Server lies about size of server public key: "
  4732.              "actual size is %d bits vs. announced %d.", rbits, bits);
  4733.         log("Warning: This may be due to an old implementation of ssh.");
  4734.     }
  4735.     /* Get the host key. */
  4736.     host_key = key_new(KEY_RSA1);
  4737.     bits = packet_get_int();
  4738.     packet_get_bignum(host_key->rsa->e);
  4739.     packet_get_bignum(host_key->rsa->n);
  4740.  
  4741.     rbits = BN_num_bits(host_key->rsa->n);
  4742.     if (bits != rbits) {
  4743.         log("Warning: Server lies about size of server host key: "
  4744.              "actual size is %d bits vs. announced %d.", rbits, bits);
  4745.         log("Warning: This may be due to an old implementation of ssh.");
  4746.     }
  4747.  
  4748.     /* Get protocol flags. */
  4749.     server_flags = packet_get_int();
  4750.     packet_set_protocol_flags(server_flags);
  4751.  
  4752.     supported_ciphers = packet_get_int();
  4753.     supported_authentications = packet_get_int();
  4754.     packet_check_eom();
  4755.  
  4756.     debug1("Received server public key (%d bits) ", BN_num_bits(server_key->rsa->n));
  4757.     debug1("and host key (%d bits).", BN_num_bits(host_key->rsa->n));
  4758.  
  4759.     if (verify_host_key(host, hostaddr, host_key) == -1) {
  4760.         fatal("host key verification failed.");
  4761.         return(-1);
  4762.     }
  4763.  
  4764.     client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
  4765.  
  4766.     compute_session_id(session_id, cookie, host_key->rsa->n, server_key->rsa->n);
  4767.  
  4768.     /* Generate a session key. */
  4769.     arc4random_stir();
  4770.  
  4771.     /*
  4772.      * Generate an encryption key for the session.   The key is a 256 bit
  4773.      * random number, interpreted as a 32-byte key, with the least
  4774.      * significant 8 bits being the first byte of the key.
  4775.      */
  4776.     for (i = 0; i < 32; i++) {
  4777.         if (i % 4 == 0)
  4778.             rand = arc4random();
  4779.         session_key[i] = rand & 0xff;
  4780.         rand >>= 8;
  4781.     }
  4782.  
  4783.     /*
  4784.      * According to the protocol spec, the first byte of the session key
  4785.      * is the highest byte of the integer.  The session key is xored with
  4786.      * the first 16 bytes of the session id.
  4787.      */
  4788.     key = BN_new();
  4789.     if (key == NULL) {
  4790.         fatal("ssh_kex: BN_new_failed");
  4791.         return(0);
  4792.     }
  4793.  
  4794.     BN_set_word(key, 0);
  4795.     for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
  4796.         BN_lshift(key, key, 8);
  4797.         if (i < 16)
  4798.             BN_add_word(key, session_key[i] ^ session_id[i]);
  4799.         else
  4800.             BN_add_word(key, session_key[i]);
  4801.     }
  4802.  
  4803.     /*
  4804.      * Encrypt the integer using the public key and host key of the
  4805.      * server (key with smaller modulus first).
  4806.      */
  4807.     if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {
  4808.         /* Public key has smaller modulus. */
  4809.         if (BN_num_bits(host_key->rsa->n) <
  4810.              BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
  4811.             fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
  4812.                    "SSH_KEY_BITS_RESERVED %d",
  4813.                    BN_num_bits(host_key->rsa->n),
  4814.                    BN_num_bits(server_key->rsa->n),
  4815.                    SSH_KEY_BITS_RESERVED);
  4816.             return -1;
  4817.         }
  4818.         rsa_public_encrypt(key, key, server_key->rsa);
  4819.         rsa_public_encrypt(key, key, host_key->rsa);
  4820.     } else {
  4821.         /* Host key has smaller modulus (or they are equal). */
  4822.         if (BN_num_bits(server_key->rsa->n) <
  4823.              BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
  4824.             fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
  4825.                    "SSH_KEY_BITS_RESERVED %d",
  4826.                    BN_num_bits(server_key->rsa->n),
  4827.                    BN_num_bits(host_key->rsa->n),
  4828.                    SSH_KEY_BITS_RESERVED);
  4829.             return -1;
  4830.         }
  4831.         rsa_public_encrypt(key, key, host_key->rsa);
  4832.         rsa_public_encrypt(key, key, server_key->rsa);
  4833.     }
  4834.  
  4835.     /* Destroy the public keys since we no longer need them. */
  4836.     RSA_free(server_key->rsa);
  4837.     RSA_free(host_key->rsa);
  4838.  
  4839.     if (options.cipher == SSH_CIPHER_NOT_SET) {
  4840.         if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
  4841.             options.cipher = ssh_cipher_default;
  4842.     } else if (options.cipher == SSH_CIPHER_ILLEGAL ||
  4843.                 !(cipher_mask_ssh1(1) & (1 << options.cipher))) {
  4844.         log("No valid SSH1 cipher, using %.100s instead.",
  4845.              cipher_name(ssh_cipher_default));
  4846.         options.cipher = ssh_cipher_default;
  4847.     }
  4848.     /* Check that the selected cipher is supported. */
  4849.     if (!(supported_ciphers & (1 << options.cipher))) {
  4850.         fatal("Selected cipher type %.100s not supported by server.",
  4851.                cipher_name(options.cipher));
  4852.         return -1;
  4853.     }
  4854.  
  4855.     debug1("Encryption type", cipher_name(options.cipher));
  4856.  
  4857.     /* Send the encrypted session key to the server. */
  4858.     packet_start(SSH_CMSG_SESSION_KEY);
  4859.     packet_put_char(options.cipher);
  4860.  
  4861.     /* Send the cookie back to the server. */
  4862.     for (i = 0; i < 8; i++)
  4863.         packet_put_char(cookie[i]);
  4864.  
  4865.     /* Send and destroy the encrypted encryption key integer. */
  4866.     packet_put_bignum(key);
  4867.     BN_clear_free(key);
  4868.  
  4869.     /* Send protocol flags. */
  4870.     packet_put_int(client_flags);
  4871.  
  4872.     /* Send the packet now. */
  4873.     packet_send();
  4874.     packet_write_wait();
  4875.  
  4876.     debug1("Sent encrypted session key.");
  4877.  
  4878.     /* Set the encryption key. */
  4879.     packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
  4880.  
  4881.     /* We will no longer need the session key here.  Destroy any extra copies. */
  4882.     memset(session_key, 0, sizeof(session_key));
  4883.  
  4884.     /*
  4885.      * Expect a success message from the server.  Note that this message
  4886.      * will be received in encrypted form.
  4887.      */
  4888.     packet_read_expect(SSH_SMSG_SUCCESS);
  4889.  
  4890.     debug1("Received encrypted confirmation.");
  4891.     return 0;
  4892. }
  4893.  
  4894. /*
  4895.  * Authenticate user
  4896.  */
  4897. int
  4898. ssh_userauth1(const char *local_user, const char *server_user, char *host,
  4899.     Sensitive *sensitive)
  4900. {
  4901.     int i, type;
  4902. #ifdef KRB5
  4903.     krb5_context context = NULL;
  4904.     krb5_auth_context auth_context = NULL;
  4905. #endif
  4906.  
  4907.     if (supported_authentications == 0) {
  4908.         fatal("ssh_userauth1: server supports no auth methods");
  4909.         return -1;
  4910.     }
  4911.  
  4912.     /* Send the name of the user to log in as on the server. */
  4913.     packet_start(SSH_CMSG_USER);
  4914.     packet_put_cstring(server_user);
  4915.     packet_send();
  4916.     packet_write_wait();
  4917.  
  4918.     /*
  4919.      * The server should respond with success if no authentication is
  4920.      * needed (the user has no password).  Otherwise the server responds
  4921.      * with failure.
  4922.      */
  4923.     type = packet_read();
  4924.  
  4925.     /* check whether the connection was accepted without authentication. */
  4926.     if (type == SSH_SMSG_SUCCESS)
  4927.         goto success;
  4928.     if (type != SSH_SMSG_FAILURE) {
  4929.         packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER",
  4930.                            type);
  4931.         return -1;
  4932.     }
  4933. #ifdef KRB5
  4934.     if ((supported_authentications &
  4935.           (1 << (ssh_k5_is_k4 ? SSH_AUTH_KRB4 : SSH_AUTH_KRB5))) &&
  4936.         options.krb5_authentication) {
  4937.         debug1("ssh_userauth1: Trying Kerberos V5 authentication.");
  4938.         if (try_krb5_authentication(&context, &auth_context)) {
  4939.             /* The server should respond with success or failure. */
  4940.                 type = packet_read();
  4941.             if (type == SSH_SMSG_SUCCESS)
  4942.                 goto success;
  4943.             if (type != SSH_SMSG_FAILURE) {
  4944.                 if (auth_context)
  4945.                     krb5_auth_con_free(context, auth_context);
  4946.                 if (context)
  4947.                     krb5_free_context(context);
  4948.                 packet_disconnect("Protocol error: got %d in response to Kerberos V5 auth", type);
  4949.                 return -1;
  4950.             }
  4951.         }
  4952.     }
  4953. #endif /* KRB5 */
  4954.  
  4955. #ifdef KRB4
  4956.     if ((supported_authentications & (1 << SSH_AUTH_KRB4)) &&
  4957.          options.krb4_authentication) {
  4958.         debug1("Trying Kerberos V4 authentication.");
  4959.         if (try_krb4_authentication()) {
  4960.             /* The server should respond with success or failure. */
  4961.             type = packet_read();
  4962.             if (type == SSH_SMSG_SUCCESS)
  4963.                 goto success;
  4964.             if (type != SSH_SMSG_FAILURE) {
  4965.                 packet_disconnect("Protocol error: got %d in response to Kerberos V4 auth", type);
  4966.                 return -1;
  4967.             }
  4968.         }
  4969.     }
  4970. #endif /* KRB4 */
  4971.  
  4972.     /*
  4973.      * Use rhosts authentication if running in privileged socket and we
  4974.      * do not wish to remain anonymous.
  4975.      */
  4976.     if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
  4977.          options.rhosts_authentication) {
  4978.         debug1("Trying rhosts authentication.");
  4979.         packet_start(SSH_CMSG_AUTH_RHOSTS);
  4980.         packet_put_cstring(local_user);
  4981.         packet_send();
  4982.         packet_write_wait();
  4983.  
  4984.         /* The server should respond with success or failure. */
  4985.         type = packet_read();
  4986.         if (type == SSH_SMSG_SUCCESS)
  4987.             goto success;
  4988.         if (type != SSH_SMSG_FAILURE) {
  4989.             packet_disconnect("Protocol error: got %d in response to rhosts auth",
  4990.                                type);
  4991.             return -1;
  4992.         }
  4993.     }
  4994.     /*
  4995.      * Try .rhosts or /etc/hosts.equiv authentication with RSA host
  4996.      * authentication.
  4997.      */
  4998.     if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
  4999.          options.rhosts_rsa_authentication) {
  5000.         for (i = 0; i < sensitive->nkeys; i++) {
  5001.             if (sensitive->keys[i] != NULL && 
  5002.                 sensitive->keys[i]->type == KEY_RSA1 &&
  5003.                  try_rhosts_rsa_authentication(local_user, sensitive->keys[i]))
  5004.                 goto success;
  5005.         }
  5006.     }
  5007.     /* Try RSA authentication if the server supports it. */
  5008.     if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
  5009.          options.rsa_authentication) {
  5010.         /*
  5011.          * Try RSA authentication using the authentication agent. The
  5012.          * agent is tried first because no passphrase is needed for
  5013.          * it, whereas identity files may require passphrases.
  5014.          */
  5015.         if (try_agent_authentication())
  5016.             goto success;
  5017.  
  5018.         /* Try RSA authentication for each identity. */
  5019.         for (i = 0; i < options.num_identity_files; i++)
  5020.             if (options.identity_keys[i] != NULL &&
  5021.                  options.identity_keys[i]->type == KEY_RSA1 &&
  5022.                  try_rsa_authentication(i))
  5023.                 goto success;
  5024.     }
  5025.     /* Try challenge response authentication if the server supports it. */
  5026.     if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
  5027.          options.challenge_response_authentication && !options.batch_mode) {
  5028.         if (try_challenge_response_authentication())
  5029.             goto success;
  5030.     }
  5031.     /* Try password authentication if the server supports it. */
  5032.     if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
  5033.          options.password_authentication && !options.batch_mode) {
  5034.         if (try_password_authentication(server_user,host))
  5035.             goto success;
  5036.     }
  5037.  
  5038.  
  5039.     /* All authentication methods have failed.  Exit with an error message. */
  5040.     fatal("Permission denied.");
  5041.     bleep(BP_FAIL);
  5042.     return -1;
  5043.  
  5044.   success:
  5045. #ifdef KRB5
  5046.     /* Try Kerberos v5 TGT passing. */
  5047.     if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
  5048.          options.kerberos_tgt_passing && context && auth_context) {
  5049.         if (options.cipher == SSH_CIPHER_NONE)
  5050.             log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
  5051.         send_krb5_tgt(context, auth_context);
  5052.     }
  5053.     if (auth_context)
  5054.         krb5_auth_con_free(context, auth_context);
  5055.     if (context)
  5056.         krb5_free_context(context);
  5057. #endif
  5058.  
  5059. #ifdef AFS
  5060.     /* Try Kerberos v4 TGT passing if the server supports it. */
  5061.     if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
  5062.          options.kerberos_tgt_passing) {
  5063.         if (options.cipher == SSH_CIPHER_NONE)
  5064.             log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
  5065.         send_krb4_tgt();
  5066.     }
  5067.  
  5068.     /* Try AFS token passing if the server supports it. */
  5069.     if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
  5070.          options.afs_token_passing && k_hasafs()) {
  5071.         if (options.cipher == SSH_CIPHER_NONE)
  5072.             log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
  5073.         send_afs_tokens();
  5074.     }
  5075. #endif /* AFS */
  5076.     return 0;
  5077. }
  5078.  
  5079. static int
  5080. verify_host_key_callback(Key *hostkey)
  5081. {
  5082.     if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) < 0)
  5083.         return -1;
  5084.     return 0;
  5085. }
  5086.  
  5087. int
  5088. ssh_kex2(char *host, struct sockaddr *hostaddr)
  5089. {
  5090.     Kex *kex;
  5091. #ifdef GSSAPI
  5092.     char *orig, *gss;
  5093.     int len;
  5094. #endif
  5095.  
  5096.     xxx_host = host;
  5097.     xxx_hostaddr = hostaddr;
  5098.  
  5099. #ifdef GSSAPI
  5100.     if ( ssh_gkx )
  5101.     {
  5102.         /* Add the GSSAPI mechanisms currently supported on this client to
  5103.          * the key exchange algorithm proposal 
  5104.          */
  5105.         orig = myproposal[PROPOSAL_KEX_ALGS];
  5106.         gss = ssh_gssapi_client_mechanisms(host);
  5107.         if (gss) {
  5108.             len = strlen(orig)+strlen(gss)+2;
  5109.             myproposal[PROPOSAL_KEX_ALGS]=malloc(len);
  5110.             snprintf(myproposal[PROPOSAL_KEX_ALGS],len,"%s,%s",gss,orig);
  5111.         }
  5112.     }
  5113. #endif
  5114.  
  5115.     if (options.ciphers == (char *)-1) {
  5116.         log("No valid ciphers for protocol version 2 given, using defaults.");
  5117.         options.ciphers = NULL;
  5118.     }
  5119.     if (options.ciphers != NULL) {
  5120.         myproposal[PROPOSAL_ENC_ALGS_CTOS] =
  5121.             myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
  5122.     }
  5123.     myproposal[PROPOSAL_ENC_ALGS_CTOS] =
  5124.         compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
  5125.     myproposal[PROPOSAL_ENC_ALGS_STOC] =
  5126.         compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
  5127.     if (options.compression) {
  5128.         myproposal[PROPOSAL_COMP_ALGS_CTOS] =
  5129.             myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";
  5130.     } else {
  5131.         myproposal[PROPOSAL_COMP_ALGS_CTOS] =
  5132.             myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
  5133.     }
  5134.     if (options.macs != NULL) {
  5135.         myproposal[PROPOSAL_MAC_ALGS_CTOS] =
  5136.             myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
  5137.     }
  5138.     if (options.hostkeyalgorithms != NULL)
  5139.         myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
  5140.             options.hostkeyalgorithms;
  5141.  
  5142. #ifdef GSSAPI
  5143.     if ( ssh_gkx )
  5144.     {
  5145.         if (gss) {
  5146.             /* If we've got GSSAPI algorithms, then we also support the
  5147.             * 'null' hostkey, as a last resort */
  5148.             orig=myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
  5149.             len = strlen(orig)+sizeof(",null");
  5150.             myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]=malloc(len);
  5151.             snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],len,"%s,null",orig);
  5152.         }
  5153.     }
  5154. #endif
  5155.  
  5156.     /* start key exchange */
  5157.     kex = kex_setup(myproposal);
  5158.     kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
  5159.     kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
  5160. #ifdef GSSAPI
  5161.     kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
  5162. #endif 
  5163.     kex->client_version_string=client_version_string;
  5164.     kex->server_version_string=server_version_string;
  5165.     kex->verify_host_key=&verify_host_key_callback;
  5166.     kex->host=host;
  5167.  
  5168. #ifdef GSSAPI
  5169.     kex->options.gss_deleg_creds=options.gss_deleg_creds;
  5170. #endif
  5171.  
  5172.     xxx_kex = kex;
  5173.  
  5174.     if (dispatch_run(DISPATCH_BLOCK, &kex->done, kex) < 0)
  5175.         return(-1);
  5176.  
  5177.     session_id2 = kex->session_id;
  5178.     session_id2_len = kex->session_id_len;
  5179. #ifdef GSSAPI
  5180.     if ( kex->kex_type == KEX_GSS_GRP1_SHA1 )
  5181.         datafellows |= SSH_BUG_NOREKEY;
  5182. #endif
  5183.  
  5184. #ifdef DEBUG_KEXDH
  5185.     /* send 1st encrypted/maced/compressed message */
  5186.     packet_start(SSH2_MSG_IGNORE);
  5187.     packet_put_cstring("markus");
  5188.     packet_send();
  5189.     packet_write_wait();
  5190. #endif
  5191.     return (0);
  5192. }
  5193.  
  5194. /*
  5195.  * Authenticate user
  5196.  */
  5197.  
  5198. typedef struct Authctxt Authctxt;
  5199. typedef struct Authmethod Authmethod;
  5200.  
  5201. typedef int sign_cb_fn(
  5202.     Authctxt *authctxt, Key *key,
  5203.     u_char **sigp, u_int *lenp, u_char *data, u_int datalen);
  5204.  
  5205. struct Authctxt {
  5206.     const char *server_user;
  5207.     const char *local_user;
  5208.     const char *host;
  5209.     const char *service;
  5210.     Authmethod *method;
  5211.     int success;
  5212.     char *authlist;
  5213.     /* pubkey */
  5214.     Key *last_key;
  5215.     sign_cb_fn *last_key_sign;
  5216.     int last_key_hint;
  5217.     AuthenticationConnection *agent;
  5218.     /* hostbased */
  5219.     Sensitive *sensitive;
  5220. #ifdef CK_SRP
  5221.     int server_auth;        /* SRP authenticates _both_ sides;
  5222.                              * this is set when the client
  5223.                              * authenticates the server. */
  5224.     SRP_CTX *srp;
  5225. #endif
  5226.     /* kbd-interactive */
  5227.     int info_req_seen;
  5228.     /* generic */
  5229.     void    *methoddata;
  5230. };
  5231.  
  5232. struct Authmethod {
  5233.     char        *name;          /* string to compare against server's list */
  5234.     int (*userauth)(Authctxt *authctxt);
  5235.     int *enabled;       /* flag in option struct that enables method */
  5236.     int *batch_flag;    /* flag in option struct that disables method */
  5237. };
  5238.  
  5239. int     input_userauth_success(int type, u_int32_t seq, void *ctxt);
  5240. int     input_userauth_failure(int type, u_int32_t seq, void *ctxt);
  5241. int     input_userauth_banner(int type, u_int32_t seq, void *ctxt);
  5242. int     input_userauth_error(int type, u_int32_t seq, void *ctxt);
  5243. int     input_userauth_info_req(int type, u_int32_t seq, void *ctxt);
  5244. int     input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt);
  5245.  
  5246. int     input_userauth_passwd_changereq(int, u_int32_t, void *);
  5247.  
  5248. int     userauth_none(Authctxt *authctxt);
  5249. int     userauth_pubkey(Authctxt *authctxt);
  5250. int     userauth_passwd(Authctxt *authctxt);
  5251. int     userauth_kbdint(Authctxt *authctxt);
  5252. int     userauth_hostbased(Authctxt *authctxt);
  5253.  
  5254. int     userauth(Authctxt *authctxt, char *authlist);
  5255.  
  5256. #ifdef CK_SRP
  5257. int     userauth_srp(Authctxt *);
  5258. int     input_userauth_srp_reply(int type, u_int32_t packlen, void *ctxt);
  5259. int     input_userauth_srp_value(int type, u_int32_t packlen, void *ctxt);
  5260. int     input_userauth_srp_proof(int type, u_int32_t packlen, void *ctxt);
  5261. #endif
  5262.  
  5263.  
  5264. #ifdef GSSAPI
  5265. int     userauth_external(Authctxt *authctxt);
  5266. int     userauth_gssapi(Authctxt *authctxt);
  5267. int    input_gssapi_response(int type, u_int32_t plen, void *ctxt);
  5268. int    input_gssapi_token(int type, u_int32_t plen, void *ctxt);
  5269. int    input_gssapi_hash(int type, u_int32_t plen, void *ctxt);
  5270. int    input_gssapi_error(int, u_int32_t, void *);
  5271. int    input_gssapi_errtok(int, u_int32_t, void *);
  5272. #endif
  5273.  
  5274. static int
  5275. sign_and_send_pubkey(Authctxt *authctxt, Key *k,
  5276.                       sign_cb_fn *sign_callback);
  5277. static void     clear_auth_state(Authctxt *authctxt);
  5278.  
  5279. static Authmethod *authmethod_get(char *authlist);
  5280. static Authmethod *authmethod_lookup(const char *name);
  5281. static char *authmethods_get(void);
  5282.  
  5283. /* These two structures must be the same */
  5284. static Authmethod authmethods_data[] = {
  5285. #ifdef GSSAPI
  5286.     {"external-keyx",
  5287.          userauth_external,
  5288.          &options.gss_authentication,
  5289.          NULL},
  5290.     {"gssapi",
  5291.          userauth_gssapi,
  5292.          &options.gss_authentication,
  5293.          NULL},
  5294. #endif
  5295.     {"hostbased",
  5296.          userauth_hostbased,
  5297.          &options.hostbased_authentication,
  5298.          NULL},
  5299.     {"publickey",
  5300.          userauth_pubkey,
  5301.          &options.pubkey_authentication,
  5302.          NULL},
  5303. #ifdef CK_SRP
  5304.     {SRP_GEX_SHA1,
  5305.          userauth_srp,
  5306.          &options.srp_authentication,
  5307.          &options.batch_mode},
  5308. #endif
  5309.     {"keyboard-interactive",
  5310.          userauth_kbdint,
  5311.          &options.kbd_interactive_authentication,
  5312.          &options.batch_mode},
  5313.     {"password",
  5314.          userauth_passwd,
  5315.          &options.password_authentication,
  5316.          &options.batch_mode},
  5317.     {"none",
  5318.          userauth_none,
  5319.          NULL,
  5320.          NULL},
  5321.     {NULL, NULL, NULL, NULL}
  5322. };
  5323.  
  5324. static Authmethod authmethods[] = {
  5325. #ifdef GSSAPI
  5326.     {"external-keyx",
  5327.          userauth_external,
  5328.          &options.gss_authentication,
  5329.          NULL},
  5330.     {"gssapi",
  5331.          userauth_gssapi,
  5332.          &options.gss_authentication,
  5333.          NULL},
  5334. #endif
  5335.     {"hostbased",
  5336.          userauth_hostbased,
  5337.          &options.hostbased_authentication,
  5338.          NULL},
  5339.     {"publickey",
  5340.          userauth_pubkey,
  5341.          &options.pubkey_authentication,
  5342.          NULL},
  5343. #ifdef CK_SRP
  5344.     {SRP_GEX_SHA1,
  5345.          userauth_srp,
  5346.          &options.srp_authentication,
  5347.          &options.batch_mode},
  5348. #endif
  5349.     {"keyboard-interactive",
  5350.          userauth_kbdint,
  5351.          &options.kbd_interactive_authentication,
  5352.          &options.batch_mode},
  5353.     {"password",
  5354.          userauth_passwd,
  5355.          &options.password_authentication,
  5356.          &options.batch_mode},
  5357.     {"none",
  5358.          userauth_none,
  5359.          NULL,
  5360.          NULL},
  5361.     {NULL, NULL, NULL, NULL}
  5362. };
  5363.  
  5364. /* XXX internal state */
  5365. static Authmethod *current = NULL;
  5366. static char *supported = NULL;
  5367. static char *preferred = NULL;
  5368.  
  5369. int
  5370. authmethod_reset(void)
  5371. {
  5372.     memcpy(&authmethods,&authmethods_data,sizeof(authmethods));
  5373.     current = NULL;
  5374.     supported = NULL;
  5375.     preferred = NULL;
  5376.     return(0);
  5377. }
  5378.  
  5379. int
  5380. ssh_userauth2(const char *local_user, const char *server_user, char *host,
  5381.     Sensitive *sensitive)
  5382. {
  5383.     Authctxt authctxt;
  5384.     int type;
  5385.  
  5386.     if (options.challenge_response_authentication)
  5387.         options.kbd_interactive_authentication = 1;
  5388.  
  5389.     packet_start(SSH2_MSG_SERVICE_REQUEST);
  5390.     packet_put_cstring("ssh-userauth");
  5391.     packet_send();
  5392.     debug1("SSH2_MSG_SERVICE_REQUEST sent");
  5393.     packet_write_wait();
  5394.     type = packet_read();
  5395.     if (type != SSH2_MSG_SERVICE_ACCEPT) {
  5396.         fatal("Service denied authentication request: %d", type);
  5397.         return -1;
  5398.     }
  5399.     if (packet_remaining() > 0) {
  5400.         char *reply = packet_get_string(NULL);
  5401.         debug2("service_accept: %s", reply);
  5402.         free(reply);
  5403.     } else {
  5404.         debug2("buggy server: service_accept w/o service");
  5405.     }
  5406.     packet_check_eom();
  5407.     debug1("SSH2_MSG_SERVICE_ACCEPT received");
  5408.  
  5409.     if (options.preferred_authentications == NULL)
  5410.         options.preferred_authentications = authmethods_get();
  5411.  
  5412.     /* setup authentication context */
  5413.     memset(&authctxt, 0, sizeof(authctxt));
  5414.     authctxt.agent = ssh_get_authentication_connection();
  5415.     authctxt.server_user = server_user;
  5416.     authctxt.local_user = local_user;
  5417.     authctxt.host = host;
  5418.     authctxt.service = "ssh-connection";                /* service name */
  5419.     authctxt.success = 0;
  5420.     authctxt.method = authmethod_lookup("none");
  5421.     authctxt.authlist = NULL;
  5422.     authctxt.methoddata = NULL;
  5423.     authctxt.sensitive = sensitive;
  5424.     authctxt.info_req_seen = 0;
  5425.     if (authctxt.method == NULL) {
  5426.         fatal("ssh_userauth2: internal error: cannot send userauth none request");
  5427.         return -1;
  5428.     }
  5429.  
  5430.     /* initial userauth request */
  5431.     userauth_none(&authctxt);
  5432.  
  5433.     dispatch_init(&input_userauth_error);
  5434.     dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
  5435.     dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
  5436.     dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
  5437.     if (dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt) < 0) /* loop until success */
  5438.                 return -1;
  5439.  
  5440.     if (authctxt.agent != NULL)
  5441.         ssh_close_authentication_connection(authctxt.agent);
  5442.  
  5443.     debug1("Authentication succeeded (%s).", authctxt.method->name);
  5444.     return (0);
  5445. }
  5446.  
  5447. int
  5448. userauth(Authctxt *authctxt, char *authlist)
  5449. {
  5450.     if (authctxt->methoddata!=NULL) {
  5451.         free(authctxt->methoddata);
  5452.         authctxt->methoddata=NULL;
  5453.     }
  5454.     if (authlist == NULL) {
  5455.         authlist = authctxt->authlist;
  5456.     } else {
  5457.         if (authctxt->authlist)
  5458.             free(authctxt->authlist);
  5459.         authctxt->authlist = authlist;
  5460.     }
  5461.     for (;;) {
  5462.         Authmethod *method = authmethod_get(authlist);
  5463.         if (method == NULL) {
  5464.             fatal("Permission denied (%s).", authlist);
  5465.             bleep(BP_FAIL);
  5466.             return -1;
  5467.         }
  5468.         authctxt->method = method;
  5469.         if (method->userauth(authctxt) > 0) {
  5470.             debug2("we sent a %s packet, wait for reply", method->name);
  5471.             break;
  5472.         } else {
  5473.             debug2("we did not send a packet, disable method: %s",method->name);
  5474.             method->enabled = NULL;
  5475.         }
  5476.     }
  5477.     return 0;
  5478. }
  5479.  
  5480. int
  5481. input_userauth_error(int type, u_int32_t seq, void *ctxt)
  5482. {
  5483.     fatal("input_userauth_error: bad message during authentication: "
  5484.            "type %d", type);
  5485.     return -1;
  5486. }
  5487. int
  5488. input_userauth_banner(int type, u_int32_t seq, void *ctxt)
  5489. {
  5490.     char *msg, *lang;
  5491.     debug3("input_userauth_banner");
  5492.     msg = packet_get_string(NULL);
  5493.     lang = packet_get_string(NULL);
  5494.     fprintf(stderr, "%s", msg);
  5495.     free(msg);
  5496.     free(lang);
  5497.     return 0;
  5498. }
  5499.  
  5500. int
  5501. input_userauth_success(int type, u_int32_t seq, void *ctxt)
  5502. {
  5503.     Authctxt *authctxt = ctxt;
  5504.     if (authctxt == NULL) {
  5505.         fatal("input_userauth_success: no authentication context");
  5506.         return -1;
  5507.     }
  5508. #ifdef CK_SRP
  5509.     if (strcmp(authctxt->method->name, SRP_GEX_SHA1) == 0 &&
  5510.          !authctxt->server_auth) {
  5511.         fatal("SRP unauthenticated server sent a SUCCESS packet");
  5512.         return(-1);
  5513.     }
  5514. #endif
  5515.     if (authctxt->authlist)
  5516.         free(authctxt->authlist);
  5517.     if (authctxt->methoddata)
  5518.         free(authctxt->methoddata);
  5519.     clear_auth_state(authctxt);
  5520.     authctxt->success = 1;                      /* break out */
  5521.     return 0;
  5522. }
  5523. int
  5524. input_userauth_failure(int type, u_int32_t seq, void *ctxt)
  5525. {
  5526.     Authctxt *authctxt = ctxt;
  5527.     char *authlist = NULL;
  5528.     int partial;
  5529.  
  5530.     if (authctxt == NULL) {
  5531.         fatal("input_userauth_failure: no authentication context");
  5532.         return -1;
  5533.     }
  5534.     authlist = packet_get_string(NULL);
  5535.     partial = packet_get_char();
  5536.     packet_check_eom();
  5537.  
  5538.     if (partial != 0)
  5539.         log("Authenticated with partial success.");
  5540.     debug1("input_userauth_failure: authentications that can continue: %s", authlist);
  5541.  
  5542.     clear_auth_state(authctxt);
  5543.     if (userauth(authctxt, authlist) < 0) {
  5544.         return -1;
  5545.     }
  5546.     return 0;
  5547. }
  5548. int
  5549. input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
  5550. {
  5551.     Authctxt *authctxt = ctxt;
  5552.     Key *key = NULL;
  5553.     Buffer b;
  5554.     int pktype, sent = 0;
  5555.     u_int alen, blen;
  5556.     char *pkalg, *fp;
  5557.     u_char *pkblob;
  5558.  
  5559.     if (authctxt == NULL) {
  5560.         fatal("input_userauth_pk_ok: no authentication context");
  5561.         return -1;
  5562.     }
  5563.     if (datafellows & SSH_BUG_PKOK) {
  5564.         /* this is similar to SSH_BUG_PKAUTH */
  5565.         debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
  5566.         pkblob = packet_get_string(&blen);
  5567.         buffer_init(&b);
  5568.         buffer_append(&b, pkblob, blen);
  5569.         pkalg = buffer_get_string(&b, &alen);
  5570.         buffer_free(&b);
  5571.     } else {
  5572.         pkalg = packet_get_string(&alen);
  5573.         pkblob = packet_get_string(&blen);
  5574.     }
  5575.     packet_check_eom();
  5576.  
  5577.     debug1("Server accepts key: pkalg: %s blen: %u lastkey: %p hint %d",
  5578.            pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
  5579.  
  5580.     do {
  5581.         if (authctxt->last_key == NULL ||
  5582.              authctxt->last_key_sign == NULL) {
  5583.             debug1("no last key or no sign cb");
  5584.             break;
  5585.         }
  5586.         if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
  5587.             debug1("unknown pkalg %s", pkalg);
  5588.             break;
  5589.         }
  5590.         if ((key = key_from_blob(pkblob, blen)) == NULL) {
  5591.             debug1("no key from blob. pkalg %s", pkalg);
  5592.             break;
  5593.         }
  5594.         if ( key->type != pktype ) {
  5595.             error("input_userauth_pk_ok: type mismatch "
  5596.                    "for decoded key (received %d, expected %d)",
  5597.                    key->type, pktype);
  5598.             break;
  5599.         }
  5600.         fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
  5601.         debug1("input_userauth_pk_ok: fp %s", fp);
  5602.         free(fp);
  5603.         if (!key_equal(key, authctxt->last_key)) {
  5604.             debug1("key != last_key");
  5605.             break;
  5606.         }
  5607.         sent = sign_and_send_pubkey(authctxt, key,
  5608.                                      authctxt->last_key_sign);
  5609.     } while(0);
  5610.  
  5611.     if (key != NULL)
  5612.         key_free(key);
  5613.     free(pkalg);
  5614.     free(pkblob);
  5615.  
  5616.     /* unregister */
  5617.     clear_auth_state(authctxt);
  5618.     dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
  5619.  
  5620.     /* try another method if we did not send a packet*/
  5621.     if (sent == 0)
  5622.         if (userauth(authctxt, NULL) < 0)
  5623.             return -1;
  5624.     return 0;
  5625. }
  5626.  
  5627. #ifdef CK_SRP
  5628. void fatal_bignum_error();
  5629.  
  5630. int
  5631. userauth_srp(Authctxt *authctxt)
  5632. {
  5633.     if (srp_attempt++ >= options.number_of_password_prompts)
  5634.         return 0;
  5635.  
  5636.  
  5637. #ifdef COMMENT
  5638.     /* Merged with the prompt */
  5639.     if (srp_attempt != 1) {
  5640.         error("Permission denied, please try again.");
  5641.         bleep(BP_FAIL);
  5642.     }
  5643. #endif /* COMMENT */
  5644.  
  5645.     /* Allocate an SRP context and update the authentication context. */
  5646.  
  5647.     authctxt->srp = SRP_CTX_new();
  5648.     authctxt->server_auth = 0;
  5649.  
  5650.     /* We begin by sending an authorization request for the method. */
  5651.  
  5652.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  5653.     packet_put_cstring(authctxt->server_user);
  5654.     packet_put_cstring(authctxt->service);
  5655.     packet_put_cstring(authctxt->method->name);
  5656.     packet_send();
  5657.  
  5658.     /* Round 1 begins when we get the reply from the server. */
  5659.  
  5660.     dispatch_set(SSH2_MSG_USERAUTH_SRP_REPLY, &input_userauth_srp_reply);
  5661.     return 1;
  5662. }
  5663.  
  5664. /* Round 1: get the SRP parameters and send the public value e. */
  5665.  
  5666. static int
  5667. input_userauth_srp_reply(int type, u_int32_t seq, void *ctxt)
  5668. {
  5669.     int i, plen;
  5670.     BIGNUM *tmp;
  5671.     Authctxt *authctxt;
  5672.     SRP_CTX *srp;
  5673.  
  5674.     /* Make sure we're where we're supposed to be. */
  5675.  
  5676.     authctxt = ctxt;
  5677.     if (authctxt == NULL || authctxt->srp == NULL) {
  5678.         fatal("input_userauth_srp_reply: no context");
  5679.         return -1;
  5680.     }
  5681.     srp = authctxt->srp;
  5682.     dispatch_set(SSH2_MSG_USERAUTH_SRP_REPLY, NULL);
  5683.  
  5684.     /* The server sent us the prime p, generator g, and salt. */
  5685.  
  5686.     packet_get_bignum2(srp->p);
  5687.     packet_get_bignum2(srp->g);
  5688.     srp->salt = packet_get_string(&srp->slen);
  5689.     packet_check_eom();
  5690.  
  5691.     /*
  5692.      * Make sure the group is OK.  XXX note that there is no check
  5693.      * that this is really the group that the user chose when
  5694.      * he or she created the verifier (that requires persistent
  5695.      * client state).
  5696.      */
  5697.     if (!is_safe_group(srp->p, srp->g)) {
  5698.         packet_disconnect("unknown/unsafe SRP group");
  5699.         return -1;
  5700.     }
  5701.  
  5702.     /* We'll need p-1 later. */
  5703.  
  5704.     if (!BN_sub(srp->pm1, srp->p, BN_value_one()))
  5705.         goto err;
  5706.  
  5707.     /*
  5708.      * The random exponent a is ALEN bits long, or the size of p,
  5709.      * whichever is less.
  5710.      */
  5711.     plen = BN_num_bits(srp->p);
  5712.     i = ALEN;
  5713.     if (plen < ALEN)
  5714.         i = plen;
  5715.  
  5716.     /*
  5717.      * Generate the random exponent a.  Loop until lg(p) < a < p-1.
  5718.      * This guarantees that 1 < e < p-1 and that e isn't some
  5719.      * obvious power of g.
  5720.      */
  5721.     if ((tmp = BN_new()) == NULL)
  5722.         goto err;
  5723.     if (!BN_set_word(tmp, plen))
  5724.         goto err;
  5725.     for (;;) {
  5726.         if (!BN_rand(srp->a, i, 0, 0))
  5727.             goto err;
  5728.         if (BN_ucmp(srp->a, tmp) > 0 && BN_ucmp(srp->a, srp->pm1) < 0)
  5729.             break;
  5730.     }
  5731.     BN_free(tmp);
  5732.  
  5733.     /* Generate the public value e = g^a mod p. */
  5734.  
  5735.     if (!BN_mod_exp(srp->e, srp->g, srp->a, srp->p, srp->ctx))
  5736.         goto err;
  5737.  
  5738.     /* Send it. */
  5739.  
  5740.     packet_start(SSH2_MSG_USERAUTH_SRP_VALUE);
  5741.     packet_put_bignum2(srp->e);
  5742.     packet_send();
  5743.  
  5744.     /* Round 2 begins when we get the server's public value. */
  5745.  
  5746.     dispatch_set(SSH2_MSG_USERAUTH_SRP_VALUE, &input_userauth_srp_value);
  5747.     return 0;
  5748.  
  5749. err:
  5750.     fatal_bignum_error();
  5751.     return -1;
  5752. }
  5753.  
  5754. static int
  5755. input_userauth_srp_value(int type, u_int32_t seq, void *ctxt)
  5756. {
  5757.     int i, plen, ok;
  5758.     char passphrase[256]="", prompt[300];
  5759.     BIGNUM *x, *K;
  5760.     Authctxt *authctxt;
  5761.     SRP_CTX *srp;
  5762.  
  5763.     /* Make sure we're where we're supposed to be. */
  5764.  
  5765.     authctxt = ctxt;
  5766.     if (authctxt == NULL || authctxt->srp == NULL) {
  5767.         fatal("input_userauth_srp_value: no context");
  5768.         return -1;
  5769.     }
  5770.     srp = authctxt->srp;
  5771.     dispatch_set(SSH2_MSG_USERAUTH_SRP_VALUE, NULL);
  5772.  
  5773.     /*
  5774.      * The server sent f = (v + g^b) mod p, where v is the
  5775.      * user's verifier and b is another random number.
  5776.      */
  5777.     packet_get_bignum2(srp->f);
  5778.     packet_check_eom();
  5779.  
  5780.     /* Sanity check f.  Abort if f is not in (1, p-1). */
  5781.  
  5782.     if (BN_cmp(srp->f, BN_value_one()) <= 0 ||
  5783.          BN_ucmp(srp->f, srp->pm1) >= 0) {
  5784.         packet_disconnect("bad SRP f value");
  5785.         return -1;
  5786.     }
  5787.  
  5788.     /* Calculate u from f. */
  5789.  
  5790.     srp->u = srp_u_calc(srp->f);
  5791.     if (srp->u == 0) {
  5792.         packet_disconnect("bad SRP u value");
  5793.         return -1;
  5794.     }
  5795.  
  5796.     /* Get the passphrase from the user. */
  5797.  
  5798.     /*
  5799.      * XXX it would actually be nice if we could display the prompt
  5800.      * and set no-echo mode earlier, and read the passphrase here,
  5801.      * since the calculations above can be lengthy and could happen
  5802.      * while the user is typing (we only need the passphrase in
  5803.      * memory at this point), but the cli_* routines don't have an
  5804.      * API for that.  :-(
  5805.      */
  5806.  
  5807.     if (srp_attempt != 1)
  5808.         bleep(BP_FAIL);
  5809.  
  5810.     if ( srp_attempt == 1 && pwbuf[0] && pwflg ) {
  5811.         ckstrncpy(passphrase,pwbuf,sizeof(passphrase));
  5812. #ifdef OS2
  5813.         if ( pwcrypt )
  5814.             ck_encrypt((char *)passphrase);
  5815. #endif /* OS2 */
  5816.         ok = 1;
  5817.     } else {
  5818.         snprintf(prompt, sizeof(prompt), "%sEnter %.30s@%.128s's SRP passphrase: ",
  5819.               srp_attempt == 1 ? "" : "Permission denied, please try again.\n",
  5820.               authctxt->server_user, authctxt->host);
  5821.         ok = uq_txt(prompt,"Passphrase: ",2,NULL,passphrase, sizeof(passphrase),NULL,
  5822.                     DEFAULT_UQ_TIMEOUT);
  5823.     }
  5824.  
  5825.     plen = ok ? strlen(passphrase) : 0;
  5826.  
  5827.     /* Calculate x = HASH(salt | HASH(username | passphrase)). */
  5828.  
  5829.     if ((x = BN_new()) == NULL)
  5830.         goto err;
  5831.     srp_x_calc(srp->salt, srp->slen, authctxt->server_user, 
  5832.                ok ? passphrase : "", x);
  5833.  
  5834.     memset(passphrase, 0, sizeof(passphrase));
  5835.  
  5836.     /* Calculate v = g^x mod p. */
  5837.  
  5838.     if (!BN_mod_exp(srp->v, srp->g, x, srp->p, srp->ctx))
  5839.         goto err;
  5840.  
  5841.     /* Now the shared secret K = (f - v) ^ (a + u * x) mod p. */
  5842.  
  5843.     if (!BN_mul_word(x, srp->u))
  5844.         goto err;
  5845.     if (!BN_add(x, srp->a, x))              /* x = (a + u * x) */
  5846.         goto err;
  5847.  
  5848.     if ((K = BN_new()) == NULL)
  5849.         goto err;
  5850.     if (BN_copy(K, srp->f) == NULL)         /* use K as temp */
  5851.         goto err;
  5852.     if (BN_cmp(K, srp->v) < 0) {
  5853.         if (!BN_add(K, K, srp->p))
  5854.             goto err;
  5855.     }
  5856.     if (!BN_sub(srp->a, K, srp->v))         /* a = (f - v) */
  5857.         goto err;
  5858.  
  5859.     if (!BN_mod_exp(K, srp->a, x, srp->p, srp->ctx))
  5860.         goto err;
  5861.     BN_clear_free(x);
  5862.  
  5863.     /* Calculate the exchange hash and proofs. */
  5864.  
  5865.     srp_hash_calc(authctxt->server_user, authctxt->service,
  5866.                    authctxt->method->name, srp, K);
  5867.     BN_clear_free(K);
  5868.  
  5869.     /* Send the client authenticator. */
  5870.  
  5871.     packet_start(SSH2_MSG_USERAUTH_SRP_PROOF);
  5872.     packet_put_string(srp->m1, srp->m1len);
  5873.     packet_send();
  5874.  
  5875.     /* Wait for the server's authenticator. */
  5876.  
  5877.     dispatch_set(SSH2_MSG_USERAUTH_SRP_PROOF, &input_userauth_srp_proof);
  5878.     return 0;
  5879.  
  5880. err:
  5881.     fatal_bignum_error();
  5882.     return -1;
  5883. }
  5884.  
  5885. /* Round 3: check the proofs. */
  5886.  
  5887. static int
  5888. input_userauth_srp_proof(int type, u_int32_t seq, void *ctxt)
  5889. {
  5890.     int i;
  5891.     u_int mlen;
  5892.     u_char *mbuf;
  5893.     Authctxt *authctxt;
  5894.     SRP_CTX *srp;
  5895.  
  5896.     /* Make sure we're where we're supposed to be. */
  5897.  
  5898.     authctxt = ctxt;
  5899.     if (authctxt == NULL || authctxt->srp == NULL) {
  5900.         fatal("input_userauth_srp_proof: no context");
  5901.         return -1;
  5902.     }
  5903.     srp = authctxt->srp;
  5904.     dispatch_set(SSH2_MSG_USERAUTH_SRP_PROOF, NULL);
  5905.  
  5906.     /* Get the server's version. */
  5907.  
  5908.     i = packet_get_char();
  5909.     mbuf = NULL;
  5910.     if (i)
  5911.         mbuf = packet_get_string(&mlen);
  5912.     packet_check_eom();
  5913.  
  5914.     /* If the flag is set, we were OK; check the server. */
  5915.  
  5916.     if (i) {
  5917.         /*
  5918.         * If we were authenticated, but the server was not,
  5919.         * there is likely to be a serious problem.
  5920.         */
  5921.         if (mlen != srp->m2len || memcmp(mbuf, srp->m2, mlen) != 0) {
  5922.             packet_disconnect("SRP server authentication failure!");
  5923.             return -1;
  5924.         }
  5925.  
  5926.         authctxt->server_auth = 1;
  5927.         free(mbuf);
  5928.     }
  5929.  
  5930.     /*
  5931.      * Done.  Free the SRP context, and return to await the server's
  5932.      * reply packet.
  5933.      */
  5934.     SRP_CTX_free(srp);
  5935.     return 0;
  5936. }
  5937. #endif /* SRP */
  5938.  
  5939. #ifdef GSSAPI
  5940. int
  5941. userauth_gssapi(Authctxt *authctxt)
  5942. {
  5943.     Gssctxt *gssctxt = NULL;
  5944.     static gss_OID_set supported = NULL;
  5945.     OM_uint32 min;
  5946.     int ok=0;
  5947.  
  5948.     /* Things work better if we send one mechanism at a time, rather
  5949.      * than them all at once.  This means that if we fail at some point
  5950.      * in the middle of a negotiation, we can come back and try something
  5951.      * different.
  5952.      */
  5953.     if ( datafellows & SSH_OLD_GSSAPI ) return 0;
  5954.  
  5955.     /* Before we offer a mechanism, check that we can support it.  Don't
  5956.      * bother trying to get credentials - as the standard fallback will
  5957.      * deal with that kind of failure.
  5958.      */
  5959.  
  5960.     if ( supported == NULL )
  5961.         if (gss_indicate_mechs(&min, &supported) == GSS_S_UNAVAILABLE)
  5962.             return 0;
  5963.  
  5964.     while ( gssapi_mech<supported->count && !ok ) {
  5965.         if ( gssctxt ) ssh_gssapi_delete_ctx(&gssctxt);
  5966.         ssh_gssapi_build_ctx(&gssctxt);
  5967.         ssh_gssapi_set_oid(gssctxt,&supported->elements[gssapi_mech]);
  5968.  
  5969.         /* The DER encoding below only works for lengths<128, 
  5970.          * so check this here 
  5971.          */
  5972.         if ( supported->elements[gssapi_mech].length < 128 &&
  5973.              !GSS_ERROR(ssh_gssapi_import_name(gssctxt, authctxt->host))) 
  5974.         {
  5975.             ok = 1; /* Mechanism works */
  5976.         } else {
  5977.             gssapi_mech++;
  5978.         }
  5979.     }
  5980.     if ( !ok )
  5981.         return 0;
  5982.  
  5983.     authctxt->methoddata=(void *)gssctxt;
  5984.  
  5985.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  5986.     packet_put_cstring(authctxt->server_user);
  5987.     packet_put_cstring(authctxt->service);
  5988.     packet_put_cstring(authctxt->method->name);
  5989.  
  5990.     packet_put_int(1);
  5991.  
  5992.     /* The newest gsskeyex draft stipulates that OIDs should 
  5993.      * be DER encoded, so we need to add the object type and
  5994.      * length information back on
  5995.      */
  5996.     if ( datafellows & SSH_BUG_GSSAPI_BER )
  5997.     {
  5998.         packet_put_string(supported->elements[gssapi_mech].elements,
  5999.                           supported->elements[gssapi_mech].length);
  6000.     } else {
  6001.         packet_put_int((supported->elements[gssapi_mech].length)+2);
  6002.         packet_put_char(0x06);
  6003.         packet_put_char(supported->elements[gssapi_mech].length);
  6004.         packet_put_raw(supported->elements[gssapi_mech].elements,
  6005.                         supported->elements[gssapi_mech].length);
  6006.     }
  6007.  
  6008.     packet_send();
  6009.     packet_write_wait();
  6010.  
  6011.     dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,&input_gssapi_response);
  6012.     dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token);
  6013.     dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,&input_gssapi_error);
  6014.     dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,&input_gssapi_errtok);
  6015.  
  6016.     gssapi_mech++; /* Move along to the next candidate */
  6017.     return 1;
  6018. }
  6019.  
  6020. int
  6021. input_gssapi_response(int type, u_int32_t seq, void *ctxt)
  6022. {
  6023.     Authctxt *authctxt = ctxt;
  6024.     Gssctxt *gssctxt;
  6025.     OM_uint32 status,ms;
  6026.     int oidlen;
  6027.     char *oidv;
  6028.     gss_buffer_desc send_tok;
  6029.  
  6030.     if (authctxt == NULL) {
  6031.         fatal("input_gssapi_response: no authentication context");
  6032.         return -1;
  6033.     }
  6034.     gssctxt = authctxt->methoddata;
  6035.  
  6036.     /* Setup our OID */
  6037.     oidv=packet_get_string(&oidlen);
  6038.  
  6039.     if ( datafellows & SSH_BUG_GSSAPI_BER ) {
  6040.         if ( !ssh_gssapi_check_oid(gssctxt,oidv,oidlen) ) {
  6041.             fatal("Server returned different OID than expected");
  6042.             return -1;
  6043.         }
  6044.         ssh_gssapi_set_oid_data(gssctxt,oidv,oidlen);
  6045.     } else {
  6046.         if ( oidv[0] != 0x06 || oidv[1] != oidlen-2 ) {
  6047.             debug1("Badly encoded mechanism OID received");
  6048.             clear_auth_state(authctxt);
  6049.             userauth(authctxt,NULL);
  6050.             return 0;
  6051.         }
  6052.         if ( !ssh_gssapi_check_oid(gssctxt,oidv+2,oidlen-2) ) {
  6053.             fatal("Server returned different OID than expected");
  6054.             return -1;
  6055.         }
  6056.         ssh_gssapi_set_oid_data(gssctxt,oidv+2,oidlen-2);
  6057.     }
  6058.  
  6059.     packet_check_eom();
  6060.  
  6061.     status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
  6062.                                   GSS_C_NO_BUFFER, &send_tok,
  6063.                                   NULL);
  6064.     if (GSS_ERROR(status)) {
  6065.         if ( send_tok.length>0 ) {
  6066.             packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
  6067.             packet_put_string(send_tok.value,send_tok.length);
  6068.             packet_send();
  6069.             packet_write_wait();
  6070.         }
  6071.         /* Start again with next method on list */
  6072.         debug1("input_gssapi_response. Trying to start again");
  6073.         clear_auth_state(authctxt);
  6074.         return userauth(authctxt,NULL);
  6075.     }
  6076.  
  6077.     /* We must have data to send */
  6078.     packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
  6079.     packet_put_string(send_tok.value,send_tok.length);
  6080.     packet_send();
  6081.     packet_write_wait();
  6082.     gss_release_buffer(&ms, &send_tok);
  6083.     return 0;
  6084. }
  6085.  
  6086. int
  6087. input_gssapi_token(int type, u_int32_t seq, void *ctxt)
  6088. {
  6089.     Authctxt *authctxt = ctxt;
  6090.     Gssctxt *gssctxt;
  6091.     gss_buffer_desc send_tok,recv_tok;
  6092.     OM_uint32 status;
  6093.  
  6094.     if (authctxt == NULL) {
  6095.         fatal("input_gssapi_response: no authentication context");
  6096.         return -1;
  6097.     }
  6098.     gssctxt = authctxt->methoddata;
  6099.  
  6100.     recv_tok.value=packet_get_string(&recv_tok.length);
  6101.  
  6102.     status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
  6103.                                    &recv_tok, &send_tok, NULL);
  6104.  
  6105.     packet_check_eom();
  6106.  
  6107.     if (GSS_ERROR(status)) {
  6108.         if ( send_tok.length>0 ) {
  6109.             packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
  6110.             packet_put_string(send_tok.value,send_tok.length);
  6111.             packet_send();
  6112.             packet_write_wait();
  6113.         }
  6114.         /* Start again with the next method in the list */
  6115.         debug1("input_gssapi_token. Trying to start again");
  6116.         clear_auth_state(authctxt);
  6117.         return userauth(authctxt,NULL);
  6118.     }
  6119.  
  6120.     if (send_tok.length>0) {
  6121.         packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
  6122.         packet_put_string(send_tok.value,send_tok.length);
  6123.         packet_send();
  6124.         packet_write_wait();
  6125.     }
  6126.  
  6127.     if (status == GSS_S_COMPLETE) {
  6128.         /* If that succeeded, send a exchange complete message */
  6129.         packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
  6130.         packet_send();
  6131.         packet_write_wait();
  6132.     }
  6133.     return 0;
  6134. }
  6135.  
  6136. int
  6137. input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)          
  6138. {                                                                  
  6139.     Authctxt *authctxt = ctxt;                                      
  6140.     Gssctxt *gssctxt;                                               
  6141.     gss_buffer_desc send_tok,recv_tok;                              
  6142.     OM_uint32 status;                                               
  6143.                                                                     
  6144.     if (authctxt == NULL) {
  6145.         fatal("input_gssapi_response: no authentication context");  
  6146.         return -1;
  6147.     }
  6148.     gssctxt = authctxt->methoddata;                                 
  6149.                                                                     
  6150.     recv_tok.value=packet_get_string(&recv_tok.length);             
  6151.                                                                    
  6152.     /* Stick it into GSSAPI and see what it says */                 
  6153.     status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,    
  6154.                    &recv_tok, &send_tok, NULL);                     
  6155.                                                                    
  6156.     packet_check_eom();                                             
  6157.                                                                     
  6158.     /* We can't send a packet to the server */                      
  6159.                                                                    
  6160.     /* The draft says that we should wait for the server to fail    
  6161.      * before starting the next authentication. So, we clear the    
  6162.      * state, but don't do anything else */                         
  6163.     clear_auth_state(authctxt);                                     
  6164.     return 0;                                                         
  6165. }                                                                  
  6166.  
  6167. int
  6168. input_gssapi_error(int type, u_int32_t seq, void *ctxt) {
  6169.     OM_uint32 maj, min;
  6170.     char * msg;
  6171.     char * lang;
  6172.  
  6173.     maj=packet_get_int();
  6174.     min=packet_get_int();
  6175.     msg=packet_get_string(NULL);
  6176.     lang=packet_get_string(NULL);
  6177.  
  6178.     packet_check_eom();
  6179.  
  6180.     xfprintf(stderr, "Server GSSAPI Error:\n%s\n", msg);
  6181.     free(msg);
  6182.     free(lang);
  6183.     return 0;
  6184. }
  6185.  
  6186. int
  6187. userauth_external(Authctxt *authctxt)
  6188. {
  6189.     if (external_attempt++ >= 1)
  6190.         return 0;
  6191.  
  6192.     debug2("userauth_external");
  6193.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6194.     packet_put_cstring(authctxt->server_user);
  6195.     packet_put_cstring(authctxt->service);
  6196.     packet_put_cstring(authctxt->method->name);
  6197.     packet_send();
  6198.     packet_write_wait();
  6199.     return 1;
  6200. }
  6201. #endif /* GSSAPI */
  6202.  
  6203. int
  6204. userauth_none(Authctxt *authctxt)
  6205. {
  6206.     /* initial userauth request */
  6207.     debug2("userauth_none");
  6208.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6209.     packet_put_cstring(authctxt->server_user);
  6210.     packet_put_cstring(authctxt->service);
  6211.     packet_put_cstring(authctxt->method->name);
  6212.     packet_send();
  6213.     return 1;
  6214. }
  6215.  
  6216. int
  6217. userauth_passwd(Authctxt *authctxt)
  6218. {
  6219.     char prompt[150];
  6220.     char password[256];
  6221.     int  ok;
  6222.  
  6223.     if (passwd_attempt++ >= options.number_of_password_prompts)
  6224.         return 0;
  6225.  
  6226.     debug2("userauth_password");
  6227.  
  6228.     if(passwd_attempt != 1)
  6229.         bleep(BP_FAIL);
  6230.     if ( passwd_attempt == 1 && pwbuf[0] && pwflg ) {
  6231.         ckstrncpy(password,pwbuf,sizeof(password));
  6232. #ifdef OS2
  6233.         if ( pwcrypt )
  6234.             ck_encrypt((char *)password);
  6235. #endif /* OS2 */
  6236.         ok = 1;
  6237.     } else {
  6238.         snprintf(prompt, sizeof(prompt), "%s%.30s@%.128s's password: ",
  6239.              passwd_attempt == 1 ? "" : "Permission denied, please try again.\n",
  6240.              authctxt->server_user, authctxt->host);
  6241.         ok = uq_txt(prompt,"Password: ",2,NULL,password, sizeof(password),NULL,
  6242.                     DEFAULT_UQ_TIMEOUT);
  6243.     }
  6244.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6245.     packet_put_cstring(authctxt->server_user);
  6246.     packet_put_cstring(authctxt->service);
  6247.     packet_put_cstring(authctxt->method->name);
  6248.     packet_put_char(0);
  6249.     packet_put_cstring(ok ? password : "");
  6250.     memset(password, 0, strlen(password));
  6251.     packet_add_padding(64);
  6252.     packet_send();
  6253.  
  6254.     dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, &input_userauth_passwd_changereq);
  6255.     return 1;
  6256. }
  6257.  
  6258. /*
  6259.  * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
  6260.  */
  6261. int
  6262. input_userauth_passwd_changereq(int type, u_int32_t seq, void *ctxt)
  6263. {
  6264.     Authctxt *authctxt = ctxt;
  6265.     char *info, *lang, oldpw[256]="", newpw[256]="", retype[256]="";
  6266.     struct txtbox tb[3];
  6267.     char prompt[150];
  6268.     int ok;
  6269.  
  6270.     debug2("input_userauth_passwd_changereq");
  6271.  
  6272.     if (authctxt == NULL) {
  6273.         fatal("input_userauth_passwd_changereq: "
  6274.                "no authentication context");
  6275.         return 0;
  6276.     }
  6277.  
  6278.     info = packet_get_string(NULL);
  6279.     lang = packet_get_string(NULL);
  6280.     if (strlen(info) > 0)
  6281.         log("%s", info);
  6282.     free(info);
  6283.     free(lang);
  6284. #ifdef COMMENT
  6285.     /* This uses three separate prompts. */
  6286.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6287.     packet_put_cstring(authctxt->server_user);
  6288.     packet_put_cstring(authctxt->service);
  6289.     packet_put_cstring(authctxt->method->name);
  6290.     packet_put_char(1);            /* additional info */
  6291.     snprintf(prompt, sizeof(prompt),
  6292.               "Enter %.30s@%.128s's old password: ",
  6293.               authctxt->server_user, authctxt->host);
  6294.     ok = uq_txt(prompt,"Old Password: ",2,NULL,
  6295.                  password, sizeof(password),NULL,DEFAULT_UQ_TIMEOUT);
  6296.     packet_put_cstring(password);
  6297.     memset(password, 0, strlen(password));
  6298.     while (!password[0]) {
  6299.         snprintf(prompt, sizeof(prompt),
  6300.                   "Enter %.30s@%.128s's new password: ",
  6301.                   authctxt->server_user, authctxt->host);
  6302.         ok = uq_txt(prompt,"New Password: ",2,NULL,
  6303.                      password, sizeof(password),NULL,DEFAULT_UQ_TIMEOUT);
  6304.         if (!ok || !password[0])
  6305.             return 1;
  6306.         snprintf(prompt, sizeof(prompt),
  6307.                   "Retype %.30s@%.128s's new password: ",
  6308.                   authctxt->server_user, authctxt->host);
  6309.         ok = uq_txt(prompt,"Retype New Password: ",2,NULL,
  6310.                      retype, sizeof(retype),NULL,DEFAULT_UQ_TIMEOUT);
  6311.         if (!ok)
  6312.             return 1;
  6313.         if (strcmp(password, retype) != 0) {
  6314.             memset(password, 0, strlen(password));
  6315.             log("Mismatch; try again, EOF to quit.");
  6316.         }
  6317.         memset(retype, 0, strlen(retype));
  6318.     }
  6319.     packet_put_cstring(password);
  6320.     memset(password, 0, strlen(password));
  6321. #else
  6322.     memset(tb,0,sizeof(struct txtbox) * 3);
  6323.     tb[0].t_buf = oldpw;
  6324.     tb[0].t_len = 256;
  6325.     tb[0].t_lbl = "Old Password: ";
  6326.     tb[0].t_dflt = NULL;
  6327.     tb[0].t_echo = 2;
  6328.     tb[1].t_buf = newpw;
  6329.     tb[1].t_len = 256;
  6330.     tb[1].t_lbl = "New Password: ";
  6331.     tb[1].t_dflt = NULL;
  6332.     tb[1].t_echo = 2;
  6333.     tb[2].t_buf = retype;
  6334.     tb[2].t_len = 256;
  6335.     tb[2].t_lbl = "New Password (again): ";
  6336.     tb[2].t_dflt = NULL;
  6337.     tb[2].t_echo = 2;
  6338.  
  6339.     snprintf(prompt, sizeof(prompt),
  6340.               "Password Change Requested for %.30s@%.128s.",
  6341.               authctxt->server_user, authctxt->host);
  6342.     while ( !newpw[0] ) {
  6343.         ok = uq_mtxt(prompt,NULL,3,tb);
  6344.         if (!ok)
  6345.             return 1;
  6346.         if (strcmp(newpw, retype) != 0) {
  6347.             memset(newpw, 0, strlen(newpw));
  6348.             log("Mismatch; try again, EOF to quit.");
  6349.         }
  6350.         memset(retype, 0, strlen(retype));
  6351.     }
  6352.  
  6353.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6354.     packet_put_cstring(authctxt->server_user);
  6355.     packet_put_cstring(authctxt->service);
  6356.     packet_put_cstring(authctxt->method->name);
  6357.     packet_put_char(1);            /* additional info */
  6358.     packet_put_cstring(oldpw);
  6359.     memset(oldpw, 0, strlen(oldpw));
  6360.     packet_put_cstring(newpw);
  6361.     memset(newpw, 0, strlen(newpw));
  6362. #endif /* COMMENT */
  6363.     packet_add_padding(64);
  6364.     packet_send();
  6365.  
  6366.     dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, &input_userauth_passwd_changereq);
  6367.     return 1;
  6368. }
  6369.  
  6370. void
  6371. clear_auth_state(Authctxt *authctxt)
  6372. {
  6373.     /* XXX clear authentication state */
  6374.     dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
  6375.  
  6376. #ifdef GSSAPI
  6377.     dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, NULL);
  6378.     dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
  6379.     dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, NULL);
  6380. #endif 
  6381.  
  6382.     if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
  6383.         debug3("clear_auth_state: key_free %p", authctxt->last_key);
  6384.         key_free(authctxt->last_key);
  6385.     }
  6386.     authctxt->last_key = NULL;
  6387.     authctxt->last_key_hint = -2;
  6388.     authctxt->last_key_sign = NULL;
  6389. }
  6390.  
  6391. static int
  6392. sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
  6393. {
  6394.     Buffer b;
  6395.     u_char *blob, *signature;
  6396.     u_int bloblen, slen;
  6397.     int skip = 0;
  6398.     int ret = -1;
  6399.     int have_sig = 1;
  6400.  
  6401.     debug3("sign_and_send_pubkey");
  6402.  
  6403.     if (key_to_blob(k, &blob, &bloblen) == 0) {
  6404.         /* we cannot handle this key */
  6405.         debug3("sign_and_send_pubkey: cannot handle key");
  6406.         return 0;
  6407.     }
  6408.     memset(&b,0,sizeof(Buffer));
  6409.     /* data to be signed */
  6410.     buffer_init(&b);
  6411.     if (datafellows & SSH_OLD_SESSIONID) {
  6412.         buffer_append(&b, session_id2, session_id2_len);
  6413.         skip = session_id2_len;
  6414.     } else {
  6415.         buffer_put_string(&b, session_id2, session_id2_len);
  6416.         skip = buffer_len(&b);
  6417.     }
  6418.     buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
  6419.     buffer_put_cstring(&b, authctxt->server_user);
  6420.     buffer_put_cstring(&b,
  6421.                         datafellows & SSH_BUG_PKSERVICE ?
  6422.                         "ssh-userauth" :
  6423.                         authctxt->service);
  6424.     if (datafellows & SSH_BUG_PKAUTH) {
  6425.         buffer_put_char(&b, have_sig);
  6426.     } else {
  6427.         buffer_put_cstring(&b, authctxt->method->name);
  6428.         buffer_put_char(&b, have_sig);
  6429.         buffer_put_cstring(&b, key_ssh_name(k));
  6430.     }
  6431.     buffer_put_string(&b, blob, bloblen);
  6432.  
  6433.     /* generate signature */
  6434.     ret = (*sign_callback)(authctxt, k, &signature, &slen,
  6435.                             buffer_ptr(&b), buffer_len(&b));
  6436.     if (ret == -1) {
  6437.         free(blob);
  6438.         buffer_free(&b);
  6439.         return 0;
  6440.     }
  6441. #ifdef DEBUG_PK
  6442.     buffer_dump(&b);
  6443. #endif
  6444.     if (datafellows & SSH_BUG_PKSERVICE) {
  6445.         buffer_clear(&b);
  6446.         buffer_append(&b, session_id2, session_id2_len);
  6447.         skip = session_id2_len;
  6448.         buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
  6449.         buffer_put_cstring(&b, authctxt->server_user);
  6450.         buffer_put_cstring(&b, authctxt->service);
  6451.         buffer_put_cstring(&b, authctxt->method->name);
  6452.         buffer_put_char(&b, have_sig);
  6453.         if (!(datafellows & SSH_BUG_PKAUTH))
  6454.             buffer_put_cstring(&b, key_ssh_name(k));
  6455.         buffer_put_string(&b, blob, bloblen);
  6456.     }
  6457.     free(blob);
  6458.  
  6459.     /* append signature */
  6460.     buffer_put_string(&b, signature, slen);
  6461.     free(signature);
  6462.  
  6463.     /* skip session id and packet type */
  6464.     if (buffer_len(&b) < skip + 1) {
  6465.         fatal("userauth_pubkey: internal error");
  6466.         return -1;
  6467.     }
  6468.     buffer_consume(&b, skip + 1);
  6469.  
  6470.     /* put remaining data from buffer into packet */
  6471.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6472.     packet_put_raw(buffer_ptr(&b), buffer_len(&b));
  6473.     buffer_free(&b);
  6474.     packet_send();
  6475.  
  6476.     return 1;
  6477. }
  6478.  
  6479. static int
  6480. send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
  6481.     int hint)
  6482. {
  6483.     u_char *blob;
  6484.     u_int bloblen, have_sig = 0;
  6485.  
  6486.     debug3("send_pubkey_test");
  6487.  
  6488.     if (key_to_blob(k, &blob, &bloblen) == 0) {
  6489.         /* we cannot handle this key */
  6490.         debug3("send_pubkey_test: cannot handle key");
  6491.         return 0;
  6492.     }
  6493.     /* register callback for USERAUTH_PK_OK message */
  6494.     authctxt->last_key_sign = sign_callback;
  6495.     authctxt->last_key_hint = hint;
  6496.     authctxt->last_key = k;
  6497.     dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
  6498.  
  6499.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6500.     packet_put_cstring(authctxt->server_user);
  6501.     packet_put_cstring(authctxt->service);
  6502.     packet_put_cstring(authctxt->method->name);
  6503.     packet_put_char(have_sig);
  6504.     if (!(datafellows & SSH_BUG_PKAUTH))
  6505.         packet_put_cstring(key_ssh_name(k));
  6506.     packet_put_string(blob, bloblen);
  6507.     free(blob);
  6508.     packet_send();
  6509.     return 1;
  6510. }
  6511.  
  6512. static Key *
  6513. load_identity_file(char *filename)
  6514. {
  6515.     Key *private;
  6516.     char prompt[300], passphrase[256]="";
  6517.     int quit, i, ok;
  6518.     struct _stat st;
  6519.  
  6520.     if (stat(filename, &st) < 0) {
  6521.         debug3("no such identity: %s", filename);
  6522.         return NULL;
  6523.     }
  6524.     private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
  6525.     if (private == NULL) {
  6526.         if (options.batch_mode)
  6527.             return NULL;
  6528.         for (i = 0; i < options.number_of_password_prompts; i++) {
  6529.             if ( i == 0 && pwbuf[0] && pwflg ) {
  6530.                 ckstrncpy(passphrase,pwbuf,sizeof(passphrase));
  6531. #ifdef OS2
  6532.                 if ( pwcrypt )
  6533.                     ck_encrypt((char *)passphrase);
  6534. #endif /* OS2 */
  6535.                 ok = 1;
  6536.             } else {
  6537.                 snprintf(prompt, sizeof prompt,
  6538.                       "%sEnter passphrase for key '%.100s': ",
  6539.                       i == 0 ? "" : "Bad passphrase given, try again...\n",
  6540.                       filename);
  6541.                 ok = uq_txt(prompt,"Passphrase: ",2,NULL,
  6542.                              passphrase, sizeof(passphrase),NULL,DEFAULT_UQ_TIMEOUT);
  6543.             }
  6544.             if (ok && strcmp(passphrase, "") != 0) {
  6545.                 private = key_load_private_type(KEY_UNSPEC, filename,
  6546.                                                  passphrase, NULL);
  6547.                 quit = 0;
  6548.             } else {
  6549.                 debug2("no passphrase given, try next key");
  6550.                 quit = 1;
  6551.             }
  6552.             memset(passphrase, 0, strlen(passphrase));
  6553.             if (private != NULL || quit)
  6554.                 break;
  6555.             debug2("bad passphrase given, try again...");
  6556.         }
  6557.     }
  6558.     return private;
  6559. }
  6560.  
  6561. static int
  6562. identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
  6563.     u_char *data, u_int datalen)
  6564. {
  6565.     Key *private;
  6566.     int idx, ret;
  6567.  
  6568.     idx = authctxt->last_key_hint;
  6569.     if (idx < 0)
  6570.         return -1;
  6571.  
  6572.     /* private key is stored in external hardware */
  6573.     if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
  6574.         return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
  6575.  
  6576.     private = load_identity_file(options.identity_files[idx]);
  6577.     if (private == NULL)
  6578.         return -1;
  6579.     ret = key_sign(private, sigp, lenp, data, datalen);
  6580.     key_free(private);
  6581.     return ret;
  6582. }
  6583.  
  6584. static int
  6585. agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
  6586.     u_char *data, u_int datalen)
  6587. {
  6588.     return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
  6589. }
  6590.  
  6591. static int
  6592. key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
  6593.     u_char *data, u_int datalen)
  6594. {
  6595.     return key_sign(key, sigp, lenp, data, datalen);
  6596. }
  6597.  
  6598. static int
  6599. userauth_pubkey_agent(Authctxt *authctxt)
  6600. {
  6601.     int ret = 0;
  6602.     char *comment;
  6603.     Key *k;
  6604.  
  6605.     if (pubkey_agent_called == 0) {
  6606.         if (ssh_get_num_identities(authctxt->agent, 2) == 0)
  6607.             debug2("userauth_pubkey_agent: no keys at all");
  6608.         pubkey_agent_called = 1;
  6609.     }
  6610.     k = ssh_get_next_identity(authctxt->agent, &comment, 2);
  6611.     if (k == NULL) {
  6612.         debug1("userauth_pubkey_agent: no more keys");
  6613.     } else {
  6614.         debug1("Offering agent key %s", comment);
  6615.         free(comment);
  6616.         ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
  6617.         if (ret == 0)
  6618.             key_free(k);
  6619.     }
  6620.     if (ret == 0)
  6621.         debug2("userauth_pubkey_agent: no message sent");
  6622.     return ret;
  6623. }
  6624.  
  6625. int
  6626. userauth_pubkey(Authctxt *authctxt)
  6627. {
  6628.     int sent = 0;
  6629.     Key *key;
  6630.     char *filename;
  6631.  
  6632.     if (authctxt->agent != NULL) {
  6633.         do {
  6634.             sent = userauth_pubkey_agent(authctxt);
  6635.         } while(!sent && authctxt->agent->howmany > 0);
  6636.     }
  6637.     while (!sent && pubkey_idx < options.num_identity_files) {
  6638.         key = options.identity_keys[pubkey_idx];
  6639.         filename = options.identity_files[pubkey_idx];
  6640.         if (key == NULL) {
  6641.             debug1("Trying private key: %s", filename);
  6642.             key = load_identity_file(filename);
  6643.             if (key != NULL) {
  6644.                 sent = sign_and_send_pubkey(authctxt, key,
  6645.                                              key_sign_cb);
  6646.                 key_free(key)   ;
  6647.             }
  6648.         } else if (key->type != KEY_RSA1) {
  6649.             debug1("Offering public key: %s", filename);
  6650.             sent = send_pubkey_test(authctxt, key,
  6651.                                      identity_sign_cb, pubkey_idx);
  6652.         }
  6653.         pubkey_idx++;
  6654.     }
  6655.     return sent;
  6656. }
  6657.  
  6658. /*
  6659.  * Send userauth request message specifying keyboard-interactive method.
  6660.  */
  6661. int
  6662. userauth_kbdint(Authctxt *authctxt)
  6663. {
  6664.     if (kbdint_attempt++ >= options.number_of_password_prompts)
  6665.         return 0;
  6666.  
  6667.     /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
  6668.     if (kbdint_attempt > 1 && !authctxt->info_req_seen) {
  6669.         debug3("userauth_kbdint: disable: no info_req_seen");
  6670.         dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
  6671.         return 0;
  6672.     }
  6673.  
  6674.     debug2("userauth_kbdint");
  6675.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6676.     packet_put_cstring(authctxt->server_user);
  6677.     packet_put_cstring(authctxt->service);
  6678.     packet_put_cstring(authctxt->method->name);
  6679.     packet_put_cstring("");                                     /* lang */
  6680.     packet_put_cstring(options.kbd_interactive_devices ?
  6681.                         options.kbd_interactive_devices : "");
  6682.     packet_send();
  6683.  
  6684.     dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
  6685.     return 1;
  6686. }
  6687.  
  6688. /*
  6689.  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
  6690.  */
  6691. int
  6692. input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
  6693. {
  6694.     Authctxt *authctxt = ctxt;
  6695.     char *name, *inst, *lang, *prompt, response[256];
  6696.     u_int num_prompts, i;
  6697.     int echo = 0;
  6698.     struct txtbox * tb = NULL;
  6699.  
  6700.     debug2("input_userauth_info_req");
  6701.  
  6702.     if (authctxt == NULL) {
  6703.         fatal("input_userauth_info_req: no authentication context");
  6704.         return -1;
  6705.     }
  6706.  
  6707.     authctxt->info_req_seen = 1;
  6708.  
  6709.     name = packet_get_string(NULL);
  6710.     inst = packet_get_string(NULL);
  6711.     lang = packet_get_string(NULL);
  6712.     if (strlen(name) > 0)
  6713.         log("%s", name);
  6714.     if (strlen(inst) > 0)
  6715.         log("%s", inst);
  6716.     free(name);
  6717.     free(inst);
  6718.     free(lang);
  6719.  
  6720.     num_prompts = packet_get_int();
  6721.     /*
  6722.      * Begin to build info response packet based on prompts requested.
  6723.      * We commit to providing the correct number of responses, so if
  6724.      * further on we run into a problem that prevents this, we have to
  6725.      * be sure and clean this up and send a correct error response.
  6726.      */
  6727.     packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
  6728.     packet_put_int(num_prompts);
  6729.  
  6730.     debug2("input_userauth_info_req: num_prompts %d", num_prompts);
  6731.     if ( num_prompts == 1 && pwbuf[0] && pwflg ) {
  6732.         prompt = packet_get_string(NULL);
  6733.         echo = packet_get_char();
  6734.  
  6735.         ckstrncpy(response,pwbuf,sizeof(response));
  6736. #ifdef OS2
  6737.         if ( pwcrypt )
  6738.             ck_encrypt((char *)response);
  6739. #endif /* OS2 */
  6740.         
  6741.         packet_put_cstring(response);
  6742.         memset(response, 0, strlen(response));
  6743.         free(prompt);
  6744.     } else if (num_prompts > 0) {
  6745.         char preface[256];
  6746.         tb = (struct txtbox *) malloc(sizeof(struct txtbox) * num_prompts);
  6747.         if ( tb != NULL ) {
  6748.             int ok;
  6749.             memset(tb,0,sizeof(struct txtbox) * num_prompts);
  6750.             for ( i=0; i < num_prompts; i++ ) {
  6751.                 tb[i].t_buf = malloc(256);
  6752.                 tb[i].t_len = 256;
  6753.                 tb[i].t_lbl = packet_get_string(NULL);
  6754.                 tb[i].t_dflt = NULL;
  6755.                 tb[i].t_echo = (packet_get_char() ? 1 : 2);
  6756.             }
  6757.  
  6758.             ckmakmsg(preface,256,"SSH Input User Authentication for \"",
  6759.                      (char *)authctxt->local_user,"\"\n",NULL);
  6760.             ok = uq_mtxt(preface,NULL,num_prompts,tb);
  6761.  
  6762.             for ( i=0; i < num_prompts; i++ ) {
  6763.                 if (ok)
  6764.                     packet_put_cstring(tb[i].t_buf);
  6765.                 memset(tb[i].t_buf, 0, tb[i].t_len);
  6766.                 free(tb[i].t_lbl);
  6767.                 free(tb[i].t_buf);
  6768.             }
  6769.             free(tb);
  6770.         }
  6771.     }
  6772.  
  6773.     packet_check_eom(); /* done with parsing incoming message. */
  6774.  
  6775.     packet_add_padding(64);
  6776.     packet_send();
  6777.     return (0);
  6778. }
  6779.  
  6780. #ifdef UNIX
  6781. static int
  6782. ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
  6783.     u_char *data, u_int datalen)
  6784. {
  6785.     Buffer b;
  6786.     struct _stat st;
  6787.     pid_t pid;
  6788.     int to[2], from[2], status, version = 2;
  6789.  
  6790.     debug2("ssh_keysign called");
  6791.  
  6792.     if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
  6793.         error("ssh_keysign: no installed: %s", strerror(errno));
  6794.         return -1;
  6795.     }
  6796.     if (fflush(stdout) != 0)
  6797.         error("ssh_keysign: fflush: %s", strerror(errno));
  6798.     if (pipe(to) < 0) {
  6799.         error("ssh_keysign: pipe: %s", strerror(errno));
  6800.         return -1;
  6801.     }
  6802.     if (pipe(from) < 0) {
  6803.         error("ssh_keysign: pipe: %s", strerror(errno));
  6804.         return -1;
  6805.     }
  6806.     if ((pid = fork()) < 0) {
  6807.         error("ssh_keysign: fork: %s", strerror(errno));
  6808.         return -1;
  6809.     }
  6810.     if (pid == 0) {
  6811.         seteuid(getuid());
  6812.         setuid(getuid());
  6813.         close(from[0]);
  6814.         if (dup2(from[1], STDOUT_FILENO) < 0)
  6815.             fatal("ssh_keysign: dup2: %s", strerror(errno));
  6816.         close(to[1]);
  6817.         if (dup2(to[0], STDIN_FILENO) < 0)
  6818.             fatal("ssh_keysign: dup2: %s", strerror(errno));
  6819.         close(from[1]);
  6820.         close(to[0]);
  6821.         execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
  6822.         fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
  6823.             strerror(errno));
  6824.     }
  6825.     close(from[1]);
  6826.     close(to[0]);
  6827.  
  6828.     buffer_init(&b);
  6829.     buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
  6830.     buffer_put_string(&b, data, datalen);
  6831.     ssh_msg_send(to[1], version, &b);
  6832.  
  6833.     if (ssh_msg_recv(from[0], &b) < 0) {
  6834.         error("ssh_keysign: no reply");
  6835.         buffer_clear(&b);
  6836.         return -1;
  6837.     }
  6838.     close(from[0]);
  6839.     close(to[1]);
  6840.  
  6841.     while (waitpid(pid, &status, 0) < 0)
  6842.         if (errno != EINTR)
  6843.             break;
  6844.  
  6845.     if (buffer_get_char(&b) != version) {
  6846.         error("ssh_keysign: bad version");
  6847.         buffer_clear(&b);
  6848.         return -1;
  6849.     }
  6850.     *sigp = buffer_get_string(&b, lenp);
  6851.     buffer_clear(&b);
  6852.  
  6853.     return 0;
  6854. }
  6855. #endif /* UNIX */
  6856.  
  6857. int
  6858. userauth_hostbased(Authctxt *authctxt)
  6859. {
  6860.     Key *private = NULL;
  6861.     Sensitive * sensitive = authctxt->sensitive;
  6862.     Buffer b;
  6863.     u_char *signature, *blob;
  6864.     char *chost, *pkalg, *p;
  6865.     const char *service;
  6866.     u_int blen, slen;
  6867.     int ok, i, len, found = 0;
  6868.  
  6869.     /* check for a useful key */
  6870.     for (i = 0; i < sensitive->nkeys; i++) {
  6871.         private = sensitive->keys[i];
  6872.         if (private && private->type != KEY_RSA1) {
  6873.             found = 1;
  6874.             /* we take and free the key */
  6875.             sensitive->keys[i] = NULL;
  6876.             break;
  6877.         }
  6878.     }
  6879.     if (!found) {
  6880.         debug1("No more client hostkeys for hostbased authentication.");
  6881.         return 0;
  6882.     }
  6883.     if (key_to_blob(private, &blob, &blen) == 0) {
  6884.         key_free(private);
  6885.         return 0;
  6886.     }
  6887.     /* figure out a name for the client host */
  6888.     p = get_local_name(packet_get_connection_in());
  6889.     if (p == NULL) {
  6890.         error("userauth_hostbased: cannot get local ipaddr/name");
  6891.         key_free(private);
  6892.         return 0;
  6893.     }
  6894.     len = strlen(p) + 2;
  6895.     chost = malloc(len);
  6896.     strlcpy(chost, p, len);
  6897.     strlcat(chost, ".", len);
  6898.     free(p);
  6899.     debug2("userauth_hostbased: chost %s", chost);
  6900.  
  6901.     service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
  6902.         authctxt->service;
  6903.     pkalg = strdup(key_ssh_name(private));
  6904.     buffer_init(&b);
  6905.     /* construct data */
  6906.     buffer_put_string(&b, session_id2, session_id2_len);
  6907.     buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
  6908.     buffer_put_cstring(&b, authctxt->server_user);
  6909.     buffer_put_cstring(&b, service);
  6910.     buffer_put_cstring(&b, authctxt->method->name);
  6911.     buffer_put_cstring(&b, pkalg);
  6912.     buffer_put_string(&b, blob, blen);
  6913.     buffer_put_cstring(&b, chost);
  6914.     buffer_put_cstring(&b, authctxt->local_user);
  6915. #ifdef DEBUG_PK
  6916.     buffer_dump(&b);
  6917. #endif
  6918. #ifdef UNIX
  6919.     if ( sensitive->external_keysign )
  6920.         ok = ssh_keysign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
  6921.     else
  6922. #endif /* UNIX */
  6923.         ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
  6924.     key_free(private);
  6925.     buffer_free(&b);
  6926.     if (ok != 0) {
  6927.         error("key_sign failed");
  6928.         free(chost);
  6929.         free(pkalg);
  6930.         return 0;
  6931.     }
  6932.     packet_start(SSH2_MSG_USERAUTH_REQUEST);
  6933.     packet_put_cstring(authctxt->server_user);
  6934.     packet_put_cstring(authctxt->service);
  6935.     packet_put_cstring(authctxt->method->name);
  6936.     packet_put_cstring(pkalg);
  6937.     packet_put_string(blob, blen);
  6938.     packet_put_cstring(chost);
  6939.     packet_put_cstring(authctxt->local_user);
  6940.     packet_put_string(signature, slen);
  6941.     memset(signature, 's', slen);
  6942.     free(signature);
  6943.     free(chost);
  6944.     free(pkalg);
  6945.  
  6946.     packet_send();
  6947.     return 1;
  6948. }
  6949.  
  6950. /* find auth method */
  6951.  
  6952. /*
  6953.  * given auth method name, if configurable options permit this method fill
  6954.  * in auth_ident field and return true, otherwise return false.
  6955.  */
  6956. static int
  6957. authmethod_is_enabled(Authmethod *method)
  6958. {
  6959.     if (method == NULL)
  6960.         return 0;
  6961.     /* return false if options indicate this method is disabled */
  6962.     if  (method->enabled == NULL || *method->enabled == 0)
  6963.         return 0;
  6964.     /* return false if batch mode is enabled but method needs interactive mode */
  6965.     if  (method->batch_flag != NULL && *method->batch_flag != 0)
  6966.         return 0;
  6967.     return 1;
  6968. }
  6969.  
  6970. static Authmethod *
  6971. authmethod_lookup(const char *name)
  6972. {
  6973.     Authmethod *method = NULL;
  6974.     if (name != NULL)
  6975.         for (method = authmethods; method->name != NULL; method++)
  6976.             if (strcmp(name, method->name) == 0)
  6977.                 return method;
  6978.     debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
  6979.     return NULL;
  6980. }
  6981.  
  6982. /*
  6983.  * Given the authentication method list sent by the server, return the
  6984.  * next method we should try.  If the server initially sends a nil list,
  6985.  * use a built-in default list.
  6986.  */
  6987. static Authmethod *
  6988. authmethod_get(char *authlist)
  6989. {
  6990.  
  6991.     char *name = NULL;
  6992.     u_int next;
  6993.  
  6994.     /* Use a suitable default if we're passed a nil list.  */
  6995.     if (authlist == NULL || strlen(authlist) == 0)
  6996.         authlist = options.preferred_authentications;
  6997.  
  6998.     if (supported == NULL || strcmp(authlist, supported) != 0) {
  6999.         debug3("start over, passed a different list %s", authlist);
  7000.         if (supported != NULL)
  7001.             free(supported);
  7002.         supported = strdup(authlist);
  7003.         preferred = options.preferred_authentications;
  7004.         debug3("preferred %s", preferred);
  7005.         current = NULL;
  7006.     } else if (current != NULL && authmethod_is_enabled(current))
  7007.         return current;
  7008.  
  7009.     for (;;) {
  7010.         if ((name = match_list(preferred, supported, &next)) == NULL) {
  7011.             debug1("No more authentication methods to try.");
  7012.             current = NULL;
  7013.             return NULL;
  7014.         }
  7015.         preferred += next;
  7016.         debug3("authmethod_lookup %s", name);
  7017.         debug3("remaining preferred: %s", preferred);
  7018.         if ((current = authmethod_lookup(name)) != NULL &&
  7019.              authmethod_is_enabled(current)) {
  7020.             debug3("authmethod_is_enabled %s", name);
  7021.             debug1("Next authentication method: %s", name);
  7022.             return current;
  7023.         }
  7024.     }
  7025.     /* NOT REACHED */
  7026. }
  7027.  
  7028.  
  7029. static char *
  7030. authmethods_get(void)
  7031. {
  7032.     Authmethod *method = NULL;
  7033.     Buffer b;
  7034.     char *list;
  7035.  
  7036.     memset(&b,0,sizeof(Buffer));
  7037.     buffer_init(&b);
  7038.     for (method = authmethods; method->name != NULL; method++) {
  7039.         if (authmethod_is_enabled(method)) {
  7040.             if ( buffer_len(&b) > 0 )
  7041.                 buffer_append(&b, ",", 1);
  7042.             buffer_append(&b, method->name, strlen(method->name));
  7043.         }
  7044.     }
  7045.     buffer_append(&b, "\0", 1);
  7046.     list = strdup(buffer_ptr(&b));
  7047.     buffer_free(&b);
  7048.     return list;
  7049. }
  7050.  
  7051. /* Format of the configuration file:
  7052.  
  7053.    # Configuration data is parsed as follows:
  7054.    #  1. command line options
  7055.    #  2. user-specific file
  7056.    #  3. system-wide file
  7057.    # Any configuration value is only changed the first time it is set.
  7058.    # Thus, host-specific definitions should be at the beginning of the
  7059.    # configuration file, and defaults at the end.
  7060.  
  7061.    # Host-specific declarations.  These may override anything above.  A single
  7062.    # host may match multiple declarations; these are processed in the order
  7063.    # that they are given in.
  7064.  
  7065.    Host *.ngs.fi ngs.fi
  7066.      User foo
  7067.  
  7068.    Host fake.com
  7069.      HostName another.host.name.real.org
  7070.      User blaah
  7071.      Port 34289
  7072.      ForwardX11 no
  7073.      ForwardAgent no
  7074.  
  7075.    Host books.com
  7076.      RemoteForward 9999 shadows.cs.hut.fi:9999
  7077.      Cipher 3des
  7078.  
  7079.    Host fascist.blob.com
  7080.      Port 23123
  7081.      User tylonen
  7082.      RhostsAuthentication no
  7083.      PasswordAuthentication no
  7084.  
  7085.    Host puukko.hut.fi
  7086.      User t35124p
  7087.      ProxyCommand ssh-proxy %h %p
  7088.  
  7089.    Host *.fr
  7090.      PublicKeyAuthentication no
  7091.  
  7092.    Host *.su
  7093.      Cipher none
  7094.      PasswordAuthentication no
  7095.  
  7096.    # Defaults for various options
  7097.    Host *
  7098.      ForwardAgent no
  7099.      ForwardX11 no
  7100.      RhostsAuthentication yes
  7101.      PasswordAuthentication yes
  7102.      RSAAuthentication yes
  7103.      RhostsRSAAuthentication yes
  7104.      StrictHostKeyChecking yes
  7105.      KeepAlives no
  7106.      IdentityFile ~/.ssh/identity
  7107.      Port 22
  7108.      EscapeChar ~
  7109.  
  7110. */
  7111.  
  7112. /* Keyword tokens. */
  7113.  
  7114. typedef enum {
  7115.         oBadOption,
  7116.         oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
  7117.         oPasswordAuthentication, oRSAAuthentication,
  7118.         oChallengeResponseAuthentication, oXAuthLocation,
  7119. #if defined(KRB4)
  7120.         oKrb4Authentication,
  7121. #endif /* KRB4 */
  7122. #if defined(KRB5)
  7123.         oKrb5Authentication,
  7124. #endif /* KRB5 */
  7125. #ifdef GSSAPI
  7126.         oGssAuthentication, oGssDelegateCreds,
  7127. #ifdef GSI
  7128.         oGssGlobusDelegateLimitedCreds,
  7129. #endif /* GSI */
  7130. #endif /* GSSAPI */
  7131. #if defined(AFS) || defined(KRB5)
  7132.         oKerberosTgtPassing,
  7133. #endif
  7134. #ifdef AFS
  7135.         oAFSTokenPassing,
  7136. #endif
  7137. #ifdef SRP
  7138.         oSRPAuthentication,
  7139. #endif
  7140.         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
  7141.         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
  7142.         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
  7143.         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
  7144.         oCompressionLevel, oKeepAlives, oHeartbeat, oNumberOfPasswordPrompts,
  7145.         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
  7146.         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
  7147.         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
  7148.         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
  7149.         oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
  7150.         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
  7151.         oEnableSSHKeysign, 
  7152.         oDeprecated
  7153. } OpCodes;
  7154.  
  7155. /* Textual representations of the tokens. */
  7156.  
  7157. static struct {
  7158.         const char *name;
  7159.         OpCodes opcode;
  7160. } keywords[] = {
  7161.         { "forwardagent", oForwardAgent },
  7162.         { "forwardx11", oForwardX11 },
  7163.         { "xauthlocation", oXAuthLocation },
  7164.         { "gatewayports", oGatewayPorts },
  7165.         { "useprivilegedport", oUsePrivilegedPort },
  7166.         { "rhostsauthentication", oRhostsAuthentication },
  7167.         { "passwordauthentication", oPasswordAuthentication },
  7168.         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
  7169.         { "kbdinteractivedevices", oKbdInteractiveDevices },
  7170.         { "rsaauthentication", oRSAAuthentication },
  7171.         { "pubkeyauthentication", oPubkeyAuthentication },
  7172.         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
  7173.         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
  7174.         { "hostbasedauthentication", oHostbasedAuthentication },
  7175.         { "challengeresponseauthentication", oChallengeResponseAuthentication },
  7176.         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
  7177.         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
  7178. #if defined(KRB4)
  7179.         { "krb4authentication", oKrb4Authentication },
  7180. #endif /* KRB4 */
  7181. #if defined(KRB5)
  7182.         { "krb5authentication", oKrb5Authentication },
  7183. #endif /* KRB5 */
  7184. #ifdef GSSAPI
  7185.         { "gssapiauthentication", oGssAuthentication },
  7186.         { "gssapidelegatecredentials", oGssDelegateCreds },
  7187. #ifdef GSI
  7188.         /* For backwards compatability with old 1.2.27 client code */
  7189.         { "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */
  7190.         { "forwardgssapiglobuslimitedproxy", oGssGlobusDelegateLimitedCreds },
  7191. #endif /* GSI */
  7192. #endif /* GSSAPI */
  7193. #if defined(AFS) || defined(KRB5)
  7194.         { "kerberostgtpassing", oKerberosTgtPassing },
  7195. #endif
  7196. #ifdef AFS
  7197.         { "afstokenpassing", oAFSTokenPassing },
  7198. #endif
  7199. #ifdef SRP
  7200.         { "srpauthentication", oSRPAuthentication },
  7201. #endif
  7202.         { "fallbacktorsh", oDeprecated },
  7203.         { "usersh", oDeprecated },
  7204.         { "identityfile", oIdentityFile },
  7205.         { "identityfile2", oIdentityFile },                     /* alias */
  7206.         { "hostname", oHostName },
  7207.         { "hostkeyalias", oHostKeyAlias },
  7208.         { "proxycommand", oProxyCommand },
  7209.         { "port", oPort },
  7210.         { "cipher", oCipher },
  7211.         { "ciphers", oCiphers },
  7212.         { "macs", oMacs },
  7213.         { "protocol", oProtocol },
  7214.         { "remoteforward", oRemoteForward },
  7215.         { "localforward", oLocalForward },
  7216.         { "user", oUser },
  7217.         { "host", oHost },
  7218.         { "escapechar", oEscapeChar },
  7219.         { "globalknownhostsfile", oGlobalKnownHostsFile },
  7220.         { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
  7221.         { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
  7222.         { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
  7223.         { "connectionattempts", oConnectionAttempts },
  7224.         { "batchmode", oBatchMode },
  7225.         { "checkhostip", oCheckHostIP },
  7226.         { "stricthostkeychecking", oStrictHostKeyChecking },
  7227.         { "compression", oCompression },
  7228.         { "compressionlevel", oCompressionLevel },
  7229.         { "keepalive", oKeepAlives },
  7230.         { "heartbeat", oHeartbeat },
  7231.         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
  7232.         { "loglevel", oLogLevel },
  7233.         { "dynamicforward", oDynamicForward },
  7234.         { "preferredauthentications", oPreferredAuthentications },
  7235.         { "hostkeyalgorithms", oHostKeyAlgorithms },
  7236.         { "bindaddress", oBindAddress },
  7237.         { "smartcarddevice", oSmartcardDevice },
  7238.         { "clearallforwardings", oClearAllForwardings },
  7239.         { "enablesshkeysign", oEnableSSHKeysign },
  7240.         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
  7241.         { NULL, oBadOption }
  7242. };
  7243.  
  7244. /*
  7245.  * Adds a local TCP/IP port forward to options.  Never returns if there is an
  7246.  * error.
  7247.  */
  7248.  
  7249. int
  7250. add_local_forward(Options *options, u_short port, const char *host,
  7251.                   u_short host_port)
  7252. {
  7253.     Forward *fwd;
  7254.  
  7255.     if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) {
  7256.         fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
  7257.         return -1;
  7258.     }
  7259.     fwd = &options->local_forwards[options->num_local_forwards++];
  7260.     fwd->port = port;
  7261.     fwd->host = strdup(host);
  7262.     fwd->host_port = host_port;
  7263.     return 0;
  7264. }
  7265.  
  7266. /*
  7267.  * Adds a remote TCP/IP port forward to options.  Never returns if there is
  7268.  * an error.
  7269.  */
  7270.  
  7271. int
  7272. add_remote_forward(Options *options, u_short port, const char *host,
  7273.                    u_short host_port)
  7274. {
  7275.     Forward *fwd;
  7276.     if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) {
  7277.         fatal("Too many remote forwards (max %d).",
  7278.                SSH_MAX_FORWARDS_PER_DIRECTION);
  7279.         return -1;
  7280.     }
  7281.     fwd = &options->remote_forwards[options->num_remote_forwards++];
  7282.     fwd->port = port;
  7283.     fwd->host = strdup(host);
  7284.     fwd->host_port = host_port;
  7285.     return 0;
  7286. }
  7287.  
  7288. static void
  7289. clear_forwardings(Options *options)
  7290. {
  7291.     int i;
  7292.  
  7293.     for (i = 0; i < options->num_local_forwards; i++)
  7294.         free(options->local_forwards[i].host);
  7295.     options->num_local_forwards = 0;
  7296.     for (i = 0; i < options->num_remote_forwards; i++)
  7297.         free(options->remote_forwards[i].host);
  7298.     options->num_remote_forwards = 0;
  7299. }
  7300.  
  7301. /*
  7302.  * Returns the number of the token pointed to by cp or oBadOption.
  7303.  */
  7304.  
  7305. static OpCodes
  7306. parse_token(const char *cp, const char *filename, int linenum)
  7307. {
  7308.     u_int i;
  7309.  
  7310.     for (i = 0; keywords[i].name; i++)
  7311.         if (strcasecmp(cp, keywords[i].name) == 0)
  7312.             return keywords[i].opcode;
  7313.  
  7314.     error("%s: line %d: Bad configuration option: %s",
  7315.            filename, linenum, cp);
  7316.     return oBadOption;
  7317. }
  7318.  
  7319. /*
  7320.  * Processes a single option line as used in the configuration files. This
  7321.  * only sets those values that have not already been set.
  7322.  */
  7323.  
  7324. #define WHITESPACE " \t\r\n"
  7325.  
  7326. int
  7327. process_config_line(Options *options, const char *host,
  7328.                     char *line, const char *filename, int linenum,
  7329.                     int *activep)
  7330. {
  7331.     char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
  7332.     int opcode, *intptr, value;
  7333.     size_t len;
  7334.     u_short fwd_port, fwd_host_port;
  7335.     char sfwd_host_port[6];
  7336.  
  7337.     s = line;
  7338.     /* Get the keyword. (Each line is supposed to begin with a keyword). */
  7339.     keyword = strdelim(&s);
  7340.     /* Ignore leading whitespace. */
  7341.     if (*keyword == '\0')
  7342.         keyword = strdelim(&s);
  7343.     if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
  7344.         return 0;
  7345.  
  7346.     opcode = parse_token(keyword, filename, linenum);
  7347.  
  7348.     switch (opcode) {
  7349.     case oBadOption:
  7350.         /* don't panic, but count bad options */
  7351.         return -1;
  7352.         /* NOTREACHED */
  7353.     case oForwardAgent:
  7354.         intptr = &options->forward_agent;
  7355.       parse_flag:
  7356.         arg = strdelim(&s);
  7357.         if (!arg || *arg == '\0') {
  7358.             fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
  7359.             return -1;
  7360.         }
  7361.         value = 0;      /* To avoid compiler warning... */
  7362.         if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
  7363.             value = 1;
  7364.         else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
  7365.             value = 0;
  7366.         else
  7367.             fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
  7368.         if (*activep && *intptr == -1)
  7369.             *intptr = value;
  7370.         break;
  7371.  
  7372.     case oForwardX11:
  7373.         intptr = &options->forward_x11;
  7374.         goto parse_flag;
  7375.  
  7376.     case oGatewayPorts:
  7377.         intptr = &options->gateway_ports;
  7378.         goto parse_flag;
  7379.  
  7380.     case oUsePrivilegedPort:
  7381.         intptr = &options->use_privileged_port;
  7382.         goto parse_flag;
  7383.  
  7384.     case oRhostsAuthentication:
  7385.         intptr = &options->rhosts_authentication;
  7386.         goto parse_flag;
  7387.  
  7388.     case oPasswordAuthentication:
  7389.         intptr = &options->password_authentication;
  7390.         goto parse_flag;
  7391.  
  7392.         case oKbdInteractiveAuthentication:
  7393.         intptr = &options->kbd_interactive_authentication;
  7394.         goto parse_flag;
  7395.  
  7396.     case oKbdInteractiveDevices:
  7397.         charptr = &options->kbd_interactive_devices;
  7398.         goto parse_string;
  7399.  
  7400.     case oPubkeyAuthentication:
  7401.         intptr = &options->pubkey_authentication;
  7402.         goto parse_flag;
  7403.  
  7404.     case oRSAAuthentication:
  7405.         intptr = &options->rsa_authentication;
  7406.         goto parse_flag;
  7407.  
  7408.     case oRhostsRSAAuthentication:
  7409.         intptr = &options->rhosts_rsa_authentication;
  7410.         goto parse_flag;
  7411.  
  7412.     case oHostbasedAuthentication:
  7413.         intptr = &options->hostbased_authentication;
  7414.         goto parse_flag;
  7415.  
  7416.     case oChallengeResponseAuthentication:
  7417.         intptr = &options->challenge_response_authentication;
  7418.         goto parse_flag;
  7419.  
  7420. #if defined (KRB4)
  7421.     case oKrb4Authentication:
  7422.         intptr = &options->krb4_authentication;
  7423.         goto parse_flag;
  7424. #endif /* KRB4 / KRB5 */
  7425.  
  7426. #if defined(KRB5)
  7427.     case oKrb5Authentication:
  7428.         intptr = &options->krb5_authentication;
  7429.         goto parse_flag;
  7430. #endif /* KRB4 / KRB5 */
  7431.  
  7432. #ifdef GSSAPI
  7433.     case oGssAuthentication:
  7434.         intptr = &options->gss_authentication;
  7435.         goto parse_flag;
  7436.  
  7437.     case oGssDelegateCreds:
  7438.         intptr = &options->gss_deleg_creds;
  7439.         goto parse_flag;
  7440.  
  7441. #ifdef GSI
  7442.     case oGssGlobusDelegateLimitedCreds:
  7443.         intptr = &options->gss_globus_deleg_limited_proxy;
  7444.         goto parse_flag;
  7445. #endif /* GSI */
  7446. #endif /* GSSAPI */
  7447.  
  7448. #if defined(AFS) || defined(KRB5)
  7449.     case oKerberosTgtPassing:
  7450.         intptr = &options->kerberos_tgt_passing;
  7451.         goto parse_flag;
  7452. #endif
  7453. #ifdef AFS
  7454.     case oAFSTokenPassing:
  7455.         intptr = &options->afs_token_passing;
  7456.         goto parse_flag;
  7457. #endif
  7458.  
  7459. #ifdef SRP
  7460.     case oSRPAuthentication:
  7461.         intptr = &options->srp_authentication;
  7462.         goto parse_flag;
  7463. #endif
  7464.  
  7465.     case oBatchMode:
  7466.         intptr = &options->batch_mode;
  7467.         goto parse_flag;
  7468.  
  7469.     case oCheckHostIP:
  7470.         intptr = &options->check_host_ip;
  7471.         goto parse_flag;
  7472.  
  7473.     case oStrictHostKeyChecking:
  7474.         intptr = &options->strict_host_key_checking;
  7475.         arg = strdelim(&s);
  7476.         if (!arg || *arg == '\0') {
  7477.             fatal("%.200s line %d: Missing yes/no/ask argument.",
  7478.                    filename, linenum);
  7479.             return -1;
  7480.         }
  7481.         value = 0;      /* To avoid compiler warning... */
  7482.         if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
  7483.             value = 1;
  7484.         else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
  7485.             value = 0;
  7486.         else if (strcmp(arg, "ask") == 0)
  7487.             value = 2;
  7488.         else {
  7489.             fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
  7490.             return -1;
  7491.         }
  7492.         if (*activep && *intptr == -1)
  7493.             *intptr = value;
  7494.         break;
  7495.  
  7496.     case oCompression:
  7497.         intptr = &options->compression;
  7498.         goto parse_flag;
  7499.  
  7500.     case oKeepAlives:
  7501.         intptr = &options->keepalives;
  7502.         goto parse_flag;
  7503.  
  7504.     case oHeartbeat:
  7505.         intptr = &options->heartbeat_interval;
  7506.         goto parse_flag;
  7507.  
  7508.     case oNumberOfPasswordPrompts:
  7509.         intptr = &options->number_of_password_prompts;
  7510.         goto parse_int;
  7511.  
  7512.     case oCompressionLevel:
  7513.         intptr = &options->compression_level;
  7514.         goto parse_int;
  7515.  
  7516.     case oIdentityFile:
  7517.         arg = strdelim(&s);
  7518.         if (!arg || *arg == '\0') {
  7519.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7520.             return -1;
  7521.         }
  7522.         if (*activep) {
  7523.             intptr = &options->num_identity_files;
  7524.             if (*intptr >= SSH_MAX_IDENTITY_FILES)
  7525.                 fatal("%.200s line %d: Too many identity files specified (max %d).",
  7526.                        filename, linenum, SSH_MAX_IDENTITY_FILES);
  7527.             charptr =  &options->identity_files[*intptr];
  7528.             *charptr = strdup(arg);
  7529.             *intptr = *intptr + 1;
  7530.         }
  7531.         break;
  7532.  
  7533.     case oXAuthLocation:
  7534.         charptr=&options->xauth_location;
  7535.         goto parse_string;
  7536.  
  7537.     case oUser:
  7538.         charptr = &options->user;
  7539.       parse_string:
  7540.         arg = strdelim(&s);
  7541.         if (!arg || *arg == '\0') {
  7542.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7543.             return -1;
  7544.         }
  7545.         if (*activep && *charptr == NULL)
  7546.             *charptr = strdup(arg);
  7547.         break;
  7548.  
  7549.     case oGlobalKnownHostsFile:
  7550.         charptr = &options->system_hostfile;
  7551.         goto parse_string;
  7552.  
  7553.     case oUserKnownHostsFile:
  7554.         charptr = &options->user_hostfile;
  7555.         goto parse_string;
  7556.  
  7557.     case oGlobalKnownHostsFile2:
  7558.         charptr = &options->system_hostfile2;
  7559.         goto parse_string;
  7560.  
  7561.     case oUserKnownHostsFile2:
  7562.         charptr = &options->user_hostfile2;
  7563.         goto parse_string;
  7564.  
  7565.     case oHostName:
  7566.         charptr = &options->hostname;
  7567.         goto parse_string;
  7568.  
  7569.     case oHostKeyAlias:
  7570.         charptr = &options->host_key_alias;
  7571.         goto parse_string;
  7572.  
  7573.     case oPreferredAuthentications:
  7574.         charptr = &options->preferred_authentications;
  7575.         goto parse_string;
  7576.  
  7577.     case oBindAddress:
  7578.         charptr = &options->bind_address;
  7579.         goto parse_string;
  7580.  
  7581.     case oSmartcardDevice:
  7582.         charptr = &options->smartcard_device;
  7583.         goto parse_string;
  7584.  
  7585.     case oProxyCommand:
  7586.         charptr = &options->proxy_command;
  7587.         len = strspn(s, WHITESPACE "=");
  7588.         if (*activep && *charptr == NULL)
  7589.             *charptr = strdup(s + len);
  7590.         return 0;
  7591.  
  7592.     case oPort:
  7593.         intptr = &options->port;
  7594.       parse_int:
  7595.         arg = strdelim(&s);
  7596.         if (!arg || *arg == '\0') {
  7597.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7598.             return -1;
  7599.         }
  7600.         if (arg[0] < '0' || arg[0] > '9') {
  7601.             fatal("%.200s line %d: Bad number.", filename, linenum);
  7602.             return -1;
  7603.         }
  7604.  
  7605.         /* Octal, decimal, or hex format? */
  7606.         value = strtol(arg, &endofnumber, 0);
  7607.         if (arg == endofnumber) {
  7608.             fatal("%.200s line %d: Bad number.", filename, linenum);
  7609.             return -1;
  7610.         }
  7611.         if (*activep && *intptr == -1)
  7612.             *intptr = value;
  7613.         break;
  7614.  
  7615.     case oConnectionAttempts:
  7616.         intptr = &options->connection_attempts;
  7617.         goto parse_int;
  7618.  
  7619.     case oCipher:
  7620.         intptr = &options->cipher;
  7621.         arg = strdelim(&s);
  7622.         if (!arg || *arg == '\0') {
  7623.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7624.             return -1;
  7625.         }
  7626.         value = cipher_number(arg);
  7627.         if (value == -1) {
  7628.             fatal("%.200s line %d: Bad cipher '%s'.",
  7629.                    filename, linenum, arg ? arg : "<NONE>");
  7630.             return -1;
  7631.         }
  7632.         if (*activep && *intptr == -1)
  7633.             *intptr = value;
  7634.         break;
  7635.  
  7636.     case oCiphers:
  7637.         arg = strdelim(&s);
  7638.         if (!arg || *arg == '\0') {
  7639.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7640.             return -1;
  7641.         }
  7642.         if (!ciphers_valid(arg)) {
  7643.             fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
  7644.                               filename, linenum, arg ? arg : "<NONE>");
  7645.             return -1;
  7646.         }
  7647.         if (*activep && options->ciphers == NULL)
  7648.             options->ciphers = strdup(arg);
  7649.         break;
  7650.  
  7651.     case oMacs:
  7652.         arg = strdelim(&s);
  7653.         if (!arg || *arg == '\0') {
  7654.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7655.             return -1;
  7656.         }
  7657.         if (!mac_valid(arg)) {
  7658.             fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
  7659.                    filename, linenum, arg ? arg : "<NONE>");
  7660.             return -1;
  7661.         }
  7662.         if (*activep && options->macs == NULL)
  7663.             options->macs = strdup(arg);
  7664.         break;
  7665.  
  7666.     case oHostKeyAlgorithms:
  7667.         arg = strdelim(&s);
  7668.         if (!arg || *arg == '\0') {
  7669.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7670.             return -1;
  7671.         }
  7672.         if (!key_names_valid2(arg)) {
  7673.             fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
  7674.                               filename, linenum, arg ? arg : "<NONE>");
  7675.             return -1;
  7676.         }
  7677.         if (*activep && options->hostkeyalgorithms == NULL)
  7678.             options->hostkeyalgorithms = strdup(arg);
  7679.         break;
  7680.  
  7681.     case oProtocol:
  7682.         intptr = &options->protocol;
  7683.         arg = strdelim(&s);
  7684.         if (!arg || *arg == '\0') {
  7685.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7686.             return -1;
  7687.         }
  7688.         value = proto_spec(arg);
  7689.         if (value == SSH_PROTO_UNKNOWN) {
  7690.             fatal("%.200s line %d: Bad protocol spec '%s'.",
  7691.                               filename, linenum, arg ? arg : "<NONE>");
  7692.             return -1;
  7693.         }
  7694.         if (*activep && *intptr == SSH_PROTO_UNKNOWN)
  7695.             *intptr = value;
  7696.         break;
  7697.  
  7698.     case oLogLevel:
  7699.         intptr = (int *) &options->log_level;
  7700.         arg = strdelim(&s);
  7701.         value = log_level_number(arg);
  7702.         if (value == SYSLOG_LEVEL_NOT_SET) {
  7703.             fatal("%.200s line %d: unsupported log level '%s'",
  7704.                               filename, linenum, arg ? arg : "<NONE>");
  7705.             return -1;
  7706.         }
  7707.         if (*activep && (LogLevel) * intptr == SYSLOG_LEVEL_NOT_SET)
  7708.             *intptr = (LogLevel) value;
  7709.         break;
  7710.  
  7711.     case oLocalForward:
  7712.     case oRemoteForward:
  7713.         arg = strdelim(&s);
  7714.         if (!arg || *arg == '\0')
  7715.             fatal("%.200s line %d: Missing port argument.",
  7716.                    filename, linenum);
  7717.         if ((fwd_port = a2port(arg)) == 0)
  7718.             fatal("%.200s line %d: Bad listen port.",
  7719.                    filename, linenum);
  7720.         arg = strdelim(&s);
  7721.         if (!arg || *arg == '\0')
  7722.             fatal("%.200s line %d: Missing second argument.",
  7723.                    filename, linenum);
  7724.         if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
  7725.              sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
  7726.             fatal("%.200s line %d: Bad forwarding specification.",
  7727.                    filename, linenum);
  7728.         if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
  7729.             fatal("%.200s line %d: Bad forwarding port.",
  7730.                    filename, linenum);
  7731.         if (*activep) {
  7732.             if (opcode == oLocalForward)
  7733.                 add_local_forward(options, fwd_port, buf,
  7734.                                    fwd_host_port);
  7735.             else if (opcode == oRemoteForward)
  7736.                 add_remote_forward(options, fwd_port, buf,
  7737.                                     fwd_host_port);
  7738.                 }
  7739.                 break;
  7740.  
  7741.     case oDynamicForward:
  7742.         arg = strdelim(&s);
  7743.         if (!arg || *arg == '\0') {
  7744.             fatal("%.200s line %d: Missing port argument.",
  7745.                    filename, linenum);
  7746.             return -1;
  7747.         }
  7748.         fwd_port = a2port(arg);
  7749.         if (fwd_port == 0) {
  7750.             fatal("%.200s line %d: Badly formatted port number.",
  7751.                    filename, linenum);
  7752.             return -1;
  7753.         }
  7754.         add_local_forward(options, fwd_port, "socks4", 0);
  7755.         break;
  7756.  
  7757.     case oClearAllForwardings:
  7758.         intptr = &options->clear_forwardings;
  7759.         goto parse_flag;
  7760.  
  7761.     case oHost:
  7762.         *activep = 0;
  7763.         while ((arg = strdelim(&s)) != NULL && *arg != '\0')
  7764.             if (match_pattern(host, arg)) {
  7765.                 debug1("Applying options for %s", arg);
  7766.                 *activep = 1;
  7767.                 break;
  7768.             }
  7769.         /* Avoid garbage check below, as strdelim is done. */
  7770.         return 0;
  7771.  
  7772.     case oEscapeChar:
  7773.         intptr = &options->escape_char;
  7774.         arg = strdelim(&s);
  7775.         if (!arg || *arg == '\0') {
  7776.             fatal("%.200s line %d: Missing argument.", filename, linenum);
  7777.             return -1;
  7778.         }
  7779.         if (arg[0] == '^' && arg[2] == 0 &&
  7780.              (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
  7781.             value = (u_char) arg[1] & 31;
  7782.         else if (strlen(arg) == 1)
  7783.             value = (u_char) arg[0];
  7784.         else if (strcmp(arg, "none") == 0)
  7785.             value = -2;
  7786.         else {
  7787.             fatal("%.200s line %d: Bad escape character.",
  7788.                    filename, linenum);
  7789.             value = 0;  /* Avoid compiler warning. */
  7790.             return -1;
  7791.         }
  7792.         if (*activep && *intptr == -1)
  7793.             *intptr = value;
  7794.         break;
  7795.  
  7796.     case oEnableSSHKeysign:
  7797.         intptr = &options->enable_ssh_keysign;
  7798.         goto parse_flag;
  7799.  
  7800.     case oDeprecated:
  7801.         debug1("%s line %d: Deprecated option \"%s\"",
  7802.                filename, linenum, keyword);
  7803.         return 0;
  7804.  
  7805.     default:
  7806.         fatal("process_config_line: Unimplemented opcode %d", opcode);
  7807.         return -1;
  7808.     }
  7809.  
  7810.     /* Check that there is no garbage at end of line. */
  7811.     if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
  7812.         fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
  7813.                filename, linenum, arg);
  7814.         return -1;
  7815.     }
  7816.     return 0;
  7817. }
  7818.  
  7819.  
  7820. /*
  7821.  * Reads the config file and modifies the options accordingly.  Options
  7822.  * should already be initialized before this call.  This never returns if
  7823.  * there is an error.  If the file does not exist, this returns immediately.
  7824.  */
  7825.  
  7826. int
  7827. read_config_file(const char *filename, const char *host, Options *options)
  7828. {
  7829.     FILE *f;
  7830.     char line[1024];
  7831.     int active, linenum;
  7832.     int bad_options = 0;
  7833.  
  7834.     /* Open the file. */
  7835.     f = fopen(filename, "r");
  7836.     if (!f)
  7837.         return 0;
  7838.  
  7839.     debug1("Reading configuration data from %s", filename);
  7840.  
  7841.     /*
  7842.      * Mark that we are now processing the options.  This flag is turned
  7843.      * on/off by Host specifications.
  7844.      */
  7845.     active = 1;
  7846.     linenum = 0;
  7847.     while (fgets(line, sizeof(line), f)) {
  7848.         /* Update line number counter. */
  7849.         linenum++;
  7850.         if (process_config_line(options, host, line, filename, linenum, &active) != 0)
  7851.             bad_options++;
  7852.     }
  7853.     fclose(f);
  7854.     if (bad_options > 0) {
  7855.         fatal("%s: terminating, %d bad configuration options",
  7856.                filename, bad_options);
  7857.         return -1;
  7858.     }
  7859.     return 0;
  7860. }
  7861.  
  7862. /*
  7863.  * Initializes options to special values that indicate that they have not yet
  7864.  * been set.  Read_config_file will only set options with this value. Options
  7865.  * are processed in the following order: command line, user config file,
  7866.  * system config file.  Last, fill_default_options is called.
  7867.  */
  7868.  
  7869. void
  7870. initialize_options(Options * options)
  7871. {
  7872.     int i;
  7873.  
  7874.     memset(options,0,sizeof(Options));
  7875.     for ( i=0; i < SSH_MAX_IDENTITY_FILES ; i++ ) {
  7876.         options->identity_files[i] = NULL;
  7877.         options->identity_keys[i] = NULL;
  7878.     }
  7879.     for ( i=0 ; i < SSH_MAX_FORWARDS_PER_DIRECTION ; i++ ) {
  7880.         options->local_forwards[i].port = 0;
  7881.         options->local_forwards[i].host = NULL;
  7882.         options->local_forwards[i].host_port = 0;
  7883.         options->remote_forwards[i].port = 0;
  7884.         options->remote_forwards[i].host = NULL;
  7885.         options->remote_forwards[i].host_port = 0;
  7886.     }
  7887.     options->forward_agent = -1;
  7888.     options->forward_x11 = -1;
  7889.     options->xauth_location = NULL;
  7890.     options->gateway_ports = -1;
  7891.     options->use_privileged_port = -1;
  7892.     options->rhosts_authentication = -1;
  7893.     options->rsa_authentication = -1;
  7894.     options->pubkey_authentication = -1;
  7895.     options->challenge_response_authentication = -1;
  7896. #if defined(KRB4)
  7897.     options->krb4_authentication = -1;
  7898. #endif
  7899. #if defined(KRB5)
  7900.     options->krb5_authentication = -1;
  7901. #endif
  7902. #ifdef GSSAPI
  7903.     options->gss_authentication = -1;
  7904.     options->gss_deleg_creds = -1;
  7905. #ifdef GSI
  7906.     options->gss_globus_deleg_limited_proxy = -1;
  7907. #endif /* GSI */
  7908. #endif /* GSSAPI */
  7909. #if defined(AFS) || defined(KRB5)
  7910.     options->kerberos_tgt_passing = -1;
  7911. #endif
  7912. #ifdef AFS
  7913.     options->afs_token_passing = -1;
  7914. #endif
  7915. #ifdef SRP
  7916.     options->srp_authentication = -1;
  7917. #endif
  7918.     options->password_authentication = -1;
  7919.     options->kbd_interactive_authentication = -1;
  7920.     options->kbd_interactive_devices = NULL;
  7921.     options->rhosts_rsa_authentication = -1;
  7922.     options->hostbased_authentication = -1;
  7923.     options->batch_mode = -1;
  7924.     options->check_host_ip = -1;
  7925.     options->strict_host_key_checking = -1;
  7926.     options->compression = -1;
  7927.     options->keepalives = -1;
  7928.     options->heartbeat_interval = -1;
  7929.     options->compression_level = -1;
  7930.     options->port = -1;
  7931.     options->connection_attempts = -1;
  7932.     options->number_of_password_prompts = -1;
  7933.     options->cipher = -1;
  7934.     options->ciphers = NULL;
  7935.     options->macs = NULL;
  7936.     options->hostkeyalgorithms = NULL;
  7937.     options->protocol = SSH_PROTO_UNKNOWN;
  7938.     options->num_identity_files = 0;
  7939.     options->hostname = NULL;
  7940.     options->host_key_alias = NULL;
  7941.     options->proxy_command = NULL;
  7942.     options->user = NULL;
  7943.     options->escape_char = -1;
  7944.     options->system_hostfile = NULL;
  7945.     options->user_hostfile = NULL;
  7946.     options->system_hostfile2 = NULL;
  7947.     options->user_hostfile2 = NULL;
  7948.     options->num_local_forwards = 0;
  7949.     options->num_remote_forwards = 0;
  7950.     options->clear_forwardings = -1;
  7951.     options->log_level = SYSLOG_LEVEL_NOT_SET;
  7952.     options->preferred_authentications = NULL;
  7953.     options->bind_address = NULL;
  7954.     options->smartcard_device = NULL;
  7955.     options->enable_ssh_keysign = -1;
  7956.     options->no_host_authentication_for_localhost = - 1;
  7957. }       
  7958.  
  7959. /*
  7960.  * Called after processing other sources of option data, this fills those
  7961.  * options for which no value has been specified with their default values.
  7962.  */
  7963.  
  7964. void
  7965. fill_default_options(Options * options)
  7966. {
  7967.     int len;
  7968.  
  7969.     if ( !options )
  7970.         return;
  7971.  
  7972.     debug(F101,"fill_default_options","",1);
  7973.     if (options->forward_agent == -1)
  7974.         options->forward_agent = 0;
  7975.     if (options->forward_x11 == -1)
  7976.         options->forward_x11 = 0;
  7977. #ifdef _XAUTH_PATH
  7978.     debug(F101,"fill_default_options","",2);
  7979.     if (options->xauth_location == NULL)
  7980.         makestr(&options->xauth_location,_XAUTH_PATH);
  7981. #endif /* XAUTH_PATH */
  7982.     debug(F101,"fill_default_options","",3);
  7983.     if (options->gateway_ports == -1)
  7984.         options->gateway_ports = 0;
  7985.     if (options->use_privileged_port == -1)
  7986.         options->use_privileged_port = 0;
  7987.     if (options->rhosts_authentication == -1)
  7988.         options->rhosts_authentication = 0;
  7989.     if (options->rsa_authentication == -1)
  7990.         options->rsa_authentication = 1;
  7991.     if (options->pubkey_authentication == -1)
  7992.         options->pubkey_authentication = 1;
  7993.     if (options->challenge_response_authentication == -1)
  7994.         options->challenge_response_authentication = 0;
  7995. #if defined(KRB4)
  7996.     if (options->krb4_authentication == -1)
  7997.         options->krb4_authentication = 1;
  7998. #endif /* KRB4 / KRB5 */
  7999. #if defined(KRB5)
  8000.     if (options->krb5_authentication == -1)
  8001.         options->krb5_authentication = 1;
  8002. #endif /* KRB4 / KRB5 */
  8003. #ifdef GSSAPI
  8004.     if (options->gss_authentication == -1)
  8005.         options->gss_authentication = 1;
  8006.     if (options->gss_deleg_creds == -1)
  8007.         options->gss_deleg_creds = 1;
  8008. #ifdef GSI
  8009.     if (options->gss_globus_deleg_limited_proxy == -1)
  8010.         options->gss_globus_deleg_limited_proxy = 0;
  8011. #endif /* GSI */
  8012. #endif /* GSSAPI */
  8013. #if defined(AFS) || defined(KRB5)
  8014. #ifdef KRB5
  8015.     if (options->kerberos_tgt_passing == -1)
  8016.     {
  8017. #ifdef HEIMDAL
  8018.         krb5_context context;
  8019.  
  8020.         if (krb5_init_context(&context))
  8021.             options->kerberos_tgt_passing = 0;
  8022.         else {
  8023.             options->kerberos_tgt_passing = krb5_config_get_bool(context,
  8024.                 NULL, "libdefaults", "forward", NULL);
  8025.             krb5_free_context(context);
  8026.         }
  8027. #else /* HEIMDAL */
  8028.         options->kerberos_tgt_passing = 1;
  8029. #endif /* HEIMDAL */
  8030.     }
  8031. #else /* KRB5 */
  8032.     if (options->kerberos_tgt_passing == -1)
  8033.         options->kerberos_tgt_passing = 1;
  8034. #endif /* KRB5 */
  8035. #endif /* AFS/KRB5 */
  8036. #ifdef AFS
  8037.     if (options->afs_token_passing == -1)
  8038.         options->afs_token_passing = 1;
  8039. #endif /* AFS */
  8040. #ifdef SRP
  8041.     if (options->srp_authentication == -1)
  8042.         options->srp_authentication = 1;
  8043. #endif
  8044.     if (options->password_authentication == -1)
  8045.         options->password_authentication = 1;
  8046.     if (options->kbd_interactive_authentication == -1)
  8047.         options->kbd_interactive_authentication = 1;
  8048.     if (options->rhosts_rsa_authentication == -1)
  8049.         options->rhosts_rsa_authentication = 0;
  8050.     if (options->hostbased_authentication == -1)
  8051.         options->hostbased_authentication = 0;
  8052.     if (options->batch_mode == -1)
  8053.         options->batch_mode = 0;
  8054.     if (options->check_host_ip == -1)
  8055.         options->check_host_ip = 1;
  8056.     if (options->strict_host_key_checking == -1)
  8057.         options->strict_host_key_checking = 2;  /* 2 is default */
  8058.     if (options->compression == -1)
  8059.         options->compression = 0;
  8060.     if (options->keepalives == -1)
  8061.         options->keepalives = 1;
  8062.     if (options->heartbeat_interval == -1)
  8063.         options->heartbeat_interval = 0;
  8064.     if (options->compression_level == -1)
  8065.         options->compression_level = 6;
  8066.     if (options->port == -1)
  8067.         options->port = 0;      /* Filled in ssh_connect. */
  8068.     if (options->connection_attempts == -1)
  8069.         options->connection_attempts = 1;
  8070.     if (options->number_of_password_prompts == -1)
  8071.         options->number_of_password_prompts = 3;
  8072.     /* Selected in ssh_login(). */
  8073.     if (options->cipher == -1)
  8074.         options->cipher = SSH_CIPHER_NOT_SET;
  8075.     /* options->ciphers, default set in myproposals.h */
  8076.     /* options->macs, default set in myproposals.h */
  8077.     /* options->hostkeyalgorithms, default set in myproposals.h */
  8078.     if (options->protocol == SSH_PROTO_UNKNOWN)
  8079.         options->protocol = SSH_PROTO_1|SSH_PROTO_2;
  8080.     if (options->num_identity_files == 0) {
  8081.         debug(F101,"fill_default_options","",4);
  8082.         if (options->protocol & SSH_PROTO_1) { 
  8083.             makestr(&options->identity_files[options->num_identity_files++],
  8084.                      (char *)_PATH_SSH_CLIENT_IDENTITY);
  8085.         }       
  8086.         debug(F101,"fill_default_options","",5);
  8087.         if (options->protocol & SSH_PROTO_2) {
  8088.             makestr(&options->identity_files[options->num_identity_files++],
  8089.                      (char *)_PATH_SSH_CLIENT_ID_RSA);
  8090.             makestr(&options->identity_files[options->num_identity_files++],
  8091.                      (char *)_PATH_SSH_CLIENT_ID_DSA);
  8092.         }       
  8093.         debug(F101,"fill_default_options","",6);
  8094.     }       
  8095.     if (options->escape_char == -1)
  8096.         options->escape_char = '~';
  8097.     if (options->system_hostfile == NULL)
  8098.         makestr(&options->system_hostfile,(char *)_PATH_SSH_SYSTEM_HOSTFILE);
  8099.     debug(F101,"fill_default_options","",7);
  8100.     if (options->user_hostfile == NULL)
  8101.         makestr(&options->user_hostfile,(char *)_PATH_SSH_USER_HOSTFILE);
  8102.     debug(F101,"fill_default_options","",8);
  8103.     if (options->system_hostfile2 == NULL)
  8104.         makestr(&options->system_hostfile2,(char *)_PATH_SSH_SYSTEM_HOSTFILE2);
  8105.     debug(F101,"fill_default_options","",9);
  8106.     if (options->user_hostfile2 == NULL)
  8107.         makestr(&options->user_hostfile2,(char *)_PATH_SSH_USER_HOSTFILE2);
  8108.     debug(F101,"fill_default_options","",10);
  8109.     if (options->log_level == SYSLOG_LEVEL_NOT_SET)
  8110.         options->log_level = SYSLOG_LEVEL_INFO;
  8111.     if (options->clear_forwardings == 1)
  8112.         clear_forwardings(options);
  8113.     if (options->no_host_authentication_for_localhost == - 1)
  8114.         options->no_host_authentication_for_localhost = 0;
  8115.     if (options->enable_ssh_keysign == -1)
  8116.         options->enable_ssh_keysign = 0;
  8117.     /* options->proxy_command should not be set by default */
  8118.     /* options->user will be set in the main program if appropriate */
  8119.     /* options->hostname will be set in the main program if appropriate */
  8120.     /* options->host_key_alias should not be set by default */
  8121.     /* options->preferred_authentications will be set in ssh */
  8122. }
  8123.  
  8124. /* Restores stdin to blocking mode. */
  8125.  
  8126. static void
  8127. leave_non_blocking(void)
  8128. {
  8129. #ifndef OS2
  8130.     if (in_non_blocking_mode) {
  8131.         (void) fcntl(fileno(stdin), F_SETFL, 0);
  8132.         in_non_blocking_mode = 0;
  8133.         fatal_remove_cleanup((void (*) (void *)) leave_non_blocking, NULL);
  8134.     }
  8135. #endif /* !OS2 */
  8136. }
  8137.  
  8138. /* Puts stdin terminal in non-blocking mode. */
  8139.  
  8140. static void
  8141. enter_non_blocking(void)
  8142. {
  8143. #ifndef OS2
  8144.     in_non_blocking_mode = 1;
  8145.     (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
  8146.     fatal_add_cleanup((void (*) (void *)) leave_non_blocking, NULL);
  8147. #endif /* !OS2 */
  8148. }
  8149.  
  8150. /*
  8151.  * Signal handler for the window change signal (SIGWINCH).  This just sets a
  8152.  * flag indicating that the window has changed.
  8153.  */
  8154. #ifndef OS2
  8155. static void
  8156. window_change_handler(int sig)
  8157. {
  8158.     received_window_change_signal = 1;
  8159.     signal(SIGWINCH, window_change_handler);
  8160. }
  8161. #else
  8162. static void
  8163. ssh_window_change(void)
  8164. {
  8165.     if (sent_initial_ws)
  8166.         received_window_change_signal = 1;
  8167. }
  8168.  
  8169. int
  8170. ssh_snaws(void)
  8171. {
  8172.     extern int tt_status[];
  8173.     if (ssh_height != (VscrnGetHeight(VTERM) - (tt_status[VTERM]?1:0)) ||
  8174.         ssh_width != VscrnGetWidth(VTERM))
  8175.         ssh_window_change();
  8176.     return 0;
  8177. }
  8178. #endif /* !OS2 */
  8179.  
  8180. /*
  8181.  * Signal handler for signals that cause the program to terminate.  These
  8182.  * signals must be trapped to restore terminal modes.
  8183.  */
  8184.  
  8185. static void
  8186. signal_handler(int sig)
  8187. {
  8188.     received_signal = sig;
  8189.     quit_pending = 1;
  8190. }
  8191.  
  8192. /*
  8193.  * This is called when the interactive is entered.  This checks if there is
  8194.  * an EOF coming on stdin.  We must check this explicitly, as select() does
  8195.  * not appear to wake up when redirecting from /dev/null.
  8196.  */
  8197.  
  8198. static void
  8199. client_check_initial_eof_on_stdin(void)
  8200. {
  8201.     int len;
  8202.     char buf[1];
  8203.  
  8204.     /*
  8205.      * If standard input is to be "redirected from /dev/null", we simply
  8206.      * mark that we have seen an EOF and send an EOF message to the
  8207.      * server. Otherwise, we try to read a single character; it appears
  8208.      * that for some files, such /dev/null, select() never wakes up for
  8209.      * read for this descriptor, which means that we never get EOF.  This
  8210.      * way we will get the EOF if stdin comes from /dev/null or similar.
  8211.      */
  8212.     if (stdin_null_flag) {
  8213.         /* Fake EOF on stdin. */
  8214.         debug1("Sending eof.");
  8215.         stdin_eof = 1;
  8216.         packet_start(SSH_CMSG_EOF);
  8217.         packet_send();
  8218.     } else {
  8219.         enter_non_blocking();
  8220.  
  8221.         /* Check for immediate EOF on stdin. */
  8222. #ifdef OS2
  8223.         len = recv(sock_stdin, buf, 1, 0);
  8224. #else
  8225.         len = read(fileno(stdin), buf, 1);
  8226. #endif /* OS2 */
  8227.         if (len == 0) {
  8228.             /* EOF.  Record that we have seen it and send EOF to server. */
  8229.             debug1("Sending eof.");
  8230.             stdin_eof = 1;
  8231.             packet_start(SSH_CMSG_EOF);
  8232.             packet_send();
  8233.         } else if (len > 0) {
  8234.             /*
  8235.              * Got data.  We must store the data in the buffer,
  8236.              * and also process it as an escape character if
  8237.              * appropriate.
  8238.              */
  8239.             if ((u_char) buf[0] == escape_char)
  8240.                 escape_pending = 1;
  8241.             else
  8242.                 buffer_append(&stdin_buffer, buf, 1);
  8243.         }
  8244.         leave_non_blocking();
  8245.     }
  8246. }
  8247.  
  8248.  
  8249. /*
  8250.  * Make packets from buffered stdin data, and buffer them for sending to the
  8251.  * connection.
  8252.  */
  8253.  
  8254. static int
  8255. client_make_packets_from_stdin_data(void)
  8256. {
  8257.     u_int len;
  8258.  
  8259.     /* Send buffered stdin data to the server. */
  8260.     while (buffer_len(&stdin_buffer) > 0 &&
  8261.             packet_not_very_much_data_to_write()) {
  8262.         len = buffer_len(&stdin_buffer);
  8263.         /* Keep the packets at reasonable size. */
  8264.         if (len > packet_get_maxsize())
  8265.             len = packet_get_maxsize();
  8266.         packet_start(SSH_CMSG_STDIN_DATA);
  8267.         packet_put_string(buffer_ptr(&stdin_buffer), len);
  8268.         packet_send();
  8269.         if (buffer_consume(&stdin_buffer, len) < 0)
  8270.             return(-1);
  8271.         stdin_bytes += len;
  8272.         /* If we have a pending EOF, send it now. */
  8273.         if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
  8274.             packet_start(SSH_CMSG_EOF);
  8275.             packet_send();
  8276.         }
  8277.     }
  8278.     return(0);
  8279. }
  8280.  
  8281. /*
  8282.  * Checks if the client window has changed, and sends a packet about it to
  8283.  * the server if so.  The actual change is detected elsewhere (by a software
  8284.  * interrupt on Unix); this just checks the flag and sends a message if
  8285.  * appropriate.
  8286.  */
  8287.  
  8288. static void
  8289. client_check_window_change(void)
  8290. {
  8291.     struct winsize ws;
  8292.  
  8293.     if (! received_window_change_signal)
  8294.         return;
  8295.  
  8296.     /** XXX race */
  8297.     received_window_change_signal = 0;
  8298.  
  8299. #ifdef OS2
  8300.     if (_getwinsize( &ws ) == -1)
  8301.         memset(&ws,0,sizeof(ws));
  8302. #else /* OS2 */
  8303.     if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
  8304.         return;
  8305. #endif /* OS2 */
  8306.  
  8307.     debug2("client_check_window_change: changed");
  8308.  
  8309.     received_window_change_signal = 0;
  8310.     ssh_width = ws.ws_col;
  8311.     ssh_height = ws.ws_row;
  8312.     if (compat20) {
  8313.         channel_request_start(session_ident, "window-change", 0);
  8314.         packet_put_int(ws.ws_col);
  8315.         packet_put_int(ws.ws_row);
  8316.         packet_put_int(ws.ws_xpixel);
  8317.         packet_put_int(ws.ws_ypixel);
  8318.         packet_send();
  8319.     } else {
  8320.         packet_start(SSH_CMSG_WINDOW_SIZE);
  8321.         packet_put_int(ws.ws_row);
  8322.         packet_put_int(ws.ws_col);
  8323.         packet_put_int(ws.ws_xpixel);
  8324.         packet_put_int(ws.ws_ypixel);
  8325.         packet_send();
  8326.     }
  8327. }
  8328.  
  8329. /*
  8330.  * Waits until the client can do something (some data becomes available on
  8331.  * one of the file descriptors).
  8332.  */
  8333.  
  8334. static time_t idle_time_last = 0;
  8335.  
  8336. static void
  8337. client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
  8338.     int *maxfdp, int *nallocp, int rekeying)
  8339. {
  8340.     int ret;
  8341.     struct timeval tv;
  8342.  
  8343.     /* Add any selections by the channel mechanism. */
  8344.     channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
  8345.  
  8346.     if (!compat20) {
  8347.         /* Read from the connection, unless our buffers are full. */
  8348.         if (buffer_len(&stdout_buffer) < buffer_high &&
  8349.              buffer_len(&stderr_buffer) < buffer_high &&
  8350.              channel_not_very_much_buffered_data())
  8351.             FD_SET(connection_in, *readsetp);
  8352.         /*
  8353.          * Read from stdin, unless we have seen EOF or have very much
  8354.          * buffered data to send to the server.
  8355.          */
  8356.         if (!stdin_eof && packet_not_very_much_data_to_write()) {
  8357. #ifdef OS2
  8358.             FD_SET(sock_stdin, *readsetp);
  8359. #else
  8360.             FD_SET(fileno(stdin), *readsetp);
  8361. #endif /* OS2 */
  8362.         }
  8363.         /* Select stdout/stderr if have data in buffer. */
  8364.         if (buffer_len(&stdout_buffer) > 0) {
  8365. #ifdef OS2
  8366.             return;
  8367. #else
  8368.             FD_SET(fileno(stdout), *writesetp);
  8369. #endif /* OS2 */
  8370.         }
  8371.         if (buffer_len(&stderr_buffer) > 0) {
  8372. #ifdef OS2
  8373.             return;
  8374. #else
  8375.             FD_SET(fileno(stderr), *writesetp);
  8376. #endif /* OS2 */
  8377.         }
  8378.     } else {
  8379.         /* channel_prepare_select could have closed the last channel */
  8380.         if (session_closed && (channel_still_open() <= 0) &&
  8381.             !packet_have_data_to_write()) {
  8382.                 /* clear mask since we did not call select() */
  8383. #ifdef OS2
  8384.             FD_ZERO(*readsetp);
  8385.             FD_ZERO(*writesetp);
  8386. #else
  8387.             memset(*readsetp, 0, *nallocp);
  8388.             memset(*writesetp, 0, *nallocp);
  8389. #endif
  8390.             return;
  8391.         } else {
  8392.             FD_SET(connection_in, *readsetp);
  8393.         }
  8394.     }
  8395.  
  8396.     /* Select server connection if have data to write to the server. */
  8397.     if (packet_have_data_to_write())
  8398.         FD_SET(connection_out, *writesetp);
  8399.  
  8400.     /*
  8401.      * Wait for something to happen.  This will suspend the process until
  8402.      * some selected descriptor can be read, written, or has some other
  8403.      * event pending. Note: if you want to implement SSH_MSG_IGNORE
  8404.      * messages to fool traffic analysis, this might be the place to do
  8405.      * it: just have a random timeout for the select, and send a random
  8406.      * SSH_MSG_IGNORE packet when the timeout expires.
  8407.      */
  8408.  
  8409.     tv.tv_sec = 0;
  8410.     tv.tv_usec = 500 * 1000;            /* time slot is 0.5 sec */
  8411.  
  8412.     ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL);
  8413.     if (ret < 0) {
  8414.         /*
  8415.          * We have to clear the select masks, because we return.
  8416.          * We have to return, because the mainloop checks for the flags
  8417.          * set by the signal handlers.
  8418.          */
  8419. #ifdef OS2
  8420.         FD_ZERO(*readsetp);
  8421.         FD_ZERO(*writesetp);
  8422. #else
  8423.         memset(*readsetp, 0, *nallocp);
  8424.         memset(*writesetp, 0, *nallocp);
  8425. #endif /* OS2 */
  8426.  
  8427.         if (errno == EINTR || quit_pending)
  8428.             return;
  8429.         /* Note: we might still have data in the buffers. */
  8430.         debug1("select: %s", sock_strerror(sock_lasterror()));
  8431.         quit_pending = 1;
  8432.     }
  8433.  
  8434.     /* If the output channel has been silent for more than a specified
  8435.      * time, send a keepalive packet (heartbeat) to the server.
  8436.      * Keepalive packet is useful for keeping the connection over
  8437.      * IP masquerade / NAT boxes, firewalls, etc.
  8438.      * Some servers equipped with a watchdog timer require keepalive
  8439.      * packets (heartbeats) to detect link down.
  8440.      *
  8441.      * Note: Although the interval between keepalive packets is not
  8442.      * very precise, it's okay.
  8443.      *
  8444.      * Note: Some old servers may crash when they receive SSH_MSG_IGNORE.
  8445.      * Those who want to connect to such a server should turn this
  8446.      * function off by the option setting (e.g. Heartbeat 0).
  8447.      */
  8448.     if (options.heartbeat_interval > 0) {
  8449.         if (FD_ISSET(connection_out,*writesetp)) {
  8450.                 /* Update the time of last data transmission. */
  8451.                 idle_time_last = time(NULL);
  8452.         }
  8453.         else if (time(NULL) - idle_time_last >= (int)options.heartbeat_interval) {
  8454.              if (compat20) {
  8455.                  packet_start(SSH2_MSG_IGNORE);
  8456.                 }       
  8457.              else {
  8458.                  packet_start(SSH_MSG_IGNORE);
  8459.              }
  8460.              packet_put_string("", 0);
  8461.              packet_send();
  8462.              /* fputs("*",stderr); */
  8463.          }
  8464.     }
  8465. }
  8466.  
  8467. #ifndef OS2
  8468. static void
  8469. client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
  8470. {
  8471. #ifndef OS2
  8472.     struct winsize oldws, newws;
  8473. #endif
  8474.  
  8475.     /* Flush stdout and stderr buffers. */
  8476.     if (buffer_len(bout) > 0)
  8477.         atomicio(write, fileno(stdout), buffer_ptr(bout), buffer_len(bout));
  8478.     if (buffer_len(berr) > 0)
  8479.         atomicio(write, fileno(stderr), buffer_ptr(berr), buffer_len(berr));
  8480.  
  8481.     leave_raw_mode();
  8482.  
  8483.     /*
  8484.      * Free (and clear) the buffer to reduce the amount of data that gets
  8485.      * written to swap.
  8486.      */
  8487.     buffer_free(bin);
  8488.     buffer_free(bout);
  8489.     buffer_free(berr);
  8490.  
  8491. #ifndef OS2
  8492.     /* Save old window size. */
  8493.     ioctl(fileno(stdin), TIOCGWINSZ, &oldws);
  8494.  
  8495.     /* Send the suspend signal to the program itself. */
  8496.     kill(getpid(), SIGTSTP);
  8497.  
  8498.     /* Check if the window size has changed. */
  8499.     if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 &&
  8500.          (oldws.ws_row != newws.ws_row ||
  8501.            oldws.ws_col != newws.ws_col ||
  8502.            oldws.ws_xpixel != newws.ws_xpixel ||
  8503.            oldws.ws_ypixel != newws.ws_ypixel))
  8504.         received_window_change_signal = 1;
  8505. #endif /* !OS2 */
  8506.  
  8507.     /* OK, we have been continued by the user. Reinitialize buffers. */
  8508.     buffer_init(bin);
  8509.     buffer_init(bout);
  8510.     buffer_init(berr);
  8511.  
  8512.     enter_raw_mode();
  8513. }
  8514. #endif /* OS2 */
  8515.  
  8516. static void
  8517. client_process_net_input(fd_set * readset)
  8518. {
  8519.     int len;
  8520.     char buf[8192];
  8521.  
  8522.     /*
  8523.      * Read input from the server, and add any such data to the buffer of
  8524.      * the packet subsystem.
  8525.      */
  8526.     if (FD_ISSET(connection_in, readset)) {
  8527.         /* Read as much as possible. */
  8528. #ifdef OS2
  8529.         len = recv(connection_in, buf, sizeof(buf),0);
  8530. #else
  8531.         len = read(connection_in, buf, sizeof(buf));
  8532. #endif /* OS2 */
  8533.         if (len == 0) {
  8534.             /* Received EOF.  The remote host has closed the connection. */
  8535.             xfprintf(stderr,"Connection to %.300s closed by remote host.\r\n",
  8536.                       host);
  8537.             quit_pending = 1;
  8538.             return;
  8539.         }
  8540.         /*
  8541.          * There is a kernel bug on Solaris that causes select to
  8542.          * sometimes wake up even though there is no data available.
  8543.          */
  8544. #ifdef OS2
  8545.         if (len < 0 && (sock_lasterror() == EAGAIN))
  8546.             len = 0;
  8547. #else
  8548.         if (len < 0 && (errno == EAGAIN || errno == EINTR))
  8549.             len = 0;
  8550. #endif /* OS2 */
  8551.  
  8552.         if (len < 0) {
  8553.             /* An error has encountered.  Perhaps there is a network problem. */
  8554. #ifdef OS2
  8555.             debug1("Read from remote host %.300s: %.100s",
  8556.                       host, sock_strerror(sock_lasterror()));
  8557. #else
  8558.             snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n",
  8559.                       host, strerror(errno));
  8560.             buffer_append(&stderr_buffer, buf, strlen(buf));
  8561. #endif /* OS2 */
  8562.             quit_pending = 1;
  8563.             return;
  8564.         }
  8565.         packet_process_incoming(buf, len);
  8566.     }
  8567. }
  8568.  
  8569. #ifdef UNIX
  8570. static void
  8571. process_cmdline(void)
  8572. {
  8573.     void (*handler)(int);
  8574.     char *s, *cmd;
  8575.     u_short fwd_port, fwd_host_port;
  8576.     char buf[1024], sfwd_port[6], sfwd_host_port[6];
  8577.     int local = 0;
  8578.  
  8579.     leave_raw_mode();
  8580.     handler = signal(SIGINT, SIG_IGN);
  8581.     cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
  8582.     if (s == NULL)
  8583.         goto out;
  8584.     while (*s && isspace(*s))
  8585.         s++;
  8586.     if (*s == 0)
  8587.         goto out;
  8588.     if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
  8589.         log("Invalid command.");
  8590.         goto out;
  8591.     }
  8592.     if (s[1] == 'L')
  8593.         local = 1;
  8594.     if (!local && !compat20) {
  8595.         log("Not supported for SSH protocol version 1.");
  8596.         goto out;
  8597.     }
  8598.     s += 2;
  8599.     while (*s && isspace(*s))
  8600.         s++;
  8601.  
  8602.     if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
  8603.         sfwd_port, buf, sfwd_host_port) != 3 &&
  8604.         sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
  8605.         sfwd_port, buf, sfwd_host_port) != 3) {
  8606.         log("Bad forwarding specification.");
  8607.         goto out;
  8608.     }
  8609.     if ((fwd_port = a2port(sfwd_port)) == 0 ||
  8610.         (fwd_host_port = a2port(sfwd_host_port)) == 0) {
  8611.         log("Bad forwarding port(s).");
  8612.         goto out;
  8613.     }
  8614.     if (local) {
  8615.         if (channel_setup_local_fwd_listener(fwd_port, buf,
  8616.             fwd_host_port, options.gateway_ports) < 0) {
  8617.             log("Port forwarding failed.");
  8618.             goto out;
  8619.         }
  8620.     } else
  8621.         channel_request_remote_forwarding(fwd_port, buf,
  8622.             fwd_host_port);
  8623.     log("Forwarding port.");
  8624. out:
  8625.     signal(SIGINT, handler);
  8626.     enter_raw_mode();
  8627.     if (cmd)
  8628.         free(cmd);
  8629. }
  8630. #endif /* UNIX */
  8631.  
  8632. /* process the characters one by one */
  8633. static int
  8634. process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
  8635. {
  8636.     char string[1024];
  8637.     pid_t pid;
  8638.     int bytes = 0;
  8639.     u_int i;
  8640.     u_char ch;
  8641.     char *s;
  8642.  
  8643.     for (i = 0; i < len; i++) {
  8644.         /* Get one character at a time. */
  8645.         ch = buf[i];
  8646.  
  8647.         if (escape_pending) {
  8648.             /* We have previously seen an escape character. */
  8649.             /* Clear the flag now. */
  8650.             escape_pending = 0;
  8651.  
  8652.             /* Process the escaped character. */
  8653.             switch (ch) {
  8654.             case '.':
  8655.                 /* Terminate the connection. */
  8656.                 snprintf(string, sizeof string, "%c.\r\n", escape_char);
  8657.                 buffer_append(berr, string, strlen(string));
  8658.                 quit_pending = 1;
  8659.                 return -1;
  8660.  
  8661. #ifndef OS2
  8662.             case 'Z' - 64:
  8663.                 /* Suspend the program. */
  8664.                 /* Print a message to that effect to the user. */
  8665.                 snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char);
  8666.                 buffer_append(berr, string, strlen(string));
  8667.  
  8668.                 /* Restore terminal modes and suspend. */
  8669.                 client_suspend_self(bin, bout, berr);
  8670.  
  8671.                 /* We have been continued. */
  8672.                 continue;
  8673. #endif /* OS2 */
  8674.             case 'R':
  8675.                 if (compat20) {
  8676.                     if (datafellows & SSH_BUG_NOREKEY)
  8677.                         log("Server does not support re-keying");
  8678.                     else
  8679.                         need_rekeying = 1;
  8680.                 }
  8681.                 continue;
  8682.  
  8683.             case '&':
  8684.                 /*
  8685.                 * Detach the program (continue to serve connections,
  8686.                 * but put in background and no more new connections).
  8687.                 */
  8688.                 /* Restore tty modes. */
  8689.                 leave_raw_mode();
  8690.  
  8691.                 /* Stop listening for new connections. */
  8692.                 channel_stop_listening();
  8693.  
  8694.                 snprintf(string, sizeof string,
  8695.                           "%c& [backgrounded]\n", escape_char);
  8696.                 buffer_append(berr, string, strlen(string));
  8697.  
  8698. #ifndef OS2
  8699.                 /* Fork into background. */
  8700.                 pid = fork();
  8701.                 if (pid < 0) {
  8702.                     error("fork: %.100s", strerror(errno));
  8703.                     continue;
  8704.                 }
  8705.                 if (pid != 0) { /* This is the parent. */
  8706.                     /* The parent just exits. */
  8707.                     exit(0);
  8708.                 }
  8709.                 /* The child continues serving connections. */
  8710. #endif /* OS2 */
  8711.                 if (compat20) {
  8712.                     buffer_append(bin, "\004", 1);
  8713.                     /* fake EOF on stdin */
  8714.                     return -1;
  8715.                 } else if (!stdin_eof) {
  8716.                     /*
  8717.                     * Sending SSH_CMSG_EOF alone does not always appear
  8718.                     * to be enough.  So we try to send an EOF character
  8719.                     * first.
  8720.                     */
  8721.                     packet_start(SSH_CMSG_STDIN_DATA);
  8722.                     packet_put_string("\004", 1);
  8723.                     packet_send();
  8724.                     /* Close stdin. */
  8725.                     stdin_eof = 1;
  8726.                     if (buffer_len(bin) == 0) {
  8727.                         packet_start(SSH_CMSG_EOF);
  8728.                         packet_send();
  8729.                     }
  8730.                 }
  8731.                 continue;
  8732.  
  8733.             case '?':
  8734.                 snprintf(string, sizeof string,
  8735.                           "%c?\r\n"
  8736.                           "Supported escape sequences:\r\n"
  8737.                           "%c.  - terminate connection\r\n"
  8738. #ifdef UNIX
  8739.                           "%cC - open a command line\r\n"
  8740. #endif /* UNIX */
  8741.                           "%cR - Request rekey (SSH protocol 2 only)\r\n"
  8742.                           "%c^Z - suspend ssh\r\n"
  8743.                           "%c#  - list forwarded connections\r\n"
  8744.                           "%c&  - background ssh (when waiting for connections to terminate)\r\n"
  8745.                           "%c?  - this message\r\n"
  8746.                           "%c%c  - send the escape character by typing it twice\r\n"
  8747.                           "(Note that escapes are only recognized immediately after newline.)\r\n",
  8748.                           escape_char,escape_char,escape_char,escape_char,escape_char,
  8749.                           escape_char,escape_char,escape_char,escape_char,escape_char);
  8750.                 buffer_append(berr, string, strlen(string));
  8751.                 continue;
  8752.  
  8753.             case '#':
  8754.                 snprintf(string, sizeof string, "%c#\r\n", escape_char);
  8755.                 buffer_append(berr, string, strlen(string));
  8756.                 s = channel_open_message();
  8757.                 buffer_append(berr, s, strlen(s));
  8758.                 free(s);
  8759.                 s = NULL;
  8760.                 continue;
  8761.  
  8762. #ifdef UNIX
  8763.             case 'C':
  8764.                 process_cmdline();
  8765.                 continue;
  8766. #endif /* UNIX */
  8767.  
  8768.             default:
  8769.                 if (ch != escape_char) {
  8770.                     buffer_put_char(bin, escape_char);
  8771.                     bytes++;
  8772.                 }
  8773.                 /* Escaped characters fall through here */
  8774.                 break;
  8775.             }
  8776.         } else {
  8777.             /*
  8778.             * The previous character was not an escape char. Check if this
  8779.             * is an escape.
  8780.             */
  8781.             if (last_was_cr && ch == escape_char) {
  8782.                 /* It is. Set the flag and continue to next character. */
  8783.                 escape_pending = 1;
  8784.                 continue;
  8785.             }
  8786.         }
  8787.  
  8788.         /*
  8789.         * Normal character.  Record whether it was a newline,
  8790.         * and append it to the buffer.
  8791.         */
  8792.         last_was_cr = (ch == '\r' || ch == '\n');
  8793.         buffer_put_char(bin, ch);
  8794.         bytes++;
  8795.     }
  8796.     return bytes;
  8797. }
  8798.  
  8799. static void
  8800. client_process_input(fd_set * readset)
  8801. {
  8802.     int len;
  8803.     char buf[8192];
  8804.     int fd;
  8805.  
  8806. #ifdef OS2
  8807.     fd = sock_stdin;
  8808. #else
  8809.     fd = fileno(stdin);
  8810. #endif /* OS2 */
  8811.  
  8812.     /* Read input from stdin. */
  8813.     if (FD_ISSET(fd, readset)) {
  8814.         /* Read as much as possible. */
  8815. #ifdef OS2
  8816.         len = recv(fd, buf, sizeof(buf),0);
  8817. #else
  8818.         len = read(fd, buf, sizeof(buf));
  8819. #endif /* OS2 */
  8820.         if (len < 0 &&
  8821. #ifdef OS2
  8822.              (sock_lasterror() == EAGAIN)
  8823. #else
  8824.              (errno == EAGAIN || errno == EINTR)
  8825. #endif /* OS2 */
  8826.              )
  8827.             return;             /* we'll try again later */
  8828.         if (len <= 0) {
  8829.             /*
  8830.             * Received EOF or error.  They are treated
  8831.             * similarly, except that an error message is printed
  8832.             * if it was an error condition.
  8833.             */
  8834.             if (len < 0) {
  8835. #ifdef OS2
  8836.                 snprintf(buf, sizeof buf, "read: %.100s\r\n",
  8837.                           sock_strerror(sock_lasterror()));
  8838. #else
  8839.                 snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno));
  8840. #endif /* OS2 */
  8841.                 buffer_append(&stderr_buffer, buf, strlen(buf));
  8842.             }
  8843.             /* Mark that we have seen EOF. */
  8844.             stdin_eof = 1;
  8845.             /*
  8846.             * Send an EOF message to the server unless there is
  8847.             * data in the buffer.  If there is data in the
  8848.             * buffer, no message will be sent now.  Code
  8849.             * elsewhere will send the EOF when the buffer
  8850.             * becomes empty if stdin_eof is set.
  8851.             */
  8852.             if (buffer_len(&stdin_buffer) == 0) {
  8853.                 packet_start(SSH_CMSG_EOF);
  8854.                 packet_send();
  8855.             }
  8856.         } else if (escape_char == SSH_ESCAPECHAR_NONE) {
  8857.             /*
  8858.             * Normal successful read, and no escape character.
  8859.             * Just append the data to buffer.
  8860.             */
  8861.             buffer_append(&stdin_buffer, buf, len);
  8862.         } else {
  8863.             /*
  8864.             * Normal, successful read.  But we have an escape character
  8865.             * and have to process the characters one by one.
  8866.             */
  8867.             if (process_escapes(&stdin_buffer, &stdout_buffer,
  8868.                                  &stderr_buffer, buf, len) == -1)
  8869.                 return;
  8870.         }
  8871.     }
  8872. }
  8873.  
  8874. static int
  8875. client_process_output(fd_set * writeset)
  8876. {
  8877.     int len;
  8878.     char buf[100];
  8879.     int set;
  8880.  
  8881. #ifdef OS2
  8882.     set = buffer_len(&stdout_buffer) > 0;
  8883. #else
  8884.     set = FD_ISSET(fileno(stdout), writeset);
  8885. #endif /* OS2 */
  8886.  
  8887.     /* Write buffered output to stdout. */
  8888.     if (set) {
  8889. #ifdef OS2
  8890.         char * p = buffer_ptr(&stdout_buffer);
  8891.  
  8892.         len = buffer_len(&stdout_buffer);
  8893.         hexdump("SSH client_process_output stdout",p,len);
  8894.         send(sock_stdout,p,len,0);
  8895. #else
  8896.         /* Write as much data as possible. */
  8897.         len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
  8898.                      buffer_len(&stdout_buffer));
  8899.         if (len <= 0) {
  8900.             if (errno == EINTR || errno == EAGAIN)
  8901.                 len = 0;
  8902.             else {
  8903.                 /*
  8904.                 * An error or EOF was encountered.  Put an
  8905.                 * error message to stderr buffer.
  8906.                 */
  8907.                 snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno));
  8908.                 buffer_append(&stderr_buffer, buf, strlen(buf));
  8909.                 quit_pending = 1;
  8910.                 return(0);
  8911.             }
  8912.         }
  8913. #endif
  8914.         /* Consume printed data from the buffer. */
  8915.         if (buffer_consume(&stdout_buffer, len) < 0)
  8916.             return(-1);
  8917.         stdout_bytes += len;
  8918.     }
  8919. #ifdef OS2
  8920.     set = buffer_len(&stderr_buffer) > 0;
  8921. #else
  8922.     set = FD_ISSET(fileno(stderr), writeset);
  8923. #endif /* OS2 */
  8924.     /* Write buffered output to stderr. */
  8925.     if (set) {
  8926.         /* Write as much data as possible. */
  8927. #ifdef OS2
  8928.         char * p = buffer_ptr(&stderr_buffer);
  8929.  
  8930.         len = buffer_len(&stderr_buffer);
  8931.         hexdump("SSH client_process_output stderr",p,len);
  8932.         send(sock_stderr,p,len,0);
  8933. #else
  8934.         len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
  8935.                      buffer_len(&stderr_buffer));
  8936.         if (len <= 0) {
  8937.             if (errno == EINTR || errno == EAGAIN)
  8938.                 len = 0;
  8939.             else {
  8940.                 /* EOF or error, but can't even print error message. */
  8941.                 quit_pending = 1;
  8942.                 return(0);
  8943.             }
  8944.         }
  8945. #endif
  8946.         /* Consume printed characters from the buffer. */
  8947.         if (buffer_consume(&stderr_buffer, len) < 0)
  8948.             return(-1);
  8949.         stderr_bytes += len;
  8950.     }
  8951.     return(0);
  8952. }
  8953.  
  8954. /*
  8955.  * Get packets from the connection input buffer, and process them as long as
  8956.  * there are packets available.
  8957.  *
  8958.  * Any unknown packets received during the actual
  8959.  * session cause the session to terminate.  This is
  8960.  * intended to make debugging easier since no
  8961.  * confirmations are sent.  Any compatible protocol
  8962.  * extensions must be negotiated during the
  8963.  * preparatory phase.
  8964.  */
  8965.  
  8966. static void
  8967. client_process_buffered_input_packets(void)
  8968. {
  8969.     dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL);
  8970. }
  8971.  
  8972. /* scan buf[] for '~' before sending data to the peer */
  8973.  
  8974. static int
  8975. simple_escape_filter(Channel *c, char *buf, int len)
  8976. {
  8977.     /* XXX we assume c->extended is writeable */
  8978.     return process_escapes(&c->input, &c->output, &c->extended, buf, len);
  8979. }
  8980.  
  8981. static void
  8982. client_channel_closed(int id, void *arg)
  8983. {
  8984.     if (id != session_ident)
  8985.         error("client_channel_closed: id %d != session_ident %d",
  8986.                id, session_ident);
  8987.     channel_cancel_cleanup(id);
  8988.     session_closed = 1;
  8989.     if (in_raw_mode())
  8990.         leave_raw_mode();
  8991. }
  8992.  
  8993. /*
  8994.  * Implements the interactive session with the server.  This is called after
  8995.  * the user has been authenticated, and a command has been started on the
  8996.  * remote host.  If escape_char != SSH_ESCAPECHAR_NONE, it is the character used as an escape
  8997.  * character for terminating or suspending the session.
  8998.  */
  8999.  
  9000. int
  9001. client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
  9002. {
  9003.     fd_set *readset = NULL, *writeset = NULL;
  9004.     time_t start_time, total_time, rekey_time;
  9005.     int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
  9006.     char buf[100];
  9007.  
  9008.     debug1("Entering interactive session.");
  9009.  
  9010. #ifndef OS2
  9011.     /* REALLY send debug messages to the application */
  9012.     fflush(stderr);
  9013. #endif /* OS2 */
  9014.  
  9015.     start_time = rekey_time = idle_time_last = time(NULL);
  9016.  
  9017.     /* Initialize variables. */
  9018.     escape_pending = 0;
  9019.     last_was_cr = 1;
  9020.     exit_status = -1;
  9021.     stdin_eof = 0;
  9022.     buffer_high = 64 * 1024;
  9023.     connection_in = packet_get_connection_in();
  9024.     connection_out = packet_get_connection_out();
  9025.     max_fd = MAX(connection_in, connection_out);
  9026.  
  9027.     if (!compat20) {
  9028. #ifndef OS2
  9029.         /* enable nonblocking unless tty */
  9030.         if (!isatty(fileno(stdin)))
  9031.             set_nonblock(fileno(stdin));
  9032.         if (!isatty(fileno(stdout)))
  9033.             set_nonblock(fileno(stdout));
  9034.         if (!isatty(fileno(stderr)))
  9035.             set_nonblock(fileno(stderr));
  9036.         max_fd = MAX(max_fd, fileno(stdin));
  9037.         max_fd = MAX(max_fd, fileno(stdout));
  9038.         max_fd = MAX(max_fd, fileno(stderr));
  9039. #endif /* OS2 */
  9040.         stdin_bytes = 0;
  9041.         stdout_bytes = 0;
  9042.         stderr_bytes = 0;
  9043.     }
  9044.     quit_pending = 0;
  9045.     escape_char = escape_char_arg;
  9046.  
  9047.     /* Initialize buffers. */
  9048.     buffer_init(&stdin_buffer);
  9049.     buffer_init(&stdout_buffer);
  9050.     buffer_init(&stderr_buffer);
  9051.  
  9052.     client_init_dispatch();
  9053.  
  9054.     /* Set signal handlers to restore non-blocking mode.  */
  9055.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  9056.         signal(SIGINT, signal_handler);
  9057.     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  9058.         signal(SIGTERM, signal_handler);
  9059. #ifndef OS2
  9060.     if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
  9061.         signal(SIGQUIT, signal_handler);
  9062.     if (have_pty)
  9063.         signal(SIGWINCH, window_change_handler);
  9064.  
  9065.     if (have_pty)
  9066.         enter_raw_mode();
  9067. #endif /* !OS2 */
  9068.  
  9069.     if (compat20) {
  9070.         session_ident = ssh2_chan_id;
  9071.         if (escape_char != SSH_ESCAPECHAR_NONE)
  9072.             channel_register_filter(session_ident,
  9073.                                      simple_escape_filter);
  9074.         if (session_ident != -1)
  9075.             channel_register_cleanup(session_ident,
  9076.                                       client_channel_closed);
  9077.     }
  9078. #ifndef OS2
  9079.     else {
  9080.         /* Check if we should immediately send eof on stdin. */
  9081.         client_check_initial_eof_on_stdin();
  9082.     }
  9083. #endif /* OS2 */
  9084.  
  9085. #ifdef OS2
  9086. #ifdef NT
  9087.         SetThreadPrty(XYP_RTP,isWin95() ? 14 : 22);
  9088. #else /* NT */
  9089.         SetThreadPrty(XYP_RTP,3);
  9090. #endif /* NT */
  9091. #endif /* OS2 */
  9092.  
  9093.     /* Main loop of the client for the interactive session mode. */
  9094.     while (!quit_pending) {
  9095.  
  9096.         /* Process buffered packets sent by the server. */
  9097.         client_process_buffered_input_packets();
  9098.  
  9099.         if (compat20 && session_closed && (channel_still_open() <= 0)) {
  9100.             debug1("client_loop: session_closed");
  9101. #ifdef OS2
  9102.             /* Process output to stdout and stderr.   Output to the connection
  9103.                is processed elsewhere (above). */
  9104.             if ((buffer_len(&stdout_buffer) > 0) ||
  9105.                  (buffer_len(&stderr_buffer) > 0)) {
  9106.                 client_process_output(writeset);
  9107.             }
  9108. #endif /* OS2 */
  9109.             break;
  9110.         }
  9111.  
  9112.         rekeying = (compat20 && xxx_kex != NULL && !xxx_kex->done);
  9113.  
  9114.         if (rekeying) {
  9115.             debug1("rekeying in progress");
  9116.             rekey_time = time(NULL);
  9117.         } else {
  9118.             /*
  9119.              * Make packets of buffered stdin data, and buffer
  9120.              * them for sending to the server.
  9121.              */
  9122.             if (!compat20)
  9123.                 client_make_packets_from_stdin_data();
  9124.  
  9125.             /*
  9126.              * Make packets from buffered channel data, and
  9127.              * enqueue them for sending to the server.
  9128.              */
  9129.             if (packet_not_very_much_data_to_write())
  9130.                 channel_output_poll();
  9131.  
  9132.             /*
  9133.              * Check if the window size has changed, and buffer a
  9134.              * message about it to the server if so.
  9135.              */
  9136.             client_check_window_change();
  9137.  
  9138.             if (quit_pending)
  9139.                 break;
  9140.         }
  9141.  
  9142. #ifdef OS2
  9143.         /* Process output to stdout and stderr.   Output to the connection
  9144.            is processed elsewhere (above). */
  9145.         if ((buffer_len(&stdout_buffer) > 0) ||
  9146.              (buffer_len(&stderr_buffer) > 0))
  9147.             client_process_output(writeset);
  9148. #endif /* OS2 */
  9149.  
  9150.         /*
  9151.          * Wait until we have something to do (something becomes
  9152.          * available on one of the descriptors).
  9153.          */
  9154.         max_fd2 = max_fd;
  9155.         client_wait_until_can_do_something(&readset, &writeset,
  9156.                     &max_fd2, &nalloc, rekeying);
  9157.  
  9158.         if (quit_pending)
  9159.             break;
  9160.  
  9161.  
  9162.         /* Do channel operations unless rekeying in progress. */
  9163.         if (!rekeying) {
  9164.             channel_after_select(readset, writeset);
  9165.  
  9166.             if ( compat20 && ssh2_ark && !(datafellows & SSH_BUG_NOREKEY)) {
  9167.                 /* If auto-rekeying, rekey every hour */
  9168.                 time_t now_t = time(NULL);
  9169.                 if ( now_t - rekey_time > 360 )
  9170.                     need_rekeying = 1;
  9171.             }
  9172.  
  9173.             if (need_rekeying) {
  9174.                 debug1("user requests rekeying");
  9175.                 if ( xxx_kex ) {
  9176.                     xxx_kex->done = 0;
  9177.                     kex_send_kexinit(xxx_kex);
  9178.                 }
  9179.                 need_rekeying = 0;
  9180.             }
  9181.         }
  9182.  
  9183.         /* Buffer input from the connection.  */
  9184.         client_process_net_input(readset);
  9185.  
  9186.         if (quit_pending)
  9187.             break;
  9188.  
  9189.         if (!compat20) {
  9190.             /* Buffer data from stdin */
  9191.             client_process_input(readset);
  9192.             /*
  9193.              * Process output to stdout and stderr.  Output to
  9194.              * the connection is processed elsewhere (above).
  9195.              */
  9196. #ifdef OS2
  9197.             if ((buffer_len(&stdout_buffer) > 0) ||
  9198.                  (buffer_len(&stderr_buffer) > 0))
  9199. #endif
  9200.                 client_process_output(writeset);
  9201.         }
  9202.  
  9203.         /* Send as much buffered packet data as possible to the sender. */
  9204.         if (FD_ISSET(connection_out, writeset))
  9205.             packet_write_poll();
  9206.     }
  9207.     if (readset) {
  9208.         free(readset);
  9209.         readset = NULL;
  9210.     }
  9211.     if (writeset) {
  9212.         free(writeset);
  9213.         writeset = NULL;
  9214.     }
  9215.  
  9216.     /* Terminate the session. */
  9217.  
  9218. #ifndef OS2
  9219.     /* Stop watching for window change. */
  9220.     if (have_pty)
  9221.         signal(SIGWINCH, SIG_DFL);
  9222. #endif /* OS2 */
  9223.  
  9224.     /* Stop listening for connections. */
  9225.     channel_free_all();
  9226.  
  9227.     if (have_pty)
  9228.         leave_raw_mode();
  9229.  
  9230. #ifndef OS2
  9231.     /* restore blocking io */
  9232.     if (!isatty(fileno(stdin)))
  9233.         unset_nonblock(fileno(stdin));
  9234.     if (!isatty(fileno(stdout)))
  9235.         unset_nonblock(fileno(stdout));
  9236.     if (!isatty(fileno(stderr)))
  9237.         unset_nonblock(fileno(stderr));
  9238. #endif /* OS2 */
  9239.  
  9240.     if (received_signal) {
  9241.         if (in_non_blocking_mode)       /* XXX */
  9242.             leave_non_blocking();
  9243.         fatal("Killed by signal %d.", (int) received_signal);
  9244.         return -1;
  9245.     }
  9246.  
  9247.     /* Output any buffered data for stdout. */
  9248.     while (buffer_len(&stdout_buffer) > 0) {
  9249. #ifdef OS2
  9250.         char * p = buffer_ptr(&stdout_buffer);
  9251.         int i;
  9252.  
  9253.         len = buffer_len(&stdout_buffer);
  9254.         if (len > 0)
  9255.             send(sock_stdout,buffer_ptr(&stdout_buffer),len,0);
  9256. #else
  9257.         len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
  9258.                      buffer_len(&stdout_buffer));
  9259.         if (len <= 0) {
  9260.             error("Write failed flushing stdout buffer.");
  9261.             break;
  9262.         }
  9263. #endif
  9264.         buffer_consume(&stdout_buffer, len);
  9265.         stdout_bytes += len;
  9266.     }
  9267.  
  9268.     /* Output any buffered data for stderr. */
  9269.     while (buffer_len(&stderr_buffer) > 0) {
  9270. #ifdef OS2
  9271.         char * p = buffer_ptr(&stderr_buffer);
  9272.         int i;
  9273.  
  9274.         len = buffer_len(&stderr_buffer);
  9275.         if ( len > 0 )
  9276.             send(sock_stderr,buffer_ptr(&stdout_buffer),len,0);
  9277. #else
  9278.         len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
  9279.                      buffer_len(&stderr_buffer));
  9280.         if (len <= 0) {
  9281.             error("Write failed flushing stderr buffer.");
  9282.             break;
  9283.         }
  9284. #endif
  9285.         buffer_consume(&stderr_buffer, len);
  9286.         stderr_bytes += len;
  9287.     }
  9288.     
  9289.     if (!compat20) {
  9290.         /* Close the connection to the remote host. */
  9291.         packet_disconnect("Client loop terminated");
  9292.  
  9293.         closesocket(sock_stdin);
  9294.         closesocket(sock_stdout);
  9295.         closesocket(sock_stderr);
  9296.     }
  9297.     /* Clear and free any buffers. */
  9298.     memset(buf, 0, sizeof(buf));
  9299.     buffer_free(&stdin_buffer);
  9300.     buffer_free(&stdout_buffer);
  9301.     buffer_free(&stderr_buffer);
  9302.  
  9303.     if ( !compat20 ) {
  9304.         /* Report bytes transferred, and transfer rates. */
  9305.         total_time = time(NULL) - start_time;
  9306.         debug1("Bytes Transferred %d stdin",stdin_bytes);
  9307.         debug1("Bytes Transferred %d stdout",stdout_bytes);
  9308.         debug1("Bytes Transferred %d stderr",stderr_bytes);
  9309.         debug1("Total Time %d seconds",total_time);
  9310.  
  9311.         if (total_time > 0) {
  9312.             debug1("Stdin %f BPS",(long)stdin_bytes/total_time);
  9313.             debug1("Stdout %f BPS",(long)stdout_bytes/total_time);
  9314.             debug1("Stderr %f BPS",(long)stderr_bytes/total_time);
  9315.         }
  9316.     }
  9317.  
  9318.     /* Return the exit status of the program. */
  9319.     debug1("Exit status: %d", exit_status);
  9320.     quit_pending = 0;           /* no longer pending */
  9321.     return exit_status;
  9322. }
  9323.  
  9324. /*********/
  9325.  
  9326. static int
  9327. client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
  9328. {
  9329.     u_int data_len;
  9330.     char *data = packet_get_string(&data_len);
  9331.     packet_check_eom();
  9332.     buffer_append(&stdout_buffer, data, data_len);
  9333.     memset(data, 0, data_len);
  9334.     free(data);
  9335.     return 0;
  9336. }
  9337. static int
  9338. client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
  9339. {
  9340.     u_int data_len;
  9341.     char *data = packet_get_string(&data_len);
  9342.     packet_check_eom();
  9343.     buffer_append(&stderr_buffer, data, data_len);
  9344.     memset(data, 0, data_len);
  9345.     free(data);
  9346.     return 0;
  9347. }
  9348. static int
  9349. client_input_exit_status(int type, u_int32_t seq, void *ctxt)
  9350. {
  9351.     exit_status = packet_get_int();
  9352.     packet_check_eom();
  9353.     /* Acknowledge the exit. */
  9354.     packet_start(SSH_CMSG_EXIT_CONFIRMATION);
  9355.     packet_send();
  9356.     /*
  9357.      * Must wait for packet to be sent since we are
  9358.      * exiting the loop.
  9359.      */
  9360.     packet_write_wait();
  9361.     /* Flag that we want to exit. */
  9362.     quit_pending = 1;
  9363.     return 0;
  9364. }
  9365.  
  9366. static Channel *
  9367. client_request_forwarded_tcpip(const char *request_type, int rchan)
  9368. {
  9369.     Channel* c = NULL;
  9370.     char *listen_address, *originator_address;
  9371.     int listen_port, originator_port;
  9372.     int sock;
  9373.  
  9374.     /* Get rest of the packet */
  9375.     listen_address = packet_get_string(NULL);
  9376.     listen_port = packet_get_int();
  9377.     originator_address = packet_get_string(NULL);
  9378.     originator_port = packet_get_int();
  9379.     packet_done_null();
  9380.  
  9381.     debug1("client_request_forwarded_tcpip: listen host %s port %d",
  9382.            listen_address, listen_port);
  9383.     debug1("client_request_forwarded_tcpip: originator host %s port %d",
  9384.            originator_address, originator_port);
  9385.  
  9386.     sock = channel_connect_by_listen_address(listen_port);
  9387.     if (sock < 0) {
  9388.         free(originator_address);
  9389.         free(listen_address);
  9390.         return NULL;
  9391.     }
  9392.     c = channel_new("forwarded-tcpip",
  9393.         SSH_CHANNEL_CONNECTING, sock, sock, -1,
  9394.         CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
  9395.         strdup(originator_address), 1);
  9396.     free(originator_address);
  9397.     free(listen_address);
  9398.     return c;
  9399. }
  9400.  
  9401. static Channel*
  9402. client_request_x11(const char *request_type, int rchan)
  9403. {
  9404.     Channel *c = NULL;
  9405.     char *originator;
  9406.     int originator_port;
  9407.     int sock;
  9408.  
  9409.     if (!options.forward_x11) {
  9410.         error("Warning: ssh server tried X11 forwarding.");
  9411.         error("Warning: this is probably a break in attempt by a malicious server.");
  9412.         return NULL;
  9413.     }
  9414.     originator = packet_get_string(NULL);
  9415.     if (datafellows & SSH_BUG_X11FWD) {
  9416.         debug2("buggy server: x11 request w/o originator_port");
  9417.         originator_port = 0;
  9418.     } else {
  9419.         originator_port = packet_get_int();
  9420.     }
  9421.     packet_done_null();
  9422.  
  9423.     /* XXX check permission */
  9424.     debug1("client_request_x11: request from originator host %s port %d",
  9425.            originator, originator_port);
  9426.     free(originator);
  9427.     sock = x11_connect_display();
  9428.     if (sock < 0)
  9429.         return NULL;
  9430.    c = channel_new("x11",
  9431.        SSH_CHANNEL_X11_OPEN, sock, sock, -1,
  9432.        CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,
  9433.        strdup("x11"), 1);
  9434.     c->force_drain = 1;
  9435.     return c;
  9436. }
  9437.  
  9438. static Channel*
  9439. client_request_agent(const char *request_type, int rchan)
  9440. {
  9441.     Channel *c = NULL;
  9442.     int sock;
  9443.  
  9444.     if (!options.forward_agent) {
  9445.         error("Warning: ssh server tried agent forwarding.");
  9446.         error("Warning: this is probably a break in attempt by a malicious server.");
  9447.         return NULL;
  9448.     }
  9449.     sock =  ssh_get_authentication_socket();
  9450.     if (sock < 0)
  9451.         return NULL;
  9452.     c = channel_new("authentication agent connection",
  9453.                      SSH_CHANNEL_OPEN, sock, sock, -1,
  9454.                      CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
  9455.                      strdup("authentication agent connection"), 1);
  9456.     c->force_drain = 1;
  9457.     return c;
  9458. }
  9459.  
  9460. /* XXXX move to generic input handler */
  9461. static int
  9462. client_input_channel_open(int type, u_int32_t seq, void *ctxt)
  9463. {
  9464.     Channel *c = NULL;
  9465.     char *ctype;
  9466.     int rchan;
  9467.     u_int rmaxpack, rwindow, len;
  9468.  
  9469.     ctype = packet_get_string(&len);
  9470.     rchan = packet_get_int();
  9471.     rwindow = packet_get_int();
  9472.     rmaxpack = packet_get_int();
  9473.  
  9474.     debug1("client_input_channel_open: ctype %s rchan %d window %d max %d",
  9475.             ctype,rchan,rwindow,rmaxpack);
  9476.  
  9477.     if (strcmp(ctype, "forwarded-tcpip") == 0) {
  9478.         c = client_request_forwarded_tcpip(ctype, rchan);
  9479.     } else if (strcmp(ctype, "x11") == 0) {
  9480.         c = client_request_x11(ctype, rchan);
  9481.     } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
  9482.         c = client_request_agent(ctype, rchan);
  9483.     }
  9484. /* XXX duplicate : */
  9485.     if (c != NULL) {
  9486.         debug1("confirm %s", ctype);
  9487.         c->remote_id = rchan;
  9488.         c->remote_window = rwindow;
  9489.         c->remote_maxpacket = rmaxpack;
  9490.  
  9491.         packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
  9492.         packet_put_int(c->remote_id);
  9493.         packet_put_int(c->self);
  9494.         packet_put_int(c->local_window);
  9495.         packet_put_int(c->local_maxpacket);
  9496.         packet_send();
  9497.     } else {
  9498.         debug1("failure %s", ctype);
  9499.         packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
  9500.         packet_put_int(rchan);
  9501.         packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
  9502.         if (!(datafellows & SSH_BUG_OPENFAILURE)) {
  9503.             packet_put_cstring("open failed");
  9504.             packet_put_cstring("");
  9505.         }
  9506.         packet_send();
  9507.     }
  9508.     free(ctype);
  9509.     return(0);
  9510. }
  9511. static int
  9512. client_input_channel_req(int type, u_int32_t seq, void *ctxt)
  9513. {
  9514.     Channel *c = NULL;
  9515.     int id, reply, success = 0;
  9516.     char *rtype;
  9517.  
  9518.     id = packet_get_int();
  9519.     rtype = packet_get_string(NULL);
  9520.     reply = packet_get_char();
  9521.  
  9522.     debug1("client_input_channel_req","channel %d rtype %s reply %s",
  9523.             id,rtype,reply);
  9524.  
  9525.     if (session_ident == -1) {
  9526.         error("client_input_channel_req: no channel %d", session_ident);
  9527.     } else if (id != session_ident) {
  9528.         error("client_input_channel_req: channel %d: wrong channel: %d",
  9529.                session_ident, id);
  9530.     }
  9531.     c = channel_lookup(id);
  9532.     if (c == NULL) {
  9533.         error("client_input_channel_req: channel %d: unknown channel", id);
  9534.     } else if (strcmp(rtype, "exit-status") == 0) {
  9535.         success = 1;
  9536.         exit_status = packet_get_int();
  9537.         packet_check_eom();
  9538.     }
  9539.     if (reply) {
  9540.         packet_start(success ?
  9541.                       SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
  9542.         packet_put_int(c->remote_id);
  9543.         packet_send();
  9544.     }
  9545.     free(rtype);
  9546.     return (success ? 0 : -1);
  9547. }
  9548.  
  9549. static int
  9550. client_input_global_request(int type, u_int32_t seq, void *ctxt)
  9551. {
  9552.     char *rtype;
  9553.     int want_reply;
  9554.     int success = 0;
  9555.  
  9556.     rtype = packet_get_string(NULL);
  9557.     want_reply = packet_get_char();
  9558.     debug1("client_input_global_request: rtype %s want_reply %d", rtype, want_reply);
  9559.     if (want_reply) {
  9560.         packet_start(success ?
  9561.             SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
  9562.         packet_send();
  9563.         packet_write_wait();
  9564.     }
  9565.     free(rtype);
  9566.     return 0;
  9567. }
  9568.  
  9569. static void
  9570. client_init_dispatch_20(void)
  9571. {
  9572.     dispatch_init(&dispatch_protocol_error);
  9573.     dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
  9574.     dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
  9575.     dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
  9576.     dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
  9577.     dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
  9578.     dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
  9579.     dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
  9580.     dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
  9581.     dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
  9582.     dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
  9583.  
  9584.     /* rekeying */
  9585.     dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
  9586.  
  9587.     /* global request reply messages */
  9588.     dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
  9589.     dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
  9590. }
  9591. static void
  9592. client_init_dispatch_13(void)
  9593. {
  9594.     dispatch_init(NULL);
  9595.     dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
  9596.     dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
  9597.     dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
  9598.     dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
  9599.     dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
  9600.     dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
  9601.     dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
  9602.     dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
  9603.     dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
  9604.  
  9605.     dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
  9606.                   &auth_input_open_request : &deny_input_open);
  9607.     dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
  9608.                   &x11_input_open : &deny_input_open);
  9609. }
  9610. static void
  9611. client_init_dispatch_15(void)
  9612. {
  9613.     client_init_dispatch_13();
  9614.     dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
  9615.     dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose);
  9616. }
  9617. static void
  9618. client_init_dispatch(void)
  9619. {
  9620.     if (compat20)
  9621.         client_init_dispatch_20();
  9622.     else if (compat13)
  9623.         client_init_dispatch_13();
  9624.     else
  9625.         client_init_dispatch_15();
  9626. }
  9627.  
  9628. /* SSH-KEYGEN */
  9629. static char *
  9630. key_type_name(int type)
  9631. {
  9632.     switch (type)
  9633.     {
  9634.     case KEY_RSA1:
  9635.         return "ssh1-rsa";
  9636.     case KEY_RSA:
  9637.         return "ssh2-rsa";
  9638.     case KEY_DSA:
  9639.         return "ssh2-dsa";
  9640.     case KEY_NULL:
  9641.         return "null";
  9642.     default:
  9643.         return "unspecified";
  9644.     }
  9645. }
  9646.  
  9647. static char identity_file[1024];
  9648.  
  9649. char *
  9650. sshkey_default_file(int type)
  9651. {
  9652.     char buf[1024], buf2[400];
  9653.     char *name = NULL;
  9654.  
  9655.     switch (type) {
  9656.     case KEY_RSA1:
  9657.         name = (char *)_PATH_SSH_CLIENT_IDENTITY;
  9658.         break;
  9659.     case KEY_SRP:
  9660.         name = (char *)_PATH_SSH_USER_VERIFIER;
  9661.         break;
  9662.     case KEY_DSA:
  9663.         name = (char *)_PATH_SSH_CLIENT_ID_DSA;
  9664.         break;
  9665.     case KEY_RSA:
  9666.         name = (char *)_PATH_SSH_CLIENT_ID_RSA;
  9667.         break;
  9668.     default:
  9669.         name = "unknown";
  9670.         break;
  9671.     }
  9672.     snprintf(identity_file, sizeof identity_file, "%s", name);
  9673.     return identity_file;
  9674. }
  9675.  
  9676. static char *
  9677. ask_filename(const char *prompt, int type)
  9678. {
  9679.     char buf[1024], buf2[400];
  9680.     int ok;
  9681.  
  9682.     snprintf(buf2, sizeof(buf2), "%s\n(%s)", prompt, sshkey_default_file(type));
  9683.     ok = uq_txt(NULL,buf2,1,NULL,buf,sizeof(buf),sshkey_default_file(type),DEFAULT_UQ_TIMEOUT);
  9684.     if (ok && strcmp(buf, "") != 0)
  9685.         strlcpy(identity_file, buf, sizeof(identity_file));
  9686.     return identity_file;
  9687. }
  9688.  
  9689. static Key *
  9690. sshkey_load_identity_file(char *filename, char * identity_passphrase)
  9691. {
  9692.     char pass[300];
  9693.     Key *prv;
  9694.  
  9695.     prv = key_load_private(filename, "", NULL);
  9696.     if (prv == NULL) {
  9697.         if (identity_passphrase)
  9698.             ckstrncpy(pass,identity_passphrase,sizeof(pass));
  9699.         else {
  9700.             char preface[256];
  9701.             int ok;
  9702.  
  9703.             ckmakmsg(preface,256,"Loading SSH Identity File: \"",
  9704.                      filename, "\"\n", NULL);
  9705.             ok = uq_txt(preface, "Enter passphrase: ", 2, NULL,
  9706.                         pass,300,NULL,DEFAULT_UQ_TIMEOUT);
  9707.             if (!ok)
  9708.                 pass[0] = '\0';
  9709.         }
  9710.         prv = key_load_private(filename, pass, NULL);
  9711.         memset(pass, 0, strlen(pass));
  9712.     }
  9713.     return prv;
  9714. }
  9715.  
  9716. #define SSH_COM_PUBLIC_BEGIN            "---- BEGIN SSH2 PUBLIC KEY ----"
  9717. #define SSH_COM_PUBLIC_END              "---- END SSH2 PUBLIC KEY ----"
  9718. #define SSH_COM_PRIVATE_BEGIN           "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
  9719. #define SSH_COM_PRIVATE_KEY_MAGIC       0x3f6ff9eb
  9720.  
  9721. int
  9722. sshkey_display_public_as_ssh2(char * filename, char * identity_passphrase)
  9723. {
  9724.     Key *k;
  9725.     int len;
  9726.     u_char *blob;
  9727.     struct _stat st;
  9728.     char kg_hostname[MAXHOSTNAMELEN];
  9729.  
  9730.     if (filename == NULL)
  9731.         filename = ask_filename("Enter file in which the key is", KEY_UNSPEC);
  9732.     if (filename == NULL)
  9733.         return -1;
  9734.     if (stat(filename, &st) < 0) {
  9735.         perror(filename);
  9736.         return -1;
  9737.     }
  9738.     if ((k = key_load_public(filename, NULL)) == NULL) {
  9739.         if ((k = sshkey_load_identity_file(filename, identity_passphrase)) == NULL) {
  9740.             fprintf(stderr, "load failed\n");
  9741.             return -1;
  9742.         }
  9743.     }
  9744.  
  9745.     if (gethostname(kg_hostname, sizeof(kg_hostname)) < 0) {
  9746.         perror("get_hostname");
  9747.         return -1;
  9748.     }
  9749.  
  9750.     if (key_to_blob(k, &blob, &len) <= 0) {
  9751.         fprintf(stderr, "key_to_blob failed\n");
  9752.         return -1;
  9753.     }
  9754.     printf("%s\n", SSH_COM_PUBLIC_BEGIN);
  9755.     printf("Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n",
  9756.              key_size(k), key_type(k),
  9757.              uidbuf, kg_hostname);
  9758.     dump_base64(stdout, blob, len);
  9759.     printf("%s\n", SSH_COM_PUBLIC_END);
  9760.     key_free(k);
  9761.     free(blob);
  9762.     return 0;
  9763. }
  9764.  
  9765. static int
  9766. buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
  9767. {
  9768.     int bits = buffer_get_int(b);
  9769.     int bytes = (bits + 7) / 8;
  9770.  
  9771.     if (buffer_len(b) < bytes) {
  9772.         ssh_error(SSH_ERROR_BUFFER_TOO_SMALL,
  9773.                    "buffer_get_bignum_bits: input buffer too small: "
  9774.                    "need %d have %d", bytes, buffer_len(b));
  9775.         return(-1);
  9776.     }
  9777.     BN_bin2bn((u_char *)buffer_ptr(b), bytes, value);
  9778.     buffer_consume(b, bytes);
  9779.     return(0);
  9780. }
  9781.  
  9782. static Key *
  9783. do_convert_private_ssh2_from_blob(char *blob, int blen)
  9784. {
  9785.     Buffer b;
  9786.     Key *key = NULL;
  9787.     char *type, *cipher;
  9788.     u_char *sig, data[] = "abcde12345";
  9789.     int magic, rlen, ktype, i1, i2, i3, i4;
  9790.     u_int slen;
  9791.     u_long e;
  9792.  
  9793.     memset(&b,0,sizeof(Buffer));
  9794.     buffer_init(&b);
  9795.     buffer_append(&b, blob, blen);
  9796.  
  9797.     magic  = buffer_get_int(&b);
  9798.     if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
  9799.         error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);
  9800.         buffer_free(&b);
  9801.         return NULL;
  9802.     }
  9803.     i1 = buffer_get_int(&b);
  9804.     type   = buffer_get_string(&b, NULL);
  9805.     cipher = buffer_get_string(&b, NULL);
  9806.     i2 = buffer_get_int(&b);
  9807.     i3 = buffer_get_int(&b);
  9808.     i4 = buffer_get_int(&b);
  9809.     debug1("ignore (%d %d %d %d)", i1,i2,i3,i4);
  9810.  
  9811.     if (strcmp(cipher, "none") != 0) {
  9812.         error("unsupported cipher %s", cipher);
  9813.         free(cipher);
  9814.         buffer_free(&b);
  9815.         free(type);
  9816.         return NULL;
  9817.     }
  9818.     free(cipher);
  9819.  
  9820.     if (strstr(type, "dsa")) {
  9821.         ktype = KEY_DSA;
  9822.     } else if (strstr(type, "rsa")) {
  9823.         ktype = KEY_RSA;
  9824.     } else {
  9825.         free(type);
  9826.         return NULL;
  9827.     }
  9828.     key = key_new_private(ktype);
  9829.     free(type);
  9830.  
  9831.         switch (key->type) {
  9832.         case KEY_DSA:
  9833.             if (buffer_get_bignum_bits(&b, key->dsa->p) < 0 ||
  9834.                  buffer_get_bignum_bits(&b, key->dsa->g) < 0 ||
  9835.                  buffer_get_bignum_bits(&b, key->dsa->q) < 0 ||
  9836.                  buffer_get_bignum_bits(&b, key->dsa->pub_key) < 0 ||
  9837.                  buffer_get_bignum_bits(&b, key->dsa->priv_key) < 0)
  9838.                 return(NULL);
  9839.             break;
  9840.         case KEY_RSA:
  9841.             e  = buffer_get_char(&b);
  9842.             if (e < 30) {
  9843.                 e <<= 8;
  9844.                 e += buffer_get_char(&b);
  9845.                 e <<= 8;
  9846.                 e += buffer_get_char(&b);
  9847.             }
  9848.             if (!BN_set_word(key->rsa->e, e)) {
  9849.                 buffer_free(&b);
  9850.                 key_free(key);
  9851.                 return NULL;
  9852.             }
  9853.             if (buffer_get_bignum_bits(&b, key->rsa->d) < 0 ||
  9854.                  buffer_get_bignum_bits(&b, key->rsa->n) < 0 ||
  9855.                  buffer_get_bignum_bits(&b, key->rsa->iqmp) < 0 ||
  9856.                  buffer_get_bignum_bits(&b, key->rsa->q) < 0 ||
  9857.                  buffer_get_bignum_bits(&b, key->rsa->p) < 0)
  9858.                 return(NULL);
  9859.             generate_additional_parameters(key->rsa);
  9860.             break;
  9861.         }
  9862.     rlen = buffer_len(&b);
  9863.     if(rlen != 0)
  9864.         error("do_convert_private_ssh2_from_blob: "
  9865.                "remaining bytes in key blob %d", rlen);
  9866.     buffer_free(&b);
  9867.     /* try the key */
  9868.     key_sign(key, &sig, &slen, data, sizeof data);
  9869.     key_verify(key, sig, slen, data, sizeof data);
  9870.     free(sig);
  9871.     return key;
  9872. }
  9873.  
  9874. #ifdef COMMENT
  9875. static int
  9876. do_convert_from_ssh2(char * source, char * dest)
  9877. {
  9878.     Key *k;
  9879.     int blen;
  9880.     char line[1024], *p;
  9881.     u_char blob[8096];
  9882.     char encoded[8096];
  9883.     struct _stat st;
  9884.     int escaped = 0, private = 0, ok;
  9885.     FILE *fp;
  9886.  
  9887.     if (filename == NULL)
  9888.         filename = ask_filename("Enter file in which the key is",KEY_UNSPEC);
  9889.     if (filename == NULL)
  9890.         return -1;
  9891.     if (stat(filename, &st) < 0) {
  9892.         perror(filename);
  9893.         return -1;
  9894.     }
  9895.     fp = fopen(filename, "r");
  9896.     if (fp == NULL) {
  9897.         perror(filename);
  9898.         return -1;
  9899.     }
  9900.     encoded[0] = '\0';
  9901.     while (fgets(line, sizeof(line), fp)) {
  9902.         if (!(p = strchr(line, '\n'))) {
  9903.             fprintf(stderr, "input line too long.\n");
  9904.             return -1;
  9905.         }
  9906.         if (p > line && p[-1] == '\\')
  9907.             escaped++;
  9908.         if (strncmp(line, "----", 4) == 0 ||
  9909.              strstr(line, ": ") != NULL) {
  9910.             if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
  9911.                 private = 1;
  9912.             if (strstr(line, " END ") != NULL) {
  9913.                 break;
  9914.             }
  9915.             /* xfprintf(stderr, "ignore: %s", line); */
  9916.             continue;
  9917.         }
  9918.         if (escaped) {
  9919.             escaped--;
  9920.                         /* xfprintf(stderr, "escaped: %s", line); */
  9921.             continue;
  9922.         }
  9923.         *p = '\0';
  9924.         strlcat(encoded, line, sizeof(encoded));
  9925.     }
  9926.     blen = uudecode(encoded, (u_char *)blob, sizeof(blob));
  9927.     if (blen < 0) {
  9928.         xfprintf(stderr, "uudecode failed.\n");
  9929.         return -1;
  9930.     }
  9931.     k = private ?
  9932.         do_convert_private_ssh2_from_blob(blob, blen) :
  9933.             key_from_blob(blob, blen);
  9934.     if (k == NULL) {
  9935.         fprintf(stderr, "decode blob failed.\n");
  9936.         return -1;
  9937.     }
  9938.     ok = private ?
  9939.         (k->type == KEY_DSA ?
  9940.           PEM_write_DSAPrivateKey(stdout, (char *)k->dsa, NULL, NULL, 0, NULL, NULL) :
  9941.           PEM_write_RSAPrivateKey(stdout, (char *)k->rsa, NULL, NULL, 0, NULL, NULL)) :
  9942.               key_write(k, stdout);
  9943.     if (!ok) {
  9944.         fprintf(stderr, "key write failed");
  9945.         return -1;
  9946.     }
  9947.     key_free(k);
  9948.     fprintf(stdout, "\n");
  9949.     fclose(fp);
  9950.     return 0;
  9951. }
  9952. #endif /* COMMENT */
  9953.  
  9954. #ifdef SMARTCARD
  9955. #define NUM_RSA_KEY_ELEMENTS 5+1
  9956. #define COPY_RSA_KEY(x, i) \
  9957.         do { \
  9958.                 len = BN_num_bytes(prv->rsa->x); \
  9959.                 elements[i] = malloc(len); \
  9960.                 debug1("#bytes %d", len); \
  9961.                 if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
  9962.                         goto done; \
  9963.         } while(0)
  9964.  
  9965. static int
  9966. get_AUT0(char *aut0)
  9967. {
  9968.         EVP_MD *evp_md = EVP_sha1();
  9969.         EVP_MD_CTX md;
  9970.         char *pass;
  9971.  
  9972.         pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
  9973.         if (pass == NULL)
  9974.                 return -1;
  9975.         EVP_DigestInit(&md, evp_md);
  9976.         EVP_DigestUpdate(&md, pass, strlen(pass));
  9977.         EVP_DigestFinal(&md, aut0, NULL);
  9978.         memset(pass, 0, strlen(pass));
  9979.         free(pass);
  9980.         return 0;
  9981. }
  9982.  
  9983. int
  9984. sshkey_do_upload(struct passwd *pw, const char *sc_reader_id, char *identity_passphrase)
  9985. {
  9986.         Key *prv = NULL;
  9987.         struct _stat st;
  9988.         u_char *elements[NUM_RSA_KEY_ELEMENTS];
  9989.         u_char key_fid[2];
  9990.         u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
  9991.         u_char AUT0[EVP_MAX_MD_SIZE];
  9992.         int len, status = 1, i, fd = -1, ret;
  9993.         int sw = 0, cla = 0x00;
  9994.  
  9995.         for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
  9996.                 elements[i] = NULL;
  9997.         if (!have_identity)
  9998.                 ask_filename(pw, "Enter file in which the key is");
  9999.         if (stat(identity_file, &st) < 0) {
  10000.                 perror(identity_file);
  10001.                 goto done;
  10002.         }
  10003.         prv = load_identity(identity_file, identity_passphrase);
  10004.         if (prv == NULL) {
  10005.                 error("load failed");
  10006.                 goto done;
  10007.         }
  10008.         COPY_RSA_KEY(q, 0);
  10009.         COPY_RSA_KEY(p, 1);
  10010.         COPY_RSA_KEY(iqmp, 2);
  10011.         COPY_RSA_KEY(dmq1, 3);
  10012.         COPY_RSA_KEY(dmp1, 4);
  10013.         COPY_RSA_KEY(n, 5);
  10014.         len = BN_num_bytes(prv->rsa->n);
  10015.         fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
  10016.         if (fd < 0) {
  10017.                 error("sectok_open failed: %s", sectok_get_sw(sw));
  10018.                 goto done;
  10019.         }
  10020.         if (! sectok_cardpresent(fd)) {
  10021.                 error("smartcard in reader %s not present",
  10022.                     sc_reader_id);
  10023.                 goto done;
  10024.         }
  10025.         ret = sectok_reset(fd, 0, NULL, &sw);
  10026.         if (ret <= 0) {
  10027.                 error("sectok_reset failed: %s", sectok_get_sw(sw));
  10028.                 goto done;
  10029.         }
  10030.         if ((cla = cyberflex_inq_class(fd)) < 0) {
  10031.                 error("cyberflex_inq_class failed");
  10032.                 goto done;
  10033.         }
  10034.         memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
  10035.         if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
  10036.                 if (get_AUT0(AUT0) < 0 ||
  10037.                     cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
  10038.                         error("cyberflex_verify_AUT0 failed");
  10039.                         goto done;
  10040.                 }
  10041.         }
  10042.         key_fid[0] = 0x00;
  10043.         key_fid[1] = 0x12;
  10044.         if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
  10045.             &sw) < 0) {
  10046.                 error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
  10047.                 goto done;
  10048.         }
  10049.         if (!sectok_swOK(sw))
  10050.                 goto done;
  10051.         log("cyberflex_load_rsa_priv done");
  10052.         key_fid[0] = 0x73;
  10053.         key_fid[1] = 0x68;
  10054.         if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
  10055.             &sw) < 0) {
  10056.                 error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
  10057.                 goto done;
  10058.         }
  10059.         if (!sectok_swOK(sw))
  10060.                 goto done;
  10061.         log("cyberflex_load_rsa_pub done");
  10062.         status = 0;
  10063.         log("loading key done");
  10064. done:
  10065.  
  10066.         memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
  10067.         memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
  10068.         memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
  10069.         memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
  10070.         memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
  10071.         memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
  10072.  
  10073.         if (prv)
  10074.                 key_free(prv);
  10075.         for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
  10076.                 if (elements[i])
  10077.                         free(elements[i]);
  10078.         if (fd != -1)
  10079.                 sectok_close(fd);
  10080.         return(status);
  10081. }
  10082.  
  10083. int
  10084. sshkey_do_download(struct passwd *pw, const char *sc_reader_id)
  10085. {
  10086.         Key *pub = NULL;
  10087.  
  10088.         pub = sc_get_key(sc_reader_id);
  10089.         if (pub == NULL)
  10090.                 fatal("cannot read public key from smartcard");
  10091.         key_write(pub, stdout);
  10092.         key_free(pub);
  10093.         fprintf(stdout, "\n");
  10094.         return(0);
  10095. }
  10096. #endif /* SMARTCARD */
  10097.  
  10098. int
  10099. sshkey_display_public(char * filename, char * identity_passphrase)
  10100. {
  10101.     Key *prv;
  10102.     struct _stat st;
  10103.  
  10104.     if (filename == NULL)
  10105.         filename = ask_filename("Enter file in which the key is",KEY_UNSPEC);
  10106.     if (filename == NULL)
  10107.         return -1;
  10108.     if (stat(filename, &st) < 0) {
  10109.         perror(filename);
  10110.         return -1;
  10111.     }
  10112.     prv = sshkey_load_identity_file(filename,identity_passphrase);
  10113.     if (prv == NULL) {
  10114.         fprintf(stderr, "load failed\n");
  10115.         return -1;
  10116.     }
  10117.     if (!key_write(prv, stdout))
  10118.         fprintf(stderr, "key_write failed");
  10119.     key_free(prv);
  10120.     fprintf(stdout, "\n");
  10121.     return 0;
  10122. }
  10123.  
  10124. int
  10125. sshkey_display_fingerprint(char * filename, int babble)
  10126. {
  10127.     FILE *f;
  10128.     Key *public;
  10129.     char *comment = NULL, *cp, *ep, line[16*1024], *fp;
  10130.     int i, skip = 0, num = 1, invalid = 1, rep, fptype;
  10131.     struct _stat st;
  10132.  
  10133.     fptype = babble ? SSH_FP_SHA1 : SSH_FP_MD5;
  10134.     rep =    babble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
  10135.  
  10136.     if (filename == NULL)
  10137.         filename = ask_filename("Enter file in which the key is",KEY_UNSPEC);
  10138.     if (filename == NULL)
  10139.         return -1;
  10140.     if (stat(filename, &st) < 0) {
  10141.         perror(filename);
  10142.         return -1;
  10143.     }
  10144.  
  10145.     /* Attempt to process the file as a V1 RSA key */
  10146.     public = key_load_public(filename, &comment);
  10147.     if (public != NULL) {
  10148.         fp = key_fingerprint(public, fptype, rep);
  10149.         printf("%d %s %s\n", key_size(public), fp, comment);
  10150.         key_free(public);
  10151.         free(comment);
  10152.         free(fp);
  10153.         return 0;
  10154.     }
  10155.     if (comment)
  10156.         free(comment);
  10157.  
  10158.     /* Its a V2 key */
  10159.     f = fopen(filename, "r");
  10160.     if (f != NULL) {
  10161.         while (fgets(line, sizeof(line), f)) {
  10162.             i = strlen(line) - 1;
  10163.             if (line[i] != '\n') {
  10164.                 error("line %d too long: %.40s...", num, line);
  10165.                 skip = 1;
  10166.                 continue;
  10167.             }
  10168.             num++;
  10169.             if (skip) {
  10170.                 skip = 0;
  10171.                 continue;
  10172.             }
  10173.             line[i] = '\0';
  10174.  
  10175.             /* Skip leading whitespace, empty and comment lines. */
  10176.             for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
  10177.                 ;
  10178.             if (!*cp || *cp == '\n' || *cp == '#')
  10179.                                 continue ;
  10180.             i = strtol(cp, &ep, 10);
  10181.             if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
  10182.                 int quoted = 0;
  10183.                 comment = cp;
  10184.                 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
  10185.                     if (*cp == '\\' && cp[1] == '"')
  10186.                         cp++;   /* Skip both */
  10187.                     else if (*cp == '"')
  10188.                         quoted = !quoted;
  10189.                 }
  10190.                 if (!*cp)
  10191.                     continue;
  10192.                 *cp++ = '\0';
  10193.             }
  10194.             ep = cp;
  10195.             public = key_new(KEY_RSA1);
  10196.             if (key_read(public, &cp) != 1) {
  10197.                 cp = ep;
  10198.                 key_free(public);
  10199.                 public = key_new(KEY_UNSPEC);
  10200.                 if (key_read(public, &cp) != 1) {
  10201.                     key_free(public);
  10202.                     continue;
  10203.                 }
  10204.             }
  10205.             comment = *cp ? cp : comment;
  10206.             fp = key_fingerprint(public, fptype, rep);
  10207.             xprintf("%d %s %s\n", key_size(public), fp,
  10208.                      comment ? comment : "no comment");
  10209.             free(fp);
  10210.             key_free(public);
  10211.             invalid = 0;
  10212.         }
  10213.         fclose(f);
  10214.     }
  10215.     if (invalid) {
  10216.         printf("%s is not a valid key file.\n", filename);
  10217.         return -1;
  10218.     }
  10219.     return 0;
  10220. }
  10221.  
  10222. /*
  10223.  * Perform changing a passphrase.  The argument is the passwd structure
  10224.  * for the current user.
  10225.  */
  10226. int
  10227. sshkey_change_passphrase(char * filename, char * oldpp, char * newpp)
  10228. {
  10229.     char *comment;
  10230.     char old_passphrase[300], passphrase1[300], passphrase2[300];
  10231.     struct _stat st;
  10232.     Key *private;
  10233.     int ok;
  10234.  
  10235.     if (!filename)
  10236.         filename = ask_filename("Enter name of file in which the key is located.",KEY_DSA);
  10237.     if (filename == NULL)
  10238.         return -1;
  10239.     if (stat(filename, &st) < 0) {
  10240.         perror(filename);
  10241.         return -1;
  10242.     }
  10243.     /* Try to load the file with empty passphrase. */
  10244.     private = key_load_private(filename, "", &comment);
  10245.     if (private == NULL) {
  10246.         if (oldpp) {
  10247.             strncpy(old_passphrase,oldpp,sizeof(old_passphrase));
  10248.             ok = 1;
  10249.         } else {
  10250.             char preface[512];
  10251.             ckmakmsg(preface,512,"Enter old passphrase to access '",
  10252.                       filename,"'.\n",NULL);
  10253.             ok = uq_txt(preface,"Old Passphrase: ",2,NULL,old_passphrase, 
  10254.                          sizeof(old_passphrase),NULL,DEFAULT_UQ_TIMEOUT);
  10255.         }
  10256.         if ( !ok ) {
  10257.             printf("Cancelled\n");
  10258.             return(-1);
  10259.         }
  10260.         private = key_load_private(filename, old_passphrase , &comment);
  10261.         memset(old_passphrase, 0, strlen(old_passphrase));
  10262.         if (private == NULL) {
  10263.             printf("Bad passphrase.\n");
  10264.             return -1;
  10265.         }
  10266.     }
  10267.     printf("Key has comment '%s'\n", comment);
  10268.  
  10269.     /* Ask the new passphrase (twice). */
  10270.     if (newpp) {
  10271.         ckstrncpy(passphrase1,newpp,sizeof(passphrase1));
  10272.         passphrase2[0] = '\0';
  10273.         ok = 1;
  10274.     } else {
  10275.         struct txtbox tb[2];
  10276.         tb[0].t_buf = passphrase1;
  10277.         tb[0].t_len = sizeof(passphrase1);
  10278.         tb[0].t_lbl = "New passphrase (empty for no passphrase): ";
  10279.         tb[0].t_dflt = NULL;
  10280.         tb[0].t_echo = 2;
  10281.         tb[1].t_buf = passphrase2;
  10282.         tb[1].t_len = sizeof(passphrase2);
  10283.         tb[1].t_lbl = "New passphrase (again): ";
  10284.         tb[1].t_dflt = NULL;
  10285.         tb[1].t_echo = 2;
  10286.  
  10287.         ok = uq_mtxt(NULL, NULL, 2, tb);
  10288.  
  10289.         if ( !ok ) {
  10290.             printf("Cancelled\n");
  10291.             return(-1);
  10292.         }
  10293.  
  10294.         /* Verify that they are the same. */
  10295.         if (strcmp(passphrase1, passphrase2) != 0) {
  10296.             memset(passphrase1, 0, strlen(passphrase1));
  10297.             memset(passphrase2, 0, strlen(passphrase2));
  10298.             printf("Pass phrases do not match.  Try again.\n");
  10299.             return -1;
  10300.         }
  10301.         /* Destroy the other copy. */
  10302.         memset(passphrase2, 0, strlen(passphrase2));
  10303.     }
  10304.  
  10305.     /* Save the file using the new passphrase. */
  10306.     if (!key_save_private(private, filename, passphrase1, comment)) {
  10307.         printf("Saving the key failed: %s.\n", filename);
  10308.         memset(passphrase1, 0, strlen(passphrase1));
  10309.         key_free(private);
  10310.         free(comment);
  10311.         return -1;
  10312.     }
  10313.     /* Destroy the passphrase and the copy of the key in memory. */
  10314.     memset(passphrase1, 0, strlen(passphrase1));
  10315.     key_free(private);           /* Destroys contents */
  10316.     free(comment);
  10317.  
  10318.     printf("Your identification has been saved with the new passphrase.\n");
  10319.     return 0;
  10320. }
  10321.  
  10322. /*
  10323.  * Change the comment of a private key file.
  10324.  */
  10325. int
  10326. sshkey_v1_change_comment(char * filename, char * new_comment, char * pp)
  10327. {
  10328.     char buf[1024], *comment, passphrase[300], pubfile[300];
  10329.     Key *private;
  10330.     Key *public;
  10331.     struct _stat st;
  10332.     FILE *f;
  10333.     int fd, ok;
  10334.  
  10335.     if (filename == NULL)
  10336.         filename = ask_filename("Enter file in which the key is",KEY_RSA1);
  10337.     if (filename == NULL)
  10338.         return -1;
  10339.     if (stat(filename, &st) < 0) {
  10340.         perror(filename);
  10341.         return -1;
  10342.     }
  10343.     private = key_load_private(filename, "", &comment);
  10344.     if (private == NULL) {
  10345.         if (pp) {
  10346.             strncpy(passphrase, pp, sizeof(passphrase));
  10347.             ok = 1;
  10348.         } else {
  10349.             ok = uq_txt(NULL,"Enter passphrase: ",2,NULL, 
  10350.                         passphrase, sizeof(passphrase), NULL,DEFAULT_UQ_TIMEOUT);
  10351.         }
  10352.  
  10353.         if ( !ok ) {
  10354.             printf("Cancelled\n");
  10355.             return(-1);
  10356.         }
  10357.  
  10358.         /* Try to load using the passphrase. */
  10359.         private = key_load_private(filename, passphrase, &comment);
  10360.         if (private == NULL) {
  10361.             memset(passphrase, 0, strlen(passphrase));
  10362.             printf("Bad passphrase.\n");
  10363.             return -1;
  10364.         }
  10365.     } else {
  10366.         passphrase[0] = '\0';
  10367.     }
  10368.     if (private->type != KEY_RSA1) {
  10369.         xfprintf(stderr, "Comments are only supported for RSA1 keys.\n");
  10370.         key_free(private);
  10371.         return -1;
  10372.     }
  10373.  
  10374.     if (new_comment == NULL) {
  10375.         char preface[256];
  10376.         int ok;
  10377.         ckmakmsg(preface,256,"Old Comment '",comment,"'\n",NULL);
  10378.         ok = uq_txt(preface,"New Comment: ",1,NULL,buf,sizeof(buf),NULL,DEFAULT_UQ_TIMEOUT);
  10379.         if ( !ok ) {
  10380.             printf("Cancelled\n");
  10381.             memset(passphrase, 0, strlen(passphrase));
  10382.             key_free(private);
  10383.             free(comment);
  10384.         }
  10385.         new_comment = buf;
  10386.     } else {
  10387.         printf("Old comment '%s'\n", comment);
  10388.         printf("New comment '%s'\n", new_comment);
  10389.     }
  10390.  
  10391.     /* Save the file using the new passphrase. */
  10392.     if (!key_save_private(private, filename, passphrase, new_comment)) {
  10393.         printf("Saving the key failed: %s.\n", filename);
  10394.         memset(passphrase, 0, strlen(passphrase));
  10395.         key_free(private);
  10396.         free(comment);
  10397.         return -1;
  10398.     }
  10399.     memset(passphrase, 0, strlen(passphrase));
  10400.     public = key_from_private(private);
  10401.     key_free(private);
  10402.  
  10403.     ckstrncpy(pubfile,filename,sizeof(pubfile));
  10404.     ckstrncat(pubfile,".pub",sizeof(pubfile));
  10405.     fd = open(pubfile, _O_WRONLY | _O_CREAT | _O_TRUNC, 0644);
  10406.         if (fd == -1) {
  10407.             printf("Could not save your public key in %s\n", pubfile);
  10408.             return -1;
  10409.         }
  10410.     f = _fdopen(fd, "w");
  10411.     if (f == NULL) {
  10412.         printf("_fdopen %s failed", pubfile);
  10413.         return -1;
  10414.     }
  10415.     if (!key_write(public, f))
  10416.         fprintf(stderr, "write key failed");
  10417.     key_free(public);
  10418.     fprintf(f, " %s\n", new_comment);
  10419.     fclose(f);
  10420.  
  10421.     free(comment);
  10422.  
  10423.     printf("The comment in your key file has been changed.\n");
  10424.     return 0;
  10425. }
  10426.  
  10427. #ifdef CK_SRP
  10428. /* Keep track of the number of different bit sizes we know. */
  10429.  
  10430. typedef struct bitslist BITSLIST;
  10431. struct bitslist {
  10432.     int bits;
  10433.     int count;
  10434.     BITSLIST *next;
  10435. };
  10436.  
  10437. static BITSLIST *Bits = NULL;
  10438.  
  10439. static BITSLIST *
  10440. bits_new(int bits, BITSLIST *next)
  10441. {
  10442.     BITSLIST *p;
  10443.  
  10444.     p = malloc(sizeof(BITSLIST));
  10445.     p->bits = bits;
  10446.     p->count = 1;
  10447.     p->next = next;
  10448.  
  10449.     return p;
  10450. }
  10451.  
  10452. static void
  10453. bits_free(BITSLIST ** pBits)
  10454. {
  10455.     BITSLIST * next;
  10456.  
  10457.     if ( pBits == NULL )
  10458.         return;
  10459.  
  10460.     if ( *pBits == NULL )
  10461.         return;
  10462.  
  10463.     next = (*pBits)->next;
  10464.     free(*pBits);
  10465.     (*pBits) = NULL;
  10466.  
  10467.     if ( next )
  10468.         bits_free(&next);
  10469. }
  10470.  
  10471. static void
  10472. bits_add(int bits)
  10473. {
  10474.     BITSLIST *p, *pp = NULL;
  10475.  
  10476.     /* Do a little insertion sort, just for fun. */
  10477.  
  10478.     if (Bits == NULL) {
  10479.         Bits = bits_new(bits, NULL);
  10480.         return;
  10481.     }
  10482.     for (p = Bits; p; p = p->next) {
  10483.         if (p->bits == bits) {
  10484.             p->count++;
  10485.             return;
  10486.         }
  10487.         if (p->bits > bits)
  10488.             break;
  10489.         pp = p;
  10490.     }
  10491.     if (pp == NULL) {
  10492.         p = Bits;
  10493.         Bits = bits_new(bits, p);
  10494.     } else {
  10495.         p = pp->next;
  10496.         pp->next = bits_new(bits, p);
  10497.     }
  10498. }
  10499.  
  10500. static void
  10501. bits_dump(void)
  10502. {
  10503.     BITSLIST *p;
  10504.  
  10505.     if (!Bits) {
  10506.         fprintf(stderr, "no known prime groups!\n");
  10507.         exit(1);
  10508.     }
  10509.     printf("Known prime group sizes (count):\n");
  10510.     for (p = Bits; p; p = p->next)
  10511.         printf("\t%d (%d)\n", p->bits, p->count);
  10512. }
  10513. #endif /* CK_SRP */
  10514.  
  10515. int
  10516. sshkey_create(char * filename, int bits, char * pp, int type, char * cmd_comment)
  10517. {
  10518.     char dotsshdir[16 * 1024], comment[1024], passphrase1[300], passphrase2[300];
  10519.     char kg_hostname[MAXHOSTNAMELEN];
  10520.     char pubfile[300];
  10521.     Key *private, *public;
  10522.     int fd;
  10523.     struct _stat st;
  10524.     FILE *f;
  10525.     int ok;
  10526.  
  10527.     if (bits < 512 || bits > 32768) {
  10528.         printf("Bits has bad value.\n");
  10529.         return -1;
  10530.     }
  10531.  
  10532.     if (type > KEY_SRP) {
  10533.         fprintf(stderr, "unsupported key type %d\n", type);
  10534.         return -1;
  10535.     }
  10536.  
  10537.     arc4random_stir();
  10538.  
  10539.     if (filename == NULL) {
  10540.         filename = ask_filename("Enter file in which to save the key",type);
  10541.         if (filename == NULL)
  10542.             return -1;
  10543.     }
  10544.  
  10545.     /* Create ~/.ssh directory if it doesn't already exist. */
  10546.     snprintf(dotsshdir, sizeof dotsshdir, "%s", (char *)_PATH_SSH_USER_DIR);
  10547.     if (strstr(filename, dotsshdir) != NULL &&
  10548.         stat(dotsshdir, &st) < 0) {
  10549.         if (mkdir(dotsshdir, 0700) < 0)
  10550.             error("Could not create directory '%s'.", dotsshdir);
  10551.         else if (!quiet)
  10552.             printf("Created directory '%s'.\n", dotsshdir);
  10553.     }
  10554.  
  10555.     /* If the file already exists, ask the user to confirm. */
  10556.     if (stat(filename, &st) >= 0) {
  10557.         char buf[300];
  10558.         int x;
  10559.         snprintf(buf, sizeof buf, "%s already exists.\n Overwrite (y/n)?",
  10560.                  filename);
  10561. #ifdef COMMENT
  10562.         if (!getyesno(buf,0))
  10563.             return -1;
  10564. #else /* COMMENT */
  10565.         x = uq_ok( "Creating SSH Key File",
  10566.                    buf, 3, NULL, 0);
  10567.         if ( x <= 0 ) 
  10568.             return(-1);
  10569. #endif /* COMMENT */
  10570.     }
  10571.  
  10572. #ifdef CK_SRP
  10573.     if ( type == KEY_SRP ) {
  10574.         BIGNUM *p, *g, *s, *x, *v;
  10575.         BN_CTX *ctx, *ctx2;
  10576.         int i, j, c, which, slen;
  10577.         char * salt = NULL, *buf=NULL;
  10578.         FILE *outfile;
  10579.  
  10580.         /* Allocate BIGNUMs and stuff. */
  10581.         if ((ctx = BN_CTX_new()) == NULL)
  10582.             goto err;
  10583.         if ((ctx2 = BN_CTX_new()) == NULL)
  10584.             goto err;
  10585.         BN_CTX_start(ctx);
  10586.         p = BN_CTX_get(ctx);
  10587.         g = BN_CTX_get(ctx);
  10588.         s = BN_CTX_get(ctx);
  10589.         x = BN_CTX_get(ctx);
  10590.         v = BN_CTX_get(ctx);
  10591.         if (v == NULL)
  10592.             goto err;
  10593.  
  10594.         /*
  10595.          * Count the number of primes we know that are bits long.
  10596.          * Just use the built-in values for now.  Better would be
  10597.          * to include the external tables as well, ignoring any
  10598.          * duplicates.  Maybe later.
  10599.          */
  10600.         c = 0;
  10601.         for (i = 0; i < SRP_nparams; i++) {
  10602.             srp_get_param(i, p, g);
  10603.             j = BN_num_bits(p);
  10604.             bits_add(j);
  10605.             if (j == bits)
  10606.                 c++;
  10607.         }
  10608.         if (c == 0) {
  10609.             printf("no primes found with %d bits\n", bits);
  10610.             bits_dump();
  10611.             return(-1);
  10612.         }
  10613.         printf("%d candidate groups found.\n", c);
  10614.  
  10615.         /* Pick one, and get it. */
  10616.         which = arc4random() % c;
  10617.         c = 0;
  10618.         for (i = 0; i < SRP_nparams; i++) {
  10619.             srp_get_param(i, p, g);
  10620.             j = BN_num_bits(p);
  10621.             if (j == bits) {
  10622.                 if (c == which)
  10623.                     break;
  10624.                 c++;
  10625.             }
  10626.         }
  10627.  
  10628.         /* Pick a random salt. */
  10629.  
  10630.         if (!BN_rand(s, SALTLEN, 0, 0))
  10631.             goto err;
  10632.         slen = BN_num_bytes(s);
  10633.         salt = malloc(slen);
  10634.         if (!BN_bn2bin(s, salt))
  10635.             goto err;
  10636.  
  10637.         if ( pp ) {
  10638.             ckstrncpy(passphrase1,pp,sizeof(passphrase1));
  10639.             passphrase2[0] = '\0';
  10640.             ok = 1;
  10641.         } else {
  10642.             struct txtbox tb[2];
  10643.             tb[0].t_buf = passphrase1;
  10644.             tb[0].t_len = sizeof(passphrase1);
  10645.             tb[0].t_lbl = "New passphrase (empty for no passphrase): ";
  10646.             tb[0].t_dflt = NULL;
  10647.             tb[0].t_echo = 2;
  10648.             tb[1].t_buf = passphrase2;
  10649.             tb[1].t_len = sizeof(passphrase2);
  10650.             tb[1].t_lbl = "New passphrase (again): ";
  10651.             tb[1].t_dflt = NULL;
  10652.             tb[1].t_echo = 2;
  10653.  
  10654.             /* Get the (new) passphrase. */
  10655.             snprintf(comment, sizeof(comment),
  10656.                       "Enter SRP passphrase for '%s'\n", uidbuf);
  10657.  
  10658.             ok = uq_mtxt(comment, NULL, 2, tb);
  10659.  
  10660.             if ( !ok ) {
  10661.                 printf("Cancelled\n");
  10662.                 return(-1);
  10663.             }
  10664.  
  10665.             if (strcmp(passphrase1, passphrase2) != 0) {
  10666.                 memset(passphrase1, 0, strlen(passphrase1));
  10667.                 memset(passphrase2, 0, strlen(passphrase2));
  10668.                 fprintf(stderr,"passphrase mismatch, no action taken\n");
  10669.                 return(-1);
  10670.             }
  10671.         }
  10672.  
  10673.         /* Calculate x = HASH(salt | HASH(username | passphrase)). */
  10674.         srp_x_calc(salt, slen, uidbuf, passphrase1, x);
  10675.  
  10676.         memset(passphrase1, 0, strlen(passphrase1));
  10677.         memset(passphrase2, 0, strlen(passphrase2));
  10678.  
  10679.         /* Calculate v = g^x mod p. */
  10680.  
  10681.         if (!BN_mod_exp(v, g, x, p, ctx2))
  10682.             goto err;
  10683.  
  10684.         /* Create the file. */
  10685.  
  10686.         fd = open(filename, _O_WRONLY | _O_CREAT | _O_TRUNC, 0600);
  10687.         if (fd < 0) {
  10688.             fprintf(stderr, "can't create '%s'\n", filename);
  10689.             return(-1);
  10690.         }
  10691.         outfile = _fdopen(fd, "w");
  10692.         if (outfile == NULL) {
  10693.             fprintf(stderr, "can't open '%s'\n", filename);
  10694.             close(fd);
  10695.             return(-1);
  10696.         }
  10697.  
  10698.         /* Convert to base64 and write it all out. */
  10699.         buf = malloc(8 * 1024);
  10700.  
  10701.         fprintf(outfile, "%s:", uidbuf);
  10702.  
  10703.         srp_bn2tfmt(buf, v);
  10704.         fprintf(outfile, "%s:", buf);
  10705.  
  10706.         srp_bn2tfmt(buf, s);
  10707.         fprintf(outfile, "%s::", buf);
  10708.  
  10709.         srp_bn2tfmt(buf, p);
  10710.         fprintf(outfile, "%s:", buf);
  10711.  
  10712.         srp_bn2tfmt(buf, g);
  10713.         fprintf(outfile, "%s\n", buf);
  10714.  
  10715.         fclose(outfile);
  10716.  
  10717.         if ( Bits )
  10718.             bits_free(&Bits);
  10719.         BN_CTX_end(ctx);
  10720.         BN_CTX_free(ctx);
  10721.         BN_CTX_free(ctx2);
  10722.         return 0;
  10723.  
  10724.       err:
  10725.         if ( Bits )
  10726.             bits_free(&Bits);
  10727.         fprintf(stderr, "BIGNUM error\n");
  10728.         return -1;
  10729.     } else
  10730. #endif /* CK_SRP */
  10731.     {
  10732.         if (!quiet)
  10733.             printf("Generating public/private %s key pair.\n", key_type_name(type));
  10734.         private = key_generate(type, bits);
  10735.         if (private == NULL) {
  10736.             fprintf(stderr, "key_generate failed");
  10737.             return -1;
  10738.         }
  10739.         public  = key_from_private(private);
  10740.  
  10741.         /* Ask for a passphrase (twice). */
  10742.         if (pp)
  10743.             ckstrncpy(passphrase1, pp, sizeof(passphrase1));
  10744.         else {
  10745.             struct txtbox tb[2];
  10746.             tb[0].t_buf = passphrase1;
  10747.             tb[0].t_len = sizeof(passphrase1);
  10748.             tb[0].t_lbl = "New passphrase (empty for no passphrase): ";
  10749.             tb[0].t_dflt = NULL;
  10750.             tb[0].t_echo = 2;
  10751.             tb[1].t_buf = passphrase2;
  10752.             tb[1].t_len = sizeof(passphrase2);
  10753.             tb[1].t_lbl = "New passphrase (again): ";
  10754.             tb[1].t_dflt = NULL;
  10755.             tb[1].t_echo = 2;
  10756.  
  10757.             /* Get the (new) passphrase. */
  10758.             snprintf(comment, sizeof(comment),
  10759.                       "Enter SSH passphrase\n");
  10760.  
  10761.             ok = uq_mtxt(comment, NULL, 2, tb);
  10762.  
  10763.             if ( !ok ) {
  10764.                 printf("Cancelled\n");
  10765.                 return(-1);
  10766.             }
  10767.  
  10768.             if (strcmp(passphrase1, passphrase2) != 0) {
  10769.                 fprintf(stderr,
  10770.                          "passphrase mismatch, no action taken\n");
  10771.                 return(-1);
  10772.             }
  10773.             if (strcmp(passphrase1, passphrase2) != 0) {
  10774.                 memset(passphrase1, 0, strlen(passphrase1));
  10775.                 memset(passphrase2, 0, strlen(passphrase2));
  10776.                 fprintf(stderr,"passphrase mismatch, no action taken\n");
  10777.                 return(-1);
  10778.             }
  10779.  
  10780.             /* Clear the other copy of the passphrase. */
  10781.             memset(passphrase2, 0, strlen(passphrase2));
  10782.         }
  10783.  
  10784.         if (cmd_comment) {
  10785.             strlcpy(comment, cmd_comment, sizeof(comment));
  10786.         } else {
  10787.             /* Create default commend field for the passphrase. */
  10788.             if (gethostname(kg_hostname, sizeof(kg_hostname)) < 0) {
  10789.                 perror("get_hostname");
  10790.                 return -1;
  10791.             }
  10792.             snprintf(comment, sizeof comment, "%s@%s", uidbuf, kg_hostname);
  10793.         }
  10794.  
  10795.         /* Save the key with the given passphrase and comment. */
  10796.         if (!key_save_private(private, filename, passphrase1, comment)) {
  10797.             printf("Saving the key failed: %s.\n", filename);
  10798.             memset(passphrase1, 0, strlen(passphrase1));
  10799.             return -1;
  10800.         }
  10801.         /* Clear the passphrase. */
  10802.         memset(passphrase1, 0, strlen(passphrase1));
  10803.  
  10804.         /* Clear the private key and the random number generator. */
  10805.         key_free(private);
  10806.         arc4random_stir();
  10807.  
  10808.         if (!quiet)
  10809.             printf("Your identification has been saved in %s.\n", filename);
  10810.  
  10811.         ckstrncpy(pubfile,filename,sizeof(pubfile));
  10812.         ckstrncat(pubfile,".pub",sizeof(pubfile));
  10813.         fd = open(pubfile, _O_WRONLY | _O_CREAT | _O_TRUNC, 0644);
  10814.         if (fd == -1) {
  10815.             printf("Could not save your public key in %s\n", pubfile);
  10816.             return -1;
  10817.         }
  10818.         f = _fdopen(fd, "w");
  10819.         if (f == NULL) {
  10820.             printf("_fdopen %s failed", pubfile);
  10821.             return -1;
  10822.         }
  10823.         if (!key_write(public, f))
  10824.             fprintf(stderr, "write key failed");
  10825.         fprintf(f, " %s\n", comment);
  10826.         fclose(f);
  10827.  
  10828.         if (!quiet) {
  10829.             char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
  10830.             printf("Your public key has been saved in %s.\n",
  10831.                     pubfile);
  10832.             printf("The key fingerprint is:\n");
  10833.             printf("%s %s\n", fp, comment);
  10834.             free(fp);
  10835.         }
  10836.  
  10837.         key_free(public);
  10838.     }
  10839.     return 0;
  10840. }
  10841.  
  10842. void
  10843. ssh_start_agent(void)
  10844. {
  10845.     extern char exedir[];
  10846.     char buf[CKMAXPATH];
  10847.     STARTUPINFO si;
  10848.     SECURITY_ATTRIBUTES sa;
  10849.     PROCESS_INFORMATION pi;
  10850.     
  10851.     ckstrncpy(buf,exedir,CKMAXPATH);
  10852.     ckstrncat(buf,"ssh-agent.exe",CKMAXPATH);
  10853.  
  10854.     memset( &si, 0, sizeof(STARTUPINFO) );     //  Initialize struct
  10855.     si.cb          = sizeof(STARTUPINFO);
  10856.     si.dwFlags     = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  10857.     si.wShowWindow = 0;        //  Don't show the console window (DOS box)
  10858.  
  10859.     printf("Starting SSH Agent...");
  10860.  
  10861.     if (CreateProcess ( NULL,
  10862.                         buf,
  10863.                         NULL,
  10864.                         NULL,
  10865.                         FALSE, // bInheritHandler
  10866.                         0,
  10867.                         NULL,
  10868.                         NULL,
  10869.                         &si,
  10870.                         &pi)) {
  10871.         CloseHandle(pi.hProcess);
  10872.         CloseHandle(pi.hThread);
  10873.         sleep(3);
  10874.         printf("Complete\n");
  10875.         return;
  10876.     }
  10877.     printf("Failed\n");
  10878. }
  10879.  
  10880. int
  10881. ssh_agent_delete_file(const char *filename)
  10882. {
  10883.     Key *public;
  10884.     char *comment = NULL;
  10885.     int success;
  10886.     AuthenticationConnection *ac = NULL;
  10887.  
  10888.     /* At first, get a connection to the authentication agent. */
  10889.     ac = ssh_get_authentication_connection();
  10890.     if (ac == NULL) {
  10891.         ssh_start_agent();
  10892.         ac = ssh_get_authentication_connection();
  10893.     }
  10894.     if (ac == NULL) {
  10895.         xprintf("?Could not open a connection to authentication agent: ssh-agent.exe.\n");
  10896.         return(-1);
  10897.     }
  10898.  
  10899.     public = key_load_public(filename, &comment);
  10900.     if (public == NULL) {
  10901.         xprintf("Bad key file %s\n", filename);
  10902.         return -1;
  10903.     }
  10904.  
  10905.     if (success = ssh_remove_identity(ac, public)) {
  10906.         if ( comment && strcmp(filename,comment))
  10907.             xfprintf(stderr, "Identity removed: %s (%s)\n", filename, comment);
  10908.         else
  10909.             xfprintf(stderr, "Identity removed: %s\n", filename);
  10910.     } else
  10911.         xfprintf(stderr, "Could not remove identity: %s\n", filename);
  10912.     key_free(public);
  10913.     if (comment) free(comment);
  10914.  
  10915.     ssh_close_authentication_connection(ac);
  10916.     return(success ? 0 : -1);
  10917. }
  10918.  
  10919. /* Send a request to remove all identities. */
  10920. int
  10921. ssh_agent_delete_all(void)
  10922. {
  10923.     int success = 1;
  10924.     AuthenticationConnection *ac = NULL;
  10925.  
  10926.     /* At first, get a connection to the authentication agent. */
  10927.     ac = ssh_get_authentication_connection();
  10928.     if (ac == NULL) {
  10929.         ssh_start_agent();
  10930.         ac = ssh_get_authentication_connection();
  10931.     }
  10932.     if (ac == NULL) {
  10933.         xprintf("?Could not open a connection to authentication agent: ssh-agent.exe.\n");
  10934.         return(-1);
  10935.     }
  10936.  
  10937.     if (!ssh_remove_all_identities(ac, 1))
  10938.         success = 0;
  10939.     /* ignore error-code for ssh2 */
  10940.     ssh_remove_all_identities(ac, 2);
  10941.  
  10942.     if (success)
  10943.         xfprintf(stderr, "All identities removed.\n");
  10944.     else
  10945.         xfprintf(stderr, "Failed to remove all identities.\n");
  10946.  
  10947.     ssh_close_authentication_connection(ac);
  10948.     return(success ? 0 : -1);
  10949. }
  10950.  
  10951. int
  10952. ssh_agent_add_file(const char *filename)
  10953. {
  10954.     struct _stat st;
  10955.     Key *private;
  10956.     char *comment = NULL;
  10957.     char msg[1024], prompt[1024];
  10958.     char pass[300]="";
  10959.     int success;
  10960.     AuthenticationConnection *ac = NULL;
  10961.  
  10962.     /* At first, get a connection to the authentication agent. */
  10963.     ac = ssh_get_authentication_connection();
  10964.     if (ac == NULL) {
  10965.         ssh_start_agent();
  10966.         ac = ssh_get_authentication_connection();
  10967.     }
  10968.     if (ac == NULL) {
  10969.         xprintf("?Could not open a connection to authentication agent: ssh-agent.exe.\n");
  10970.         return(-1);
  10971.     }
  10972.  
  10973.     if (stat(filename, &st) < 0) {
  10974.         perror(filename);
  10975.         return(-1);
  10976.     }
  10977.     /* At first, try empty passphrase */
  10978.     private = key_load_private(filename, "", &comment);
  10979.     /* try last */
  10980.     if (private == NULL) {
  10981.         /* clear passphrase since it did not work */
  10982.         snprintf(msg, sizeof msg, "Passphrase required to access %.200s\n", 
  10983.                  filename);
  10984.         if (comment != NULL)
  10985.             snprintf(prompt, sizeof prompt, "Enter passphrase for \"%.200s\": ",
  10986.                       comment);
  10987.         else
  10988.             snprintf(prompt, sizeof prompt, "Enter passphrase: ");
  10989.  
  10990.         for (;;) {
  10991.             int ok = uq_txt(msg,prompt,2,NULL,pass,300,NULL,DEFAULT_UQ_TIMEOUT);
  10992.             if (!ok || strcmp(pass, "") == 0) {
  10993.                 free(comment);
  10994.                 memset(pass,0,strlen(pass));
  10995.                 return(0);
  10996.             }
  10997.             private = key_load_private(filename, pass, &comment);
  10998.             if (private != NULL)
  10999.                 break;
  11000.             snprintf(msg, sizeof msg, 
  11001.                      "Bad passphrase, try again!\n"
  11002.                      "Need passphrase for %.200s\n",
  11003.                      filename);
  11004.             memset(pass,0,strlen(pass));
  11005.         }
  11006.     }
  11007.     if (success = ssh_add_identity(ac, private, comment ? comment : filename)) {
  11008.         if ( comment && strcmp(filename,comment))
  11009.             xfprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
  11010.         else
  11011.             xfprintf(stderr, "Identity added: %s\n", filename);
  11012.     } else {
  11013.         xfprintf(stderr, "Could not add identity: %s\n", filename);
  11014.     }
  11015.     if (comment) free(comment);
  11016.     key_free(private);
  11017.     ssh_close_authentication_connection(ac);
  11018.     return(success ? 0 : -1);
  11019. }
  11020.  
  11021. int
  11022. ssh_agent_list_identities(int do_fp)
  11023. {
  11024.     Key *key;
  11025.     char *comment, *fp;
  11026.     int had_identities = 0;
  11027.     int version;
  11028.     AuthenticationConnection *ac = NULL;
  11029.  
  11030.     /* At first, get a connection to the authentication agent. */
  11031.     ac = ssh_get_authentication_connection();
  11032.     if (ac == NULL) {
  11033.         ssh_start_agent();
  11034.         ac = ssh_get_authentication_connection();
  11035.     }
  11036.     if (ac == NULL) {
  11037.         xprintf("?Could not open a connection to authentication agent: ssh-agent.exe.\n");
  11038.         return(-1);
  11039.     }
  11040.  
  11041.     for (version = 1; version <= 2; version++) {
  11042.         for (key = ssh_get_first_identity(ac, &comment, version);
  11043.               key != NULL;
  11044.               key = ssh_get_next_identity(ac, &comment, version)) {
  11045.             had_identities = 1;
  11046.             if (do_fp) {
  11047.                 fp = key_fingerprint(key, SSH_FP_MD5,
  11048.                                       SSH_FP_HEX);
  11049.                 xprintf("%d %s %s (%s)\n",
  11050.                          key_size(key), fp, comment, key_type(key));
  11051.                 free(fp);
  11052.             } else {
  11053.                 if (!key_write(key, stdout))
  11054.                     xfprintf(stderr, "key_write failed");
  11055.                 xfprintf(stdout, " %s\n", comment);
  11056.             }
  11057.             key_free(key);
  11058.             free(comment);
  11059.         }
  11060.     }
  11061.     if (!had_identities)
  11062.         xprintf("The agent has no identities.\n");
  11063.     ssh_close_authentication_connection(ac);
  11064.     return (0);
  11065. }
  11066. #endif /* SSHBUILTIN */
  11067. #endif /* CK_SSL */
  11068.  
  11069. #ifdef COMMENT
  11070. ssh [-l login_name] hostname | user@hostname [command]
  11071.  
  11072. ssh  [ - afgknqstvxACNPTX1246]  [ - b  bind_address]  [ -  c
  11073.                                                         cipher_spec]  [ - e  escape_char]  [ - i  identity_file] [-l
  11074.                                                                                                                    login_name] [-m mac_spec] [-o option] [-p port] [-F  config-
  11075.                                                                                                                                                                      file]  [ - L port:host:hostport] [-R port:host:hostport] [-D
  11076.                                                                                                                                                                                                                                 port] hostname | user@hostname [command]
  11077.  
  11078.  
  11079. The options are as follows:
  11080.  
  11081. -a    Disables forwarding of the authentication  agent  con-
  11082. nection.
  11083.  
  11084. -A    Enables forwarding of the authentication agent connec-
  11085. tion.   This  can also be specified on a per-host basis
  11086. in a configuration file.
  11087.  
  11088. -b bind_address
  11089. Specify the interface to transmit from on machines with
  11090. multiple interfaces or aliased addresses.
  11091.  
  11092. -c blowfish|3des|des
  11093. Selects the cipher to use for encrypting  the  session.
  11094. 3des  is used by default.  It is believed to be secure.
  11095. 3des (triple-des) is an encrypt-decrypt-encrypt  triple
  11096.     with  three  different  keys.  blowfish is a fast block
  11097.     cipher, it appears very secure and is much faster  than
  11098.     3des.   des  is  only  supported  in the ssh client for
  11099.     interoperability with legacy protocol 1 implementations
  11100.     that  do  not  support  the  3des  cipher.   Its use is
  11101.     strongly discouraged due to cryptographic weaknesses.
  11102.  
  11103.     -c cipher_spec
  11104.     Additionally, for protocol version 2 a  comma-separated
  11105.     list   of   ciphers   can  be  specified  in  order  of
  11106.     preference.  See Ciphers for more information.
  11107.  
  11108.     -e ch|^ch|none
  11109.     Sets the escape  character  for  sessions  with  a  pty
  11110.     (default:  `~' ) .  The escape character is only recog-
  11111.       nized at the beginning of a line.  The escape character
  11112.       followed  by  a  dot (`.')  closes the connection, fol-
  11113.                              lowed by control-Z suspends the  connection,  and  fol-
  11114.                              lowed  by itself sends the escape character once.  Set-
  11115.                              ting the character to ``none'' disables any escapes and
  11116.                              makes the session fully transparent.
  11117.  
  11118.                              -f    Requests ssh to go to background just  before  command
  11119.                              execution.   This  is useful if ssh is going to ask for
  11120.                              passwords or passphrases, but the user wants it in  the
  11121.                              background.   This  implies -n.  The recommended way to
  11122.                              start X11 programs at a remote site is  with  something
  11123.                              like ssh -f host xterm.
  11124.  
  11125.                              -g    Allows remote hosts  to  connect  to  local  forwarded
  11126.                              ports.
  11127.  
  11128.                              -i identity_file
  11129.                              Selects a file from which the  identity  (private  key)
  11130.                              for  RSA or DSA authentication is read.  The default is
  11131.                              $HOME/.ssh/identity  for  protocol   version   1,   and
  11132.                              $HOME/.ssh/id_rsa  and  $HOME/.ssh/id_dsa  for protocol
  11133.                              version 2.  Identity files may also be specified  on  a
  11134.                              per-host basis in the configuration file.  It is possi-
  11135.                              ble to have multiple -i options (and  multiple  identi-
  11136.                                                                ties specified in configuration files).
  11137.  
  11138.                              -I smartcard_device
  11139.                              Specifies which smartcard device to use.  The  argument
  11140.                              is  the  device  ssh  should  use to communicate with a
  11141.                              smartcard used for storing the user's private RSA key.
  11142.  
  11143.                              - k    Disables  forwarding  of  Kerberos  tickets  and  AFS
  11144.                              tokens.  This may also be specified on a per-host basis
  11145.                              in the configuration file.
  11146.  
  11147.                              -l login_name
  11148.                              Specifies the user to log in as on the remote  machine.
  11149.                              This  also  may be specified on a per-host basis in the
  11150.                              configuration file.
  11151.  
  11152.                              -m mac_spec
  11153.                              Additionally, for protocol version 2 a  comma-separated
  11154.                              list  of  MAC  (message authentication code) algorithms
  11155.                              can be specified in order of preference.  See the  MACs
  11156.                              keyword for more information.
  11157.  
  11158.                              -n    Redirects stdin  from  /dev/null  (actually,  prevents
  11159.                                                                        reading from stdin).  This must be used when ssh is run
  11160.                              in the background.  A common trick is to  use  this  to
  11161.                              run X11 programs on a remote machine.  For example, ssh
  11162.                              -n shadows.cs.hut.fi emacs & will  start  an  emacs  on
  11163.                              shadows.cs.hut.fi,  and  the  X11  connection  will  be
  11164.                              automatically forwarded over an encrypted channel.  The
  11165.                              ssh  program will be put in the background.  (This does
  11166.                                                                             not work  if  ssh  needs  to  ask  for  a  password  or
  11167.                                                                             passphrase; see also the -f option.)
  11168.  
  11169.                              -N    Do not execute a remote command.  This is  useful  for
  11170.                              just forwarding ports (protocol version 2 only).
  11171.  
  11172.                              -o option
  11173.                              Can be used to give options in the format used  in  the
  11174.                              configuration  file.   This  is  useful  for specifying
  11175.                              options for which there  is  no  separate  command-line
  11176.                              flag.
  11177.  
  11178.                              -p port
  11179.                              Port to connect to on the remote  host.   This  can  be
  11180.                              specified  on  a  per-host  basis  in the configuration
  11181.                              file.
  11182.  
  11183.                              -P    Use a non-privileged port  for  outgoing  connections.
  11184.                              This  can be used if a firewall does not permit connec-
  11185.                              tions from privileged ports.   Note  that  this  option
  11186.                              turns off RhostsAuthentication and RhostsRSAAuthentica-
  11187.                              tion for older servers.
  11188.  
  11189.                              -q    Quiet mode.  Causes all warning  and  diagnostic  mes-
  11190.                              sages to be suppressed.
  11191.  
  11192.                              -s    May be used to request invocation of  a  subsystem  on
  11193.                              the remote system. Subsystems are a feature of the SSH2
  11194.                              protocol which facilitate the use of SSH  as  a  secure
  11195.                              transport  for  other applications (eg. sftp). The sub-
  11196.                              system is specified as the remote command.
  11197.  
  11198.                              -t    Force pseudo-tty allocation.  This can be used to exe-
  11199.                              cute   arbitrary  screen-based  programs  on  a  remote
  11200.                              machine, which can be very useful,  e.g.,  when  imple-
  11201.                              menting  menu  services.  Multiple -t options force tty
  11202.                              allocation, even if ssh has no local tty.
  11203.  
  11204.                              -T    Disable pseudo-tty allocation.
  11205.  
  11206.                              -v    Verbose mode.  Causes ssh to print debugging  messages
  11207.                              about  its progress.  This is helpful in debugging con-
  11208.                              nection, authentication,  and  configuration  problems.
  11209.                              Multiple  - v options increases the verbosity.  Maximum
  11210.                              is 3.
  11211.  
  11212.                              -x    Disables X11 forwarding.
  11213.  
  11214.                              -X    Enables X11 forwarding.  This can also be specified on
  11215.                              a per-host basis in a configuration file.
  11216.  
  11217.                              -C    Requests compression of  all  data  (including  stdin,
  11218.                                                                          stdout,  stderr,  and data for forwarded X11 and TCP/IP
  11219.                                                                          connections).  The compression algorithm  is  the  same
  11220.                              used by gzip(1), and the ``level'' can be controlled by
  11221.                              the CompressionLevel option (see  below).   Compression
  11222.                              is desirable on modem lines and other slow connections,
  11223.                              but will only slow down things on fast  networks.   The
  11224.                              default value can be set on a host-by-host basis in the
  11225.                              configuration files; see the Compression option below.
  11226.  
  11227.                              -F configfile
  11228.                              Specifies an alternative per-user  configuration  file.
  11229.                              If  a  configuration file is given on the command line,
  11230.                              the        system-wide        configuration        file
  11231.                              (/etc/ssh/ssh_config) will be ignored.  The default for
  11232.                              the per-user configuration file is $HOME/.ssh/config.
  11233.  
  11234.                              -L port:host:hostport
  11235.                              Specifies that the given port  on  the  local  (client)
  11236.                              host  is  to be forwarded to the given host and port on
  11237.                              the remote side.  This works by allocating a socket  to
  11238.                              listen  to  port on the local side, and whenever a con-
  11239.                              nection is made to this port, the  connection  is  for-
  11240.                              warded  over  the  secure  channel, and a connection is
  11241.                              made to host port hostport  from  the  remote  machine.
  11242.                              Port  forwardings  can  also be specified in the confi-
  11243.                              guration file.  Only root can forward privileged ports.
  11244.                              IPv6  addresses  can  be  specified with an alternative
  11245.                            syntax:  port/host/hostport
  11246.  
  11247.                              -R port:host:hostport
  11248.                              Specifies that the given port on  the  remote  (server)
  11249.                              host  is  to be forwarded to the given host and port on
  11250.                              the local side.  This works by allocating a  socket  to
  11251.                              listen  to port on the remote side, and whenever a con-
  11252.                              nection is made to this port, the  connection  is  for-
  11253.                              warded  over  the  secure  channel, and a connection is
  11254.                              made to host port  hostport  from  the  local  machine.
  11255.                              Port  forwardings  can  also be specified in the confi-
  11256.                              guration file.  Privileged ports can be forwarded  only
  11257.                              when  logging  in  as root on the remote machine.  IPv6
  11258.                              addresses can be specified with an alternative  syntax:
  11259.                              port/host/hostport
  11260.  
  11261.                              -D port
  11262.                              Specifies a local  ``dynamic''  application-level  port
  11263.                              forwarding.   This  works  by  allocating  a  socket to
  11264.                              listen to port on the local side, and whenever  a  con-
  11265.                              nection  is  made  to this port, the connection is for-
  11266.                              warded over the secure  channel,  and  the  application
  11267.                              protocol  is then used to determine where to connect to
  11268.                              from the remote machine.  Currently the SOCKS4 protocol
  11269.                              is  supported,  and  ssh  will  act as a SOCKS4 server.
  11270.                              Only root can forward privileged ports.   Dynamic  port
  11271.                              forwardings  can also be specified in the configuration
  11272.                              file.
  11273.  
  11274.                              -1    Forces ssh to try protocol version 1 only.
  11275.  
  11276.                              -2    Forces ssh to try protocol version 2 only.
  11277.  
  11278.                              -4    Forces ssh to use IPv4 addresses only.
  11279.  
  11280.                              -6    Forces ssh to use IPv6 addresses only.
  11281. #endif /* COMMENT */
  11282.