[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.9.2.5 and 1.10

version 1.9.2.5, 2003/04/03 22:35:17 version 1.10, 2002/05/12 23:53:45
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 244 
Line 227 
 }  }
   
 Authctxt *  Authctxt *
 monitor_child_preauth(struct monitor *pmonitor)  monitor_child_preauth(struct monitor *monitor)
 {  {
         struct mon_table *ent;          struct mon_table *ent;
         int authenticated = 0;          int authenticated = 0;
Line 267 
Line 250 
   
         /* The first few requests do not require asynchronous access */          /* The first few requests do not require asynchronous access */
         while (!authenticated) {          while (!authenticated) {
                 authenticated = monitor_read(pmonitor, mon_dispatch, &ent);                  authenticated = monitor_read(monitor, mon_dispatch, &ent);
                 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(monitor);
   
         return (authctxt);          return (authctxt);
 }  }
   
 void  void
 monitor_child_postauth(struct monitor *pmonitor)  monitor_child_postauth(struct monitor *monitor)
 {  {
         if (compat20) {          if (compat20) {
                 mon_dispatch = mon_dispatch_postauth20;                  mon_dispatch = mon_dispatch_postauth20;
Line 317 
Line 300 
         }          }
   
         for (;;)          for (;;)
                 monitor_read(pmonitor, mon_dispatch, NULL);                  monitor_read(monitor, mon_dispatch, NULL);
 }  }
   
 void  void
 monitor_sync(struct monitor *pmonitor)  monitor_sync(struct monitor *monitor)
 {  {
         if (options.compression) {          /* The member allocation is not visible, so sync it */
                 /* The member allocation is not visible, so sync it */          mm_share_sync(&monitor->m_zlib, &monitor->m_zback);
                 mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);  
         }  
 }  }
   
 int  int
 monitor_read(struct monitor *pmonitor, struct mon_table *ent,  monitor_read(struct monitor *monitor, struct mon_table *ent,
     struct mon_table **pent)      struct mon_table **pent)
 {  {
         Buffer m;          Buffer m;
Line 339 
Line 320 
   
         buffer_init(&m);          buffer_init(&m);
   
         mm_request_receive(pmonitor->m_sendfd, &m);          mm_request_receive(monitor->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)(monitor->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 */
         authenticated = options.password_authentication &&          authenticated = authctxt->valid && auth_password(authctxt, passwd);
             authctxt->valid && auth_password(authctxt, passwd);  
         memset(passwd, 0, strlen(passwd));          memset(passwd, 0, strlen(passwd));
         xfree(passwd);          xfree(passwd);
   
         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 615 
Line 587 
         u_int numprompts;          u_int numprompts;
         u_int *echo_on;          u_int *echo_on;
         char **prompts;          char **prompts;
         u_int success;          int res;
   
         success = bsdauth_query(authctxt, &name, &infotxt, &numprompts,          res = bsdauth_query(authctxt, &name, &infotxt, &numprompts,
             &prompts, &echo_on) < 0 ? 0 : 1;              &prompts, &echo_on);
   
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, success);          buffer_put_int(m, res);
         if (success)          if (res != -1)
                 buffer_put_cstring(m, prompts[0]);                  buffer_put_cstring(m, prompts[0]);
   
         debug3("%s: sending challenge success: %u", __func__, success);          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 (success) {          if (res != -1) {
                 xfree(name);                  xfree(name);
                 xfree(infotxt);                  xfree(infotxt);
                 xfree(prompts);                  xfree(prompts);
Line 645 
Line 617 
         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 = 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 672 
Line 643 
 {  {
         struct skey skey;          struct skey skey;
         char challenge[1024];          char challenge[1024];
         u_int success;          int res;
   
         success = skeychallenge(&skey, authctxt->user, challenge) < 0 ? 0 : 1;          res = skeychallenge(&skey, authctxt->user, challenge);
   
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, success);          buffer_put_int(m, res);
         if (success)          if (res != -1)
                 buffer_put_cstring(m, challenge);                  buffer_put_cstring(m, challenge);
   
         debug3("%s: sending challenge success: %u", __func__, success);          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 695 
Line 666 
   
         response = buffer_get_string(m, NULL);          response = buffer_get_string(m, NULL);
   
         authok = (options.challenge_response_authentication &&          authok = (authctxt->valid &&
             authctxt->valid &&  
             skey_haskey(authctxt->pw->pw_name) == 0 &&              skey_haskey(authctxt->pw->pw_name) == 0 &&
             skey_passcheck(authctxt->pw->pw_name, response) != -1);              skey_passcheck(authctxt->pw->pw_name, response) != -1);
   
Line 705 
Line 675 
         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 688 
 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 699 
 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 715 
   
         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) {
                 case MM_USERKEY:                  case MM_USERKEY:
                         allowed = options.pubkey_authentication &&                          allowed = user_key_allowed(authctxt->pw, key);
                             user_key_allowed(authctxt->pw, key);  
                         break;                          break;
                 case MM_HOSTKEY:                  case MM_HOSTKEY:
                         allowed = options.hostbased_authentication &&                          allowed = hostbased_key_allowed(authctxt->pw,
                             hostbased_key_allowed(authctxt->pw,  
                             cuser, chost, key);                              cuser, chost, key);
                         break;                          break;
                 case MM_RSAHOSTKEY:                  case MM_RSAHOSTKEY:
                         key->type = KEY_RSA1; /* XXX */                          key->type = KEY_RSA1; /* XXX */
                         allowed = options.rhosts_rsa_authentication &&                          allowed = auth_rhosts_rsa_key_allowed(authctxt->pw,
                             auth_rhosts_rsa_key_allowed(authctxt->pw,  
                             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;
                 }                  }
         }  
         if (key != NULL)  
                 key_free(key);                  key_free(key);
           }
   
         /* clear temporarily storage (used by verify) */          /* clear temporarily storage (used by verify) */
         monitor_reset_key_state();          monitor_reset_key_state();
Line 788 
Line 753 
         }          }
   
         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);
         buffer_put_int(m, forced_command != NULL);  
   
         mm_append_debug(m);          mm_append_debug(m);
   
Line 808 
Line 772 
 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 861 
Line 817 
 }  }
   
 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 931 
Line 884 
   
         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 950 
Line 903 
                 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 = "publickey";
   
         return (verified);          return (verified);
 }  }
   
Line 983 
Line 936 
          * 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 994 
Line 947 
         /* 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 1012 
Line 965 
 int  int
 mm_answer_pty(int socket, Buffer *m)  mm_answer_pty(int socket, Buffer *m)
 {  {
         extern struct monitor *pmonitor;          extern struct monitor *monitor;
         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 1024 
Line 977 
                 goto error;                  goto error;
         s->authctxt = authctxt;          s->authctxt = authctxt;
         s->pw = authctxt->pw;          s->pw = authctxt->pw;
         s->pid = pmonitor->m_pid;          s->pid = monitor->m_pid;
         res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));          res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
         if (res == 0)          if (res == 0)
                 goto error;                  goto error;
Line 1040 
Line 993 
   
         /* 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 1049 
Line 1002 
   
         /* 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 1059 
Line 1012 
         /* 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 1077 
Line 1030 
         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 1097 
Line 1050 
         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 1122 
Line 1075 
 {  {
         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 1144 
Line 1097 
         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 (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);
         }          }
         buffer_clear(m);          buffer_clear(m);
         buffer_put_int(m, allowed);          buffer_put_int(m, allowed);
         buffer_put_int(m, forced_command != NULL);  
   
         /* clear temporarily storage (used by generate challenge) */          /* clear temporarily storage (used by generate challenge) */
         monitor_reset_key_state();          monitor_reset_key_state();
Line 1163 
Line 1115 
         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 */
                 key_blob = blob;                  key_blob = blob;
                 key_bloblen = blen;                  key_bloblen = blen;
                 key_blobtype = MM_RSAUSERKEY;                  key_blobtype = MM_RSAUSERKEY;
         }  
         if (key != NULL)  
                 key_free(key);                  key_free(key);
           }
   
         mm_append_debug(m);          mm_append_debug(m);
   
Line 1190 
Line 1141 
         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 1209 
Line 1160 
         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);
   
         xfree(blob);  
         key_free(key);  
         return (0);          return (0);
 }  }
   
Line 1227 
Line 1175 
         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);
   
         xfree(blob);  
         key_free(key);          key_free(key);
         xfree(response);          xfree(response);
   
Line 1264 
Line 1211 
         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 *monitor;
         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);
   
         while (waitpid(pmonitor->m_pid, &status, 0) == -1)          while (waitpid(monitor->m_pid, &status, 0) == -1)
                 if (errno != EINTR)                  if (errno != EINTR)
                         exit(1);                          exit(1);
   
Line 1369 
Line 1233 
 }  }
   
 void  void
 monitor_apply_keystate(struct monitor *pmonitor)  monitor_apply_keystate(struct monitor *monitor)
 {  {
         if (compat20) {          if (compat20) {
                 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 1400 
Line 1265 
             sizeof(outgoing_stream));              sizeof(outgoing_stream));
   
         /* Update with new address */          /* Update with new address */
         if (options.compression)          mm_init_compression(monitor->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 1426 
Line 1290 
         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->kex[KEX_DH_GRP1_SHA1] = kexdh_server;  
         kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;  
         kex->server = 1;          kex->server = 1;
         kex->hostkey_type = buffer_get_int(m);          kex->hostkey_type = buffer_get_int(m);
         kex->kex_type = buffer_get_int(m);          kex->kex_type = buffer_get_int(m);
Line 1457 
Line 1315 
 /* This function requries careful sanity checking */  /* This function requries careful sanity checking */
   
 void  void
 mm_get_keystate(struct monitor *pmonitor)  mm_get_keystate(struct monitor *monitor)
 {  {
         Buffer m;          Buffer m;
         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(monitor->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);
                 goto skip;                  goto skip;
         } else {          } else {
                 /* Get the Kex for rekeying */                  /* Get the Kex for rekeying */
                 *pmonitor->m_pkex = mm_get_kex(&m);                  *monitor->m_pkex = mm_get_kex(&m);
         }          }
   
         blob = buffer_get_string(&m, &bloblen);          blob = buffer_get_string(&m, &bloblen);
         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 1499 
Line 1355 
         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 1526 
Line 1382 
 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_t) 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 1566 
Line 1418 
 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 1587 
Line 1439 
         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.9.2.5  
changed lines
  Added in v.1.10