void input_userauth_success(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; if (authctxt == NULL) fatal("input_userauth_success: no authentication context"); if (authctxt->authlist) xfree(authctxt->authlist); clear_auth_state(authctxt); authctxt->success = 1; /* break out */ }
void input_userauth_failure(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; char *authlist = NULL; int partial; if (authctxt == NULL) fatal("input_userauth_failure: no authentication context"); authlist = packet_get_string(NULL); partial = packet_get_char(); packet_check_eom(); if (partial != 0) log("Authenticated with partial success."); debug("Authentications that can continue: %s", authlist); clear_auth_state(authctxt); userauth(authctxt, authlist); }
void input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) { OM_uint32 min_status; Authctxt *authctxt = ctxt; Gssctxt *gssctxt; gss_buffer_desc send_tok, recv_tok; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; recv_tok.value=packet_get_string(&recv_tok.length); /* Stick it into GSSAPI and see what it says */ (void) ssh_gssapi_init_ctx(gssctxt, authctxt->host, options.gss_deleg_creds, &recv_tok, &send_tok); xfree(recv_tok.value); (void) gss_release_buffer(&min_status, &send_tok); debug("Server sent a GSS-API error token during GSS userauth -- %s", ssh_gssapi_last_error(gssctxt, NULL, NULL)); packet_check_eom(); /* We can't send a packet to the server */ /* The draft says that we should wait for the server to fail * before starting the next authentication. So, we clear the * state, but don't do anything else */ clear_auth_state(authctxt); return; }
int userauth_gssapi_keyex(Authctxt *authctxt) { Gssctxt *gssctxt; gss_buffer_desc send_tok; OM_uint32 status; static int attempt = 0; if (authctxt == NULL || authctxt->method == NULL) fatal("input_gssapi_response: no authentication context"); if (xxx_gssctxt == NULL || xxx_gssctxt->context == GSS_C_NO_CONTEXT) return 0; if (strcmp(authctxt->method->name, "gssapi-keyex") == 0) authctxt->methoddata = gssctxt = xxx_gssctxt; if (attempt++ >= 1) return 0; if (strcmp(authctxt->method->name, "gssapi-keyex") == 0) { gss_buffer_desc g_mic_data; Buffer mic_data; debug2("Authenticating with GSS-API context from key exchange (w/ MIC)"); /* Make data buffer to MIC */ buffer_init(&mic_data); buffer_put_string(&mic_data, session_id2, session_id2_len); buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&mic_data, authctxt->server_user); buffer_put_cstring(&mic_data, authctxt->service); buffer_put_cstring(&mic_data, authctxt->method->name); /* Make MIC */ g_mic_data.value = buffer_ptr(&mic_data); g_mic_data.length = buffer_len(&mic_data); status = ssh_gssapi_get_mic(gssctxt, &g_mic_data, &send_tok); buffer_clear(&mic_data); if (GSS_ERROR(status) || send_tok.length == 0) { /* * Oops, now what? There's no error token... * Next userauth */ debug("GSS_GetMIC() failed! - " "Abandoning GSSAPI userauth"); clear_auth_state(authctxt); userauth(authctxt,NULL); return 0; } packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_put_string(send_tok.value,send_tok.length); /* MIC */ packet_send(); packet_write_wait(); (void) gss_release_buffer(&status, &send_tok); } else if (strcmp(authctxt->method->name, "external-keyx") == 0) { debug2("Authentication with deprecated \"external-keyx\"" " method not supported"); return 0; } return 1; }
void input_gssapi_token(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; gss_buffer_desc send_tok, recv_tok, g_mic_data; Buffer mic_data; OM_uint32 status; u_int slen; if (authctxt == NULL || authctxt->method == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; recv_tok.value=packet_get_string(&slen); recv_tok.length=slen; /* safe typecast */ status=ssh_gssapi_init_ctx(gssctxt, authctxt->host, options.gss_deleg_creds, &recv_tok, &send_tok); packet_check_eom(); if (GSS_ERROR(status)) { if (send_tok.length>0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); packet_put_string(send_tok.value,send_tok.length); packet_send(); packet_write_wait(); } /* Start again with the next method in the list */ clear_auth_state(authctxt); userauth(authctxt,NULL); return; } if (send_tok.length>0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); packet_put_string(send_tok.value,send_tok.length); packet_send(); packet_write_wait(); } if (status != GSS_S_COMPLETE) return; /* Make data buffer to MIC */ buffer_init(&mic_data); buffer_put_string(&mic_data, session_id2, session_id2_len); buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&mic_data, authctxt->server_user); buffer_put_cstring(&mic_data, authctxt->service); buffer_put_cstring(&mic_data, authctxt->method->name); /* Make MIC */ g_mic_data.value = buffer_ptr(&mic_data); g_mic_data.length = buffer_len(&mic_data); status = ssh_gssapi_get_mic(gssctxt, &g_mic_data, &send_tok); buffer_clear(&mic_data); if (GSS_ERROR(status) || send_tok.length == 0) { /* * Oops, now what? There's no error token... * Next userauth */ debug("GSS_GetMIC() failed! - " "Abandoning GSSAPI userauth"); clear_auth_state(authctxt); userauth(authctxt,NULL); return; } packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); packet_put_string(send_tok.value,send_tok.length); packet_send(); packet_write_wait(); }
void input_gssapi_response(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; OM_uint32 status,ms; u_int oidlen; char *oidv; gss_buffer_desc send_tok; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; /* Setup our OID */ oidv=packet_get_string(&oidlen); if (datafellows & SSH_BUG_GSSAPI_BER) { if (!ssh_gssapi_check_mech_oid(gssctxt,oidv,oidlen)) { gss_OID oid; oid = ssh_gssapi_make_oid(oidlen, oidv); debug("Server returned different OID (%s) than expected (%s)", ssh_gssapi_oid_to_str(oid), ssh_gssapi_oid_to_str(gssctxt->desired_mech)); ssh_gssapi_release_oid(&oid); clear_auth_state(authctxt); userauth(authctxt,NULL); return; } } else { if(oidv[0]!=0x06 || oidv[1]!=oidlen-2) { debug("Badly encoded mechanism OID received"); clear_auth_state(authctxt); userauth(authctxt,NULL); return; } if (!ssh_gssapi_check_mech_oid(gssctxt,oidv+2,oidlen-2)) { gss_OID oid; oid = ssh_gssapi_make_oid(oidlen-2, oidv+2); debug("Server returned different OID (%s) than expected (%s)", ssh_gssapi_oid_to_str(oid), ssh_gssapi_oid_to_str(gssctxt->desired_mech)); clear_auth_state(authctxt); userauth(authctxt,NULL); return; } } packet_check_eom(); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,&input_gssapi_error); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,&input_gssapi_errtok); status = ssh_gssapi_init_ctx(gssctxt, authctxt->host, options.gss_deleg_creds, GSS_C_NO_BUFFER, &send_tok); if (GSS_ERROR(status)) { if (send_tok.length>0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); packet_put_string(send_tok.value,send_tok.length); packet_send(); packet_write_wait(); } /* Start again with next method on list */ debug("Trying to start again"); clear_auth_state(authctxt); userauth(authctxt,NULL); return; } /* We must have data to send */ packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); packet_put_string(send_tok.value,send_tok.length); packet_send(); packet_write_wait(); gss_release_buffer(&ms, &send_tok); }
void input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; Key *key = NULL; Buffer b; int pktype, sent = 0; u_int alen, blen; char *pkalg, *fp; u_char *pkblob; if (authctxt == NULL) fatal("input_userauth_pk_ok: no authentication context"); if (datafellows & SSH_BUG_PKOK) { /* this is similar to SSH_BUG_PKAUTH */ debug2("input_userauth_pk_ok: SSH_BUG_PKOK"); pkblob = packet_get_string(&blen); buffer_init(&b); buffer_append(&b, pkblob, blen); pkalg = buffer_get_string(&b, &alen); buffer_free(&b); } else { pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); } packet_check_eom(); debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d", pkalg, blen, authctxt->last_key, authctxt->last_key_hint); do { if (authctxt->last_key == NULL || authctxt->last_key_sign == NULL) { debug("no last key or no sign cb"); break; } if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { debug("unknown pkalg %s", pkalg); break; } if ((key = key_from_blob(pkblob, blen)) == NULL) { debug("no key from blob. pkalg %s", pkalg); break; } if (key->type != pktype) { error("input_userauth_pk_ok: type mismatch " "for decoded key (received %d, expected %d)", key->type, pktype); break; } fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); debug2("input_userauth_pk_ok: fp %s", fp); xfree(fp); if (!key_equal(key, authctxt->last_key)) { debug("key != last_key"); break; } sent = sign_and_send_pubkey(authctxt, key, authctxt->last_key_sign); } while (0); if (key != NULL) key_free(key); xfree(pkalg); xfree(pkblob); /* unregister */ clear_auth_state(authctxt); dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL); /* try another method if we did not send a packet */ if (sent == 0) userauth(authctxt, NULL); }