📄 sshconnect2.c
字号:
if (gssctxt) ssh_gssapi_delete_ctx(&gssctxt); ssh_gssapi_build_ctx(&gssctxt); ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]); /* My DER encoding requires length<128 */ if (gss_supported->elements[mech].length < 128 && !GSS_ERROR(ssh_gssapi_import_name(gssctxt, authctxt->host))) { ok = 1; /* Mechanism works */ } else { mech++; } } if (!ok) return 0; authctxt->methoddata=(void *)gssctxt; 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_int(1); packet_put_int((gss_supported->elements[mech].length) + 2); packet_put_char(SSH_GSS_OIDTYPE); packet_put_char(gss_supported->elements[mech].length); packet_put_raw(gss_supported->elements[mech].elements, gss_supported->elements[mech].length); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); 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); mech++; /* Move along to next candidate */ return 1;}static OM_uint32process_gssapi_token(void *ctxt, gss_buffer_t recv_tok){ Authctxt *authctxt = ctxt; Gssctxt *gssctxt = authctxt->methoddata; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc gssbuf, mic; OM_uint32 status, ms, flags; Buffer b; status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, recv_tok, &send_tok, &flags); if (send_tok.length > 0) { if (GSS_ERROR(status)) packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); else packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); packet_put_string(send_tok.value, send_tok.length); packet_send(); gss_release_buffer(&ms, &send_tok); } if (status == GSS_S_COMPLETE) { /* send either complete or MIC, depending on mechanism */ if (!(flags & GSS_C_INTEG_FLAG)) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); packet_send(); } else { ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, "gssapi-with-mic"); gssbuf.value = buffer_ptr(&b); gssbuf.length = buffer_len(&b); status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); if (!GSS_ERROR(status)) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); packet_put_string(mic.value, mic.length); packet_send(); } buffer_free(&b); gss_release_buffer(&ms, &mic); } } return status;}voidinput_gssapi_response(int type, u_int32_t plen, void *ctxt){ Authctxt *authctxt = ctxt; Gssctxt *gssctxt; int oidlen; char *oidv; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; /* Setup our OID */ oidv = packet_get_string(&oidlen); if (oidlen <= 2 || oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen - 2) { xfree(oidv); debug("Badly encoded mechanism OID received"); userauth(authctxt, NULL); return; } if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) fatal("Server returned different OID than expected"); packet_check_eom(); xfree(oidv); if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { /* Start again with next method on list */ debug("Trying to start again"); userauth(authctxt, NULL); return; }}voidinput_gssapi_token(int type, u_int32_t plen, void *ctxt){ Authctxt *authctxt = ctxt; gss_buffer_desc recv_tok; OM_uint32 status; u_int slen; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); recv_tok.value = packet_get_string(&slen); recv_tok.length = slen; /* safe typecast */ packet_check_eom(); status = process_gssapi_token(ctxt, &recv_tok); xfree(recv_tok.value); if (GSS_ERROR(status)) { /* Start again with the next method in the list */ userauth(authctxt, NULL); return; }}voidinput_gssapi_errtok(int type, u_int32_t plen, void *ctxt){ Authctxt *authctxt = ctxt; Gssctxt *gssctxt; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; gss_buffer_desc recv_tok; OM_uint32 status, ms; u_int len; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); gssctxt = authctxt->methoddata; recv_tok.value = packet_get_string(&len); recv_tok.length = len; packet_check_eom(); /* Stick it into GSSAPI and see what it says */ status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, &recv_tok, &send_tok, NULL); xfree(recv_tok.value); gss_release_buffer(&ms, &send_tok); /* Server will be returning a failed packet after this one */}voidinput_gssapi_error(int type, u_int32_t plen, void *ctxt){ OM_uint32 maj, min; char *msg; char *lang; maj=packet_get_int(); min=packet_get_int(); msg=packet_get_string(NULL); lang=packet_get_string(NULL); packet_check_eom(); debug("Server GSSAPI Error:\n%s\n", msg); xfree(msg); xfree(lang);}#endif /* GSSAPI */intuserauth_none(Authctxt *authctxt){ /* initial userauth request */ packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); packet_put_cstring(authctxt->method->name); packet_send(); return 1;}intuserauth_passwd(Authctxt *authctxt){ static int attempt = 0; char prompt[150]; char *password; if (attempt++ >= options.number_of_password_prompts) return 0; if (attempt != 1) error("Permission denied, please try again."); snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", authctxt->server_user, authctxt->host); password = read_passphrase(prompt, 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_char(0); packet_put_cstring(password); memset(password, 0, strlen(password)); xfree(password); packet_add_padding(64); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, &input_userauth_passwd_changereq); return 1;}/* * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST */voidinput_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt){ Authctxt *authctxt = ctxt; char *info, *lang, *password = NULL, *retype = NULL; char prompt[150]; debug2("input_userauth_passwd_changereq"); if (authctxt == NULL) fatal("input_userauth_passwd_changereq: " "no authentication context"); info = packet_get_string(NULL); lang = packet_get_string(NULL); if (strlen(info) > 0) logit("%s", info); xfree(info); xfree(lang); 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_char(1); /* additional info */ snprintf(prompt, sizeof(prompt), "Enter %.30s@%.128s's old password: ", authctxt->server_user, authctxt->host); password = read_passphrase(prompt, 0); packet_put_cstring(password); memset(password, 0, strlen(password)); xfree(password); password = NULL; while (password == NULL) { snprintf(prompt, sizeof(prompt), "Enter %.30s@%.128s's new password: ", authctxt->server_user, authctxt->host); password = read_passphrase(prompt, RP_ALLOW_EOF); if (password == NULL) { /* bail out */ return; } snprintf(prompt, sizeof(prompt), "Retype %.30s@%.128s's new password: ", authctxt->server_user, authctxt->host); retype = read_passphrase(prompt, 0); if (strcmp(password, retype) != 0) { memset(password, 0, strlen(password)); xfree(password); logit("Mismatch; try again, EOF to quit."); password = NULL; } memset(retype, 0, strlen(retype)); xfree(retype); } packet_put_cstring(password); memset(password, 0, strlen(password)); xfree(password); packet_add_padding(64); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, &input_userauth_passwd_changereq);}static intidentity_sign(Identity *id, u_char **sigp, u_int *lenp, u_char *data, u_int datalen){ Key *prv; int ret; /* the agent supports this key */ if (id->ac) return (ssh_agent_sign(id->ac, id->key, sigp, lenp, data, datalen)); /* * we have already loaded the private key or * the private key is stored in external hardware */ if (id->isprivate || (id->key->flags & KEY_FLAG_EXT)) return (key_sign(id->key, sigp, lenp, data, datalen)); /* load the private key from the file */ if ((prv = load_identity_file(id->filename)) == NULL) return (-1); ret = key_sign(prv, sigp, lenp, data, datalen); key_free(prv); return (ret);}static intsign_and_send_pubkey(Authctxt *authctxt, Identity *id){ Buffer b; u_char *blob, *signature; u_int bloblen, slen; u_int skip = 0; int ret = -1; int have_sig = 1; debug3("sign_and_send_pubkey"); if (key_to_blob(id->key, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("sign_and_send_pubkey: cannot handle key"); return 0; } /* data to be signed */ buffer_init(&b); if (datafellows & SSH_OLD_SESSIONID) { buffer_append(&b, session_id2, session_id2_len); skip = session_id2_len; } else { buffer_put_string(&b, session_id2, session_id2_len); skip = buffer_len(&b); } buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->server_user); buffer_put_cstring(&b, datafellows & SSH_BUG_PKSERVICE ? "ssh-userauth" : authctxt->service); if (datafellows & SSH_BUG_PKAUTH) { buffer_put_char(&b, have_sig); } else { buffer_put_cstring(&b, authctxt->method->name); buffer_put_char(&b, have_sig); buffer_put_cstring(&b, key_ssh_name(id->key)); } buffer_put_string(&b, blob, bloblen); /* generate signature */ ret = identity_sign(id, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); if (ret == -1) { xfree(blob); buffer_free(&b); return 0; }#ifdef DEBUG_PK buffer_dump(&b);#endif if (datafellows & SSH_BUG_PKSERVICE) { buffer_clear(&b); buffer_append(&b, session_id2, session_id2_len); skip = session_id2_len; buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->server_user); buffer_put_cstring(&b, authctxt->service); buffer_put_cstring(&b, authctxt->method->name); buffer_put_char(&b, have_sig); if (!(datafellows & SSH_BUG_PKAUTH)) buffer_put_cstring(&b, key_ssh_name(id->key)); buffer_put_string(&b, blob, bloblen); } xfree(blob); /* append signature */ buffer_put_string(&b, signature, slen); xfree(signature); /* skip session id and packet type */ if (buffer_len(&b) < skip + 1) fatal("userauth_pubkey: internal error"); buffer_consume(&b, skip + 1); /* put remaining data from buffer into packet */ packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_raw(buffer_ptr(&b), buffer_len(&b)); buffer_free(&b); packet_send(); return 1;}static intsend_pubkey_test(Authctxt *authctxt, Identity *id){ u_char *blob; u_int bloblen, have_sig = 0; debug3("send_pubkey_test"); if (key_to_blob(id->key, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("send_pubkey_test: cannot handle key"); return 0; } /* register callback for USERAUTH_PK_OK message */ dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); 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_char(have_sig); if (!(datafellows & SSH_BUG_PKAUTH)) packet_put_cstring(key_ssh_name(id->key)); packet_put_string(blob, bloblen); xfree(blob); packet_send(); return 1;}static Key *load_identity_file(char *filename){ Key *private; char prompt[300], *passphrase; int quit, i; struct stat st; if (stat(filename, &st) < 0) { debug3("no such identity: %s", filename); return NULL; } private = key_load_private_type(KEY_UNSPEC, filename, "", NULL); if (private == NULL) { if (options.batch_mode) return NULL; snprintf(prompt, sizeof prompt, "Enter passphrase for key '%.100s': ", filename); for (i = 0; i < options.number_of_password_prompts; i++) { passphrase = read_passphrase(prompt, 0); if (strcmp(passphrase, "") != 0) { private = key_load_private_type(KEY_UNSPEC, filename, passphrase, NULL); quit = 0; } else { debug2("no passphrase given, try next key"); quit = 1; } memset(passphrase, 0, strlen(passphrase)); xfree(passphrase); if (private != NULL || quit) break; debug2("bad passphrase given, try again..."); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -