int mm_answer_rsa_keyallowed(int sock, Buffer *m) { BIGNUM *client_n; Key *key = NULL; u_char *blob = NULL; u_int blen = 0; int allowed = 0; debug3("%s entering", __func__); auth_method = "rsa"; if (options.rsa_authentication && authctxt->valid) { if ((client_n = BN_new()) == NULL) fatal("%s: BN_new", __func__); buffer_get_bignum2(m, client_n); allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key); BN_clear_free(client_n); } buffer_clear(m); buffer_put_int(m, allowed); buffer_put_int(m, forced_command != NULL); /* clear temporarily storage (used by generate challenge) */ monitor_reset_key_state(); if (allowed && key != NULL) { key->type = KEY_RSA; /* cheat for key_to_blob */ if (key_to_blob(key, &blob, &blen) == 0) fatal("%s: key_to_blob failed", __func__); buffer_put_string(m, blob, blen); /* Save temporarily for comparison in verify */ key_blob = blob; key_bloblen = blen; key_blobtype = MM_RSAUSERKEY; } if (key != NULL) key_free(key); mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); return (0); }
int mm_answer_pam_account(int sock, Buffer *m) { u_int ret; if (!options.use_pam) fatal("%s: PAM not enabled", __func__); ret = do_pam_account(); buffer_put_int(m, ret); buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); return (ret); }
char *mm_auth2_read_banner(void) { Buffer m; char *banner; debug3("%s entering", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); buffer_clear(&m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m); banner = buffer_get_string(&m, NULL); buffer_free(&m); return (banner); }
int mm_answer_pam_free_ctx(int sock, Buffer *m) { int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; debug3("%s", __func__); if (sshpam_ctxt == NULL) fatal("%s: no context", __func__); (sshpam_device.free_ctx)(sshpam_ctxt); sshpam_ctxt = sshpam_authok = NULL; buffer_clear(m); mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); /* Allow another attempt */ monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); auth_method = "keyboard-interactive"; auth_submethod = "pam"; return r; }
OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) { Buffer m; OM_uint32 major; buffer_init(&m); buffer_put_string(&m, gssbuf->value, gssbuf->length); buffer_put_string(&m, gssmic->value, gssmic->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, &m); major = buffer_get_int(&m); buffer_free(&m); return(major); }
int mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); buffer_clear(m); buffer_put_int(m, authenticated); debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); auth_method = "gssapi-with-mic"; /* Monitor loop will terminate if authenticated */ return (authenticated); }
int mm_ssh_gssapi_userok(char *user) { Buffer m; int authenticated = 0; buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, &m); authenticated = buffer_get_int(&m); buffer_free(&m); debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); }
int mm_answer_pam_init_ctx(int sock, Buffer *m) { debug3("%s", __func__); authctxt->user = buffer_get_string(m, NULL); sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); sshpam_authok = NULL; buffer_clear(m); if (sshpam_ctxt != NULL) { monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); buffer_put_int(m, 1); } else { buffer_put_int(m, 0); } mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); return (0); }
int mm_answer_jpake_step1(int sock, Buffer *m) { struct jpake_ctx *pctx; u_char *x3_proof, *x4_proof; u_int x3_proof_len, x4_proof_len; if (!options.zero_knowledge_password_authentication) fatal("zero_knowledge_password_authentication disabled"); if (authctxt->jpake_ctx != NULL) fatal("%s: authctxt->jpake_ctx already set (%p)", __func__, authctxt->jpake_ctx); authctxt->jpake_ctx = pctx = jpake_new(); jpake_step1(pctx->grp, &pctx->server_id, &pctx->server_id_len, &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, &x3_proof, &x3_proof_len, &x4_proof, &x4_proof_len); JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); buffer_clear(m); buffer_put_string(m, pctx->server_id, pctx->server_id_len); buffer_put_bignum2(m, pctx->g_x3); buffer_put_bignum2(m, pctx->g_x4); buffer_put_string(m, x3_proof, x3_proof_len); buffer_put_string(m, x4_proof, x4_proof_len); debug3("%s: sending step1", __func__); mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); bzero(x3_proof, x3_proof_len); bzero(x4_proof, x4_proof_len); xfree(x3_proof); xfree(x4_proof); monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); return 0; }
int mm_answer_rsa_response(int sock, Buffer *m) { Key *key = NULL; u_char *blob, *response; u_int blen, len; int success; debug3("%s entering", __func__); if (!authctxt->valid) fatal("%s: authctxt not valid", __func__); if (ssh1_challenge == NULL) fatal("%s: no ssh1_challenge", __func__); blob = buffer_get_string(m, &blen); if (!monitor_allowed_key(blob, blen)) fatal("%s: bad key, not previously allowed", __func__); if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) fatal("%s: key type mismatch: %d", __func__, key_blobtype); if ((key = key_from_blob(blob, blen)) == NULL) fatal("%s: received bad key", __func__); response = buffer_get_string(m, &len); if (len != 16) fatal("%s: received bad response to challenge", __func__); success = auth_rsa_verify_response(key, ssh1_challenge, response); xfree(blob); key_free(key); xfree(response); auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; /* reset state */ BN_clear_free(ssh1_challenge); ssh1_challenge = NULL; monitor_reset_key_state(); buffer_clear(m); buffer_put_int(m, success); mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); return (success); }
int mm_answer_sign(int sock, Buffer *m) { Key *key; u_char *p; u_char *signature; u_int siglen, datlen; int keyid; debug3("%s", __func__); keyid = buffer_get_int(m); p = buffer_get_string(m, &datlen); if (datlen != 20) fatal("%s: data length incorrect: %u", __func__, datlen); /* save session id, it will be passed on the first call */ if (session_id2_len == 0) { session_id2_len = datlen; session_id2 = xmalloc(session_id2_len); memcpy(session_id2, p, session_id2_len); } if ((key = get_hostkey_by_index(keyid)) == NULL) fatal("%s: no hostkey from index %d", __func__, keyid); if (key_sign(key, &signature, &siglen, p, datlen) < 0) fatal("%s: key_sign failed", __func__); debug3("%s: signature %p(%u)", __func__, signature, siglen); buffer_clear(m); buffer_put_string(m, signature, siglen); xfree(p); xfree(signature); mm_request_send(sock, MONITOR_ANS_SIGN, m); /* Turn on permissions for getpwnam */ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); return (0); }
int mm_ssh1_session_key(BIGNUM *num) { int rsafail; Buffer m; buffer_init(&m); buffer_put_bignum2(&m, num); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); rsafail = buffer_get_int(&m); buffer_get_bignum2(&m, num); buffer_free(&m); return (rsafail); }
int mm_answer_skeyquery(int socket, Buffer *m) { struct skey skey; char challenge[1024]; u_int success; success = skeychallenge(&skey, authctxt->user, challenge) < 0 ? 0 : 1; buffer_clear(m); buffer_put_int(m, success); if (success) buffer_put_cstring(m, challenge); debug3("%s: sending challenge success: %u", __func__, success); mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m); return (0); }
int mm_answer_skeyquery(int socket, Buffer *m) { struct skey skey; char challenge[1024]; int res; res = skeychallenge(&skey, authctxt->user, challenge); buffer_clear(m); buffer_put_int(m, res); if (res != -1) buffer_put_cstring(m, challenge); debug3("%s: sending challenge res: %d", __func__, res); mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m); return (0); }
int mm_sshpam_respond(void *ctx, u_int num, char **resp) { Buffer m; int i, ret; debug3("%s", __func__); buffer_init(&m); buffer_put_int(&m, num); for (i = 0; i < num; ++i) buffer_put_cstring(&m, resp[i]); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); ret = buffer_get_int(&m); debug3("%s: pam_respond returned %d", __func__, ret); buffer_free(&m); return (ret); }
int mm_answer_gss_userok(int sock, struct sshbuf *m) { int r, authenticated; authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); auth_method = "gssapi-with-mic"; /* Monitor loop will terminate if authenticated */ return (authenticated); }
int mm_answer_krb4(int socket, Buffer *m) { KTEXT_ST auth, reply; char *client, *p; int success; u_int alen; reply.length = auth.length = 0; p = buffer_get_string(m, &alen); if (alen >= MAX_KTXT_LEN) fatal("%s: auth too large", __func__); memcpy(auth.dat, p, alen); auth.length = alen; memset(p, 0, alen); xfree(p); success = options.kerberos_authentication && authctxt->valid && auth_krb4(authctxt, &auth, &client, &reply); memset(auth.dat, 0, alen); buffer_clear(m); buffer_put_int(m, success); if (success) { buffer_put_cstring(m, client); buffer_put_string(m, reply.dat, reply.length); if (client) xfree(client); if (reply.length) memset(reply.dat, 0, reply.length); } debug3("%s: sending result %d", __func__, success); mm_request_send(socket, MONITOR_ANS_KRB4, m); auth_method = "kerberos"; /* Causes monitor loop to terminate if authenticated */ return (success); }
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) { Buffer m; OM_uint32 major; /* Client doesn't get to see the context */ *ctx = NULL; buffer_init(&m); buffer_put_string(&m, goid->elements, goid->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); major = buffer_get_int(&m); buffer_free(&m); return (major); }
void * mm_sshpam_init_ctx(Authctxt *authctxt) { Buffer m; int success; debug3("%s", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); success = buffer_get_int(&m); if (success == 0) { debug3("%s: pam_init_ctx failed", __func__); buffer_free(&m); return (NULL); } buffer_free(&m); return (authctxt); }
void mm_session_pty_cleanup2(Session *s) { Buffer m; if (s->ttyfd == -1) return; buffer_init(&m); buffer_put_cstring(&m, s->tty); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); buffer_free(&m); /* closed dup'ed master */ if (s->ptymaster != -1 && close(s->ptymaster) < 0) error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); /* unlink pty from session */ s->ttyfd = -1; }
int mm_answer_pam_init_ctx(int sock, Buffer *m) { debug3("%s", __func__); if (!options.kbd_interactive_authentication) fatal("%s: kbd-int authentication not enabled", __func__); if (sshpam_ctxt != NULL) fatal("%s: already called", __func__); sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); sshpam_authok = NULL; buffer_clear(m); if (sshpam_ctxt != NULL) { monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 1); buffer_put_int(m, 1); } else { buffer_put_int(m, 0); } mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); return (0); }
OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) { Buffer m; OM_uint32 major; u_int len; buffer_init(&m); buffer_put_string(&m, data->value, data->length); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m); major = buffer_get_int(&m); hash->value = buffer_get_string(&m, &len); hash->length = len; buffer_free(&m); return(major); }
int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { Buffer m; int ok; buffer_init(&m); buffer_put_cstring(&m, store->filename ? store->filename : ""); buffer_put_cstring(&m, store->envvar ? store->envvar : ""); buffer_put_cstring(&m, store->envval ? store->envval : ""); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m); ok = buffer_get_int(&m); buffer_free(&m); return (ok); }
int mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) { Kex *kex = *pmonitor->m_pkex; Buffer m; debug3("%s entering", __func__); buffer_init(&m); buffer_put_int(&m, kex->host_key_index(key)); buffer_put_string(&m, data, datalen); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); *sigp = buffer_get_string(&m, lenp); buffer_free(&m); return (0); }
void mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s, char **hash_scheme, char **salt) { Buffer m; debug3("%s entering", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_JPAKE_GET_PWDATA, &m); debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_JPAKE_GET_PWDATA, &m); *hash_scheme = buffer_get_string(&m, NULL); *salt = buffer_get_string(&m, NULL); buffer_free(&m); }
int mm_answer_rsa_challenge(int sock, struct sshbuf *m) { struct sshkey *key = NULL; u_char *blob; size_t blen; int r; debug3("%s entering", __func__); if (!authctxt->valid) fatal("%s: authctxt not valid", __func__); if ((r = sshbuf_get_string(m, &blob, &blen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (!monitor_allowed_key(blob, blen)) fatal("%s: bad key, not previously allowed", __func__); if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) fatal("%s: key type mismatch", __func__); if ((r = sshkey_from_blob(blob, blen, &key)) != 0) fatal("%s: received bad key: %s", __func__, ssh_err(r)); if (key->type != KEY_RSA) fatal("%s: received bad key type %d", __func__, key->type); key->type = KEY_RSA1; if (ssh1_challenge) BN_clear_free(ssh1_challenge); ssh1_challenge = auth_rsa_generate_challenge(key); sshbuf_reset(m); if ((r = sshbuf_put_bignum2(m, ssh1_challenge)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("%s sending reply", __func__); mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); free(blob); sshkey_free(key); return (0); }
int mm_skey_query(void *ctx, char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) { Buffer m; int len; u_int success; char *p, *challenge; debug3("%s: entering", __func__); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, &m); success = buffer_get_int(&m); if (success == 0) { debug3("%s: no challenge", __func__); buffer_free(&m); return (-1); } /* Get the challenge, and format the response */ challenge = buffer_get_string(&m, NULL); buffer_free(&m); debug3("%s: received challenge: %s", __func__, challenge); mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); len = strlen(challenge) + strlen(SKEY_PROMPT) + 1; p = xmalloc(len); strlcpy(p, challenge, len); strlcat(p, SKEY_PROMPT, len); (*prompts)[0] = p; xfree(challenge); return (0); }
int mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) { Buffer m; u_char *blob; u_int len; int allowed = 0, have_forced = 0; debug3("%s entering", __func__); /* Convert the key to a blob and the pass it over */ if (!key_to_blob(key, &blob, &len)) return (0); buffer_init(&m); buffer_put_int(&m, type); buffer_put_cstring(&m, user ? user : ""); buffer_put_cstring(&m, host ? host : ""); buffer_put_string(&m, blob, len); xfree(blob); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); allowed = buffer_get_int(&m); /* fake forced command */ auth_clear_options(); have_forced = buffer_get_int(&m); forced_command = have_forced ? xstrdup("true") : NULL; /* Send potential debug messages */ mm_send_debug(&m); buffer_free(&m); return (allowed); }
int mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) { Buffer m; int authok; debug3("%s: entering", __func__); if (numresponses != 1) return (-1); buffer_init(&m); buffer_put_cstring(&m, responses[0]); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHRESPOND, &m); authok = buffer_get_int(&m); buffer_free(&m); return ((authok == 0) ? -1 : 0); }
void mm_jpake_step2(struct modp_group *grp, BIGNUM *s, BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2, const u_char *theirid, u_int theirid_len, const u_char *myid, u_int myid_len, const u_char *theirpub1_proof, u_int theirpub1_proof_len, const u_char *theirpub2_proof, u_int theirpub2_proof_len, BIGNUM **newpub, u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len) { Buffer m; debug3("%s entering", __func__); buffer_init(&m); /* monitor already has all bignums except theirpub1, theirpub2 */ buffer_put_bignum2(&m, theirpub1); buffer_put_bignum2(&m, theirpub2); /* monitor already knows our id */ buffer_put_string(&m, theirid, theirid_len); buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len); buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_JPAKE_STEP2, &m); debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_JPAKE_STEP2, &m); if ((*newpub = BN_new()) == NULL) fatal("%s: BN_new", __func__); buffer_get_bignum2(&m, *newpub); *newpub_exponent_proof = buffer_get_string(&m, newpub_exponent_proof_len); buffer_free(&m); }