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

Diff for /src/usr.bin/ssh/monitor_wrap.c between version 1.81 and 1.82

version 1.81, 2015/01/13 19:31:40 version 1.82, 2015/01/19 19:52:16
Line 72 
Line 72 
 #include "servconf.h"  #include "servconf.h"
 #include "roaming.h"  #include "roaming.h"
   
   #include "ssherr.h"
   
 /* Imports */  /* Imports */
 extern int compat20;  extern int compat20;
 extern z_stream incoming_stream;  extern z_stream incoming_stream;
Line 454 
Line 456 
         return (verified);          return (verified);
 }  }
   
 /* Export key state after authentication */  
 Newkeys *  
 mm_newkeys_from_blob(u_char *blob, int blen)  
 {  
         Buffer b;  
         u_int len;  
         Newkeys *newkey = NULL;  
         Enc *enc;  
         Mac *mac;  
         Comp *comp;  
   
         debug3("%s: %p(%d)", __func__, blob, blen);  
 #ifdef DEBUG_PK  
         dump_base64(stderr, blob, blen);  
 #endif  
         buffer_init(&b);  
         buffer_append(&b, blob, blen);  
   
         newkey = xcalloc(1, sizeof(*newkey));  
         enc = &newkey->enc;  
         mac = &newkey->mac;  
         comp = &newkey->comp;  
   
         /* Enc structure */  
         enc->name = buffer_get_string(&b, NULL);  
         buffer_get(&b, &enc->cipher, sizeof(enc->cipher));  
         enc->enabled = buffer_get_int(&b);  
         enc->block_size = buffer_get_int(&b);  
         enc->key = buffer_get_string(&b, &enc->key_len);  
         enc->iv = buffer_get_string(&b, &enc->iv_len);  
   
         if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)  
                 fatal("%s: bad cipher name %s or pointer %p", __func__,  
                     enc->name, enc->cipher);  
   
         /* Mac structure */  
         if (cipher_authlen(enc->cipher) == 0) {  
                 mac->name = buffer_get_string(&b, NULL);  
                 if (mac->name == NULL || mac_setup(mac, mac->name) != 0)  
                         fatal("%s: can not setup mac %s", __func__, mac->name);  
                 mac->enabled = buffer_get_int(&b);  
                 mac->key = buffer_get_string(&b, &len);  
                 if (len > mac->key_len)  
                         fatal("%s: bad mac key length: %u > %d", __func__, len,  
                             mac->key_len);  
                 mac->key_len = len;  
         }  
   
         /* Comp structure */  
         comp->type = buffer_get_int(&b);  
         comp->enabled = buffer_get_int(&b);  
         comp->name = buffer_get_string(&b, NULL);  
   
         len = buffer_len(&b);  
         if (len != 0)  
                 error("newkeys_from_blob: remaining bytes in blob %u", len);  
         buffer_free(&b);  
         return (newkey);  
 }  
   
 int  
 mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)  
 {  
         Buffer b;  
         int len;  
         Enc *enc;  
         Mac *mac;  
         Comp *comp;  
         Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode);  
   
         debug3("%s: converting %p", __func__, newkey);  
   
         if (newkey == NULL) {  
                 error("%s: newkey == NULL", __func__);  
                 return 0;  
         }  
         enc = &newkey->enc;  
         mac = &newkey->mac;  
         comp = &newkey->comp;  
   
         buffer_init(&b);  
         /* Enc structure */  
         buffer_put_cstring(&b, enc->name);  
         /* The cipher struct is constant and shared, you export pointer */  
         buffer_append(&b, &enc->cipher, sizeof(enc->cipher));  
         buffer_put_int(&b, enc->enabled);  
         buffer_put_int(&b, enc->block_size);  
         buffer_put_string(&b, enc->key, enc->key_len);  
         packet_get_keyiv(mode, enc->iv, enc->iv_len);  
         buffer_put_string(&b, enc->iv, enc->iv_len);  
   
         /* Mac structure */  
         if (cipher_authlen(enc->cipher) == 0) {  
                 buffer_put_cstring(&b, mac->name);  
                 buffer_put_int(&b, mac->enabled);  
                 buffer_put_string(&b, mac->key, mac->key_len);  
         }  
   
         /* Comp structure */  
         buffer_put_int(&b, comp->type);  
         buffer_put_int(&b, comp->enabled);  
         buffer_put_cstring(&b, comp->name);  
   
         len = buffer_len(&b);  
         if (lenp != NULL)  
                 *lenp = len;  
         if (blobp != NULL) {  
                 *blobp = xmalloc(len);  
                 memcpy(*blobp, buffer_ptr(&b), len);  
         }  
         explicit_bzero(buffer_ptr(&b), len);  
         buffer_free(&b);  
         return len;  
 }  
   
 static void  
 mm_send_kex(Buffer *m, Kex *kex)  
 {  
         buffer_put_string(m, kex->session_id, kex->session_id_len);  
         buffer_put_int(m, kex->we_need);  
         buffer_put_int(m, kex->hostkey_type);  
         buffer_put_int(m, kex->kex_type);  
         buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));  
         buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));  
         buffer_put_int(m, kex->flags);  
         buffer_put_cstring(m, kex->client_version_string);  
         buffer_put_cstring(m, kex->server_version_string);  
 }  
   
 void  void
 mm_send_keystate(struct monitor *monitor)  mm_send_keystate(struct monitor *monitor)
 {  {
         Buffer m, *input, *output;          struct ssh *ssh = active_state;         /* XXX */
         u_char *blob, *p;          struct sshbuf *m;
         u_int bloblen, plen;          int r;
         u_int32_t seqnr, packets;  
         u_int64_t blocks, bytes;  
   
         buffer_init(&m);          if ((m = sshbuf_new()) == NULL)
                   fatal("%s: sshbuf_new failed", __func__);
         if (!compat20) {          if ((r = ssh_packet_get_state(ssh, m)) != 0)
                 u_char iv[24];                  fatal("%s: get_state failed: %s",
                 u_char *key;                      __func__, ssh_err(r));
                 u_int ivlen, keylen;          mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
   
                 buffer_put_int(&m, packet_get_protocol_flags());  
   
                 buffer_put_int(&m, packet_get_ssh1_cipher());  
   
                 debug3("%s: Sending ssh1 KEY+IV", __func__);  
                 keylen = packet_get_encryption_key(NULL);  
                 key = xmalloc(keylen+1);        /* add 1 if keylen == 0 */  
                 keylen = packet_get_encryption_key(key);  
                 buffer_put_string(&m, key, keylen);  
                 explicit_bzero(key, keylen);  
                 free(key);  
   
                 ivlen = packet_get_keyiv_len(MODE_OUT);  
                 packet_get_keyiv(MODE_OUT, iv, ivlen);  
                 buffer_put_string(&m, iv, ivlen);  
                 ivlen = packet_get_keyiv_len(MODE_IN);  
                 packet_get_keyiv(MODE_IN, iv, ivlen);  
                 buffer_put_string(&m, iv, ivlen);  
                 goto skip;  
         } else {  
                 /* Kex for rekeying */  
                 mm_send_kex(&m, *monitor->m_pkex);  
         }  
   
         debug3("%s: Sending new keys: %p %p",  
             __func__, packet_get_newkeys(MODE_OUT),  
             packet_get_newkeys(MODE_IN));  
   
         /* Keys from Kex */  
         if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))  
                 fatal("%s: conversion of newkeys failed", __func__);  
   
         buffer_put_string(&m, blob, bloblen);  
         free(blob);  
   
         if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))  
                 fatal("%s: conversion of newkeys failed", __func__);  
   
         buffer_put_string(&m, blob, bloblen);  
         free(blob);  
   
         packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes);  
         buffer_put_int(&m, seqnr);  
         buffer_put_int64(&m, blocks);  
         buffer_put_int(&m, packets);  
         buffer_put_int64(&m, bytes);  
         packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes);  
         buffer_put_int(&m, seqnr);  
         buffer_put_int64(&m, blocks);  
         buffer_put_int(&m, packets);  
         buffer_put_int64(&m, bytes);  
   
         debug3("%s: New keys have been sent", __func__);  
  skip:  
         /* More key context */  
         plen = packet_get_keycontext(MODE_OUT, NULL);  
         p = xmalloc(plen+1);  
         packet_get_keycontext(MODE_OUT, p);  
         buffer_put_string(&m, p, plen);  
         free(p);  
   
         plen = packet_get_keycontext(MODE_IN, NULL);  
         p = xmalloc(plen+1);  
         packet_get_keycontext(MODE_IN, p);  
         buffer_put_string(&m, p, plen);  
         free(p);  
   
         /* Compression state */  
         debug3("%s: Sending compression state", __func__);  
         buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));  
         buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));  
   
         /* Network I/O buffers */  
         input = (Buffer *)packet_get_input();  
         output = (Buffer *)packet_get_output();  
         buffer_put_string(&m, buffer_ptr(input), buffer_len(input));  
         buffer_put_string(&m, buffer_ptr(output), buffer_len(output));  
   
         /* Roaming */  
         if (compat20) {  
                 buffer_put_int64(&m, get_sent_bytes());  
                 buffer_put_int64(&m, get_recv_bytes());  
         }  
   
         mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);  
         debug3("%s: Finished sending state", __func__);          debug3("%s: Finished sending state", __func__);
           sshbuf_free(m);
         buffer_free(&m);  
 }  }
   
 int  int

Legend:
Removed from v.1.81  
changed lines
  Added in v.1.82