static char * list_hostkey_types(void) { Buffer b; const char *p; char *ret; int i; buffer_init(&b); for (i = 0; i < options.num_host_key_files; i++) { Key *key = sensitive_data.host_keys[i]; if (key == NULL) continue; switch (key->type) { case KEY_RSA: case KEY_DSA: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); buffer_append(&b, p, strlen(p)); break; } } buffer_append(&b, "\0", 1); ret = xstrdup(buffer_ptr(&b)); buffer_free(&b); debug("list_hostkey_types: %s", ret); return ret; }
static int send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback, int hint) { u_char *blob; u_int bloblen, have_sig = 0; debug3("send_pubkey_test"); if (key_to_blob(k, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("send_pubkey_test: cannot handle key"); return 0; } /* register callback for USERAUTH_PK_OK message */ authctxt->last_key_sign = sign_callback; authctxt->last_key_hint = hint; authctxt->last_key = k; 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(k)); packet_put_string(blob, bloblen); xfree(blob); packet_send(); return 1; }
static void ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) { buffer_put_cstring(b, key_ssh_name(key)); switch (key->type) { case KEY_RSA: buffer_put_bignum2(b, key->rsa->n); buffer_put_bignum2(b, key->rsa->e); buffer_put_bignum2(b, key->rsa->d); buffer_put_bignum2(b, key->rsa->iqmp); buffer_put_bignum2(b, key->rsa->p); buffer_put_bignum2(b, key->rsa->q); break; case KEY_RSA_CERT_V00: case KEY_RSA_CERT: if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) fatal("%s: no cert/certblob", __func__); buffer_put_string(b, buffer_ptr(&key->cert->certblob), buffer_len(&key->cert->certblob)); buffer_put_bignum2(b, key->rsa->d); buffer_put_bignum2(b, key->rsa->iqmp); buffer_put_bignum2(b, key->rsa->p); buffer_put_bignum2(b, key->rsa->q); break; case KEY_DSA: buffer_put_bignum2(b, key->dsa->p); buffer_put_bignum2(b, key->dsa->q); buffer_put_bignum2(b, key->dsa->g); buffer_put_bignum2(b, key->dsa->pub_key); buffer_put_bignum2(b, key->dsa->priv_key); break; case KEY_DSA_CERT_V00: case KEY_DSA_CERT: if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) fatal("%s: no cert/certblob", __func__); buffer_put_string(b, buffer_ptr(&key->cert->certblob), buffer_len(&key->cert->certblob)); buffer_put_bignum2(b, key->dsa->priv_key); break; #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), EC_KEY_get0_public_key(key->ecdsa)); buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); break; case KEY_ECDSA_CERT: if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) fatal("%s: no cert/certblob", __func__); buffer_put_string(b, buffer_ptr(&key->cert->certblob), buffer_len(&key->cert->certblob)); buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); break; #endif } buffer_put_cstring(b, comment); }
int userauth_pubkey_from_id(const char *ruser, Identity * id, Buffer * session_id2) { Buffer b = { 0 }; char *pkalg = NULL; u_char *pkblob = NULL, *sig = NULL; u_int blen = 0, slen = 0; int authenticated = 0; pkalg = (char *) key_ssh_name(id->key); /* first test if this key is even allowed */ if(! pam_user_key_allowed(ruser, id->key)) goto user_auth_clean_exit; if(pamsshagentauth_key_to_blob(id->key, &pkblob, &blen) == 0) goto user_auth_clean_exit; /* construct packet to sign and test */ pamsshagentauth_buffer_init(&b); pamsshagentauth_buffer_put_string(&b, session_id2->buf + session_id2->offset, session_id2->end - session_id2->offset); pamsshagentauth_buffer_put_char(&b, SSH2_MSG_USERAUTH_TRUST_REQUEST); pamsshagentauth_buffer_put_cstring(&b, ruser); pamsshagentauth_buffer_put_cstring(&b, "pam_ssh_agent_auth"); pamsshagentauth_buffer_put_cstring(&b, "publickey"); pamsshagentauth_buffer_put_char(&b, 1); pamsshagentauth_buffer_put_cstring(&b, pkalg); pamsshagentauth_buffer_put_string(&b, pkblob, blen); if(ssh_agent_sign(id->ac, id->key, &sig, &slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) != 0) goto user_auth_clean_exit; /* test for correct signature */ if(pamsshagentauth_key_verify(id->key, sig, slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) == 1) authenticated = 1; user_auth_clean_exit: /* if(&b != NULL) */ pamsshagentauth_buffer_free(&b); if(sig != NULL) pamsshagentauth_xfree(sig); if(pkblob != NULL) pamsshagentauth_xfree(pkblob); CRYPTO_cleanup_all_ex_data(); return authenticated; }
static void ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) { pamsshagentauth_buffer_put_cstring(b, key_ssh_name(key)); switch (key->type) { case KEY_RSA: pamsshagentauth_buffer_put_bignum2(b, key->rsa->n); pamsshagentauth_buffer_put_bignum2(b, key->rsa->e); pamsshagentauth_buffer_put_bignum2(b, key->rsa->d); pamsshagentauth_buffer_put_bignum2(b, key->rsa->iqmp); pamsshagentauth_buffer_put_bignum2(b, key->rsa->p); pamsshagentauth_buffer_put_bignum2(b, key->rsa->q); break; case KEY_DSA: pamsshagentauth_buffer_put_bignum2(b, key->dsa->p); pamsshagentauth_buffer_put_bignum2(b, key->dsa->q); pamsshagentauth_buffer_put_bignum2(b, key->dsa->g); pamsshagentauth_buffer_put_bignum2(b, key->dsa->pub_key); pamsshagentauth_buffer_put_bignum2(b, key->dsa->priv_key); break; } pamsshagentauth_buffer_put_cstring(b, comment); }
static void privsep_postauth(Authctxt *authctxt) { #ifdef DISABLE_FD_PASSING if (1) { #else if (authctxt->pw->pw_uid == 0 || options.use_login) { #endif /* File descriptor passing is broken or root login */ monitor_apply_keystate(pmonitor); use_privsep = 0; return; } /* Authentication complete */ alarm(0); if (startup_pipe != -1) { close(startup_pipe); startup_pipe = -1; } /* New socket pair */ monitor_reinit(pmonitor); pmonitor->m_pid = fork(); if (pmonitor->m_pid == -1) fatal("fork of unprivileged child failed"); else if (pmonitor->m_pid != 0) { debug2("User child is on pid %ld", (long)pmonitor->m_pid); close(pmonitor->m_recvfd); buffer_clear(&loginmsg); monitor_child_postauth(pmonitor); /* NEVERREACHED */ exit(0); } close(pmonitor->m_sendfd); /* Demote the private keys to public keys. */ demote_sensitive_data(); /* Drop privileges */ do_setusercontext(authctxt->pw); /* It is safe now to apply the key state */ monitor_apply_keystate(pmonitor); } static char * list_hostkey_types(void) { Buffer b; const char *p; char *ret; int i; buffer_init(&b); for (i = 0; i < options.num_host_key_files; i++) { Key *key = sensitive_data.host_keys[i]; if (key == NULL) continue; switch (key->type) { case KEY_RSA: case KEY_DSA: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); buffer_append(&b, p, strlen(p)); break; } } buffer_append(&b, "\0", 1); ret = xstrdup(buffer_ptr(&b)); buffer_free(&b); debug("list_hostkey_types: %s", ret); return ret; }
static int sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) { Buffer b; u_char *blob, *signature; u_int bloblen, slen; int skip = 0; int ret = -1; int have_sig = 1; debug3("sign_and_send_pubkey"); if (key_to_blob(k, &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(k)); } buffer_put_string(&b, blob, bloblen); /* generate signature */ ret = (*sign_callback)(authctxt, k, &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(k)); 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; }