LCOV - code coverage report
Current view: top level - openssh-6.6p1 - monitor_wrap.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 347 468 74.1 %
Date: 2014-08-01 Functions: 23 31 74.2 %
Branches: 74 146 50.7 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: monitor_wrap.c,v 1.79 2014/02/02 03:44:31 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
       4                 :            :  * Copyright 2002 Markus Friedl <markus@openbsd.org>
       5                 :            :  * All rights reserved.
       6                 :            :  *
       7                 :            :  * Redistribution and use in source and binary forms, with or without
       8                 :            :  * modification, are permitted provided that the following conditions
       9                 :            :  * are met:
      10                 :            :  * 1. Redistributions of source code must retain the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer.
      12                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer in the
      14                 :            :  *    documentation and/or other materials provided with the distribution.
      15                 :            :  *
      16                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      17                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19                 :            :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      20                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26                 :            :  */
      27                 :            : 
      28                 :            : #include "includes.h"
      29                 :            : 
      30                 :            : #include <sys/types.h>
      31                 :            : #include <sys/uio.h>
      32                 :            : 
      33                 :            : #include <errno.h>
      34                 :            : #include <pwd.h>
      35                 :            : #include <signal.h>
      36                 :            : #include <stdarg.h>
      37                 :            : #include <stdio.h>
      38                 :            : #include <string.h>
      39                 :            : #include <unistd.h>
      40                 :            : 
      41                 :            : #include <openssl/bn.h>
      42                 :            : #include <openssl/dh.h>
      43                 :            : #include <openssl/evp.h>
      44                 :            : 
      45                 :            : #include "openbsd-compat/sys-queue.h"
      46                 :            : #include "xmalloc.h"
      47                 :            : #include "ssh.h"
      48                 :            : #include "dh.h"
      49                 :            : #include "buffer.h"
      50                 :            : #include "key.h"
      51                 :            : #include "cipher.h"
      52                 :            : #include "kex.h"
      53                 :            : #include "hostfile.h"
      54                 :            : #include "auth.h"
      55                 :            : #include "auth-options.h"
      56                 :            : #include "packet.h"
      57                 :            : #include "mac.h"
      58                 :            : #include "log.h"
      59                 :            : #ifdef TARGET_OS_MAC    /* XXX Broken krb5 headers on Mac */
      60                 :            : #undef TARGET_OS_MAC
      61                 :            : #include "zlib.h"
      62                 :            : #define TARGET_OS_MAC 1
      63                 :            : #else
      64                 :            : #include "zlib.h"
      65                 :            : #endif
      66                 :            : #include "monitor.h"
      67                 :            : #ifdef GSSAPI
      68                 :            : #include "ssh-gss.h"
      69                 :            : #endif
      70                 :            : #include "monitor_wrap.h"
      71                 :            : #include "atomicio.h"
      72                 :            : #include "monitor_fdpass.h"
      73                 :            : #include "misc.h"
      74                 :            : #include "uuencode.h"
      75                 :            : 
      76                 :            : #include "channels.h"
      77                 :            : #include "session.h"
      78                 :            : #include "servconf.h"
      79                 :            : #include "roaming.h"
      80                 :            : 
      81                 :            : /* Imports */
      82                 :            : extern int compat20;
      83                 :            : extern z_stream incoming_stream;
      84                 :            : extern z_stream outgoing_stream;
      85                 :            : extern struct monitor *pmonitor;
      86                 :            : extern Buffer loginmsg;
      87                 :            : extern ServerOptions options;
      88                 :            : 
      89                 :            : void
      90                 :      62807 : mm_log_handler(LogLevel level, const char *msg, void *ctx)
      91                 :            : {
      92                 :            :         Buffer log_msg;
      93                 :      62807 :         struct monitor *mon = (struct monitor *)ctx;
      94                 :            : 
      95         [ -  + ]:      62807 :         if (mon->m_log_sendfd == -1)
      96                 :          0 :                 fatal("%s: no log channel", __func__);
      97                 :            : 
      98                 :      62807 :         buffer_init(&log_msg);
      99                 :            :         /*
     100                 :            :          * Placeholder for packet length. Will be filled in with the actual
     101                 :            :          * packet length once the packet has been constucted. This saves
     102                 :            :          * fragile math.
     103                 :            :          */
     104                 :      62807 :         buffer_put_int(&log_msg, 0);
     105                 :            : 
     106                 :      62807 :         buffer_put_int(&log_msg, level);
     107                 :      62807 :         buffer_put_cstring(&log_msg, msg);
     108                 :      62807 :         put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4);
     109         [ -  + ]:     125614 :         if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg),
     110                 :     125614 :             buffer_len(&log_msg)) != buffer_len(&log_msg))
     111                 :          0 :                 fatal("%s: write: %s", __func__, strerror(errno));
     112                 :      62807 :         buffer_free(&log_msg);
     113                 :      62807 : }
     114                 :            : 
     115                 :            : int
     116                 :       3130 : mm_is_monitor(void)
     117                 :            : {
     118                 :            :         /*
     119                 :            :          * m_pid is only set in the privileged part, and
     120                 :            :          * points to the unprivileged child.
     121                 :            :          */
     122 [ +  - ][ +  + ]:       3130 :         return (pmonitor && pmonitor->m_pid > 0);
     123                 :            : }
     124                 :            : 
     125                 :            : void
     126                 :       9371 : mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
     127                 :            : {
     128                 :       9371 :         u_int mlen = buffer_len(m);
     129                 :            :         u_char buf[5];
     130                 :            : 
     131                 :       9371 :         debug3("%s entering: type %d", __func__, type);
     132                 :            : 
     133                 :       9371 :         put_u32(buf, mlen + 1);
     134                 :       9371 :         buf[4] = (u_char) type;         /* 1st byte of payload is mesg-type */
     135         [ -  + ]:       9371 :         if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
     136                 :          0 :                 fatal("%s: write: %s", __func__, strerror(errno));
     137         [ -  + ]:       9371 :         if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
     138                 :          0 :                 fatal("%s: write: %s", __func__, strerror(errno));
     139                 :       9371 : }
     140                 :            : 
     141                 :            : void
     142                 :       9371 : mm_request_receive(int sock, Buffer *m)
     143                 :            : {
     144                 :            :         u_char buf[4];
     145                 :            :         u_int msg_len;
     146                 :            : 
     147                 :       9371 :         debug3("%s entering", __func__);
     148                 :            : 
     149         [ -  + ]:       9371 :         if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
     150         [ #  # ]:          0 :                 if (errno == EPIPE)
     151                 :          0 :                         cleanup_exit(255);
     152                 :          0 :                 fatal("%s: read: %s", __func__, strerror(errno));
     153                 :            :         }
     154                 :       9371 :         msg_len = get_u32(buf);
     155         [ -  + ]:       9371 :         if (msg_len > 256 * 1024)
     156                 :          0 :                 fatal("%s: read: bad msg_len %d", __func__, msg_len);
     157                 :       9371 :         buffer_clear(m);
     158                 :       9371 :         buffer_append_space(m, msg_len);
     159         [ -  + ]:       9371 :         if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
     160                 :          0 :                 fatal("%s: read: %s", __func__, strerror(errno));
     161                 :       9371 : }
     162                 :            : 
     163                 :            : void
     164                 :       4674 : mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
     165                 :            : {
     166                 :            :         u_char rtype;
     167                 :            : 
     168                 :       4674 :         debug3("%s entering: type %d", __func__, type);
     169                 :            : 
     170                 :       4674 :         mm_request_receive(sock, m);
     171                 :       4674 :         rtype = buffer_get_char(m);
     172         [ -  + ]:       4674 :         if (rtype != type)
     173                 :          0 :                 fatal("%s: read: rtype %d != type %d", __func__,
     174                 :            :                     rtype, type);
     175                 :       4674 : }
     176                 :            : 
     177                 :            : DH *
     178                 :         16 : mm_choose_dh(int min, int nbits, int max)
     179                 :            : {
     180                 :            :         BIGNUM *p, *g;
     181                 :         16 :         int success = 0;
     182                 :            :         Buffer m;
     183                 :            : 
     184                 :         16 :         buffer_init(&m);
     185                 :         16 :         buffer_put_int(&m, min);
     186                 :         16 :         buffer_put_int(&m, nbits);
     187                 :         16 :         buffer_put_int(&m, max);
     188                 :            : 
     189                 :         16 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
     190                 :            : 
     191                 :         16 :         debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
     192                 :         16 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
     193                 :            : 
     194                 :         16 :         success = buffer_get_char(&m);
     195         [ -  + ]:         16 :         if (success == 0)
     196                 :          0 :                 fatal("%s: MONITOR_ANS_MODULI failed", __func__);
     197                 :            : 
     198         [ -  + ]:         16 :         if ((p = BN_new()) == NULL)
     199                 :          0 :                 fatal("%s: BN_new failed", __func__);
     200         [ -  + ]:         16 :         if ((g = BN_new()) == NULL)
     201                 :          0 :                 fatal("%s: BN_new failed", __func__);
     202                 :         16 :         buffer_get_bignum2(&m, p);
     203                 :         16 :         buffer_get_bignum2(&m, g);
     204                 :            : 
     205                 :         16 :         debug3("%s: remaining %d", __func__, buffer_len(&m));
     206                 :         16 :         buffer_free(&m);
     207                 :            : 
     208                 :         16 :         return (dh_new_group(g, p));
     209                 :            : }
     210                 :            : 
     211                 :            : int
     212                 :        660 : mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
     213                 :            : {
     214                 :        660 :         Kex *kex = *pmonitor->m_pkex;
     215                 :            :         Buffer m;
     216                 :            : 
     217                 :        660 :         debug3("%s entering", __func__);
     218                 :            : 
     219                 :        660 :         buffer_init(&m);
     220                 :        660 :         buffer_put_int(&m, kex->host_key_index(key));
     221                 :        660 :         buffer_put_string(&m, data, datalen);
     222                 :            : 
     223                 :        660 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
     224                 :            : 
     225                 :        660 :         debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
     226                 :        660 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
     227                 :        660 :         *sigp  = buffer_get_string(&m, lenp);
     228                 :        660 :         buffer_free(&m);
     229                 :            : 
     230                 :        660 :         return (0);
     231                 :            : }
     232                 :            : 
     233                 :            : struct passwd *
     234                 :        761 : mm_getpwnamallow(const char *username)
     235                 :            : {
     236                 :            :         Buffer m;
     237                 :            :         struct passwd *pw;
     238                 :            :         u_int len, i;
     239                 :            :         ServerOptions *newopts;
     240                 :            : 
     241                 :        761 :         debug3("%s entering", __func__);
     242                 :            : 
     243                 :        761 :         buffer_init(&m);
     244                 :        761 :         buffer_put_cstring(&m, username);
     245                 :            : 
     246                 :        761 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
     247                 :            : 
     248                 :        761 :         debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
     249                 :        761 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
     250                 :            : 
     251         [ +  - ]:        761 :         if (buffer_get_char(&m) == 0) {
     252                 :            :                 pw = NULL;
     253                 :            :                 goto out;
     254                 :            :         }
     255                 :        761 :         pw = buffer_get_string(&m, &len);
     256         [ -  + ]:        761 :         if (len != sizeof(struct passwd))
     257                 :          0 :                 fatal("%s: struct passwd size mismatch", __func__);
     258                 :        761 :         pw->pw_name = buffer_get_string(&m, NULL);
     259                 :        761 :         pw->pw_passwd = buffer_get_string(&m, NULL);
     260                 :            : #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
     261                 :        761 :         pw->pw_gecos = buffer_get_string(&m, NULL);
     262                 :            : #endif
     263                 :            : #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
     264                 :            :         pw->pw_class = buffer_get_string(&m, NULL);
     265                 :            : #endif
     266                 :        761 :         pw->pw_dir = buffer_get_string(&m, NULL);
     267                 :        761 :         pw->pw_shell = buffer_get_string(&m, NULL);
     268                 :            : 
     269                 :            : out:
     270                 :            :         /* copy options block as a Match directive may have changed some */
     271                 :        761 :         newopts = buffer_get_string(&m, &len);
     272         [ -  + ]:        761 :         if (len != sizeof(*newopts))
     273                 :          0 :                 fatal("%s: option block size mismatch", __func__);
     274                 :            : 
     275                 :            : #define M_CP_STROPT(x) do { \
     276                 :            :                 if (newopts->x != NULL) \
     277                 :            :                         newopts->x = buffer_get_string(&m, NULL); \
     278                 :            :         } while (0)
     279                 :            : #define M_CP_STRARRAYOPT(x, nx) do { \
     280                 :            :                 for (i = 0; i < newopts->nx; i++) \
     281                 :            :                         newopts->x[i] = buffer_get_string(&m, NULL); \
     282                 :            :         } while (0)
     283                 :            :         /* See comment in servconf.h */
     284 [ +  + ][ +  + ]:       3048 :         COPY_MATCH_STRING_OPTS();
         [ +  + ][ +  + ]
         [ -  + ][ -  + ]
         [ +  + ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ +  + ]
                 [ -  + ]
     285                 :            : #undef M_CP_STROPT
     286                 :            : #undef M_CP_STRARRAYOPT
     287                 :            : 
     288                 :        761 :         copy_set_server_options(&options, newopts, 1);
     289                 :        761 :         free(newopts);
     290                 :            : 
     291                 :        761 :         buffer_free(&m);
     292                 :            : 
     293                 :        761 :         return (pw);
     294                 :            : }
     295                 :            : 
     296                 :            : char *
     297                 :          8 : mm_auth2_read_banner(void)
     298                 :            : {
     299                 :            :         Buffer m;
     300                 :            :         char *banner;
     301                 :            : 
     302                 :          8 :         debug3("%s entering", __func__);
     303                 :            : 
     304                 :          8 :         buffer_init(&m);
     305                 :          8 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
     306                 :          8 :         buffer_clear(&m);
     307                 :            : 
     308                 :          8 :         mm_request_receive_expect(pmonitor->m_recvfd,
     309                 :            :             MONITOR_ANS_AUTH2_READ_BANNER, &m);
     310                 :          8 :         banner = buffer_get_string(&m, NULL);
     311                 :          8 :         buffer_free(&m);
     312                 :            : 
     313                 :            :         /* treat empty banner as missing banner */
     314         [ +  + ]:          8 :         if (strlen(banner) == 0) {
     315                 :          2 :                 free(banner);
     316                 :          2 :                 banner = NULL;
     317                 :            :         }
     318                 :          8 :         return (banner);
     319                 :            : }
     320                 :            : 
     321                 :            : /* Inform the privileged process about service and style */
     322                 :            : 
     323                 :            : void
     324                 :        658 : mm_inform_authserv(char *service, char *style)
     325                 :            : {
     326                 :            :         Buffer m;
     327                 :            : 
     328                 :        658 :         debug3("%s entering", __func__);
     329                 :            : 
     330                 :        658 :         buffer_init(&m);
     331                 :        658 :         buffer_put_cstring(&m, service);
     332         [ +  + ]:        658 :         buffer_put_cstring(&m, style ? style : "");
     333                 :            : 
     334                 :        658 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
     335                 :            : 
     336                 :        658 :         buffer_free(&m);
     337                 :        658 : }
     338                 :            : 
     339                 :            : /* Do the password authentication */
     340                 :            : int
     341                 :          0 : mm_auth_password(Authctxt *authctxt, char *password)
     342                 :            : {
     343                 :            :         Buffer m;
     344                 :          0 :         int authenticated = 0;
     345                 :            : 
     346                 :          0 :         debug3("%s entering", __func__);
     347                 :            : 
     348                 :          0 :         buffer_init(&m);
     349                 :          0 :         buffer_put_cstring(&m, password);
     350                 :          0 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
     351                 :            : 
     352                 :          0 :         debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
     353                 :          0 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
     354                 :            : 
     355                 :          0 :         authenticated = buffer_get_int(&m);
     356                 :            : 
     357                 :          0 :         buffer_free(&m);
     358                 :            : 
     359         [ #  # ]:          0 :         debug3("%s: user %sauthenticated",
     360                 :            :             __func__, authenticated ? "" : "not ");
     361                 :          0 :         return (authenticated);
     362                 :            : }
     363                 :            : 
     364                 :            : int
     365                 :       1398 : mm_user_key_allowed(struct passwd *pw, Key *key)
     366                 :            : {
     367                 :       1398 :         return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
     368                 :            : }
     369                 :            : 
     370                 :            : int
     371                 :          0 : mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
     372                 :            :     Key *key)
     373                 :            : {
     374                 :          0 :         return (mm_key_allowed(MM_HOSTKEY, user, host, key));
     375                 :            : }
     376                 :            : 
     377                 :            : int
     378                 :          0 : mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
     379                 :            :     char *host, Key *key)
     380                 :            : {
     381                 :            :         int ret;
     382                 :            : 
     383                 :          0 :         key->type = KEY_RSA; /* XXX hack for key_to_blob */
     384                 :          0 :         ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
     385                 :          0 :         key->type = KEY_RSA1;
     386                 :          0 :         return (ret);
     387                 :            : }
     388                 :            : 
     389                 :            : int
     390                 :       1398 : mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
     391                 :            : {
     392                 :            :         Buffer m;
     393                 :            :         u_char *blob;
     394                 :            :         u_int len;
     395                 :       1398 :         int allowed = 0, have_forced = 0;
     396                 :            : 
     397                 :       1398 :         debug3("%s entering", __func__);
     398                 :            : 
     399                 :            :         /* Convert the key to a blob and the pass it over */
     400         [ +  - ]:       1398 :         if (!key_to_blob(key, &blob, &len))
     401                 :            :                 return (0);
     402                 :            : 
     403                 :       1398 :         buffer_init(&m);
     404                 :       1398 :         buffer_put_int(&m, type);
     405         [ -  + ]:       1398 :         buffer_put_cstring(&m, user ? user : "");
     406         [ -  + ]:       1398 :         buffer_put_cstring(&m, host ? host : "");
     407                 :       1398 :         buffer_put_string(&m, blob, len);
     408                 :       1398 :         free(blob);
     409                 :            : 
     410                 :       1398 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
     411                 :            : 
     412                 :       1398 :         debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
     413                 :       1398 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
     414                 :            : 
     415                 :       1398 :         allowed = buffer_get_int(&m);
     416                 :            : 
     417                 :            :         /* fake forced command */
     418                 :       1398 :         auth_clear_options();
     419                 :       1398 :         have_forced = buffer_get_int(&m);
     420         [ +  + ]:       1398 :         forced_command = have_forced ? xstrdup("true") : NULL;
     421                 :            : 
     422                 :       1398 :         buffer_free(&m);
     423                 :            : 
     424                 :       1398 :         return (allowed);
     425                 :            : }
     426                 :            : 
     427                 :            : /*
     428                 :            :  * This key verify needs to send the key type along, because the
     429                 :            :  * privileged parent makes the decision if the key is allowed
     430                 :            :  * for authentication.
     431                 :            :  */
     432                 :            : 
     433                 :            : int
     434                 :        658 : mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
     435                 :            : {
     436                 :            :         Buffer m;
     437                 :            :         u_char *blob;
     438                 :            :         u_int len;
     439                 :        658 :         int verified = 0;
     440                 :            : 
     441                 :        658 :         debug3("%s entering", __func__);
     442                 :            : 
     443                 :            :         /* Convert the key to a blob and the pass it over */
     444         [ +  - ]:        658 :         if (!key_to_blob(key, &blob, &len))
     445                 :            :                 return (0);
     446                 :            : 
     447                 :        658 :         buffer_init(&m);
     448                 :        658 :         buffer_put_string(&m, blob, len);
     449                 :        658 :         buffer_put_string(&m, sig, siglen);
     450                 :        658 :         buffer_put_string(&m, data, datalen);
     451                 :        658 :         free(blob);
     452                 :            : 
     453                 :        658 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
     454                 :            : 
     455                 :        658 :         debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
     456                 :        658 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
     457                 :            : 
     458                 :        658 :         verified = buffer_get_int(&m);
     459                 :            : 
     460                 :        658 :         buffer_free(&m);
     461                 :            : 
     462                 :        658 :         return (verified);
     463                 :            : }
     464                 :            : 
     465                 :            : /* Export key state after authentication */
     466                 :            : Newkeys *
     467                 :       1316 : mm_newkeys_from_blob(u_char *blob, int blen)
     468                 :            : {
     469                 :            :         Buffer b;
     470                 :            :         u_int len;
     471                 :       1316 :         Newkeys *newkey = NULL;
     472                 :            :         Enc *enc;
     473                 :            :         Mac *mac;
     474                 :            :         Comp *comp;
     475                 :            : 
     476                 :       1316 :         debug3("%s: %p(%d)", __func__, blob, blen);
     477                 :            : #ifdef DEBUG_PK
     478                 :            :         dump_base64(stderr, blob, blen);
     479                 :            : #endif
     480                 :       1316 :         buffer_init(&b);
     481                 :       1316 :         buffer_append(&b, blob, blen);
     482                 :            : 
     483                 :       1316 :         newkey = xcalloc(1, sizeof(*newkey));
     484                 :       1316 :         enc = &newkey->enc;
     485                 :       1316 :         mac = &newkey->mac;
     486                 :       1316 :         comp = &newkey->comp;
     487                 :            : 
     488                 :            :         /* Enc structure */
     489                 :       1316 :         enc->name = buffer_get_string(&b, NULL);
     490                 :       1316 :         buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
     491                 :       1316 :         enc->enabled = buffer_get_int(&b);
     492                 :       1316 :         enc->block_size = buffer_get_int(&b);
     493                 :       1316 :         enc->key = buffer_get_string(&b, &enc->key_len);
     494                 :       1316 :         enc->iv = buffer_get_string(&b, &enc->iv_len);
     495                 :            : 
     496 [ +  - ][ -  + ]:       1316 :         if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
     497                 :          0 :                 fatal("%s: bad cipher name %s or pointer %p", __func__,
     498                 :            :                     enc->name, enc->cipher);
     499                 :            : 
     500                 :            :         /* Mac structure */
     501         [ +  + ]:       1316 :         if (cipher_authlen(enc->cipher) == 0) {
     502                 :       1250 :                 mac->name = buffer_get_string(&b, NULL);
     503 [ +  - ][ -  + ]:       1250 :                 if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
     504                 :          0 :                         fatal("%s: can not setup mac %s", __func__, mac->name);
     505                 :       1250 :                 mac->enabled = buffer_get_int(&b);
     506                 :       1250 :                 mac->key = buffer_get_string(&b, &len);
     507         [ -  + ]:       1250 :                 if (len > mac->key_len)
     508                 :          0 :                         fatal("%s: bad mac key length: %u > %d", __func__, len,
     509                 :            :                             mac->key_len);
     510                 :       1250 :                 mac->key_len = len;
     511                 :            :         }
     512                 :            : 
     513                 :            :         /* Comp structure */
     514                 :       1316 :         comp->type = buffer_get_int(&b);
     515                 :       1316 :         comp->enabled = buffer_get_int(&b);
     516                 :       1316 :         comp->name = buffer_get_string(&b, NULL);
     517                 :            : 
     518                 :       1316 :         len = buffer_len(&b);
     519         [ -  + ]:       1316 :         if (len != 0)
     520                 :          0 :                 error("newkeys_from_blob: remaining bytes in blob %u", len);
     521                 :       1316 :         buffer_free(&b);
     522                 :       1316 :         return (newkey);
     523                 :            : }
     524                 :            : 
     525                 :            : int
     526                 :       1316 : mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
     527                 :            : {
     528                 :            :         Buffer b;
     529                 :            :         int len;
     530                 :            :         Enc *enc;
     531                 :            :         Mac *mac;
     532                 :            :         Comp *comp;
     533                 :       1316 :         Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode);
     534                 :            : 
     535                 :       1316 :         debug3("%s: converting %p", __func__, newkey);
     536                 :            : 
     537         [ -  + ]:       1316 :         if (newkey == NULL) {
     538                 :          0 :                 error("%s: newkey == NULL", __func__);
     539                 :          0 :                 return 0;
     540                 :            :         }
     541                 :       1316 :         enc = &newkey->enc;
     542                 :       1316 :         mac = &newkey->mac;
     543                 :       1316 :         comp = &newkey->comp;
     544                 :            : 
     545                 :       1316 :         buffer_init(&b);
     546                 :            :         /* Enc structure */
     547                 :       1316 :         buffer_put_cstring(&b, enc->name);
     548                 :            :         /* The cipher struct is constant and shared, you export pointer */
     549                 :       1316 :         buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
     550                 :       1316 :         buffer_put_int(&b, enc->enabled);
     551                 :       1316 :         buffer_put_int(&b, enc->block_size);
     552                 :       1316 :         buffer_put_string(&b, enc->key, enc->key_len);
     553                 :       1316 :         packet_get_keyiv(mode, enc->iv, enc->iv_len);
     554                 :       1316 :         buffer_put_string(&b, enc->iv, enc->iv_len);
     555                 :            : 
     556                 :            :         /* Mac structure */
     557         [ +  + ]:       1316 :         if (cipher_authlen(enc->cipher) == 0) {
     558                 :       1250 :                 buffer_put_cstring(&b, mac->name);
     559                 :       1250 :                 buffer_put_int(&b, mac->enabled);
     560                 :       1250 :                 buffer_put_string(&b, mac->key, mac->key_len);
     561                 :            :         }
     562                 :            : 
     563                 :            :         /* Comp structure */
     564                 :       1316 :         buffer_put_int(&b, comp->type);
     565                 :       1316 :         buffer_put_int(&b, comp->enabled);
     566                 :       1316 :         buffer_put_cstring(&b, comp->name);
     567                 :            : 
     568                 :       1316 :         len = buffer_len(&b);
     569         [ +  - ]:       1316 :         if (lenp != NULL)
     570                 :       1316 :                 *lenp = len;
     571         [ +  - ]:       1316 :         if (blobp != NULL) {
     572                 :       1316 :                 *blobp = xmalloc(len);
     573                 :       1316 :                 memcpy(*blobp, buffer_ptr(&b), len);
     574                 :            :         }
     575                 :       1316 :         explicit_bzero(buffer_ptr(&b), len);
     576                 :       1316 :         buffer_free(&b);
     577                 :       1316 :         return len;
     578                 :            : }
     579                 :            : 
     580                 :            : static void
     581                 :        658 : mm_send_kex(Buffer *m, Kex *kex)
     582                 :            : {
     583                 :        658 :         buffer_put_string(m, kex->session_id, kex->session_id_len);
     584                 :        658 :         buffer_put_int(m, kex->we_need);
     585                 :        658 :         buffer_put_int(m, kex->hostkey_type);
     586                 :        658 :         buffer_put_int(m, kex->kex_type);
     587                 :        658 :         buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
     588                 :        658 :         buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
     589                 :        658 :         buffer_put_int(m, kex->flags);
     590                 :        658 :         buffer_put_cstring(m, kex->client_version_string);
     591                 :        658 :         buffer_put_cstring(m, kex->server_version_string);
     592                 :        658 : }
     593                 :            : 
     594                 :            : void
     595                 :        761 : mm_send_keystate(struct monitor *monitor)
     596                 :            : {
     597                 :            :         Buffer m, *input, *output;
     598                 :            :         u_char *blob, *p;
     599                 :            :         u_int bloblen, plen;
     600                 :            :         u_int32_t seqnr, packets;
     601                 :            :         u_int64_t blocks, bytes;
     602                 :            : 
     603                 :        761 :         buffer_init(&m);
     604                 :            : 
     605         [ +  + ]:        761 :         if (!compat20) {
     606                 :            :                 u_char iv[24];
     607                 :            :                 u_char *key;
     608                 :            :                 u_int ivlen, keylen;
     609                 :            : 
     610                 :        103 :                 buffer_put_int(&m, packet_get_protocol_flags());
     611                 :            : 
     612                 :        103 :                 buffer_put_int(&m, packet_get_ssh1_cipher());
     613                 :            : 
     614                 :        103 :                 debug3("%s: Sending ssh1 KEY+IV", __func__);
     615                 :        103 :                 keylen = packet_get_encryption_key(NULL);
     616                 :        103 :                 key = xmalloc(keylen+1);        /* add 1 if keylen == 0 */
     617                 :        103 :                 keylen = packet_get_encryption_key(key);
     618                 :        103 :                 buffer_put_string(&m, key, keylen);
     619                 :        103 :                 explicit_bzero(key, keylen);
     620                 :        103 :                 free(key);
     621                 :            : 
     622                 :        103 :                 ivlen = packet_get_keyiv_len(MODE_OUT);
     623                 :        103 :                 packet_get_keyiv(MODE_OUT, iv, ivlen);
     624                 :        103 :                 buffer_put_string(&m, iv, ivlen);
     625                 :        103 :                 ivlen = packet_get_keyiv_len(MODE_IN);
     626                 :        103 :                 packet_get_keyiv(MODE_IN, iv, ivlen);
     627                 :        103 :                 buffer_put_string(&m, iv, ivlen);
     628                 :            :                 goto skip;
     629                 :            :         } else {
     630                 :            :                 /* Kex for rekeying */
     631                 :        658 :                 mm_send_kex(&m, *monitor->m_pkex);
     632                 :            :         }
     633                 :            : 
     634                 :        658 :         debug3("%s: Sending new keys: %p %p",
     635                 :            :             __func__, packet_get_newkeys(MODE_OUT),
     636                 :            :             packet_get_newkeys(MODE_IN));
     637                 :            : 
     638                 :            :         /* Keys from Kex */
     639         [ -  + ]:        658 :         if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
     640                 :          0 :                 fatal("%s: conversion of newkeys failed", __func__);
     641                 :            : 
     642                 :        658 :         buffer_put_string(&m, blob, bloblen);
     643                 :        658 :         free(blob);
     644                 :            : 
     645         [ -  + ]:        658 :         if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
     646                 :          0 :                 fatal("%s: conversion of newkeys failed", __func__);
     647                 :            : 
     648                 :        658 :         buffer_put_string(&m, blob, bloblen);
     649                 :        658 :         free(blob);
     650                 :            : 
     651                 :        658 :         packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes);
     652                 :        658 :         buffer_put_int(&m, seqnr);
     653                 :        658 :         buffer_put_int64(&m, blocks);
     654                 :        658 :         buffer_put_int(&m, packets);
     655                 :        658 :         buffer_put_int64(&m, bytes);
     656                 :        658 :         packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes);
     657                 :        658 :         buffer_put_int(&m, seqnr);
     658                 :        658 :         buffer_put_int64(&m, blocks);
     659                 :        658 :         buffer_put_int(&m, packets);
     660                 :        658 :         buffer_put_int64(&m, bytes);
     661                 :            : 
     662                 :        658 :         debug3("%s: New keys have been sent", __func__);
     663                 :            :  skip:
     664                 :            :         /* More key context */
     665                 :        761 :         plen = packet_get_keycontext(MODE_OUT, NULL);
     666                 :        761 :         p = xmalloc(plen+1);
     667                 :        761 :         packet_get_keycontext(MODE_OUT, p);
     668                 :        761 :         buffer_put_string(&m, p, plen);
     669                 :        761 :         free(p);
     670                 :            : 
     671                 :        761 :         plen = packet_get_keycontext(MODE_IN, NULL);
     672                 :        761 :         p = xmalloc(plen+1);
     673                 :        761 :         packet_get_keycontext(MODE_IN, p);
     674                 :        761 :         buffer_put_string(&m, p, plen);
     675                 :        761 :         free(p);
     676                 :            : 
     677                 :            :         /* Compression state */
     678                 :        761 :         debug3("%s: Sending compression state", __func__);
     679                 :        761 :         buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
     680                 :        761 :         buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
     681                 :            : 
     682                 :            :         /* Network I/O buffers */
     683                 :        761 :         input = (Buffer *)packet_get_input();
     684                 :        761 :         output = (Buffer *)packet_get_output();
     685                 :        761 :         buffer_put_string(&m, buffer_ptr(input), buffer_len(input));
     686                 :        761 :         buffer_put_string(&m, buffer_ptr(output), buffer_len(output));
     687                 :            : 
     688                 :            :         /* Roaming */
     689         [ +  + ]:        761 :         if (compat20) {
     690                 :        658 :                 buffer_put_int64(&m, get_sent_bytes());
     691                 :        658 :                 buffer_put_int64(&m, get_recv_bytes());
     692                 :            :         }
     693                 :            : 
     694                 :        761 :         mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
     695                 :        761 :         debug3("%s: Finished sending state", __func__);
     696                 :            : 
     697                 :        761 :         buffer_free(&m);
     698                 :        761 : }
     699                 :            : 
     700                 :            : int
     701                 :          0 : mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
     702                 :            : {
     703                 :            :         Buffer m;
     704                 :            :         char *p, *msg;
     705                 :          0 :         int success = 0, tmp1 = -1, tmp2 = -1;
     706                 :            : 
     707                 :            :         /* Kludge: ensure there are fds free to receive the pty/tty */
     708 [ #  # ][ #  # ]:          0 :         if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
     709                 :          0 :             (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
     710                 :          0 :                 error("%s: cannot allocate fds for pty", __func__);
     711         [ #  # ]:          0 :                 if (tmp1 > 0)
     712                 :          0 :                         close(tmp1);
     713         [ #  # ]:          0 :                 if (tmp2 > 0)
     714                 :          0 :                         close(tmp2);
     715                 :            :                 return 0;
     716                 :            :         }
     717                 :          0 :         close(tmp1);
     718                 :          0 :         close(tmp2);
     719                 :            : 
     720                 :          0 :         buffer_init(&m);
     721                 :          0 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
     722                 :            : 
     723                 :          0 :         debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
     724                 :          0 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
     725                 :            : 
     726                 :          0 :         success = buffer_get_int(&m);
     727         [ #  # ]:          0 :         if (success == 0) {
     728                 :          0 :                 debug3("%s: pty alloc failed", __func__);
     729                 :          0 :                 buffer_free(&m);
     730                 :          0 :                 return (0);
     731                 :            :         }
     732                 :          0 :         p = buffer_get_string(&m, NULL);
     733                 :          0 :         msg = buffer_get_string(&m, NULL);
     734                 :          0 :         buffer_free(&m);
     735                 :            : 
     736                 :          0 :         strlcpy(namebuf, p, namebuflen); /* Possible truncation */
     737                 :          0 :         free(p);
     738                 :            : 
     739                 :          0 :         buffer_append(&loginmsg, msg, strlen(msg));
     740                 :          0 :         free(msg);
     741                 :            : 
     742   [ #  #  #  # ]:          0 :         if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
     743                 :          0 :             (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
     744                 :          0 :                 fatal("%s: receive fds failed", __func__);
     745                 :            : 
     746                 :            :         /* Success */
     747                 :            :         return (1);
     748                 :            : }
     749                 :            : 
     750                 :            : void
     751                 :          0 : mm_session_pty_cleanup2(Session *s)
     752                 :            : {
     753                 :            :         Buffer m;
     754                 :            : 
     755         [ #  # ]:          0 :         if (s->ttyfd == -1)
     756                 :          0 :                 return;
     757                 :          0 :         buffer_init(&m);
     758                 :          0 :         buffer_put_cstring(&m, s->tty);
     759                 :          0 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
     760                 :          0 :         buffer_free(&m);
     761                 :            : 
     762                 :            :         /* closed dup'ed master */
     763 [ #  # ][ #  # ]:          0 :         if (s->ptymaster != -1 && close(s->ptymaster) < 0)
     764                 :          0 :                 error("close(s->ptymaster/%d): %s",
     765                 :          0 :                     s->ptymaster, strerror(errno));
     766                 :            : 
     767                 :            :         /* unlink pty from session */
     768                 :          0 :         s->ttyfd = -1;
     769                 :            : }
     770                 :            : 
     771                 :            : #ifdef USE_PAM
     772                 :            : void
     773                 :            : mm_start_pam(Authctxt *authctxt)
     774                 :            : {
     775                 :            :         Buffer m;
     776                 :            : 
     777                 :            :         debug3("%s entering", __func__);
     778                 :            :         if (!options.use_pam)
     779                 :            :                 fatal("UsePAM=no, but ended up in %s anyway", __func__);
     780                 :            : 
     781                 :            :         buffer_init(&m);
     782                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
     783                 :            : 
     784                 :            :         buffer_free(&m);
     785                 :            : }
     786                 :            : 
     787                 :            : u_int
     788                 :            : mm_do_pam_account(void)
     789                 :            : {
     790                 :            :         Buffer m;
     791                 :            :         u_int ret;
     792                 :            :         char *msg;
     793                 :            : 
     794                 :            :         debug3("%s entering", __func__);
     795                 :            :         if (!options.use_pam)
     796                 :            :                 fatal("UsePAM=no, but ended up in %s anyway", __func__);
     797                 :            : 
     798                 :            :         buffer_init(&m);
     799                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
     800                 :            : 
     801                 :            :         mm_request_receive_expect(pmonitor->m_recvfd,
     802                 :            :             MONITOR_ANS_PAM_ACCOUNT, &m);
     803                 :            :         ret = buffer_get_int(&m);
     804                 :            :         msg = buffer_get_string(&m, NULL);
     805                 :            :         buffer_append(&loginmsg, msg, strlen(msg));
     806                 :            :         free(msg);
     807                 :            : 
     808                 :            :         buffer_free(&m);
     809                 :            : 
     810                 :            :         debug3("%s returning %d", __func__, ret);
     811                 :            : 
     812                 :            :         return (ret);
     813                 :            : }
     814                 :            : 
     815                 :            : void *
     816                 :            : mm_sshpam_init_ctx(Authctxt *authctxt)
     817                 :            : {
     818                 :            :         Buffer m;
     819                 :            :         int success;
     820                 :            : 
     821                 :            :         debug3("%s", __func__);
     822                 :            :         buffer_init(&m);
     823                 :            :         buffer_put_cstring(&m, authctxt->user);
     824                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
     825                 :            :         debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
     826                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
     827                 :            :         success = buffer_get_int(&m);
     828                 :            :         if (success == 0) {
     829                 :            :                 debug3("%s: pam_init_ctx failed", __func__);
     830                 :            :                 buffer_free(&m);
     831                 :            :                 return (NULL);
     832                 :            :         }
     833                 :            :         buffer_free(&m);
     834                 :            :         return (authctxt);
     835                 :            : }
     836                 :            : 
     837                 :            : int
     838                 :            : mm_sshpam_query(void *ctx, char **name, char **info,
     839                 :            :     u_int *num, char ***prompts, u_int **echo_on)
     840                 :            : {
     841                 :            :         Buffer m;
     842                 :            :         u_int i;
     843                 :            :         int ret;
     844                 :            : 
     845                 :            :         debug3("%s", __func__);
     846                 :            :         buffer_init(&m);
     847                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
     848                 :            :         debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
     849                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
     850                 :            :         ret = buffer_get_int(&m);
     851                 :            :         debug3("%s: pam_query returned %d", __func__, ret);
     852                 :            :         *name = buffer_get_string(&m, NULL);
     853                 :            :         *info = buffer_get_string(&m, NULL);
     854                 :            :         *num = buffer_get_int(&m);
     855                 :            :         if (*num > PAM_MAX_NUM_MSG)
     856                 :            :                 fatal("%s: recieved %u PAM messages, expected <= %u",
     857                 :            :                     __func__, *num, PAM_MAX_NUM_MSG);
     858                 :            :         *prompts = xcalloc((*num + 1), sizeof(char *));
     859                 :            :         *echo_on = xcalloc((*num + 1), sizeof(u_int));
     860                 :            :         for (i = 0; i < *num; ++i) {
     861                 :            :                 (*prompts)[i] = buffer_get_string(&m, NULL);
     862                 :            :                 (*echo_on)[i] = buffer_get_int(&m);
     863                 :            :         }
     864                 :            :         buffer_free(&m);
     865                 :            :         return (ret);
     866                 :            : }
     867                 :            : 
     868                 :            : int
     869                 :            : mm_sshpam_respond(void *ctx, u_int num, char **resp)
     870                 :            : {
     871                 :            :         Buffer m;
     872                 :            :         u_int i;
     873                 :            :         int ret;
     874                 :            : 
     875                 :            :         debug3("%s", __func__);
     876                 :            :         buffer_init(&m);
     877                 :            :         buffer_put_int(&m, num);
     878                 :            :         for (i = 0; i < num; ++i)
     879                 :            :                 buffer_put_cstring(&m, resp[i]);
     880                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
     881                 :            :         debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
     882                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
     883                 :            :         ret = buffer_get_int(&m);
     884                 :            :         debug3("%s: pam_respond returned %d", __func__, ret);
     885                 :            :         buffer_free(&m);
     886                 :            :         return (ret);
     887                 :            : }
     888                 :            : 
     889                 :            : void
     890                 :            : mm_sshpam_free_ctx(void *ctxtp)
     891                 :            : {
     892                 :            :         Buffer m;
     893                 :            : 
     894                 :            :         debug3("%s", __func__);
     895                 :            :         buffer_init(&m);
     896                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
     897                 :            :         debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
     898                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
     899                 :            :         buffer_free(&m);
     900                 :            : }
     901                 :            : #endif /* USE_PAM */
     902                 :            : 
     903                 :            : /* Request process termination */
     904                 :            : 
     905                 :            : void
     906                 :         25 : mm_terminate(void)
     907                 :            : {
     908                 :            :         Buffer m;
     909                 :            : 
     910                 :         25 :         buffer_init(&m);
     911                 :         25 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
     912                 :         25 :         buffer_free(&m);
     913                 :         25 : }
     914                 :            : 
     915                 :            : int
     916                 :        103 : mm_ssh1_session_key(BIGNUM *num)
     917                 :            : {
     918                 :            :         int rsafail;
     919                 :            :         Buffer m;
     920                 :            : 
     921                 :        103 :         buffer_init(&m);
     922                 :        103 :         buffer_put_bignum2(&m, num);
     923                 :        103 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
     924                 :            : 
     925                 :        103 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
     926                 :            : 
     927                 :        103 :         rsafail = buffer_get_int(&m);
     928                 :        103 :         buffer_get_bignum2(&m, num);
     929                 :            : 
     930                 :        103 :         buffer_free(&m);
     931                 :            : 
     932                 :        103 :         return (rsafail);
     933                 :            : }
     934                 :            : 
     935                 :            : static void
     936                 :          0 : mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
     937                 :            :     char ***prompts, u_int **echo_on)
     938                 :            : {
     939                 :          0 :         *name = xstrdup("");
     940                 :          0 :         *infotxt = xstrdup("");
     941                 :          0 :         *numprompts = 1;
     942                 :          0 :         *prompts = xcalloc(*numprompts, sizeof(char *));
     943                 :          0 :         *echo_on = xcalloc(*numprompts, sizeof(u_int));
     944                 :          0 :         (*echo_on)[0] = 0;
     945                 :          0 : }
     946                 :            : 
     947                 :            : int
     948                 :          0 : mm_bsdauth_query(void *ctx, char **name, char **infotxt,
     949                 :            :    u_int *numprompts, char ***prompts, u_int **echo_on)
     950                 :            : {
     951                 :            :         Buffer m;
     952                 :            :         u_int success;
     953                 :            :         char *challenge;
     954                 :            : 
     955                 :          0 :         debug3("%s: entering", __func__);
     956                 :            : 
     957                 :          0 :         buffer_init(&m);
     958                 :          0 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
     959                 :            : 
     960                 :          0 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
     961                 :            :             &m);
     962                 :          0 :         success = buffer_get_int(&m);
     963         [ #  # ]:          0 :         if (success == 0) {
     964                 :          0 :                 debug3("%s: no challenge", __func__);
     965                 :          0 :                 buffer_free(&m);
     966                 :          0 :                 return (-1);
     967                 :            :         }
     968                 :            : 
     969                 :            :         /* Get the challenge, and format the response */
     970                 :          0 :         challenge  = buffer_get_string(&m, NULL);
     971                 :          0 :         buffer_free(&m);
     972                 :            : 
     973                 :          0 :         mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
     974                 :          0 :         (*prompts)[0] = challenge;
     975                 :            : 
     976                 :          0 :         debug3("%s: received challenge: %s", __func__, challenge);
     977                 :            : 
     978                 :          0 :         return (0);
     979                 :            : }
     980                 :            : 
     981                 :            : int
     982                 :          0 : mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
     983                 :            : {
     984                 :            :         Buffer m;
     985                 :            :         int authok;
     986                 :            : 
     987                 :          0 :         debug3("%s: entering", __func__);
     988         [ #  # ]:          0 :         if (numresponses != 1)
     989                 :            :                 return (-1);
     990                 :            : 
     991                 :          0 :         buffer_init(&m);
     992                 :          0 :         buffer_put_cstring(&m, responses[0]);
     993                 :          0 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
     994                 :            : 
     995                 :          0 :         mm_request_receive_expect(pmonitor->m_recvfd,
     996                 :            :             MONITOR_ANS_BSDAUTHRESPOND, &m);
     997                 :            : 
     998                 :          0 :         authok = buffer_get_int(&m);
     999                 :          0 :         buffer_free(&m);
    1000                 :            : 
    1001         [ #  # ]:          0 :         return ((authok == 0) ? -1 : 0);
    1002                 :            : }
    1003                 :            : 
    1004                 :            : #ifdef SKEY
    1005                 :            : int
    1006                 :            : mm_skey_query(void *ctx, char **name, char **infotxt,
    1007                 :            :    u_int *numprompts, char ***prompts, u_int **echo_on)
    1008                 :            : {
    1009                 :            :         Buffer m;
    1010                 :            :         u_int success;
    1011                 :            :         char *challenge;
    1012                 :            : 
    1013                 :            :         debug3("%s: entering", __func__);
    1014                 :            : 
    1015                 :            :         buffer_init(&m);
    1016                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
    1017                 :            : 
    1018                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
    1019                 :            :             &m);
    1020                 :            :         success = buffer_get_int(&m);
    1021                 :            :         if (success == 0) {
    1022                 :            :                 debug3("%s: no challenge", __func__);
    1023                 :            :                 buffer_free(&m);
    1024                 :            :                 return (-1);
    1025                 :            :         }
    1026                 :            : 
    1027                 :            :         /* Get the challenge, and format the response */
    1028                 :            :         challenge  = buffer_get_string(&m, NULL);
    1029                 :            :         buffer_free(&m);
    1030                 :            : 
    1031                 :            :         debug3("%s: received challenge: %s", __func__, challenge);
    1032                 :            : 
    1033                 :            :         mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
    1034                 :            : 
    1035                 :            :         xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
    1036                 :            :         free(challenge);
    1037                 :            : 
    1038                 :            :         return (0);
    1039                 :            : }
    1040                 :            : 
    1041                 :            : int
    1042                 :            : mm_skey_respond(void *ctx, u_int numresponses, char **responses)
    1043                 :            : {
    1044                 :            :         Buffer m;
    1045                 :            :         int authok;
    1046                 :            : 
    1047                 :            :         debug3("%s: entering", __func__);
    1048                 :            :         if (numresponses != 1)
    1049                 :            :                 return (-1);
    1050                 :            : 
    1051                 :            :         buffer_init(&m);
    1052                 :            :         buffer_put_cstring(&m, responses[0]);
    1053                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
    1054                 :            : 
    1055                 :            :         mm_request_receive_expect(pmonitor->m_recvfd,
    1056                 :            :             MONITOR_ANS_SKEYRESPOND, &m);
    1057                 :            : 
    1058                 :            :         authok = buffer_get_int(&m);
    1059                 :            :         buffer_free(&m);
    1060                 :            : 
    1061                 :            :         return ((authok == 0) ? -1 : 0);
    1062                 :            : }
    1063                 :            : #endif /* SKEY */
    1064                 :            : 
    1065                 :            : void
    1066                 :        103 : mm_ssh1_session_id(u_char session_id[16])
    1067                 :            : {
    1068                 :            :         Buffer m;
    1069                 :            :         int i;
    1070                 :            : 
    1071                 :        103 :         debug3("%s entering", __func__);
    1072                 :            : 
    1073                 :        103 :         buffer_init(&m);
    1074         [ +  + ]:       1751 :         for (i = 0; i < 16; i++)
    1075                 :       1648 :                 buffer_put_char(&m, session_id[i]);
    1076                 :            : 
    1077                 :        103 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
    1078                 :        103 :         buffer_free(&m);
    1079                 :        103 : }
    1080                 :            : 
    1081                 :            : int
    1082                 :        103 : mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
    1083                 :            : {
    1084                 :            :         Buffer m;
    1085                 :            :         Key *key;
    1086                 :            :         u_char *blob;
    1087                 :            :         u_int blen;
    1088                 :        103 :         int allowed = 0, have_forced = 0;
    1089                 :            : 
    1090                 :        103 :         debug3("%s entering", __func__);
    1091                 :            : 
    1092                 :        103 :         buffer_init(&m);
    1093                 :        103 :         buffer_put_bignum2(&m, client_n);
    1094                 :            : 
    1095                 :        103 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
    1096                 :        103 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
    1097                 :            : 
    1098                 :        103 :         allowed = buffer_get_int(&m);
    1099                 :            : 
    1100                 :            :         /* fake forced command */
    1101                 :        103 :         auth_clear_options();
    1102                 :        103 :         have_forced = buffer_get_int(&m);
    1103         [ +  + ]:        103 :         forced_command = have_forced ? xstrdup("true") : NULL;
    1104                 :            : 
    1105         [ +  - ]:        103 :         if (allowed && rkey != NULL) {
    1106                 :        103 :                 blob = buffer_get_string(&m, &blen);
    1107         [ -  + ]:        103 :                 if ((key = key_from_blob(blob, blen)) == NULL)
    1108                 :          0 :                         fatal("%s: key_from_blob failed", __func__);
    1109                 :        103 :                 *rkey = key;
    1110                 :        103 :                 free(blob);
    1111                 :            :         }
    1112                 :        103 :         buffer_free(&m);
    1113                 :            : 
    1114                 :        103 :         return (allowed);
    1115                 :            : }
    1116                 :            : 
    1117                 :            : BIGNUM *
    1118                 :        103 : mm_auth_rsa_generate_challenge(Key *key)
    1119                 :            : {
    1120                 :            :         Buffer m;
    1121                 :            :         BIGNUM *challenge;
    1122                 :            :         u_char *blob;
    1123                 :            :         u_int blen;
    1124                 :            : 
    1125                 :        103 :         debug3("%s entering", __func__);
    1126                 :            : 
    1127         [ -  + ]:        103 :         if ((challenge = BN_new()) == NULL)
    1128                 :          0 :                 fatal("%s: BN_new failed", __func__);
    1129                 :            : 
    1130                 :        103 :         key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
    1131         [ -  + ]:        103 :         if (key_to_blob(key, &blob, &blen) == 0)
    1132                 :          0 :                 fatal("%s: key_to_blob failed", __func__);
    1133                 :        103 :         key->type = KEY_RSA1;
    1134                 :            : 
    1135                 :        103 :         buffer_init(&m);
    1136                 :        103 :         buffer_put_string(&m, blob, blen);
    1137                 :        103 :         free(blob);
    1138                 :            : 
    1139                 :        103 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
    1140                 :        103 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
    1141                 :            : 
    1142                 :        103 :         buffer_get_bignum2(&m, challenge);
    1143                 :        103 :         buffer_free(&m);
    1144                 :            : 
    1145                 :        103 :         return (challenge);
    1146                 :            : }
    1147                 :            : 
    1148                 :            : int
    1149                 :        103 : mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
    1150                 :            : {
    1151                 :            :         Buffer m;
    1152                 :            :         u_char *blob;
    1153                 :            :         u_int blen;
    1154                 :        103 :         int success = 0;
    1155                 :            : 
    1156                 :        103 :         debug3("%s entering", __func__);
    1157                 :            : 
    1158                 :        103 :         key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
    1159         [ -  + ]:        103 :         if (key_to_blob(key, &blob, &blen) == 0)
    1160                 :          0 :                 fatal("%s: key_to_blob failed", __func__);
    1161                 :        103 :         key->type = KEY_RSA1;
    1162                 :            : 
    1163                 :        103 :         buffer_init(&m);
    1164                 :        103 :         buffer_put_string(&m, blob, blen);
    1165                 :        103 :         buffer_put_string(&m, response, 16);
    1166                 :        103 :         free(blob);
    1167                 :            : 
    1168                 :        103 :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
    1169                 :        103 :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
    1170                 :            : 
    1171                 :        103 :         success = buffer_get_int(&m);
    1172                 :        103 :         buffer_free(&m);
    1173                 :            : 
    1174                 :        103 :         return (success);
    1175                 :            : }
    1176                 :            : 
    1177                 :            : #ifdef SSH_AUDIT_EVENTS
    1178                 :            : void
    1179                 :            : mm_audit_event(ssh_audit_event_t event)
    1180                 :            : {
    1181                 :            :         Buffer m;
    1182                 :            : 
    1183                 :            :         debug3("%s entering", __func__);
    1184                 :            : 
    1185                 :            :         buffer_init(&m);
    1186                 :            :         buffer_put_int(&m, event);
    1187                 :            : 
    1188                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
    1189                 :            :         buffer_free(&m);
    1190                 :            : }
    1191                 :            : 
    1192                 :            : void
    1193                 :            : mm_audit_run_command(const char *command)
    1194                 :            : {
    1195                 :            :         Buffer m;
    1196                 :            : 
    1197                 :            :         debug3("%s entering command %s", __func__, command);
    1198                 :            : 
    1199                 :            :         buffer_init(&m);
    1200                 :            :         buffer_put_cstring(&m, command);
    1201                 :            : 
    1202                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
    1203                 :            :         buffer_free(&m);
    1204                 :            : }
    1205                 :            : #endif /* SSH_AUDIT_EVENTS */
    1206                 :            : 
    1207                 :            : #ifdef GSSAPI
    1208                 :            : OM_uint32
    1209                 :            : mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
    1210                 :            : {
    1211                 :            :         Buffer m;
    1212                 :            :         OM_uint32 major;
    1213                 :            : 
    1214                 :            :         /* Client doesn't get to see the context */
    1215                 :            :         *ctx = NULL;
    1216                 :            : 
    1217                 :            :         buffer_init(&m);
    1218                 :            :         buffer_put_string(&m, goid->elements, goid->length);
    1219                 :            : 
    1220                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
    1221                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
    1222                 :            : 
    1223                 :            :         major = buffer_get_int(&m);
    1224                 :            : 
    1225                 :            :         buffer_free(&m);
    1226                 :            :         return (major);
    1227                 :            : }
    1228                 :            : 
    1229                 :            : OM_uint32
    1230                 :            : mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
    1231                 :            :     gss_buffer_desc *out, OM_uint32 *flags)
    1232                 :            : {
    1233                 :            :         Buffer m;
    1234                 :            :         OM_uint32 major;
    1235                 :            :         u_int len;
    1236                 :            : 
    1237                 :            :         buffer_init(&m);
    1238                 :            :         buffer_put_string(&m, in->value, in->length);
    1239                 :            : 
    1240                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
    1241                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
    1242                 :            : 
    1243                 :            :         major = buffer_get_int(&m);
    1244                 :            :         out->value = buffer_get_string(&m, &len);
    1245                 :            :         out->length = len;
    1246                 :            :         if (flags)
    1247                 :            :                 *flags = buffer_get_int(&m);
    1248                 :            : 
    1249                 :            :         buffer_free(&m);
    1250                 :            : 
    1251                 :            :         return (major);
    1252                 :            : }
    1253                 :            : 
    1254                 :            : OM_uint32
    1255                 :            : mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
    1256                 :            : {
    1257                 :            :         Buffer m;
    1258                 :            :         OM_uint32 major;
    1259                 :            : 
    1260                 :            :         buffer_init(&m);
    1261                 :            :         buffer_put_string(&m, gssbuf->value, gssbuf->length);
    1262                 :            :         buffer_put_string(&m, gssmic->value, gssmic->length);
    1263                 :            : 
    1264                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
    1265                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
    1266                 :            :             &m);
    1267                 :            : 
    1268                 :            :         major = buffer_get_int(&m);
    1269                 :            :         buffer_free(&m);
    1270                 :            :         return(major);
    1271                 :            : }
    1272                 :            : 
    1273                 :            : int
    1274                 :            : mm_ssh_gssapi_userok(char *user)
    1275                 :            : {
    1276                 :            :         Buffer m;
    1277                 :            :         int authenticated = 0;
    1278                 :            : 
    1279                 :            :         buffer_init(&m);
    1280                 :            : 
    1281                 :            :         mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
    1282                 :            :         mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
    1283                 :            :                                   &m);
    1284                 :            : 
    1285                 :            :         authenticated = buffer_get_int(&m);
    1286                 :            : 
    1287                 :            :         buffer_free(&m);
    1288                 :            :         debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
    1289                 :            :         return (authenticated);
    1290                 :            : }
    1291                 :            : #endif /* GSSAPI */
    1292                 :            : 

Generated by: LCOV version 1.9