+
+#ifdef GSSAPI
+
+int
+mm_answer_gss_setup_ctx(int socket, Buffer *m) {
+ gss_OID_desc oid;
+ OM_uint32 major;
+ int len;
+
+ oid.elements=buffer_get_string(m,&len);
+ oid.length=len;
+
+ major=ssh_gssapi_server_ctx(&gsscontext,&oid);
+
+ xfree(oid.elements);
+
+ buffer_clear(m);
+ buffer_put_int(m,major);
+
+ mm_request_send(socket,MONITOR_ANS_GSSSETUP,m);
+
+ /* Now we have a context, enable the step and sign */
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP,1);
+
+ return(0);
+}
+
+int
+mm_answer_gss_accept_ctx(int socket, Buffer *m) {
+ gss_buffer_desc in,out;
+ OM_uint32 major,minor;
+ OM_uint32 flags = 0; /* GSI needs this */
+
+ in.value = buffer_get_string(m,&in.length);
+ major=ssh_gssapi_accept_ctx(gsscontext,&in,&out,&flags);
+ xfree(in.value);
+
+ buffer_clear(m);
+ buffer_put_int(m, major);
+ buffer_put_string(m, out.value, out.length);
+ buffer_put_int(m, flags);
+ mm_request_send(socket,MONITOR_ANS_GSSSTEP,m);
+
+ gss_release_buffer(&minor, &out);
+
+ /* Complete - now we can do signing */
+ if (major==GSS_S_COMPLETE) {
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP,0);
+ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN,1);
+ }
+ return(0);
+}
+
+int
+mm_answer_gss_userok(int socket, 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(socket, MONITOR_ANS_GSSUSEROK, m);
+
+ /* XXX - auth method could also be 'external' */
+ auth_method="gssapi";
+
+ /* Monitor loop will terminate if authenticated */
+ return(authenticated);
+}
+
+int
+mm_answer_gss_sign(int socket, Buffer *m) {
+ gss_buffer_desc data,hash;
+ OM_uint32 major,minor;
+
+ data.value = buffer_get_string(m,&data.length);
+ if (data.length != 16) { /* HACK - i.e. we are using SSHv1 */
+ if (data.length != 20)
+ fatal("%s: data length incorrect: %d", __func__, data.length);
+
+ /* Save the session ID - only first time round */
+ if (session_id2_len == 0) {
+ session_id2_len=data.length;
+ session_id2 = xmalloc(session_id2_len);
+ memcpy(session_id2, data.value, session_id2_len);
+ }
+ } /* HACK - end */
+ major=ssh_gssapi_sign(gsscontext, &data, &hash);
+
+ xfree(data.value);
+
+ buffer_clear(m);
+ buffer_put_int(m, major);
+ buffer_put_string(m, hash.value, hash.length);
+
+ mm_request_send(socket,MONITOR_ANS_GSSSIGN,m);
+
+ gss_release_buffer(&minor,&hash);
+
+ /* Turn on permissions for getpwnam */
+ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
+
+ return(0);
+}
+
+int
+mm_answer_gss_error(int socket, Buffer *m) {
+ OM_uint32 major,minor;
+ char *msg;
+
+ msg=ssh_gssapi_last_error(gsscontext,&major,&minor);
+ buffer_clear(m);
+ buffer_put_int(m,major);
+ buffer_put_int(m,minor);
+ buffer_put_cstring(m,msg);
+
+ mm_request_send(socket,MONITOR_ANS_GSSERR,m);
+
+ xfree(msg);
+
+ return(0);
+}
+
+int
+mm_answer_gss_indicate_mechs(int socket, Buffer *m) {
+ OM_uint32 major,minor;
+ gss_OID_set mech_set;
+ int i;
+
+ major=gss_indicate_mechs(&minor, &mech_set);
+
+ buffer_clear(m);
+ buffer_put_int(m, major);
+ buffer_put_int(m, mech_set->count);
+ for (i=0; i < mech_set->count; i++) {
+ buffer_put_string(m, mech_set->elements[i].elements,
+ mech_set->elements[i].length);
+ }
+
+#if !defined(MECHGLUE) /* mechglue memory management bug ??? */
+ gss_release_oid_set(&minor,&mech_set);
+#endif
+
+ mm_request_send(socket,MONITOR_ANS_GSSMECHS,m);
+
+ return(0);
+}
+
+int
+mm_answer_gss_localname(int socket, Buffer *m) {
+ char *name;
+
+ ssh_gssapi_localname(&name);
+
+ buffer_clear(m);
+ if (name) {
+ buffer_put_cstring(m, name);
+ debug3("%s: sending result %s", __func__, name);
+ xfree(name);
+ } else {
+ buffer_put_cstring(m, "");
+ debug3("%s: sending result \"\"", __func__);
+ }
+
+ mm_request_send(socket, MONITOR_ANS_GSSLOCALNAME, m);
+
+ return(0);
+}
+#endif /* GSSAPI */
+
+#ifdef GSI
+
+int
+mm_answer_gsi_gridmap(int socket, Buffer *m) {
+ char *subject, *name;
+
+ subject = buffer_get_string(m, NULL);
+
+ gsi_gridmap(subject, &name);
+
+ buffer_clear(m);
+ if (name) {
+ buffer_put_cstring(m, name);
+ debug3("%s: sending result %s", __func__, name);
+ xfree(name);
+ } else {
+ buffer_put_cstring(m, "");
+ debug3("%s: sending result \"\"", __func__);
+ }
+
+ mm_request_send(socket, MONITOR_ANS_GSIGRIDMAP, m);
+
+ return(0);
+}
+
+#endif /* GSI */