int main(void) { isc_fsaccess_t access; isc_result_t result; remove(PATH); fopen(PATH, "w"); chmod(PATH, 0); access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER | ISC_FSACCESS_GROUP, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); printf("fsaccess=%d\n", access); isc_fsaccess_add(ISC_FSACCESS_OTHER, ISC_FSACCESS_READ, &access); printf("fsaccess=%d\n", access); result = isc_fsaccess_set(PATH, access); if (result != ISC_R_SUCCESS) fprintf(stderr, "result = %s\n", isc_result_totext(result)); return (0); }
int main(void) { isc_fsaccess_t access; isc_result_t result; FILE *fp; int n; n = remove(PATH); if (n != 0 && errno != ENOENT) { fprintf(stderr, "unable to remove(%s)\n", PATH); exit(1); } fp = fopen(PATH, "w"); if (fp == NULL) { fprintf(stderr, "unable to fopen(%s)\n", PATH); exit(1); } n = chmod(PATH, 0); if (n != 0) { fprintf(stderr, "unable chmod(%s, 0)\n", PATH); exit(1); } access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER | ISC_FSACCESS_GROUP, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); printf("fsaccess=%d\n", access); isc_fsaccess_add(ISC_FSACCESS_OTHER, ISC_FSACCESS_READ, &access); printf("fsaccess=%d\n", access); result = isc_fsaccess_set(PATH, access); if (result != ISC_R_SUCCESS) fprintf(stderr, "result = %s\n", isc_result_totext(result)); (void)fclose(fp); return (0); }
int dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, const char *directory) { FILE *fp; int ret, i; isc_result_t iret; char filename[ISC_DIR_NAMEMAX]; char buffer[MAXFIELDSIZE * 2]; isc_buffer_t b; isc_fsaccess_t access; REQUIRE(priv != NULL); if (check_data(priv, dst_key_alg(key)) < 0) return (DST_R_INVALIDPRIVATEKEY); isc_buffer_init(&b, filename, sizeof(filename)); ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); if (ret != ISC_R_SUCCESS) return (ret); if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); /* XXXDCL return value should be checked for full filesystem */ fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, MAJOR_VERSION, MINOR_VERSION); fprintf(fp, "%s %d ", ALGORITHM_STR, dst_key_alg(key)); /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (dst_key_alg(key)) { case DST_ALG_RSAMD5: fprintf(fp, "(RSA)\n"); break; case DST_ALG_DH: fprintf(fp, "(DH)\n"); break; case DST_ALG_DSA: fprintf(fp, "(DSA)\n"); break; case DST_ALG_RSASHA1: fprintf(fp, "(RSASHA1)\n"); break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; default: fprintf(fp, "(?)\n"); break; } for (i = 0; i < priv->nelements; i++) { isc_buffer_t b; isc_region_t r; const char *s; s = find_tag(priv->elements[i].tag); r.base = priv->elements[i].data; r.length = priv->elements[i].length; isc_buffer_init(&b, buffer, sizeof(buffer)); iret = isc_base64_totext(&r, sizeof(buffer), "", &b); if (iret != ISC_R_SUCCESS) { fclose(fp); return (DST_R_INVALIDPRIVATEKEY); } isc_buffer_usedregion(&b, &r); fprintf(fp, "%s ", s); fwrite(r.base, 1, r.length, fp); fprintf(fp, "\n"); } fclose(fp); return (ISC_R_SUCCESS); }
/*% * Writes a public key to disk in DNS format. */ static isc_result_t write_public_key(const dst_key_t *key, int type, const char *directory) { FILE *fp; isc_buffer_t keyb, textb, fileb, classb; isc_region_t r; char filename[ISC_DIR_NAMEMAX]; unsigned char key_array[DST_KEY_MAXSIZE]; char text_array[DST_KEY_MAXTEXTSIZE]; char class_array[10]; isc_result_t ret; dns_rdata_t rdata = DNS_RDATA_INIT; isc_fsaccess_t access; REQUIRE(VALID_KEY(key)); isc_buffer_init(&keyb, key_array, sizeof(key_array)); isc_buffer_init(&textb, text_array, sizeof(text_array)); isc_buffer_init(&classb, class_array, sizeof(class_array)); ret = dst_key_todns(key, &keyb); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_usedregion(&keyb, &r); dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r); ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); ret = dns_rdataclass_totext(key->key_class, &classb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); /* * Make the filename. */ isc_buffer_init(&fileb, filename, sizeof(filename)); ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb); if (ret != ISC_R_SUCCESS) return (ret); /* * Create public key file. */ if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); if (issymmetric(key)) { access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); } /* Write key information in comments */ if ((type & DST_TYPE_KEY) == 0) { fprintf(fp, "; This is a %s%s-signing key, keyid %d, for ", (key->key_flags & DNS_KEYFLAG_REVOKE) != 0 ? "revoked " : "", (key->key_flags & DNS_KEYFLAG_KSK) != 0 ? "key" : "zone", key->key_id); ret = dns_name_print(key->key_name, fp); if (ret != ISC_R_SUCCESS) { fclose(fp); return (ret); } fputc('\n', fp); printtime(key, DST_TIME_CREATED, "; Created", fp); printtime(key, DST_TIME_PUBLISH, "; Publish", fp); printtime(key, DST_TIME_ACTIVATE, "; Activate", fp); printtime(key, DST_TIME_REVOKE, "; Revoke", fp); printtime(key, DST_TIME_INACTIVE, "; Inactive", fp); printtime(key, DST_TIME_DELETE, "; Delete", fp); } /* Now print the actual key */ ret = dns_name_print(key->key_name, fp); fprintf(fp, " "); if (key->key_ttl != 0) fprintf(fp, "%d ", key->key_ttl); isc_buffer_usedregion(&classb, &r); if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length) ret = DST_R_WRITEERROR; if ((type & DST_TYPE_KEY) != 0) fprintf(fp, " KEY "); else fprintf(fp, " DNSKEY "); isc_buffer_usedregion(&textb, &r); if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length) ret = DST_R_WRITEERROR; fputc('\n', fp); fflush(fp); if (ferror(fp)) ret = DST_R_WRITEERROR; fclose(fp); return (ret); }
isc_result_t dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, const char *directory) { FILE *fp; isc_result_t result; char filename[ISC_DIR_NAMEMAX]; char buffer[MAXFIELDSIZE * 2]; isc_fsaccess_t access; isc_stdtime_t when; isc_uint32_t value; isc_buffer_t b; isc_region_t r; int major, minor; mode_t mode; int i, ret; REQUIRE(priv != NULL); ret = check_data(priv, dst_key_alg(key), ISC_FALSE, key->external); if (ret < 0) return (DST_R_INVALIDPRIVATEKEY); else if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, filename, sizeof(filename)); result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); if (result != ISC_R_SUCCESS) return (result); result = isc_file_mode(filename, &mode); if (result == ISC_R_SUCCESS && mode != 0600) { /* File exists; warn that we are changing its permissions */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, "Permissions on the file %s " "have changed from 0%o to 0600 as " "a result of this operation.", filename, (unsigned int)mode); } if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); dst_key_getprivateformat(key, &major, &minor); if (major == 0 && minor == 0) { major = DST_MAJOR_VERSION; minor = DST_MINOR_VERSION; } /* XXXDCL return value should be checked for full filesystem */ fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, major, minor); fprintf(fp, "%s %d ", ALGORITHM_STR, dst_key_alg(key)); /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (dst_key_alg(key)) { case DST_ALG_RSAMD5: fprintf(fp, "(RSA)\n"); break; case DST_ALG_DH: fprintf(fp, "(DH)\n"); break; case DST_ALG_DSA: fprintf(fp, "(DSA)\n"); break; case DST_ALG_RSASHA1: fprintf(fp, "(RSASHA1)\n"); break; case DST_ALG_NSEC3RSASHA1: fprintf(fp, "(NSEC3RSASHA1)\n"); break; case DST_ALG_NSEC3DSA: fprintf(fp, "(NSEC3DSA)\n"); break; case DST_ALG_RSASHA256: fprintf(fp, "(RSASHA256)\n"); break; case DST_ALG_RSASHA512: fprintf(fp, "(RSASHA512)\n"); break; case DST_ALG_ECCGOST: fprintf(fp, "(ECC-GOST)\n"); break; case DST_ALG_ECDSA256: fprintf(fp, "(ECDSAP256SHA256)\n"); break; case DST_ALG_ECDSA384: fprintf(fp, "(ECDSAP384SHA384)\n"); break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; case DST_ALG_HMACSHA1: fprintf(fp, "(HMAC_SHA1)\n"); break; case DST_ALG_HMACSHA224: fprintf(fp, "(HMAC_SHA224)\n"); break; case DST_ALG_HMACSHA256: fprintf(fp, "(HMAC_SHA256)\n"); break; case DST_ALG_HMACSHA384: fprintf(fp, "(HMAC_SHA384)\n"); break; case DST_ALG_HMACSHA512: fprintf(fp, "(HMAC_SHA512)\n"); break; default: fprintf(fp, "(?)\n"); break; } for (i = 0; i < priv->nelements; i++) { const char *s; s = find_tag(priv->elements[i].tag); r.base = priv->elements[i].data; r.length = priv->elements[i].length; isc_buffer_init(&b, buffer, sizeof(buffer)); result = isc_base64_totext(&r, sizeof(buffer), "", &b); if (result != ISC_R_SUCCESS) { fclose(fp); return (DST_R_INVALIDPRIVATEKEY); } isc_buffer_usedregion(&b, &r); fprintf(fp, "%s %.*s\n", s, (int)r.length, r.base); } if (key->external) fprintf(fp, "External:\n"); /* Add the metadata tags */ if (major > 1 || (major == 1 && minor >= 3)) { for (i = 0; i < NUMERIC_NTAGS; i++) { result = dst_key_getnum(key, i, &value); if (result != ISC_R_SUCCESS) continue; fprintf(fp, "%s %u\n", numerictags[i], value); } for (i = 0; i < TIMING_NTAGS; i++) { result = dst_key_gettime(key, i, &when); if (result != ISC_R_SUCCESS) continue; isc_buffer_init(&b, buffer, sizeof(buffer)); result = dns_time32_totext(when, &b); if (result != ISC_R_SUCCESS) { fclose(fp); return (DST_R_INVALIDPRIVATEKEY); } isc_buffer_usedregion(&b, &r); fprintf(fp, "%s %.*s\n", timetags[i], (int)r.length, r.base); } } fflush(fp); result = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS; fclose(fp); return (result); }
/*% * Writes a public key to disk in DNS format. */ static isc_result_t write_public_key(const dst_key_t *key, int type, const char *directory) { FILE *fp; isc_buffer_t keyb, textb, fileb, classb; isc_region_t r; char filename[ISC_DIR_NAMEMAX]; unsigned char key_array[DST_KEY_MAXSIZE]; char text_array[DST_KEY_MAXTEXTSIZE]; char class_array[10]; isc_result_t ret; dns_rdata_t rdata = DNS_RDATA_INIT; isc_fsaccess_t access; REQUIRE(VALID_KEY(key)); isc_buffer_init(&keyb, key_array, sizeof(key_array)); isc_buffer_init(&textb, text_array, sizeof(text_array)); isc_buffer_init(&classb, class_array, sizeof(class_array)); ret = dst_key_todns(key, &keyb); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_usedregion(&keyb, &r); dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r); ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); ret = dns_rdataclass_totext(key->key_class, &classb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); /* * Make the filename. */ isc_buffer_init(&fileb, filename, sizeof(filename)); ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb); if (ret != ISC_R_SUCCESS) return (ret); /* * Create public key file. */ if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); if (issymmetric(key)) { access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); } ret = dns_name_print(key->key_name, fp); if (ret != ISC_R_SUCCESS) { fclose(fp); return (ret); } fprintf(fp, " "); isc_buffer_usedregion(&classb, &r); fwrite(r.base, 1, r.length, fp); if ((type & DST_TYPE_KEY) != 0) fprintf(fp, " KEY "); else fprintf(fp, " DNSKEY "); isc_buffer_usedregion(&textb, &r); fwrite(r.base, 1, r.length, fp); fputc('\n', fp); fclose(fp); return (ISC_R_SUCCESS); }