+
+ return (rsafail);
+}
+
+static void
+mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
+ char ***prompts, u_int **echo_on)
+{
+ *name = xstrdup("");
+ *infotxt = xstrdup("");
+ *numprompts = 1;
+ *prompts = xcalloc(*numprompts, sizeof(char *));
+ *echo_on = xcalloc(*numprompts, sizeof(u_int));
+ (*echo_on)[0] = 0;
+}
+
+int
+mm_bsdauth_query(void *ctx, char **name, char **infotxt,
+ u_int *numprompts, char ***prompts, u_int **echo_on)
+{
+ Buffer m;
+ u_int success;
+ char *challenge;
+
+ debug3("%s: entering", __func__);
+
+ buffer_init(&m);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
+ &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);
+
+ mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
+ (*prompts)[0] = challenge;
+
+ debug3("%s: received challenge: %s", __func__, challenge);
+
+ return (0);
+}
+
+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);
+}
+
+#ifdef SKEY
+int
+mm_skey_query(void *ctx, char **name, char **infotxt,
+ u_int *numprompts, char ***prompts, u_int **echo_on)
+{
+ Buffer m;
+ u_int success;
+ char *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);
+
+ xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
+ xfree(challenge);
+
+ return (0);
+}
+
+int
+mm_skey_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_SKEYRESPOND, &m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd,
+ MONITOR_ANS_SKEYRESPOND, &m);
+
+ authok = buffer_get_int(&m);
+ buffer_free(&m);
+
+ return ((authok == 0) ? -1 : 0);
+}
+#endif /* SKEY */
+
+void
+mm_ssh1_session_id(u_char session_id[16])
+{
+ Buffer m;
+ int i;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ for (i = 0; i < 16; i++)
+ buffer_put_char(&m, session_id[i]);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
+ buffer_free(&m);
+}
+
+int
+mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
+{
+ Buffer m;
+ Key *key;
+ u_char *blob;
+ u_int blen;
+ int allowed = 0, have_forced = 0;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_bignum2(&m, client_n);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &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;
+
+ if (allowed && rkey != NULL) {
+ blob = buffer_get_string(&m, &blen);
+ if ((key = key_from_blob(blob, blen)) == NULL)
+ fatal("%s: key_from_blob failed", __func__);
+ *rkey = key;
+ xfree(blob);
+ }
+ mm_send_debug(&m);
+ buffer_free(&m);
+
+ return (allowed);
+}
+
+BIGNUM *
+mm_auth_rsa_generate_challenge(Key *key)
+{
+ Buffer m;
+ BIGNUM *challenge;
+ u_char *blob;
+ u_int blen;
+
+ debug3("%s entering", __func__);
+
+ if ((challenge = BN_new()) == NULL)
+ fatal("%s: BN_new failed", __func__);
+
+ key->type = KEY_RSA; /* XXX cheat for key_to_blob */
+ if (key_to_blob(key, &blob, &blen) == 0)
+ fatal("%s: key_to_blob failed", __func__);
+ key->type = KEY_RSA1;
+
+ buffer_init(&m);
+ buffer_put_string(&m, blob, blen);
+ xfree(blob);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
+
+ buffer_get_bignum2(&m, challenge);
+ buffer_free(&m);
+
+ return (challenge);
+}
+
+int
+mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
+{
+ Buffer m;
+ u_char *blob;
+ u_int blen;
+ int success = 0;
+
+ debug3("%s entering", __func__);
+
+ key->type = KEY_RSA; /* XXX cheat for key_to_blob */
+ if (key_to_blob(key, &blob, &blen) == 0)
+ fatal("%s: key_to_blob failed", __func__);
+ key->type = KEY_RSA1;
+
+ buffer_init(&m);
+ buffer_put_string(&m, blob, blen);
+ buffer_put_string(&m, response, 16);
+ xfree(blob);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
+
+ success = buffer_get_int(&m);
+ buffer_free(&m);
+
+ return (success);
+}
+
+#ifdef SSH_AUDIT_EVENTS
+void
+mm_audit_event(ssh_audit_event_t event)
+{
+ Buffer m;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_int(&m, event);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
+ buffer_free(&m);
+}
+
+void
+mm_audit_run_command(const char *command)
+{
+ Buffer m;
+
+ debug3("%s entering command %s", __func__, command);
+
+ buffer_init(&m);
+ buffer_put_cstring(&m, command);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
+ buffer_free(&m);
+}
+#endif /* SSH_AUDIT_EVENTS */
+
+#ifdef GSSAPI
+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);
+}
+
+OM_uint32
+mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
+ gss_buffer_desc *out, OM_uint32 *flags)
+{
+ Buffer m;
+ OM_uint32 major;
+ u_int len;
+
+ buffer_init(&m);
+ buffer_put_string(&m, in->value, in->length);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
+
+ major = buffer_get_int(&m);
+ out->value = buffer_get_string(&m, &len);
+ out->length = len;
+ if (flags)
+ *flags = buffer_get_int(&m);
+
+ buffer_free(&m);
+
+ return (major);
+}
+
+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_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);