📄 sshconnect2.c
字号:
Key *key; char *filename; if (authctxt->agent != NULL) { do { sent = userauth_pubkey_agent(authctxt); } while (!sent && authctxt->agent->howmany > 0); } while (!sent && idx < options.num_identity_files) { key = options.identity_keys[idx]; filename = options.identity_files[idx]; if (key == NULL) { debug("try privkey: %s", filename); key = load_identity_file(filename); if (key != NULL) { sent = sign_and_send_pubkey(authctxt, key, key_sign_cb); key_free(key); } } else if (key->type != KEY_RSA1) { debug("try pubkey: %s", filename); sent = send_pubkey_test(authctxt, key, identity_sign_cb, idx); } idx++; } return sent;}/* * Send userauth request message specifying keyboard-interactive method. */intuserauth_kbdint(Authctxt *authctxt){ static int attempt = 0; if (attempt++ >= options.number_of_password_prompts) return 0; /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ if (attempt > 1 && !authctxt->info_req_seen) { debug3("userauth_kbdint: disable: no info_req_seen"); dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); return 0; } debug2("userauth_kbdint"); 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_cstring(""); /* lang */ packet_put_cstring(options.kbd_interactive_devices ? options.kbd_interactive_devices : ""); packet_send(); dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); return 1;}/* * parse INFO_REQUEST, prompt user and send INFO_RESPONSE */voidinput_userauth_info_req(int type, u_int32_t seq, void *ctxt){ Authctxt *authctxt = ctxt; char *name, *inst, *lang, *prompt, *response; u_int num_prompts, i; int echo = 0; debug2("input_userauth_info_req"); if (authctxt == NULL) fatal("input_userauth_info_req: no authentication context"); authctxt->info_req_seen = 1; name = packet_get_string(NULL); inst = packet_get_string(NULL); lang = packet_get_string(NULL); if (strlen(name) > 0) log("%s", name); if (strlen(inst) > 0) log("%s", inst); xfree(name); xfree(inst); xfree(lang); num_prompts = packet_get_int(); /* * Begin to build info response packet based on prompts requested. * We commit to providing the correct number of responses, so if * further on we run into a problem that prevents this, we have to * be sure and clean this up and send a correct error response. */ packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); packet_put_int(num_prompts); debug2("input_userauth_info_req: num_prompts %d", num_prompts); for (i = 0; i < num_prompts; i++) { prompt = packet_get_string(NULL); echo = packet_get_char(); response = read_passphrase(prompt, echo ? RP_ECHO : 0); packet_put_cstring(response); memset(response, 0, strlen(response)); xfree(response); xfree(prompt); } packet_check_eom(); /* done with parsing incoming message. */ packet_add_padding(64); packet_send();}static intssh_keysign( Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen){ Buffer b; struct stat st; pid_t pid; int to[2], from[2], status, version = 2; debug("ssh_keysign called"); if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { error("ssh_keysign: no installed: %s", strerror(errno)); return -1; } if (fflush(stdout) != 0) error("ssh_keysign: fflush: %s", strerror(errno)); if (pipe(to) < 0) { error("ssh_keysign: pipe: %s", strerror(errno)); return -1; } if (pipe(from) < 0) { error("ssh_keysign: pipe: %s", strerror(errno)); return -1; } if ((pid = fork()) < 0) { error("ssh_keysign: fork: %s", strerror(errno)); return -1; } if (pid == 0) { seteuid(getuid()); setuid(getuid()); close(from[0]); if (dup2(from[1], STDOUT_FILENO) < 0) fatal("ssh_keysign: dup2: %s", strerror(errno)); close(to[1]); if (dup2(to[0], STDIN_FILENO) < 0) fatal("ssh_keysign: dup2: %s", strerror(errno)); close(from[1]); close(to[0]); execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, strerror(errno)); } close(from[1]); close(to[0]); buffer_init(&b); buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */ buffer_put_string(&b, data, datalen); msg_send(to[1], version, &b); if (msg_recv(from[0], &b) < 0) { error("ssh_keysign: no reply"); buffer_clear(&b); return -1; } close(from[0]); close(to[1]); while (waitpid(pid, &status, 0) < 0) if (errno != EINTR) break; if (buffer_get_char(&b) != version) { error("ssh_keysign: bad version"); buffer_clear(&b); return -1; } *sigp = buffer_get_string(&b, lenp); buffer_clear(&b); return 0;}intuserauth_hostbased(Authctxt *authctxt){ Key *private = NULL; Sensitive *sensitive = authctxt->sensitive; Buffer b; u_char *signature, *blob; char *chost, *pkalg, *p; const char *service; u_int blen, slen; int ok, i, len, found = 0; /* check for a useful key */ for (i = 0; i < sensitive->nkeys; i++) { private = sensitive->keys[i]; if (private && private->type != KEY_RSA1) { found = 1; /* we take and free the key */ sensitive->keys[i] = NULL; break; } } if (!found) { debug("userauth_hostbased: no more client hostkeys"); return 0; } if (key_to_blob(private, &blob, &blen) == 0) { key_free(private); return 0; } /* figure out a name for the client host */ p = get_local_name(packet_get_connection_in()); if (p == NULL) { error("userauth_hostbased: cannot get local ipaddr/name"); key_free(private); return 0; } len = strlen(p) + 2; chost = xmalloc(len); strlcpy(chost, p, len); strlcat(chost, ".", len); debug2("userauth_hostbased: chost %s", chost); service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : authctxt->service; pkalg = xstrdup(key_ssh_name(private)); buffer_init(&b); /* construct data */ buffer_put_string(&b, session_id2, session_id2_len); buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); buffer_put_cstring(&b, authctxt->server_user); buffer_put_cstring(&b, service); buffer_put_cstring(&b, authctxt->method->name); buffer_put_cstring(&b, pkalg); buffer_put_string(&b, blob, blen); buffer_put_cstring(&b, chost); buffer_put_cstring(&b, authctxt->local_user);#ifdef DEBUG_PK buffer_dump(&b);#endif if (sensitive->external_keysign) ok = ssh_keysign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); else ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); key_free(private); buffer_free(&b); if (ok != 0) { error("key_sign failed"); xfree(chost); xfree(pkalg); 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_cstring(pkalg); packet_put_string(blob, blen); packet_put_cstring(chost); packet_put_cstring(authctxt->local_user); packet_put_string(signature, slen); memset(signature, 's', slen); xfree(signature); xfree(chost); xfree(pkalg); packet_send(); return 1;}/* find auth method *//* * given auth method name, if configurable options permit this method fill * in auth_ident field and return true, otherwise return false. */static intauthmethod_is_enabled(Authmethod *method){ if (method == NULL) return 0; /* return false if options indicate this method is disabled */ if (method->enabled == NULL || *method->enabled == 0) return 0; /* return false if batch mode is enabled but method needs interactive mode */ if (method->batch_flag != NULL && *method->batch_flag != 0) return 0; return 1;}static Authmethod *authmethod_lookup(const char *name){ Authmethod *method = NULL; if (name != NULL) for (method = authmethods; method->name != NULL; method++) if (strcmp(name, method->name) == 0) return method; debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); return NULL;}/* XXX internal state */static Authmethod *current = NULL;static char *supported = NULL;static char *preferred = NULL;/* * Given the authentication method list sent by the server, return the * next method we should try. If the server initially sends a nil list, * use a built-in default list. */static Authmethod *authmethod_get(char *authlist){ char *name = NULL; u_int next; /* Use a suitable default if we're passed a nil list. */ if (authlist == NULL || strlen(authlist) == 0) authlist = options.preferred_authentications; if (supported == NULL || strcmp(authlist, supported) != 0) { debug3("start over, passed a different list %s", authlist); if (supported != NULL) xfree(supported); supported = xstrdup(authlist); preferred = options.preferred_authentications; debug3("preferred %s", preferred); current = NULL; } else if (current != NULL && authmethod_is_enabled(current)) return current; for (;;) { if ((name = match_list(preferred, supported, &next)) == NULL) { debug("no more auth methods to try"); current = NULL; return NULL; } preferred += next; debug3("authmethod_lookup %s", name); debug3("remaining preferred: %s", preferred); if ((current = authmethod_lookup(name)) != NULL && authmethod_is_enabled(current)) { debug3("authmethod_is_enabled %s", name); debug("next auth method to try is %s", name); return current; } }}static char *authmethods_get(void){ Authmethod *method = NULL; Buffer b; char *list; buffer_init(&b); for (method = authmethods; method->name != NULL; method++) { if (authmethod_is_enabled(method)) { if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); buffer_append(&b, method->name, strlen(method->name)); } } buffer_append(&b, "\0", 1); list = xstrdup(buffer_ptr(&b)); buffer_free(&b); return list;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -