📄 authfile.c
字号:
{ int i, check1, check2, cipher_type; off_t len; Buffer buffer, decrypted; u_char *cp; CipherContext ciphercontext; Cipher *cipher; Key *prv = NULL; len = lseek(fd, (off_t) 0, SEEK_END); lseek(fd, (off_t) 0, SEEK_SET); buffer_init(&buffer); cp = buffer_append_space(&buffer, len); if (read(fd, cp, (size_t) len) != (size_t) len) { debug("Read from key file %.200s failed: %.100s", filename, strerror(errno)); buffer_free(&buffer); close(fd); return NULL; } /* Check that it is at least big enough to contain the ID string. */ if (len < sizeof(authfile_id_string)) { debug3("Not a RSA1 key file %.200s.", filename); buffer_free(&buffer); close(fd); return NULL; } /* * Make sure it begins with the id string. Consume the id string * from the buffer. */ for (i = 0; i < sizeof(authfile_id_string); i++) if (buffer_get_char(&buffer) != authfile_id_string[i]) { debug3("Not a RSA1 key file %.200s.", filename); buffer_free(&buffer); close(fd); return NULL; } /* Read cipher type. */ cipher_type = buffer_get_char(&buffer); (void) buffer_get_int(&buffer); /* Reserved data. */ /* Read the public key from the buffer. */ buffer_get_int(&buffer); prv = key_new_private(KEY_RSA1); buffer_get_bignum(&buffer, prv->rsa->n); buffer_get_bignum(&buffer, prv->rsa->e); if (commentp) *commentp = buffer_get_string(&buffer, NULL); else xfree(buffer_get_string(&buffer, NULL)); /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); if (cipher == NULL) { debug("Unsupported cipher %d used in key file %.200s.", cipher_type, filename); buffer_free(&buffer); goto fail; } /* Initialize space for decrypted data. */ buffer_init(&decrypted); cp = buffer_append_space(&decrypted, buffer_len(&buffer)); /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT); cipher_crypt(&ciphercontext, cp, buffer_ptr(&buffer), buffer_len(&buffer)); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); buffer_free(&buffer); check1 = buffer_get_char(&decrypted); check2 = buffer_get_char(&decrypted); if (check1 != buffer_get_char(&decrypted) || check2 != buffer_get_char(&decrypted)) { if (strcmp(passphrase, "") != 0) debug("Bad passphrase supplied for key file %.200s.", filename); /* Bad passphrase. */ buffer_free(&decrypted); goto fail; } /* Read the rest of the private key. */ buffer_get_bignum(&decrypted, prv->rsa->d); buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ /* in SSL and SSH v1 p and q are exchanged */ buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ /* calculate p-1 and q-1 */ rsa_generate_additional_parameters(prv->rsa); buffer_free(&decrypted); close(fd); return prv;fail: if (commentp) xfree(*commentp); close(fd); key_free(prv); return NULL;}Key *key_load_private_pem(int fd, int type, const char *passphrase, char **commentp){ FILE *fp; EVP_PKEY *pk = NULL; Key *prv = NULL; char *name = "<no key>"; fp = fdopen(fd, "r"); if (fp == NULL) { error("fdopen failed: %s", strerror(errno)); close(fd); return NULL; } pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); if (pk == NULL) { debug("PEM_read_PrivateKey failed"); (void)ERR_get_error(); } else if (pk->type == EVP_PKEY_RSA && (type == KEY_UNSPEC||type==KEY_RSA)) { prv = key_new(KEY_UNSPEC); prv->rsa = EVP_PKEY_get1_RSA(pk); prv->type = KEY_RSA; name = "rsa w/o comment";#ifdef DEBUG_PK RSA_print_fp(stderr, prv->rsa, 8);#endif } else if (pk->type == EVP_PKEY_DSA && (type == KEY_UNSPEC||type==KEY_DSA)) { prv = key_new(KEY_UNSPEC); prv->dsa = EVP_PKEY_get1_DSA(pk); prv->type = KEY_DSA; name = "dsa w/o comment";#ifdef DEBUG_PK DSA_print_fp(stderr, prv->dsa, 8);#endif } else { error("PEM_read_PrivateKey: mismatch or " "unknown EVP_PKEY save_type %d", pk->save_type); } fclose(fp); if (pk != NULL) EVP_PKEY_free(pk); if (prv != NULL && commentp) *commentp = xstrdup(name); debug("read PEM private key done: type %s", prv ? key_type(prv) : "<unknown>"); return prv;}static intkey_perm_ok(int fd, const char *filename){ struct stat st; if (fstat(fd, &st) < 0) return 0; /* * if a key owned by the user is accessed, then we check the * permissions of the file. if the key owned by a different user, * then we don't care. */#ifdef HAVE_CYGWIN if (check_ntsec(filename))#endif if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("Permissions 0%3.3o for '%s' are too open.", st.st_mode & 0777, filename); error("It is recommended that your private key files are NOT accessible by others."); error("This private key will be ignored."); return 0; } return 1;}Key *key_load_private_type(int type, const char *filename, const char *passphrase, char **commentp){ int fd; fd = open(filename, O_RDONLY); if (fd < 0) return NULL; if (!key_perm_ok(fd, filename)) { error("bad permissions: ignore key: %s", filename); close(fd); return NULL; } switch (type) { case KEY_RSA1: return key_load_private_rsa1(fd, filename, passphrase, commentp); /* closes fd */ break; case KEY_DSA: case KEY_RSA: case KEY_UNSPEC: return key_load_private_pem(fd, type, passphrase, commentp); /* closes fd */ break; default: close(fd); break; } return NULL;}Key *key_load_private(const char *filename, const char *passphrase, char **commentp){ Key *pub, *prv; int fd; fd = open(filename, O_RDONLY); if (fd < 0) return NULL; if (!key_perm_ok(fd, filename)) { error("bad permissions: ignore key: %s", filename); close(fd); return NULL; } pub = key_load_public_rsa1(fd, filename, commentp); lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ if (pub == NULL) { /* closes fd */ prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); /* use the filename as a comment for PEM */ if (commentp && prv) *commentp = xstrdup(filename); } else { /* it's a SSH v1 key if the public key part is readable */ key_free(pub); /* closes fd */ prv = key_load_private_rsa1(fd, filename, passphrase, NULL); } return prv;}static intkey_try_load_public(Key *k, const char *filename, char **commentp){ FILE *f; char line[4096]; char *cp; f = fopen(filename, "r"); if (f != NULL) { while (fgets(line, sizeof(line), f)) { line[sizeof(line)-1] = '\0'; cp = line; switch (*cp) { case '#': case '\n': case '\0': continue; } /* Skip leading whitespace. */ for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) ; if (*cp) { if (key_read(k, &cp) == 1) { if (commentp) *commentp=xstrdup(filename); fclose(f); return 1; } } } fclose(f); } return 0;}/* load public key from ssh v1 private or any pubkey file */Key *key_load_public(const char *filename, char **commentp){ Key *pub; char file[MAXPATHLEN]; pub = key_load_public_type(KEY_RSA1, filename, commentp); if (pub != NULL) return pub; pub = key_new(KEY_UNSPEC); if (key_try_load_public(pub, filename, commentp) == 1) return pub; if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && (strlcat(file, ".pub", sizeof file) < sizeof(file)) && (key_try_load_public(pub, file, commentp) == 1)) return pub; key_free(pub); return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -