/* * Returns success if the specified "key" is listed in the file "filename", * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. * If "strict_type" is set then the key type must match exactly, * otherwise a comparison that ignores certficiate data is performed. * If "check_ca" is set and "key" is a certificate, then its CA key is * also checked and sshkey_in_file() will return success if either is found. */ int sshkey_in_file(struct sshkey *key, const char *filename, int strict_type, int check_ca) { FILE *f; char *line = NULL, *cp; size_t linesize = 0; int r = 0; struct sshkey *pub = NULL; int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = strict_type ? sshkey_equal : sshkey_equal_public; if ((f = fopen(filename, "r")) == NULL) return SSH_ERR_SYSTEM_ERROR; while (getline(&line, &linesize, f) != -1) { sshkey_free(pub); pub = NULL; cp = line; /* Skip leading whitespace. */ for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) ; /* Skip comments and empty lines */ switch (*cp) { case '#': case '\n': case '\0': continue; } if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } switch (r = sshkey_read(pub, &cp)) { case 0: break; case SSH_ERR_KEY_LENGTH: continue; default: goto out; } if (sshkey_compare(key, pub) || (check_ca && sshkey_is_cert(key) && sshkey_compare(key->cert->signature_key, pub))) { r = 0; goto out; } } r = SSH_ERR_KEY_NOT_FOUND; out: free(line); sshkey_free(pub); fclose(f); return r; }
/* * Returns success if the specified "key" is listed in the file "filename", * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. * If "strict_type" is set then the key type must match exactly, * otherwise a comparison that ignores certficiate data is performed. * If "check_ca" is set and "key" is a certificate, then its CA key is * also checked and sshkey_in_file() will return success if either is found. */ int sshkey_in_file(struct sshkey *key, const char *filename, int strict_type, int check_ca) { FILE *f; char line[SSH_MAX_PUBKEY_BYTES]; char *cp; u_long linenum = 0; int r = 0; struct sshkey *pub = NULL; int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = strict_type ? sshkey_equal : sshkey_equal_public; if ((f = fopen(filename, "r")) == NULL) return SSH_ERR_SYSTEM_ERROR; while (read_keyfile_line(f, filename, line, sizeof(line), &linenum) != -1) { cp = line; /* Skip leading whitespace. */ for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) ; /* Skip comments and empty lines */ switch (*cp) { case '#': case '\n': case '\0': continue; } if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshkey_read(pub, &cp)) != 0) goto out; if (sshkey_compare(key, pub) || (check_ca && sshkey_is_cert(key) && sshkey_compare(key->cert->signature_key, pub))) { r = 0; goto out; } sshkey_free(pub); pub = NULL; } r = SSH_ERR_KEY_NOT_FOUND; out: if (pub != NULL) sshkey_free(pub); fclose(f); return r; }