[BACK]Return to monitor.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/monitor.c between version 1.11.2.4 and 1.12

version 1.11.2.4, 2002/10/11 14:53:06 version 1.12, 2002/06/04 19:42:35
Line 83 
Line 83 
         u_int ivinlen;          u_int ivinlen;
         u_char *ivout;          u_char *ivout;
         u_int ivoutlen;          u_int ivoutlen;
         u_char *ssh1key;  
         u_int ssh1keylen;  
         int ssh1cipher;          int ssh1cipher;
         int ssh1protoflags;          int ssh1protoflags;
         u_char *input;          u_char *input;
Line 116 
Line 114 
 int mm_answer_sesskey(int, Buffer *);  int mm_answer_sesskey(int, Buffer *);
 int mm_answer_sessid(int, Buffer *);  int mm_answer_sessid(int, Buffer *);
   
 #ifdef KRB4  
 int mm_answer_krb4(int, Buffer *);  
 #endif  
 #ifdef KRB5  
 int mm_answer_krb5(int, Buffer *);  
 #endif  
   
 static Authctxt *authctxt;  static Authctxt *authctxt;
 static BIGNUM *ssh1_challenge = NULL;   /* used for ssh1 rsa auth */  static BIGNUM *ssh1_challenge = NULL;   /* used for ssh1 rsa auth */
   
Line 130 
Line 121 
 static u_char *key_blob = NULL;  static u_char *key_blob = NULL;
 static u_int key_bloblen = 0;  static u_int key_bloblen = 0;
 static int key_blobtype = MM_NOKEY;  static int key_blobtype = MM_NOKEY;
 static char *hostbased_cuser = NULL;  static u_char *hostbased_cuser = NULL;
 static char *hostbased_chost = NULL;  static u_char *hostbased_chost = NULL;
 static char *auth_method = "unknown";  static char *auth_method = "unknown";
 static int session_id2_len = 0;  
 static u_char *session_id2 = NULL;  
   
 struct mon_table {  struct mon_table {
         enum monitor_reqtype type;          enum monitor_reqtype type;
Line 196 
Line 185 
     {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},      {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
     {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},      {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
 #endif  #endif
 #ifdef KRB4  
     {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4},  
 #endif  
 #ifdef KRB5  
     {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5},  
 #endif  
     {0, 0, NULL}      {0, 0, NULL}
 };  };
   
Line 271 
Line 254 
                 if (authenticated) {                  if (authenticated) {
                         if (!(ent->flags & MON_AUTHDECIDE))                          if (!(ent->flags & MON_AUTHDECIDE))
                                 fatal("%s: unexpected authentication from %d",                                  fatal("%s: unexpected authentication from %d",
                                     __func__, ent->type);                                      __FUNCTION__, ent->type);
                         if (authctxt->pw->pw_uid == 0 &&                          if (authctxt->pw->pw_uid == 0 &&
                             !auth_root_allowed(auth_method))                              !auth_root_allowed(auth_method))
                                 authenticated = 0;                                  authenticated = 0;
Line 286 
Line 269 
         }          }
   
         if (!authctxt->valid)          if (!authctxt->valid)
                 fatal("%s: authenticated invalid user", __func__);                  fatal("%s: authenticated invalid user", __FUNCTION__);
   
         debug("%s: %s has been authenticated by privileged process",          debug("%s: %s has been authenticated by privileged process",
             __func__, authctxt->user);              __FUNCTION__, authctxt->user);
   
         mm_get_keystate(pmonitor);          mm_get_keystate(pmonitor);
   
Line 323 
Line 306 
 void  void
 monitor_sync(struct monitor *pmonitor)  monitor_sync(struct monitor *pmonitor)
 {  {
         if (options.compression) {          /* The member allocation is not visible, so sync it */
                 /* The member allocation is not visible, so sync it */          mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);
                 mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);  
         }  
 }  }
   
 int  int
Line 342 
Line 323 
         mm_request_receive(pmonitor->m_sendfd, &m);          mm_request_receive(pmonitor->m_sendfd, &m);
         type = buffer_get_char(&m);          type = buffer_get_char(&m);
   
         debug3("%s: checking request %d", __func__, type);          debug3("%s: checking request %d", __FUNCTION__, type);
   
         while (ent->f != NULL) {          while (ent->f != NULL) {
                 if (ent->type == type)                  if (ent->type == type)
Line 352 
Line 333 
   
         if (ent->f != NULL) {          if (ent->f != NULL) {
                 if (!(ent->flags & MON_PERMIT))                  if (!(ent->flags & MON_PERMIT))
                         fatal("%s: unpermitted request %d", __func__,                          fatal("%s: unpermitted request %d", __FUNCTION__,
                             type);                              type);
                 ret = (*ent->f)(pmonitor->m_sendfd, &m);                  ret = (*ent->f)(pmonitor->m_sendfd, &m);
                 buffer_free(&m);                  buffer_free(&m);
   
                 /* The child may use this request only once, disable it */                  /* The child may use this request only once, disable it */
                 if (ent->flags & MON_ONCE) {                  if (ent->flags & MON_ONCE) {
                         debug2("%s: %d used once, disabling now", __func__,                          debug2("%s: %d used once, disabling now", __FUNCTION__,
                             type);                              type);
                         ent->flags &= ~MON_PERMIT;                          ent->flags &= ~MON_PERMIT;
                 }                  }
Line 370 
Line 351 
                 return ret;                  return ret;
         }          }
   
         fatal("%s: unsupported request: %d", __func__, type);          fatal("%s: unsupported request: %d", __FUNCTION__, type);
   
         /* NOTREACHED */          /* NOTREACHED */
         return (-1);          return (-1);
Line 415 
Line 396 
         max = buffer_get_int(m);          max = buffer_get_int(m);
   
         debug3("%s: got parameters: %d %d %d",          debug3("%s: got parameters: %d %d %d",
             __func__, min, want, max);              __FUNCTION__, min, want, max);
         /* We need to check here, too, in case the child got corrupted */          /* We need to check here, too, in case the child got corrupted */
         if (max < min || want < min || max < want)          if (max < min || want < min || max < want)
                 fatal("%s: bad parameters: %d %d %d",                  fatal("%s: bad parameters: %d %d %d",
                     __func__, min, want, max);                      __FUNCTION__, min, want, max);
   
         buffer_clear(m);          buffer_clear(m);
   
Line 448 
Line 429 
         u_int siglen, datlen;          u_int siglen, datlen;
         int keyid;          int keyid;
   
         debug3("%s", __func__);          debug3("%s", __FUNCTION__);
   
         keyid = buffer_get_int(m);          keyid = buffer_get_int(m);
         p = buffer_get_string(m, &datlen);          p = buffer_get_string(m, &datlen);
   
         if (datlen != 20)          if (datlen != 20)
                 fatal("%s: data length incorrect: %u", __func__, datlen);                  fatal("%s: data length incorrect: %d", __FUNCTION__, datlen);
   
         /* save session id, it will be passed on the first call */  
         if (session_id2_len == 0) {  
                 session_id2_len = datlen;  
                 session_id2 = xmalloc(session_id2_len);  
                 memcpy(session_id2, p, session_id2_len);  
         }  
   
         if ((key = get_hostkey_by_index(keyid)) == NULL)          if ((key = get_hostkey_by_index(keyid)) == NULL)
                 fatal("%s: no hostkey from index %d", __func__, keyid);                  fatal("%s: no hostkey from index %d", __FUNCTION__, keyid);
         if (key_sign(key, &signature, &siglen, p, datlen) < 0)          if (key_sign(key, &signature, &siglen, p, datlen) < 0)
                 fatal("%s: key_sign failed", __func__);                  fatal("%s: key_sign failed", __FUNCTION__);
   
         debug3("%s: signature %p(%u)", __func__, signature, siglen);          debug3("%s: signature %p(%d)", __FUNCTION__, signature, siglen);
   
         buffer_clear(m);          buffer_clear(m);
         buffer_put_string(m, signature, siglen);          buffer_put_string(m, signature, siglen);
Line 493 
Line 467 
         struct passwd *pwent;          struct passwd *pwent;
         int allowed = 0;          int allowed = 0;
   
         debug3("%s", __func__);          debug3("%s", __FUNCTION__);
   
         if (authctxt->attempt++ != 0)          if (authctxt->attempt++ != 0)
                 fatal("%s: multiple attempts for getpwnam", __func__);                  fatal("%s: multiple attempts for getpwnam", __FUNCTION__);
   
         login = buffer_get_string(m, NULL);          login = buffer_get_string(m, NULL);
   
Line 527 
Line 501 
         buffer_put_cstring(m, pwent->pw_shell);          buffer_put_cstring(m, pwent->pw_shell);
   
  out:   out:
         debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);          debug3("%s: sending MONITOR_ANS_PWNAM: %d", __FUNCTION__, allowed);
         mm_request_send(socket, MONITOR_ANS_PWNAM, m);          mm_request_send(socket, MONITOR_ANS_PWNAM, m);
   
         /* For SSHv1 allow authentication now */          /* For SSHv1 allow authentication now */
Line 553 
Line 527 
         mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m);          mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m);
   
         if (banner != NULL)          if (banner != NULL)
                 xfree(banner);                  free(banner);
   
         return (0);          return (0);
 }  }
Line 566 
Line 540 
         authctxt->service = buffer_get_string(m, NULL);          authctxt->service = buffer_get_string(m, NULL);
         authctxt->style = buffer_get_string(m, NULL);          authctxt->style = buffer_get_string(m, NULL);
         debug3("%s: service=%s, style=%s",          debug3("%s: service=%s, style=%s",
             __func__, authctxt->service, authctxt->style);              __FUNCTION__, authctxt->service, authctxt->style);
   
         if (strlen(authctxt->style) == 0) {          if (strlen(authctxt->style) == 0) {
                 xfree(authctxt->style);                  xfree(authctxt->style);
Line 581 
Line 555 
 {  {
         static int call_count;          static int call_count;
         char *passwd;          char *passwd;
         int authenticated;          int authenticated, plen;
         u_int plen;  
   
         passwd = buffer_get_string(m, &plen);          passwd = buffer_get_string(m, &plen);
         /* Only authenticate if the context is valid */          /* Only authenticate if the context is valid */
Line 594 
Line 567 
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, authenticated);          buffer_put_int(m, authenticated);
   
         debug3("%s: sending result %d", __func__, authenticated);          debug3("%s: sending result %d", __FUNCTION__, authenticated);
         mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m);          mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m);
   
         call_count++;          call_count++;
Line 625 
Line 598 
         if (res != -1)          if (res != -1)
                 buffer_put_cstring(m, prompts[0]);                  buffer_put_cstring(m, prompts[0]);
   
         debug3("%s: sending challenge res: %d", __func__, res);          debug3("%s: sending challenge res: %d", __FUNCTION__, res);
         mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m);          mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m);
   
         if (res != -1) {          if (res != -1) {
Line 645 
Line 618 
         int authok;          int authok;
   
         if (authctxt->as == 0)          if (authctxt->as == 0)
                 fatal("%s: no bsd auth session", __func__);                  fatal("%s: no bsd auth session", __FUNCTION__);
   
         response = buffer_get_string(m, NULL);          response = buffer_get_string(m, NULL);
         authok = options.challenge_response_authentication &&          authok = options.challenge_response_authentication &&
             auth_userresponse(authctxt->as, response, 0);              auth_userresponse(authctxt->as, response, 0);
         authctxt->as = NULL;          authctxt->as = NULL;
         debug3("%s: <%s> = <%d>", __func__, response, authok);          debug3("%s: <%s> = <%d>", __FUNCTION__, response, authok);
         xfree(response);          xfree(response);
   
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, authok);          buffer_put_int(m, authok);
   
         debug3("%s: sending authenticated: %d", __func__, authok);          debug3("%s: sending authenticated: %d", __FUNCTION__, authok);
         mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m);          mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m);
   
         auth_method = "bsdauth";          auth_method = "bsdauth";
Line 681 
Line 654 
         if (res != -1)          if (res != -1)
                 buffer_put_cstring(m, challenge);                  buffer_put_cstring(m, challenge);
   
         debug3("%s: sending challenge res: %d", __func__, res);          debug3("%s: sending challenge res: %d", __FUNCTION__, res);
         mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m);          mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m);
   
         return (0);          return (0);
Line 705 
Line 678 
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, authok);          buffer_put_int(m, authok);
   
         debug3("%s: sending authenticated: %d", __func__, authok);          debug3("%s: sending authenticated: %d", __FUNCTION__, authok);
         mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m);          mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m);
   
         auth_method = "skey";          auth_method = "skey";
Line 718 
Line 691 
 mm_append_debug(Buffer *m)  mm_append_debug(Buffer *m)
 {  {
         if (auth_debug_init && buffer_len(&auth_debug)) {          if (auth_debug_init && buffer_len(&auth_debug)) {
                 debug3("%s: Appending debug messages for child", __func__);                  debug3("%s: Appending debug messages for child", __FUNCTION__);
                 buffer_append(m, buffer_ptr(&auth_debug),                  buffer_append(m, buffer_ptr(&auth_debug),
                     buffer_len(&auth_debug));                      buffer_len(&auth_debug));
                 buffer_clear(&auth_debug);                  buffer_clear(&auth_debug);
Line 729 
Line 702 
 mm_answer_keyallowed(int socket, Buffer *m)  mm_answer_keyallowed(int socket, Buffer *m)
 {  {
         Key *key;          Key *key;
         char *cuser, *chost;          u_char *cuser, *chost, *blob;
         u_char *blob;  
         u_int bloblen;          u_int bloblen;
         enum mm_keytype type = 0;          enum mm_keytype type = 0;
         int allowed = 0;          int allowed = 0;
   
         debug3("%s entering", __func__);          debug3("%s entering", __FUNCTION__);
   
         type = buffer_get_int(m);          type = buffer_get_int(m);
         cuser = buffer_get_string(m, NULL);          cuser = buffer_get_string(m, NULL);
Line 746 
Line 718 
   
         if ((compat20 && type == MM_RSAHOSTKEY) ||          if ((compat20 && type == MM_RSAHOSTKEY) ||
             (!compat20 && type != MM_RSAHOSTKEY))              (!compat20 && type != MM_RSAHOSTKEY))
                 fatal("%s: key type and protocol mismatch", __func__);                  fatal("%s: key type and protocol mismatch", __FUNCTION__);
   
         debug3("%s: key_from_blob: %p", __func__, key);          debug3("%s: key_from_blob: %p", __FUNCTION__, key);
   
         if (key != NULL && authctxt->pw != NULL) {          if (key != NULL && authctxt->pw != NULL) {
                 switch(type) {                  switch(type) {
Line 768 
Line 740 
                             cuser, chost, key);                              cuser, chost, key);
                         break;                          break;
                 default:                  default:
                         fatal("%s: unknown key type %d", __func__, type);                          fatal("%s: unknown key type %d", __FUNCTION__, type);
                         break;                          break;
                 }                  }
                 key_free(key);                  key_free(key);
Line 787 
Line 759 
         }          }
   
         debug3("%s: key %p is %s",          debug3("%s: key %p is %s",
             __func__, key, allowed ? "allowed" : "disallowed");              __FUNCTION__, key, allowed ? "allowed" : "disallowed");
   
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, allowed);          buffer_put_int(m, allowed);
Line 806 
Line 778 
 monitor_valid_userblob(u_char *data, u_int datalen)  monitor_valid_userblob(u_char *data, u_int datalen)
 {  {
         Buffer b;          Buffer b;
         char *p;          u_char *p;
         u_int len;          u_int len;
         int fail = 0;          int fail = 0;
           int session_id2_len = 20 /*XXX should get from [net] */;
   
         buffer_init(&b);          buffer_init(&b);
         buffer_append(&b, data, datalen);          buffer_append(&b, data, datalen);
   
         if (datafellows & SSH_OLD_SESSIONID) {          if (datafellows & SSH_OLD_SESSIONID) {
                 p = buffer_ptr(&b);  
                 len = buffer_len(&b);  
                 if ((session_id2 == NULL) ||  
                     (len < session_id2_len) ||  
                     (memcmp(p, session_id2, session_id2_len) != 0))  
                         fail++;  
                 buffer_consume(&b, session_id2_len);                  buffer_consume(&b, session_id2_len);
         } else {          } else {
                 p = buffer_get_string(&b, &len);                  xfree(buffer_get_string(&b, &len));
                 if ((session_id2 == NULL) ||                  if (len != session_id2_len)
                     (len != session_id2_len) ||  
                     (memcmp(p, session_id2, session_id2_len) != 0))  
                         fail++;                          fail++;
                 xfree(p);  
         }          }
         if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)          if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
                 fail++;                  fail++;
Line 859 
Line 823 
 }  }
   
 static int  static int
 monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,  monitor_valid_hostbasedblob(u_char *data, u_int datalen, u_char *cuser,
     char *chost)      u_char *chost)
 {  {
         Buffer b;          Buffer b;
         char *p;          u_char *p;
         u_int len;          u_int len;
         int fail = 0;          int fail = 0;
           int session_id2_len = 20 /*XXX should get from [net] */;
   
         buffer_init(&b);          buffer_init(&b);
         buffer_append(&b, data, datalen);          buffer_append(&b, data, datalen);
   
         p = buffer_get_string(&b, &len);          xfree(buffer_get_string(&b, &len));
         if ((session_id2 == NULL) ||          if (len != session_id2_len)
             (len != session_id2_len) ||  
             (memcmp(p, session_id2, session_id2_len) != 0))  
                 fail++;                  fail++;
         xfree(p);  
   
         if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)          if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
                 fail++;                  fail++;
         p = buffer_get_string(&b, NULL);          p = buffer_get_string(&b, NULL);
Line 929 
Line 890 
   
         if (hostbased_cuser == NULL || hostbased_chost == NULL ||          if (hostbased_cuser == NULL || hostbased_chost == NULL ||
           !monitor_allowed_key(blob, bloblen))            !monitor_allowed_key(blob, bloblen))
                 fatal("%s: bad key, not previously allowed", __func__);                  fatal("%s: bad key, not previously allowed", __FUNCTION__);
   
         key = key_from_blob(blob, bloblen);          key = key_from_blob(blob, bloblen);
         if (key == NULL)          if (key == NULL)
                 fatal("%s: bad public key blob", __func__);                  fatal("%s: bad public key blob", __FUNCTION__);
   
         switch (key_blobtype) {          switch (key_blobtype) {
         case MM_USERKEY:          case MM_USERKEY:
Line 948 
Line 909 
                 break;                  break;
         }          }
         if (!valid_data)          if (!valid_data)
                 fatal("%s: bad signature data blob", __func__);                  fatal("%s: bad signature data blob", __FUNCTION__);
   
         verified = key_verify(key, signature, signaturelen, data, datalen);          verified = key_verify(key, signature, signaturelen, data, datalen);
         debug3("%s: key %p signature %s",          debug3("%s: key %p signature %s",
             __func__, key, verified ? "verified" : "unverified");              __FUNCTION__, key, verified ? "verified" : "unverified");
   
         key_free(key);          key_free(key);
         xfree(blob);          xfree(blob);
         xfree(signature);          xfree(signature);
         xfree(data);          xfree(data);
   
         auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";  
   
         monitor_reset_key_state();          monitor_reset_key_state();
   
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, verified);          buffer_put_int(m, verified);
         mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);          mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);
   
           auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
   
         return (verified);          return (verified);
 }  }
   
Line 981 
Line 942 
          * the address be 0.0.0.0.           * the address be 0.0.0.0.
          */           */
         memset(&from, 0, sizeof(from));          memset(&from, 0, sizeof(from));
         fromlen = sizeof(from);  
         if (packet_connection_is_on_socket()) {          if (packet_connection_is_on_socket()) {
                   fromlen = sizeof(from);
                 if (getpeername(packet_get_connection_in(),                  if (getpeername(packet_get_connection_in(),
                         (struct sockaddr *) & from, &fromlen) < 0) {                          (struct sockaddr *) & from, &fromlen) < 0) {
                         debug("getpeername: %.100s", strerror(errno));                          debug("getpeername: %.100s", strerror(errno));
Line 992 
Line 953 
         /* Record that there was a login on that tty from the remote host. */          /* Record that there was a login on that tty from the remote host. */
         record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,          record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,
             get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),              get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
             (struct sockaddr *)&from, fromlen);              (struct sockaddr *)&from);
 }  }
   
 static void  static void
 mm_session_close(Session *s)  mm_session_close(Session *s)
 {  {
         debug3("%s: session %d pid %d", __func__, s->self, s->pid);          debug3("%s: session %d pid %d", __FUNCTION__, s->self, s->pid);
         if (s->ttyfd != -1) {          if (s->ttyfd != -1) {
                 debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ptyfd);                  debug3("%s: tty %s ptyfd %d",  __FUNCTION__, s->tty, s->ptyfd);
                 fatal_remove_cleanup(session_pty_cleanup2, (void *)s);                  fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
                 session_pty_cleanup2(s);                  session_pty_cleanup2(s);
         }          }
Line 1014 
Line 975 
         Session *s;          Session *s;
         int res, fd0;          int res, fd0;
   
         debug3("%s entering", __func__);          debug3("%s entering", __FUNCTION__);
   
         buffer_clear(m);          buffer_clear(m);
         s = session_new();          s = session_new();
Line 1038 
Line 999 
   
         /* We need to trick ttyslot */          /* We need to trick ttyslot */
         if (dup2(s->ttyfd, 0) == -1)          if (dup2(s->ttyfd, 0) == -1)
                 fatal("%s: dup2", __func__);                  fatal("%s: dup2", __FUNCTION__);
   
         mm_record_login(s, authctxt->pw);          mm_record_login(s, authctxt->pw);
   
Line 1047 
Line 1008 
   
         /* make sure nothing uses fd 0 */          /* make sure nothing uses fd 0 */
         if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)          if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
                 fatal("%s: open(/dev/null): %s", __func__, strerror(errno));                  fatal("%s: open(/dev/null): %s", __FUNCTION__, strerror(errno));
         if (fd0 != 0)          if (fd0 != 0)
                 error("%s: fd0 %d != 0", __func__, fd0);                  error("%s: fd0 %d != 0", __FUNCTION__, fd0);
   
         /* slave is not needed */          /* slave is not needed */
         close(s->ttyfd);          close(s->ttyfd);
Line 1057 
Line 1018 
         /* no need to dup() because nobody closes ptyfd */          /* no need to dup() because nobody closes ptyfd */
         s->ptymaster = s->ptyfd;          s->ptymaster = s->ptyfd;
   
         debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ttyfd);          debug3("%s: tty %s ptyfd %d",  __FUNCTION__, s->tty, s->ttyfd);
   
         return (0);          return (0);
   
Line 1075 
Line 1036 
         Session *s;          Session *s;
         char *tty;          char *tty;
   
         debug3("%s entering", __func__);          debug3("%s entering", __FUNCTION__);
   
         tty = buffer_get_string(m, NULL);          tty = buffer_get_string(m, NULL);
         if ((s = session_by_tty(tty)) != NULL)          if ((s = session_by_tty(tty)) != NULL)
Line 1095 
Line 1056 
         monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);          monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
   
         if ((p = BN_new()) == NULL)          if ((p = BN_new()) == NULL)
                 fatal("%s: BN_new", __func__);                  fatal("%s: BN_new", __FUNCTION__);
   
         buffer_get_bignum2(m, p);          buffer_get_bignum2(m, p);
   
Line 1120 
Line 1081 
 {  {
         int i;          int i;
   
         debug3("%s entering", __func__);          debug3("%s entering", __FUNCTION__);
   
         if (buffer_len(m) != 16)          if (buffer_len(m) != 16)
                 fatal("%s: bad ssh1 session id", __func__);                  fatal("%s: bad ssh1 session id", __FUNCTION__);
         for (i = 0; i < 16; i++)          for (i = 0; i < 16; i++)
                 session_id[i] = buffer_get_char(m);                  session_id[i] = buffer_get_char(m);
   
Line 1142 
Line 1103 
         u_int blen = 0;          u_int blen = 0;
         int allowed = 0;          int allowed = 0;
   
         debug3("%s entering", __func__);          debug3("%s entering", __FUNCTION__);
   
         if (options.rsa_authentication && authctxt->valid) {          if (options.rsa_authentication && authctxt->valid) {
                 if ((client_n = BN_new()) == NULL)                  if ((client_n = BN_new()) == NULL)
                         fatal("%s: BN_new", __func__);                          fatal("%s: BN_new", __FUNCTION__);
                 buffer_get_bignum2(m, client_n);                  buffer_get_bignum2(m, client_n);
                 allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key);                  allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key);
                 BN_clear_free(client_n);                  BN_clear_free(client_n);
Line 1160 
Line 1121 
         if (allowed && key != NULL) {          if (allowed && key != NULL) {
                 key->type = KEY_RSA;    /* cheat for key_to_blob */                  key->type = KEY_RSA;    /* cheat for key_to_blob */
                 if (key_to_blob(key, &blob, &blen) == 0)                  if (key_to_blob(key, &blob, &blen) == 0)
                         fatal("%s: key_to_blob failed", __func__);                          fatal("%s: key_to_blob failed", __FUNCTION__);
                 buffer_put_string(m, blob, blen);                  buffer_put_string(m, blob, blen);
   
                 /* Save temporarily for comparison in verify */                  /* Save temporarily for comparison in verify */
Line 1186 
Line 1147 
         u_char *blob;          u_char *blob;
         u_int blen;          u_int blen;
   
         debug3("%s entering", __func__);          debug3("%s entering", __FUNCTION__);
   
         if (!authctxt->valid)          if (!authctxt->valid)
                 fatal("%s: authctxt not valid", __func__);                  fatal("%s: authctxt not valid", __FUNCTION__);
         blob = buffer_get_string(m, &blen);          blob = buffer_get_string(m, &blen);
         if (!monitor_allowed_key(blob, blen))          if (!monitor_allowed_key(blob, blen))
                 fatal("%s: bad key, not previously allowed", __func__);                  fatal("%s: bad key, not previously allowed", __FUNCTION__);
         if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)          if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
                 fatal("%s: key type mismatch", __func__);                  fatal("%s: key type mismatch", __FUNCTION__);
         if ((key = key_from_blob(blob, blen)) == NULL)          if ((key = key_from_blob(blob, blen)) == NULL)
                 fatal("%s: received bad key", __func__);                  fatal("%s: received bad key", __FUNCTION__);
   
         if (ssh1_challenge)          if (ssh1_challenge)
                 BN_clear_free(ssh1_challenge);                  BN_clear_free(ssh1_challenge);
Line 1205 
Line 1166 
         buffer_clear(m);          buffer_clear(m);
         buffer_put_bignum2(m, ssh1_challenge);          buffer_put_bignum2(m, ssh1_challenge);
   
         debug3("%s sending reply", __func__);          debug3("%s sending reply", __FUNCTION__);
         mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m);          mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m);
   
         monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);          monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);
Line 1220 
Line 1181 
         u_int blen, len;          u_int blen, len;
         int success;          int success;
   
         debug3("%s entering", __func__);          debug3("%s entering", __FUNCTION__);
   
         if (!authctxt->valid)          if (!authctxt->valid)
                 fatal("%s: authctxt not valid", __func__);                  fatal("%s: authctxt not valid", __FUNCTION__);
         if (ssh1_challenge == NULL)          if (ssh1_challenge == NULL)
                 fatal("%s: no ssh1_challenge", __func__);                  fatal("%s: no ssh1_challenge", __FUNCTION__);
   
         blob = buffer_get_string(m, &blen);          blob = buffer_get_string(m, &blen);
         if (!monitor_allowed_key(blob, blen))          if (!monitor_allowed_key(blob, blen))
                 fatal("%s: bad key, not previously allowed", __func__);                  fatal("%s: bad key, not previously allowed", __FUNCTION__);
         if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)          if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
                 fatal("%s: key type mismatch: %d", __func__, key_blobtype);                  fatal("%s: key type mismatch: %d", __FUNCTION__, key_blobtype);
         if ((key = key_from_blob(blob, blen)) == NULL)          if ((key = key_from_blob(blob, blen)) == NULL)
                 fatal("%s: received bad key", __func__);                  fatal("%s: received bad key", __FUNCTION__);
         response = buffer_get_string(m, &len);          response = buffer_get_string(m, &len);
         if (len != 16)          if (len != 16)
                 fatal("%s: received bad response to challenge", __func__);                  fatal("%s: received bad response to challenge", __FUNCTION__);
         success = auth_rsa_verify_response(key, ssh1_challenge, response);          success = auth_rsa_verify_response(key, ssh1_challenge, response);
   
         key_free(key);          key_free(key);
Line 1256 
Line 1217 
         return (success);          return (success);
 }  }
   
 #ifdef KRB4  
 int  int
 mm_answer_krb4(int socket, Buffer *m)  
 {  
         KTEXT_ST auth, reply;  
         char  *client, *p;  
         int success;  
         u_int alen;  
   
         reply.length = auth.length = 0;  
   
         p = buffer_get_string(m, &alen);  
         if (alen >=  MAX_KTXT_LEN)  
                  fatal("%s: auth too large", __func__);  
         memcpy(auth.dat, p, alen);  
         auth.length = alen;  
         memset(p, 0, alen);  
         xfree(p);  
   
         success = options.kerberos_authentication &&  
             authctxt->valid &&  
             auth_krb4(authctxt, &auth, &client, &reply);  
   
         memset(auth.dat, 0, alen);  
         buffer_clear(m);  
         buffer_put_int(m, success);  
   
         if (success) {  
                 buffer_put_cstring(m, client);  
                 buffer_put_string(m, reply.dat, reply.length);  
                 if (client)  
                         xfree(client);  
                 if (reply.length)  
                         memset(reply.dat, 0, reply.length);  
         }  
   
         debug3("%s: sending result %d", __func__, success);  
         mm_request_send(socket, MONITOR_ANS_KRB4, m);  
   
         auth_method = "kerberos";  
   
         /* Causes monitor loop to terminate if authenticated */  
         return (success);  
 }  
 #endif  
   
 #ifdef KRB5  
 int  
 mm_answer_krb5(int socket, Buffer *m)  
 {  
         krb5_data tkt, reply;  
         char *client_user;  
         u_int len;  
         int success;  
   
         /* use temporary var to avoid size issues on 64bit arch */  
         tkt.data = buffer_get_string(m, &len);  
         tkt.length = len;  
   
         success = options.kerberos_authentication &&  
             authctxt->valid &&  
             auth_krb5(authctxt, &tkt, &client_user, &reply);  
   
         if (tkt.length)  
                 xfree(tkt.data);  
   
         buffer_clear(m);  
         buffer_put_int(m, success);  
   
         if (success) {  
                 buffer_put_cstring(m, client_user);  
                 buffer_put_string(m, reply.data, reply.length);  
                 if (client_user)  
                         xfree(client_user);  
                 if (reply.length)  
                         xfree(reply.data);  
         }  
         mm_request_send(socket, MONITOR_ANS_KRB5, m);  
   
         return success;  
 }  
 #endif  
   
 int  
 mm_answer_term(int socket, Buffer *req)  mm_answer_term(int socket, Buffer *req)
 {  {
         extern struct monitor *pmonitor;          extern struct monitor *pmonitor;
         int res, status;          int res, status;
   
         debug3("%s: tearing down sessions", __func__);          debug3("%s: tearing down sessions", __FUNCTION__);
   
         /* The child is terminating */          /* The child is terminating */
         session_destroy_all(&mm_session_close);          session_destroy_all(&mm_session_close);
Line 1367 
Line 1245 
                 set_newkeys(MODE_IN);                  set_newkeys(MODE_IN);
                 set_newkeys(MODE_OUT);                  set_newkeys(MODE_OUT);
         } else {          } else {
                   u_char key[SSH_SESSION_KEY_LENGTH];
   
                   memset(key, 'a', sizeof(key));
                 packet_set_protocol_flags(child_state.ssh1protoflags);                  packet_set_protocol_flags(child_state.ssh1protoflags);
                 packet_set_encryption_key(child_state.ssh1key,                  packet_set_encryption_key(key, SSH_SESSION_KEY_LENGTH,
                     child_state.ssh1keylen, child_state.ssh1cipher);                      child_state.ssh1cipher);
                 xfree(child_state.ssh1key);  
         }          }
   
         /* for rc4 and other stateful ciphers */  
         packet_set_keycontext(MODE_OUT, child_state.keyout);          packet_set_keycontext(MODE_OUT, child_state.keyout);
         xfree(child_state.keyout);          xfree(child_state.keyout);
         packet_set_keycontext(MODE_IN, child_state.keyin);          packet_set_keycontext(MODE_IN, child_state.keyin);
Line 1392 
Line 1271 
             sizeof(outgoing_stream));              sizeof(outgoing_stream));
   
         /* Update with new address */          /* Update with new address */
         if (options.compression)          mm_init_compression(pmonitor->m_zlib);
                 mm_init_compression(pmonitor->m_zlib);  
   
         /* Network I/O buffers */          /* Network I/O buffers */
         /* XXX inefficient for large buffers, need: buffer_init_from_string */          /* XXX inefficient for large buffers, need: buffer_init_from_string */
Line 1418 
Line 1296 
         kex = xmalloc(sizeof(*kex));          kex = xmalloc(sizeof(*kex));
         memset(kex, 0, sizeof(*kex));          memset(kex, 0, sizeof(*kex));
         kex->session_id = buffer_get_string(m, &kex->session_id_len);          kex->session_id = buffer_get_string(m, &kex->session_id_len);
         if ((session_id2 == NULL) ||  
             (kex->session_id_len != session_id2_len) ||  
             (memcmp(kex->session_id, session_id2, session_id2_len) != 0))  
                 fatal("mm_get_get: internal error: bad session id");  
         kex->we_need = buffer_get_int(m);          kex->we_need = buffer_get_int(m);
         kex->server = 1;          kex->server = 1;
         kex->hostkey_type = buffer_get_int(m);          kex->hostkey_type = buffer_get_int(m);
Line 1453 
Line 1327 
         u_char *blob, *p;          u_char *blob, *p;
         u_int bloblen, plen;          u_int bloblen, plen;
   
         debug3("%s: Waiting for new keys", __func__);          debug3("%s: Waiting for new keys", __FUNCTION__);
   
         buffer_init(&m);          buffer_init(&m);
         mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m);          mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m);
         if (!compat20) {          if (!compat20) {
                 child_state.ssh1protoflags = buffer_get_int(&m);                  child_state.ssh1protoflags = buffer_get_int(&m);
                 child_state.ssh1cipher = buffer_get_int(&m);                  child_state.ssh1cipher = buffer_get_int(&m);
                 child_state.ssh1key = buffer_get_string(&m,  
                     &child_state.ssh1keylen);  
                 child_state.ivout = buffer_get_string(&m,                  child_state.ivout = buffer_get_string(&m,
                     &child_state.ivoutlen);                      &child_state.ivoutlen);
                 child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);                  child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);
Line 1475 
Line 1347 
         current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);          current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
         xfree(blob);          xfree(blob);
   
         debug3("%s: Waiting for second key", __func__);          debug3("%s: Waiting for second key", __FUNCTION__);
         blob = buffer_get_string(&m, &bloblen);          blob = buffer_get_string(&m, &bloblen);
         current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);          current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
         xfree(blob);          xfree(blob);
Line 1489 
Line 1361 
         child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);          child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
         child_state.keyin  = buffer_get_string(&m, &child_state.keyinlen);          child_state.keyin  = buffer_get_string(&m, &child_state.keyinlen);
   
         debug3("%s: Getting compression state", __func__);          debug3("%s: Getting compression state", __FUNCTION__);
         /* Get compression state */          /* Get compression state */
         p = buffer_get_string(&m, &plen);          p = buffer_get_string(&m, &plen);
         if (plen != sizeof(child_state.outgoing))          if (plen != sizeof(child_state.outgoing))
                 fatal("%s: bad request size", __func__);                  fatal("%s: bad request size", __FUNCTION__);
         memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));          memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
         xfree(p);          xfree(p);
   
         p = buffer_get_string(&m, &plen);          p = buffer_get_string(&m, &plen);
         if (plen != sizeof(child_state.incoming))          if (plen != sizeof(child_state.incoming))
                 fatal("%s: bad request size", __func__);                  fatal("%s: bad request size", __FUNCTION__);
         memcpy(&child_state.incoming, p, sizeof(child_state.incoming));          memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
         xfree(p);          xfree(p);
   
         /* Network I/O buffers */          /* Network I/O buffers */
         debug3("%s: Getting Network I/O buffers", __func__);          debug3("%s: Getting Network I/O buffers", __FUNCTION__);
         child_state.input = buffer_get_string(&m, &child_state.ilen);          child_state.input = buffer_get_string(&m, &child_state.ilen);
         child_state.output = buffer_get_string(&m, &child_state.olen);          child_state.output = buffer_get_string(&m, &child_state.olen);
   
Line 1516 
Line 1388 
 void *  void *
 mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)  mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
 {  {
         size_t len = size * ncount;  
         void *address;          void *address;
   
         if (len == 0 || ncount > SIZE_T_MAX / size)          address = mm_malloc(mm, size * ncount);
                 fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);  
   
         address = mm_malloc(mm, len);  
   
         return (address);          return (address);
 }  }
   
Line 1556 
Line 1424 
 monitor_socketpair(int *pair)  monitor_socketpair(int *pair)
 {  {
         if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)          if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
                 fatal("%s: socketpair", __func__);                  fatal("%s: socketpair", __FUNCTION__);
         FD_CLOSEONEXEC(pair[0]);          FD_CLOSEONEXEC(pair[0]);
         FD_CLOSEONEXEC(pair[1]);          FD_CLOSEONEXEC(pair[1]);
 }  }
Line 1577 
Line 1445 
         mon->m_sendfd = pair[1];          mon->m_sendfd = pair[1];
   
         /* Used to share zlib space across processes */          /* Used to share zlib space across processes */
         if (options.compression) {          mon->m_zback = mm_create(NULL, MM_MEMSIZE);
                 mon->m_zback = mm_create(NULL, MM_MEMSIZE);          mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
                 mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);  
   
                 /* Compression needs to share state across borders */          /* Compression needs to share state across borders */
                 mm_init_compression(mon->m_zlib);          mm_init_compression(mon->m_zlib);
         }  
   
         return mon;          return mon;
 }  }

Legend:
Removed from v.1.11.2.4  
changed lines
  Added in v.1.12