static void test_copy_file(void) { _cleanup_free_ char *buf = NULL; char fn[] = "/tmp/test-copy_file.XXXXXX"; char fn_copy[] = "/tmp/test-copy_file.XXXXXX"; size_t sz = 0; int fd; fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC); assert_se(fd >= 0); close(fd); fd = mkostemp_safe(fn_copy, O_RDWR|O_CLOEXEC); assert_se(fd >= 0); close(fd); assert_se(write_string_file(fn, "foo bar bar bar foo") == 0); assert_se(copy_file(fn, fn_copy, 0, 0644) == 0); assert_se(read_full_file(fn_copy, &buf, &sz) == 0); assert_se(streq(buf, "foo bar bar bar foo\n")); assert_se(sz == 20); unlink(fn); unlink(fn_copy); }
static int exec_addpubkey(int argc, char **argv) { CRYPT_KEYSET keyset; CRYPT_CERTIFICATE cert; const char *certfilename, *keysetfilename; void *data; int data_len; int status; if (argc != 2) { fprintf(stderr, "usage: addpubkey keyset cert\n"); return 1; } keysetfilename = argv[0]; certfilename = argv[1]; status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keysetfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); data = read_full_file(certfilename, &data_len); status = cryptImportCert(data, data_len, CRYPT_UNUSED, &cert); WARN_AND_RETURN_IF(status); status = cryptAddPublicKey(keyset, cert); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(keyset); WARN_AND_RETURN_IF(status); free(data); return 0; }
static void test_copy_file(void) { _cleanup_free_ char *buf = NULL; char fn[] = "/tmp/test-copy_file.XXXXXX"; char fn_copy[] = "/tmp/test-copy_file.XXXXXX"; size_t sz = 0; int fd; log_info("%s", __func__); fd = mkostemp_safe(fn); assert_se(fd >= 0); close(fd); fd = mkostemp_safe(fn_copy); assert_se(fd >= 0); close(fd); assert_se(write_string_file(fn, "foo bar bar bar foo", WRITE_STRING_FILE_CREATE) == 0); assert_se(copy_file(fn, fn_copy, 0, 0644, 0, COPY_REFLINK) == 0); assert_se(read_full_file(fn_copy, &buf, &sz) == 0); assert_se(streq(buf, "foo bar bar bar foo\n")); assert_se(sz == 20); unlink(fn); unlink(fn_copy); }
static int proc_read_buffer(const char *path, struct buffer *b) { assert(path); assert(b); if (b->data) return 0; return read_full_file(path, (void**) &b->data, &b->size); }
STRV_FOREACH(p, files) { _cleanup_free_ char *buf = NULL; size_t sz = 0; char *f = strappenda(copy_dir, *p); assert_se(access(f, F_OK) == 0); assert_se(read_full_file(f, &buf, &sz) == 0); assert_se(streq(buf, "file\n")); }
int sysctl_read(const char *property, char **content) { char *p; assert(property); assert(content); p = strjoina("/proc/sys/", property); return read_full_file(p, content, NULL); }
/* Add .bin bitstream */ static int bif_add_bin(struct bif_entry *bf) { size_t size; char *bin = read_full_file(bf->filename, &size); if (!bf->dest_dev) bf->dest_dev = PART_ATTR_DEST_DEVICE_PS; bf->flags |= 1ULL << BIF_FLAG_BIN_FILE; return bif_add_part(bf, bin, size); }
void load_config(struct config *config) { char *data = read_full_file(config->config_path); if(NULL == data) { fatal("Can't read config file \"%s\".", config->config_path); } char *err = load_config_from_string(config, data, 0); if(err) { log_error("%s", err); fatal("Broken config file \"%s\".", config->config_path); } free(data); }
static int generate_display_manager_alias(void) { _cleanup_free_ char *default_dm_path = NULL, *enabled_dm_unit = NULL; const char *default_dm = NULL, *in_mem_symlink = NULL, *target_unit_path = NULL; bool dm_service_exists = true; int r; r = read_full_file(default_dm_file, &default_dm_path, NULL); if (r < 0) { log_debug("No %s file, nothing to generate", default_dm_file); return 0; } default_dm = strstrip(basename(default_dm_path)); r = readlink_value(dm_service_unit, &enabled_dm_unit); if (r < 0) { enabled_dm_unit = strdup(""); dm_service_exists = false; } /* all is fine if the info matches */ if (streq(strappenda(default_dm, ".service"), enabled_dm_unit)) return 0; target_unit_path = strappenda(SYSTEM_DATA_UNIT_PATH, "/", default_dm, ".service"); /* we only create the alias symlink for non sysvinit services */ if (access(target_unit_path, F_OK) < 0 && (errno == ENOENT)) { /* if the dm service was already disabled, nothing to be done */ if (!dm_service_exists) { log_debug("No %s file, nothing to mask", dm_service_unit); return 0; } log_warning("%s is not a systemd unit, we disable the systemd enabled display manager", target_unit_path); target_unit_path = "/dev/null"; } else { log_warning("%s points at %s while the default systemd unit is %s. Reconfiguring %s as default.", default_dm_file, default_dm, enabled_dm_unit, default_dm); } in_mem_symlink = strappenda(dest, "/display-manager.service"); mkdir_parents_label(in_mem_symlink, 0755); if (symlink(target_unit_path, in_mem_symlink) < 0) { log_error("Failed to create symlink %s: %m", in_mem_symlink); return -errno; } return 0; }
static void test_packet_from_file(const char* filename, bool canonical) { _cleanup_free_ char *data = NULL; size_t data_size, packet_size, offset; assert_se(read_full_file(filename, &data, &data_size) >= 0); assert_se(data); assert_se(data_size > 8); log_info("============== %s %s==============", filename, canonical ? "canonical " : ""); for (offset = 0; offset < data_size; offset += 8 + packet_size) { _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL, *p2 = NULL; _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL, *rr2 = NULL; const char *s, *s2; uint64_t hash1, hash2; packet_size = le64toh( *(uint64_t*)(data + offset) ); assert_se(packet_size > 0); assert_se(offset + 8 + packet_size <= data_size); assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, 0) >= 0); assert_se(dns_packet_append_blob(p, data + offset + 8, packet_size, NULL) >= 0); assert_se(dns_packet_read_rr(p, &rr, NULL, NULL) >= 0); s = dns_resource_record_to_string(rr); assert_se(s); puts(s); hash1 = hash(rr); assert_se(dns_resource_record_to_wire_format(rr, canonical) >= 0); assert_se(dns_packet_new(&p2, DNS_PROTOCOL_DNS, 0) >= 0); assert_se(dns_packet_append_blob(p2, rr->wire_format, rr->wire_format_size, NULL) >= 0); assert_se(dns_packet_read_rr(p2, &rr2, NULL, NULL) >= 0); s2 = dns_resource_record_to_string(rr); assert_se(s2); assert_se(streq(s, s2)); hash2 = hash(rr); assert_se(hash1 == hash2); } }
static int exec_request(int argc, char **argv) { int status; const char *dbfilename, *csrfilename; void *csr_data; int csr_len; CRYPT_KEYSET store; CRYPT_CERTIFICATE request; if (argc != 2) { fprintf(stderr, "usage: request dbfilename csrfilename\n"); return 1; }; dbfilename = argv[0]; csrfilename = argv[1]; if (opt_verbose) fprintf(stderr, "exec request db \"%s\" csr \"%s\"\n", dbfilename, csrfilename); status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE); if (opt_verbose) fprintf(stderr, "finished opening ks\n"); if (!cryptStatusOK(status)) { fprintf(stderr, "(%s:%d) -> %d\n", __FILE__, __LINE__, status); return status; } csr_data = read_full_file(csrfilename, &csr_len); if (opt_verbose) fprintf(stderr, "finished reading csr\n"); fflush(stderr); status = cryptImportCert(csr_data, csr_len, CRYPT_UNUSED, &request); free(csr_data); if (opt_verbose) fprintf(stderr, "finished importing csr\n"); WARN_AND_RETURN_IF(status); status = cryptCAAddItem(store, request); WARN_AND_RETURN_IF(status); if (opt_verbose) fprintf(stderr, "finished adding csr to store\n"); status = cryptDestroyCert(request); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(store); WARN_AND_RETURN_IF(status); if (opt_verbose) fprintf(stderr, "finished closing store\n"); return 0; }
static int routing_policy_rule_read_full_file(const char *state_file, char **ret) { _cleanup_free_ char *s = NULL; size_t size; int r; assert(state_file); r = read_full_file(state_file, &s, &size); if (r == -ENOENT) return -ENODATA; if (r < 0) return r; if (size <= 0) return -ENODATA; *ret = TAKE_PTR(s); return size; }
/** * Retrieve one field from a file like /proc/self/status. pattern * should start with '\n' and end with a ':'. Whitespace and zeros * after the ':' will be skipped. field must be freed afterwards. */ int get_status_field(const char *filename, const char *pattern, char **field) { _cleanup_free_ char *status = NULL; char *t; size_t len; int r; assert(filename); assert(pattern); assert(field); r = read_full_file(filename, &status, NULL); if (r < 0) return r; t = strstr(status, pattern); if (!t) return -ENOENT; t += strlen(pattern); if (*t) { t += strspn(t, " \t"); /* Also skip zeros, because when this is used for * capabilities, we don't want the zeros. This way the * same capability set always maps to the same string, * irrespective of the total capability set size. For * other numbers it shouldn't matter. */ t += strspn(t, "0"); /* Back off one char if there's nothing but whitespace and zeros */ if (!*t || isspace(*t)) t --; } len = strcspn(t, WHITESPACE); *field = strndup(t, len); if (!*field) return -ENOMEM; return 0; }
static int bif_add_elf(struct bif_entry *bf) { size_t size; size_t elf_size; char *elf; char *flat; size_t load_addr; Elf32_Ehdr *ehdr32; Elf64_Ehdr *ehdr64; elf = read_full_file(bf->filename, &elf_size); if (!elf) return -1; ehdr32 = (void *)elf; ehdr64 = (void *)elf; switch (ehdr32->e_ident[EI_CLASS]) { case ELFCLASS32: flat = elf2flat32(elf, &size, &load_addr); bf->entry = le32_to_cpu(ehdr32->e_entry); bf->flags |= 1ULL << BIF_FLAG_AARCH32; break; case ELFCLASS64: flat = elf2flat64(elf, &size, &load_addr); bf->entry = le64_to_cpu(ehdr64->e_entry); break; default: printf("Unknown ELF class: %d\n", ehdr32->e_ident[EI_CLASS]); return -1; } if (!flat) return -1; bf->load = load_addr; if (!bf->dest_dev) bf->dest_dev = PART_ATTR_DEST_DEVICE_PS; bf->flags |= 1ULL << BIF_FLAG_ELF_FILE; return bif_add_part(bf, flat, size); }
_public_ int sd_network_link_get_lldp(int ifindex, char **lldp) { _cleanup_free_ char *s = NULL, *p = NULL; size_t size; int r; assert_return(ifindex > 0, -EINVAL); assert_return(lldp, -EINVAL); if (asprintf(&p, "/run/systemd/netif/lldp/%d", ifindex) < 0) return -ENOMEM; r = read_full_file(p, &s, &size); if (r == -ENOENT) return -ENODATA; if (r < 0) return r; if (size <= 0) return -ENODATA; *lldp = s; s = NULL; return 0; }
static int parse_env_file_internal( FILE *f, const char *fname, const char *newline, int (*push) (const char *filename, unsigned line, const char *key, char *value, void *userdata, int *n_pushed), void *userdata, int *n_pushed) { size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1; _cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL; unsigned line = 1; char *p; int r; enum { PRE_KEY, KEY, PRE_VALUE, VALUE, VALUE_ESCAPE, SINGLE_QUOTE_VALUE, SINGLE_QUOTE_VALUE_ESCAPE, DOUBLE_QUOTE_VALUE, DOUBLE_QUOTE_VALUE_ESCAPE, COMMENT, COMMENT_ESCAPE } state = PRE_KEY; assert(newline); if (f) r = read_full_stream(f, &contents, NULL); else r = read_full_file(fname, &contents, NULL); if (r < 0) return r; for (p = contents; *p; p++) { char c = *p; switch (state) { case PRE_KEY: if (strchr(COMMENTS, c)) state = COMMENT; else if (!strchr(WHITESPACE, c)) { state = KEY; last_key_whitespace = (size_t) -1; if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) return -ENOMEM; key[n_key++] = c; } break; case KEY: if (strchr(newline, c)) { state = PRE_KEY; line++; n_key = 0; } else if (c == '=') { state = PRE_VALUE; last_value_whitespace = (size_t) -1; } else { if (!strchr(WHITESPACE, c)) last_key_whitespace = (size_t) -1; else if (last_key_whitespace == (size_t) -1) last_key_whitespace = n_key; if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) return -ENOMEM; key[n_key++] = c; } break; case PRE_VALUE: if (strchr(newline, c)) { state = PRE_KEY; line++; key[n_key] = 0; if (value) value[n_value] = 0; /* strip trailing whitespace from key */ if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; r = push(fname, line, key, value, userdata, n_pushed); if (r < 0) return r; n_key = 0; value = NULL; value_alloc = n_value = 0; } else if (c == '\'') state = SINGLE_QUOTE_VALUE; else if (c == '\"') state = DOUBLE_QUOTE_VALUE; else if (c == '\\') state = VALUE_ESCAPE; else if (!strchr(WHITESPACE, c)) { state = VALUE; if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; value[n_value++] = c; } break; case VALUE: if (strchr(newline, c)) { state = PRE_KEY; line++; key[n_key] = 0; if (value) value[n_value] = 0; /* Chomp off trailing whitespace from value */ if (last_value_whitespace != (size_t) -1) value[last_value_whitespace] = 0; /* strip trailing whitespace from key */ if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; r = push(fname, line, key, value, userdata, n_pushed); if (r < 0) return r; n_key = 0; value = NULL; value_alloc = n_value = 0; } else if (c == '\\') { state = VALUE_ESCAPE; last_value_whitespace = (size_t) -1; } else { if (!strchr(WHITESPACE, c)) last_value_whitespace = (size_t) -1; else if (last_value_whitespace == (size_t) -1) last_value_whitespace = n_value; if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; value[n_value++] = c; } break; case VALUE_ESCAPE: state = VALUE; if (!strchr(newline, c)) { /* Escaped newlines we eat up entirely */ if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; value[n_value++] = c; } break; case SINGLE_QUOTE_VALUE: if (c == '\'') state = PRE_VALUE; else if (c == '\\') state = SINGLE_QUOTE_VALUE_ESCAPE; else { if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; value[n_value++] = c; } break; case SINGLE_QUOTE_VALUE_ESCAPE: state = SINGLE_QUOTE_VALUE; if (!strchr(newline, c)) { if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; value[n_value++] = c; } break; case DOUBLE_QUOTE_VALUE: if (c == '\"') state = PRE_VALUE; else if (c == '\\') state = DOUBLE_QUOTE_VALUE_ESCAPE; else { if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; value[n_value++] = c; } break; case DOUBLE_QUOTE_VALUE_ESCAPE: state = DOUBLE_QUOTE_VALUE; if (!strchr(newline, c)) { if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) return -ENOMEM; value[n_value++] = c; } break; case COMMENT: if (c == '\\') state = COMMENT_ESCAPE; else if (strchr(newline, c)) { state = PRE_KEY; line++; } break; case COMMENT_ESCAPE: state = COMMENT; break; } } if (IN_SET(state, PRE_VALUE, VALUE, VALUE_ESCAPE, SINGLE_QUOTE_VALUE, SINGLE_QUOTE_VALUE_ESCAPE, DOUBLE_QUOTE_VALUE, DOUBLE_QUOTE_VALUE_ESCAPE)) { key[n_key] = 0; if (value) value[n_value] = 0; if (state == VALUE) if (last_value_whitespace != (size_t) -1) value[last_value_whitespace] = 0; /* strip trailing whitespace from key */ if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; r = push(fname, line, key, value, userdata, n_pushed); if (r < 0) return r; value = NULL; } return 0; }
int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) { _cleanup_free_ char *buf = NULL; struct acpi_table_header *tbl; size_t l = 0; struct acpi_fpdt_header *rec; int r; uint64_t ptr = 0; _cleanup_close_ int fd = -1; struct acpi_fpdt_boot_header hbrec; struct acpi_fpdt_boot brec; r = read_full_file("/sys/firmware/acpi/tables/FPDT", &buf, &l); if (r < 0) return r; if (l < sizeof(struct acpi_table_header) + sizeof(struct acpi_fpdt_header)) return -EINVAL; tbl = (struct acpi_table_header *)buf; if (l != tbl->length) return -EINVAL; if (memcmp(tbl->signature, "FPDT", 4) != 0) return -EINVAL; /* find Firmware Basic Boot Performance Pointer Record */ for (rec = (struct acpi_fpdt_header *)(buf + sizeof(struct acpi_table_header)); (char *)rec < buf + l; rec = (struct acpi_fpdt_header *)((char *)rec + rec->length)) { if (rec->length <= 0) break; if (rec->type != ACPI_FPDT_TYPE_BOOT) continue; if (rec->length != sizeof(struct acpi_fpdt_header)) continue; ptr = rec->ptr; break; } if (ptr == 0) return -EINVAL; /* read Firmware Basic Boot Performance Data Record */ fd = open("/dev/mem", O_CLOEXEC|O_RDONLY); if (fd < 0) return -errno; l = pread(fd, &hbrec, sizeof(struct acpi_fpdt_boot_header), ptr); if (l != sizeof(struct acpi_fpdt_boot_header)) return -EINVAL; if (memcmp(hbrec.signature, "FBPT", 4) != 0) return -EINVAL; if (hbrec.length < sizeof(struct acpi_fpdt_boot_header) + sizeof(struct acpi_fpdt_boot)) return -EINVAL; l = pread(fd, &brec, sizeof(struct acpi_fpdt_boot), ptr + sizeof(struct acpi_fpdt_boot_header)); if (l != sizeof(struct acpi_fpdt_boot)) return -EINVAL; if (brec.length != sizeof(struct acpi_fpdt_boot)) return -EINVAL; if (brec.type != ACPI_FPDT_BOOT_REC) return -EINVAL; if (brec.startup_start == 0 || brec.exit_services_exit < brec.startup_start) return -EINVAL; if (brec.exit_services_exit > NSEC_PER_HOUR) return -EINVAL; if (loader_start) *loader_start = brec.startup_start / 1000; if (loader_exit) *loader_exit = brec.exit_services_exit / 1000; return 0; }
static int bif_add_part(struct bif_entry *bf, const char *data, size_t len) { size_t parthdr_offset = 0; struct partition_header parthdr = { .len_enc = cpu_to_le32(len / 4), .len_unenc = cpu_to_le32(len / 4), .len = cpu_to_le32(len / 4), .entry_point = cpu_to_le64(bf->entry), .load_address = cpu_to_le64(bf->load), }; int r; uint32_t csum; if (bf->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE)) return bif_add_pmufw(bf, data, len); r = bif_add_blob(data, len, &bf->offset); if (r) return r; parthdr.offset = cpu_to_le32(bf->offset / 4); if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) { if (bif_output.last_part) { printf("ERROR: Bootloader expected before others\n"); return -1; } parthdr.offset = cpu_to_le32(bif_output.header->image_offset); parthdr.len = cpu_to_le32((bf->offset + len - bif_output.header->image_offset) / 4); parthdr.len_enc = parthdr.len; parthdr.len_unenc = parthdr.len; } /* Normalize EL */ bf->exp_lvl = bf->exp_lvl ? bf->exp_lvl - 1 : 3; parthdr.attributes |= bf->exp_lvl << PART_ATTR_TARGET_EL_SHIFT; parthdr.attributes |= bf->dest_dev; parthdr.attributes |= bf->dest_cpu; if (bf->flags & (1ULL << BIF_FLAG_TZ)) parthdr.attributes |= PART_ATTR_TZ_SECURE; if (bf->flags & (1ULL << BIF_FLAG_PART_OWNER_UBOOT)) parthdr.attributes |= PART_ATTR_PART_OWNER_UBOOT; switch (bf->dest_cpu) { case PART_ATTR_DEST_CPU_NONE: case PART_ATTR_DEST_CPU_A53_0: case PART_ATTR_DEST_CPU_A53_1: case PART_ATTR_DEST_CPU_A53_2: case PART_ATTR_DEST_CPU_A53_3: if (bf->flags & (1ULL << BIF_FLAG_AARCH32)) parthdr.attributes |= PART_ATTR_A53_EXEC_AARCH32; } csum = zynqmp_csum(&parthdr, &parthdr.checksum); parthdr.checksum = cpu_to_le32(csum); r = bif_add_blob(&parthdr, sizeof(parthdr), &parthdr_offset); if (r) return r; /* Add image header table if not there yet */ if (!bif_output.imgheader) { size_t imghdr_off = 0; struct image_header_table imghdr = { .version = cpu_to_le32(0x01020000), .nr_parts = 0, }; r = bif_add_blob(&imghdr, sizeof(imghdr), &imghdr_off); if (r) return r; bif_output.header->image_header_table_offset = imghdr_off; bif_output.imgheader = (void *)(bif_output.data + imghdr_off); } bif_output.imgheader->nr_parts = cpu_to_le32(le32_to_cpu( bif_output.imgheader->nr_parts) + 1); /* Link to this partition header */ if (bif_output.last_part) { bif_output.last_part->next_partition_offset = cpu_to_le32(parthdr_offset / 4); /* Recalc checksum of last_part */ csum = zynqmp_csum(bif_output.last_part, &bif_output.last_part->checksum); bif_output.last_part->checksum = cpu_to_le32(csum); } else { bif_output.imgheader->partition_header_offset = cpu_to_le32(parthdr_offset / 4); } bif_output.last_part = (void *)(bif_output.data + parthdr_offset); if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) { bif_output.header->image_load = cpu_to_le32(bf->load); if (!bif_output.header->image_offset) bif_output.header->image_offset = cpu_to_le32(bf->offset); bif_output.header->image_size = cpu_to_le32(len); bif_output.header->image_stored_size = cpu_to_le32(len); bif_output.header->image_attributes &= ~HEADER_CPU_SELECT_MASK; switch (bf->dest_cpu) { default: case PART_ATTR_DEST_CPU_A53_0: if (bf->flags & BIF_FLAG_AARCH32) bif_output.header->image_attributes |= HEADER_CPU_SELECT_A53_32BIT; else bif_output.header->image_attributes |= HEADER_CPU_SELECT_A53_64BIT; break; case PART_ATTR_DEST_CPU_R5_0: bif_output.header->image_attributes |= HEADER_CPU_SELECT_R5_SINGLE; break; case PART_ATTR_DEST_CPU_R5_L: bif_output.header->image_attributes |= HEADER_CPU_SELECT_R5_DUAL; break; } } return 0; } /* Add .bit bitstream */ static int bif_add_bit(struct bif_entry *bf) { char *bit = read_full_file(bf->filename, NULL); char *bitbin; uint8_t initial_header[] = { 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61 }; uint16_t len; uint32_t bitlen; int i; if (!bit) return -1; /* Skip initial header */ if (memcmp(bit, initial_header, sizeof(initial_header))) return -1; bit += sizeof(initial_header); /* Design name */ len = be16_to_cpu(*(uint16_t *)bit); bit += sizeof(uint16_t); debug("Design: %s\n", bit); bit += len; /* Device identifier */ if (*bit != 'b') return -1; bit++; len = be16_to_cpu(*(uint16_t *)bit); bit += sizeof(uint16_t); debug("Device: %s\n", bit); bit += len; /* Date */ if (*bit != 'c') return -1; bit++; len = be16_to_cpu(*(uint16_t *)bit); bit += sizeof(uint16_t); debug("Date: %s\n", bit); bit += len; /* Time */ if (*bit != 'd') return -1; bit++; len = be16_to_cpu(*(uint16_t *)bit); bit += sizeof(uint16_t); debug("Time: %s\n", bit); bit += len; /* Bitstream length */ if (*bit != 'e') return -1; bit++; bitlen = be32_to_cpu(*(uint32_t *)bit); bit += sizeof(uint32_t); bitbin = bit; debug("Bitstream Length: 0x%x\n", bitlen); for (i = 0; i < bitlen; i += sizeof(uint32_t)) { uint32_t *bitbin32 = (uint32_t *)&bitbin[i]; *bitbin32 = __swab32(*bitbin32); } if (!bf->dest_dev) bf->dest_dev = PART_ATTR_DEST_DEVICE_PL; bf->load = 0xffffffff; bf->entry = 0; bf->flags |= 1ULL << BIF_FLAG_BIT_FILE; return bif_add_part(bf, bit, bitlen); }
/** * Retrieve one field from a file like /proc/self/status. pattern * should not include whitespace or the delimiter (':'). pattern matches only * the beginning of a line. Whitespace before ':' is skipped. Whitespace and * zeros after the ':' will be skipped. field must be freed afterwards. * terminator specifies the terminating characters of the field value (not * included in the value). */ int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) { _cleanup_free_ char *status = NULL; char *t, *f; size_t len; int r; assert(terminator); assert(filename); assert(pattern); assert(field); r = read_full_file(filename, &status, NULL); if (r < 0) return r; t = status; do { bool pattern_ok; do { t = strstr(t, pattern); if (!t) return -ENOENT; /* Check that pattern occurs in beginning of line. */ pattern_ok = (t == status || t[-1] == '\n'); t += strlen(pattern); } while (!pattern_ok); t += strspn(t, " \t"); if (!*t) return -ENOENT; } while (*t != ':'); t++; if (*t) { t += strspn(t, " \t"); /* Also skip zeros, because when this is used for * capabilities, we don't want the zeros. This way the * same capability set always maps to the same string, * irrespective of the total capability set size. For * other numbers it shouldn't matter. */ t += strspn(t, "0"); /* Back off one char if there's nothing but whitespace and zeros */ if (!*t || isspace(*t)) t--; } len = strcspn(t, terminator); f = strndup(t, len); if (!f) return -ENOMEM; *field = f; return 0; }
int main(int argc, char* argv[]) { /* The small core field we allocate on the stack, to keep things simple */ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, *core_session = NULL, *core_exe = NULL, *core_comm = NULL, *core_cmdline = NULL, *core_cgroup = NULL, *core_cwd = NULL, *core_root = NULL, *core_unit = NULL, *core_slice = NULL; /* The larger ones we allocate on the heap */ _cleanup_free_ char *core_timestamp = NULL, *core_message = NULL, *coredump_data = NULL, *core_owner_uid = NULL, *core_open_fds = NULL, *core_proc_status = NULL, *core_proc_maps = NULL, *core_proc_limits = NULL, *core_proc_cgroup = NULL, *core_environ = NULL; _cleanup_free_ char *exe = NULL, *comm = NULL, *filename = NULL; const char *info[_INFO_LEN]; _cleanup_close_ int coredump_fd = -1; struct iovec iovec[26]; uint64_t coredump_size; int r, j = 0; uid_t uid, owner_uid; gid_t gid; pid_t pid; char *t; const char *p; /* Make sure we never enter a loop */ prctl(PR_SET_DUMPABLE, 0); /* First, log to a safe place, since we don't know what * crashed and it might be journald which we'd rather not log * to then. */ log_set_target(LOG_TARGET_KMSG); log_open(); if (argc < INFO_COMM + 1) { log_error("Not enough arguments passed from kernel (%d, expected %d).", argc - 1, INFO_COMM + 1 - 1); r = -EINVAL; goto finish; } /* Ignore all parse errors */ parse_config(); log_debug("Selected storage '%s'.", coredump_storage_to_string(arg_storage)); log_debug("Selected compression %s.", yes_no(arg_compress)); r = parse_uid(argv[INFO_UID + 1], &uid); if (r < 0) { log_error("Failed to parse UID."); goto finish; } r = parse_pid(argv[INFO_PID + 1], &pid); if (r < 0) { log_error("Failed to parse PID."); goto finish; } r = parse_gid(argv[INFO_GID + 1], &gid); if (r < 0) { log_error("Failed to parse GID."); goto finish; } if (get_process_comm(pid, &comm) < 0) { log_warning("Failed to get COMM, falling back to the command line."); comm = strv_join(argv + INFO_COMM + 1, " "); } if (get_process_exe(pid, &exe) < 0) log_warning("Failed to get EXE."); info[INFO_PID] = argv[INFO_PID + 1]; info[INFO_UID] = argv[INFO_UID + 1]; info[INFO_GID] = argv[INFO_GID + 1]; info[INFO_SIGNAL] = argv[INFO_SIGNAL + 1]; info[INFO_TIMESTAMP] = argv[INFO_TIMESTAMP + 1]; info[INFO_COMM] = comm; info[INFO_EXE] = exe; if (cg_pid_get_unit(pid, &t) >= 0) { if (streq(t, SPECIAL_JOURNALD_SERVICE)) { free(t); /* If we are journald, we cut things short, * don't write to the journal, but still * create a coredump. */ if (arg_storage != COREDUMP_STORAGE_NONE) arg_storage = COREDUMP_STORAGE_EXTERNAL; r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size); if (r < 0) goto finish; r = maybe_remove_external_coredump(filename, coredump_size); if (r < 0) goto finish; log_info("Detected coredump of the journal daemon itself, diverted to %s.", filename); goto finish; } core_unit = strjoina("COREDUMP_UNIT=", t); free(t); } else if (cg_pid_get_user_unit(pid, &t) >= 0) { core_unit = strjoina("COREDUMP_USER_UNIT=", t); free(t); } if (core_unit) IOVEC_SET_STRING(iovec[j++], core_unit); /* OK, now we know it's not the journal, hence we can make use * of it now. */ log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); log_open(); core_pid = strjoina("COREDUMP_PID=", info[INFO_PID]); IOVEC_SET_STRING(iovec[j++], core_pid); core_uid = strjoina("COREDUMP_UID=", info[INFO_UID]); IOVEC_SET_STRING(iovec[j++], core_uid); core_gid = strjoina("COREDUMP_GID=", info[INFO_GID]); IOVEC_SET_STRING(iovec[j++], core_gid); core_signal = strjoina("COREDUMP_SIGNAL=", info[INFO_SIGNAL]); IOVEC_SET_STRING(iovec[j++], core_signal); if (sd_pid_get_session(pid, &t) >= 0) { core_session = strjoina("COREDUMP_SESSION=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_session); } if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) { r = asprintf(&core_owner_uid, "COREDUMP_OWNER_UID=" UID_FMT, owner_uid); if (r > 0) IOVEC_SET_STRING(iovec[j++], core_owner_uid); } if (sd_pid_get_slice(pid, &t) >= 0) { core_slice = strjoina("COREDUMP_SLICE=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_slice); } if (comm) { core_comm = strjoina("COREDUMP_COMM=", comm); IOVEC_SET_STRING(iovec[j++], core_comm); } if (exe) { core_exe = strjoina("COREDUMP_EXE=", exe); IOVEC_SET_STRING(iovec[j++], core_exe); } if (get_process_cmdline(pid, 0, false, &t) >= 0) { core_cmdline = strjoina("COREDUMP_CMDLINE=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_cmdline); } if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0) { core_cgroup = strjoina("COREDUMP_CGROUP=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_cgroup); } if (compose_open_fds(pid, &t) >= 0) { core_open_fds = strappend("COREDUMP_OPEN_FDS=", t); free(t); if (core_open_fds) IOVEC_SET_STRING(iovec[j++], core_open_fds); } p = procfs_file_alloca(pid, "status"); if (read_full_file(p, &t, NULL) >= 0) { core_proc_status = strappend("COREDUMP_PROC_STATUS=", t); free(t); if (core_proc_status) IOVEC_SET_STRING(iovec[j++], core_proc_status); } p = procfs_file_alloca(pid, "maps"); if (read_full_file(p, &t, NULL) >= 0) { core_proc_maps = strappend("COREDUMP_PROC_MAPS=", t); free(t); if (core_proc_maps) IOVEC_SET_STRING(iovec[j++], core_proc_maps); } p = procfs_file_alloca(pid, "limits"); if (read_full_file(p, &t, NULL) >= 0) { core_proc_limits = strappend("COREDUMP_PROC_LIMITS=", t); free(t); if (core_proc_limits) IOVEC_SET_STRING(iovec[j++], core_proc_limits); } p = procfs_file_alloca(pid, "cgroup"); if (read_full_file(p, &t, NULL) >=0) { core_proc_cgroup = strappend("COREDUMP_PROC_CGROUP=", t); free(t); if (core_proc_cgroup) IOVEC_SET_STRING(iovec[j++], core_proc_cgroup); } if (get_process_cwd(pid, &t) >= 0) { core_cwd = strjoina("COREDUMP_CWD=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_cwd); } if (get_process_root(pid, &t) >= 0) { core_root = strjoina("COREDUMP_ROOT=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_root); } if (get_process_environ(pid, &t) >= 0) { core_environ = strappend("COREDUMP_ENVIRON=", t); free(t); if (core_environ) IOVEC_SET_STRING(iovec[j++], core_environ); } core_timestamp = strjoin("COREDUMP_TIMESTAMP=", info[INFO_TIMESTAMP], "000000", NULL); if (core_timestamp) IOVEC_SET_STRING(iovec[j++], core_timestamp); IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1"); IOVEC_SET_STRING(iovec[j++], "PRIORITY=2"); /* Vacuum before we write anything again */ coredump_vacuum(-1, arg_keep_free, arg_max_use); /* Always stream the coredump to disk, if that's possible */ r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size); if (r < 0) /* skip whole core dumping part */ goto log; /* If we don't want to keep the coredump on disk, remove it * now, as later on we will lack the privileges for * it. However, we keep the fd to it, so that we can still * process it and log it. */ r = maybe_remove_external_coredump(filename, coredump_size); if (r < 0) goto finish; if (r == 0) { const char *coredump_filename; coredump_filename = strjoina("COREDUMP_FILENAME=", filename); IOVEC_SET_STRING(iovec[j++], coredump_filename); } /* Vacuum again, but exclude the coredump we just created */ coredump_vacuum(coredump_fd, arg_keep_free, arg_max_use); /* Now, let's drop privileges to become the user who owns the * segfaulted process and allocate the coredump memory under * the user's uid. This also ensures that the credentials * journald will see are the ones of the coredumping user, * thus making sure the user gets access to the core * dump. Let's also get rid of all capabilities, if we run as * root, we won't need them anymore. */ r = drop_privileges(uid, gid, 0); if (r < 0) { log_error_errno(r, "Failed to drop privileges: %m"); goto finish; } #ifdef HAVE_ELFUTILS /* Try to get a strack trace if we can */ if (coredump_size <= arg_process_size_max) { _cleanup_free_ char *stacktrace = NULL; r = coredump_make_stack_trace(coredump_fd, exe, &stacktrace); if (r >= 0) core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.\n\n", stacktrace, NULL); else if (r == -EINVAL) log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno())); else log_warning_errno(r, "Failed to generate stack trace: %m"); } if (!core_message) #endif log: core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.", NULL); if (core_message) IOVEC_SET_STRING(iovec[j++], core_message); /* Optionally store the entire coredump in the journal */ if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) && coredump_size <= arg_journal_size_max) { size_t sz = 0; /* Store the coredump itself in the journal */ r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz); if (r >= 0) { iovec[j].iov_base = coredump_data; iovec[j].iov_len = sz; j++; } } r = sd_journal_sendv(iovec, j); if (r < 0) log_error_errno(r, "Failed to log coredump: %m"); finish: return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
int parse_env_file( const char *fname, const char *separator, ...) { int r = 0; char *contents = NULL, *p; assert(fname); assert(separator); r = read_full_file(fname, &contents, NULL); if (r < 0) return r; p = contents; for (;;) { const char *key = NULL; p += strspn(p, separator); p += strspn(p, WHITESPACE); if (!*p) break; if (!strchr(COMMENTS, *p)) { va_list ap; char **value; va_start(ap, separator); while ((key = va_arg(ap, char *))) { size_t n; char *v; value = va_arg(ap, char **); n = strlen(key); if (!strneq(p, key, n) || p[n] != '=') continue; p += n + 1; n = strcspn(p, separator); if (n >= 2 && strchr(QUOTES, p[0]) && p[n-1] == p[0]) v = strndup(p+1, n-2); else v = strndup(p, n); if (!v) { r = -ENOMEM; va_end(ap); goto fail; } if (v[0] == '\0') { /* return empty value strings as NULL */ free(v); v = NULL; } free(*value); *value = v; p += n; r ++; break; } va_end(ap); } if (!key) p += strcspn(p, separator); }
static int parse_env_file_internal( const char *fname, const char *newline, int (*push) (const char *key, char *value, void *userdata), void *userdata) { _cleanup_free_ char *contents = NULL, *key = NULL; size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1; char *p, *value = NULL; int r; enum { PRE_KEY, KEY, PRE_VALUE, VALUE, VALUE_ESCAPE, SINGLE_QUOTE_VALUE, SINGLE_QUOTE_VALUE_ESCAPE, DOUBLE_QUOTE_VALUE, DOUBLE_QUOTE_VALUE_ESCAPE, COMMENT, COMMENT_ESCAPE } state = PRE_KEY; assert(fname); assert(newline); r = read_full_file(fname, &contents, NULL); if (r < 0) return r; for (p = contents; *p; p++) { char c = *p; switch (state) { case PRE_KEY: if (strchr(COMMENTS, c)) state = COMMENT; else if (!strchr(WHITESPACE, c)) { state = KEY; last_key_whitespace = (size_t) -1; if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) { r = -ENOMEM; goto fail; } key[n_key++] = c; } break; case KEY: if (strchr(newline, c)) { state = PRE_KEY; n_key = 0; } else if (c == '=') { state = PRE_VALUE; last_value_whitespace = (size_t) -1; } else { if (!strchr(WHITESPACE, c)) last_key_whitespace = (size_t) -1; else if (last_key_whitespace == (size_t) -1) last_key_whitespace = n_key; if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) { r = -ENOMEM; goto fail; } key[n_key++] = c; } break; case PRE_VALUE: if (strchr(newline, c)) { state = PRE_KEY; key[n_key] = 0; if (value) value[n_value] = 0; /* strip trailing whitespace from key */ if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; r = push(key, value, userdata); if (r < 0) goto fail; n_key = 0; value = NULL; value_alloc = n_value = 0; } else if (c == '\'') state = SINGLE_QUOTE_VALUE; else if (c == '\"') state = DOUBLE_QUOTE_VALUE; else if (c == '\\') state = VALUE_ESCAPE; else if (!strchr(WHITESPACE, c)) { state = VALUE; if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; goto fail; } value[n_value++] = c; } break; case VALUE: if (strchr(newline, c)) { state = PRE_KEY; key[n_key] = 0; if (value) value[n_value] = 0; /* Chomp off trailing whitespace from value */ if (last_value_whitespace != (size_t) -1) value[last_value_whitespace] = 0; /* strip trailing whitespace from key */ if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; r = push(key, value, userdata); if (r < 0) goto fail; n_key = 0; value = NULL; value_alloc = n_value = 0; } else if (c == '\\') { state = VALUE_ESCAPE; last_value_whitespace = (size_t) -1; } else { if (!strchr(WHITESPACE, c)) last_value_whitespace = (size_t) -1; else if (last_value_whitespace == (size_t) -1) last_value_whitespace = n_value; if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; goto fail; } value[n_value++] = c; } break; case VALUE_ESCAPE: state = VALUE; if (!strchr(newline, c)) { /* Escaped newlines we eat up entirely */ if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; goto fail; } value[n_value++] = c; } break; case SINGLE_QUOTE_VALUE: if (c == '\'') state = PRE_VALUE; else if (c == '\\') state = SINGLE_QUOTE_VALUE_ESCAPE; else { if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; goto fail; } value[n_value++] = c; } break; case SINGLE_QUOTE_VALUE_ESCAPE: state = SINGLE_QUOTE_VALUE; if (!strchr(newline, c)) { if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; goto fail; } value[n_value++] = c; } break; case DOUBLE_QUOTE_VALUE: if (c == '\"') state = PRE_VALUE; else if (c == '\\') state = DOUBLE_QUOTE_VALUE_ESCAPE; else { if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; goto fail; } value[n_value++] = c; } break; case DOUBLE_QUOTE_VALUE_ESCAPE: state = DOUBLE_QUOTE_VALUE; if (!strchr(newline, c)) { if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; goto fail; } value[n_value++] = c; } break; case COMMENT: if (c == '\\') state = COMMENT_ESCAPE; else if (strchr(newline, c)) state = PRE_KEY; break; case COMMENT_ESCAPE: state = COMMENT; break; } } if (state == PRE_VALUE || state == VALUE || state == VALUE_ESCAPE || state == SINGLE_QUOTE_VALUE || state == SINGLE_QUOTE_VALUE_ESCAPE || state == DOUBLE_QUOTE_VALUE || state == DOUBLE_QUOTE_VALUE_ESCAPE) { key[n_key] = 0; if (value) value[n_value] = 0; if (state == VALUE) if (last_value_whitespace != (size_t) -1) value[last_value_whitespace] = 0; /* strip trailing whitespace from key */ if (last_key_whitespace != (size_t) -1) key[last_key_whitespace] = 0; r = push(key, value, userdata); if (r < 0) goto fail; } return 0; fail: free(value); return r; }
static int exec_cmpcli_init(int argc, char **argv) { CRYPT_SESSION session; CRYPT_CERTIFICATE cert, cacert, req; CRYPT_CONTEXT keypair; CRYPT_KEYSET privkeys; const char *cmd, *uid, *ipwd, *crtfilename, *cacrtfilename, *kpfilename; void *crtdata; int status, data_len; if (argc != 6) { fprintf(stderr, "cmpcli argv!=6\n"); return 1; } cmd = argv[0]; uid = argv[1]; ipwd = argv[2]; crtfilename=argv[3]; cacrtfilename=argv[4]; kpfilename = argv[5]; fprintf(stderr, "uid=\"%s\" ipwd=\"%s\"\n", uid, ipwd); #if 0 crtdata = read_full_file(crtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cert); WARN_AND_RETURN_IF(status); free(crtdata); #endif crtdata = read_full_file(cacrtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cacert); WARN_AND_RETURN_IF(status); free(crtdata); status = create_keypair(&keypair, DEFAULT_PRIVKEY_LABEL); WARN_AND_RETURN_IF(status); status = cryptKeysetOpen(&privkeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, kpfilename, CRYPT_KEYOPT_CREATE); WARN_AND_RETURN_IF(status); status = cryptAddPrivateKey(privkeys, keypair, DEFAULT_PASSWORD); WARN_AND_RETURN_IF(status); status = cryptCreateCert(&req, CRYPT_UNUSED, CRYPT_CERTTYPE_REQUEST_CERT); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(req, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, keypair); WARN_AND_RETURN_IF(status); status = cryptSignCert(req, keypair); WARN_AND_RETURN_IF(status); status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_INITIALIZATION); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CACERTIFICATE, cacert); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_REQUEST, req); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_USERNAME, uid, strlen(uid)); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_PASSWORD, ipwd, strlen(ipwd)); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1); WARN_AND_RETURN_IF(status); status = cryptGetAttribute(session, CRYPT_SESSINFO_RESPONSE, &cert); WARN_AND_RETURN_IF(status); status = export_cert(cert, crtfilename); WARN_AND_RETURN_IF(status); status = cryptAddPublicKey(privkeys, cert); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(privkeys); WARN_AND_RETURN_IF(status); status = cryptDestroySession(session); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cacert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(req); WARN_AND_RETURN_IF(status); status = cryptDestroyContext(keypair); return 0; }
static int device_read_db(sd_device *device) { _cleanup_free_ char *db = NULL; char *path; const char *id, *value; char key; size_t db_len; unsigned i; int r; enum { PRE_KEY, KEY, PRE_VALUE, VALUE, INVALID_LINE, } state = PRE_KEY; assert(device); if (device->db_loaded || device->sealed) return 0; r = device_get_id_filename(device, &id); if (r < 0) return r; path = strjoina("/run/udev/data/", id); r = read_full_file(path, &db, &db_len); if (r < 0) { if (r == -ENOENT) return 0; else return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path); } /* devices with a database entry are initialized */ device_set_is_initialized(device); for (i = 0; i < db_len; i++) { switch (state) { case PRE_KEY: if (!strchr(NEWLINE, db[i])) { key = db[i]; state = KEY; } break; case KEY: if (db[i] != ':') { log_debug("sd-device: ignoring invalid db entry with key '%c'", key); state = INVALID_LINE; } else { db[i] = '\0'; state = PRE_VALUE; } break; case PRE_VALUE: value = &db[i]; state = VALUE; break; case INVALID_LINE: if (strchr(NEWLINE, db[i])) state = PRE_KEY; break; case VALUE: if (strchr(NEWLINE, db[i])) { db[i] = '\0'; r = handle_db_line(device, key, value); if (r < 0) log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value); state = PRE_KEY; } break; default: assert_not_reached("invalid state when parsing db"); } } device->db_loaded = true; return 0; }
static int exec_cmpcli_revoke(int argc, char **argv) { CRYPT_SESSION session; CRYPT_CONTEXT privkey; CRYPT_KEYSET privkeys; CRYPT_CERTIFICATE cert, cacert, revreq; const char *cmd, *crtfilename, *cacrtfilename, *kpfilename; void *crtdata; int status, data_len; if (argc != 4) { fprintf(stderr, "cmpcli revoke argv!=4\n"); return 1; } cmd = argv[0]; crtfilename=argv[1]; cacrtfilename=argv[2]; kpfilename = argv[3]; if (strcmp(cmd, "revoke") != 0) { fprintf(stderr, "cmpcli knows revoke only\n"); return 1; } crtdata = read_full_file(crtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cert); WARN_AND_RETURN_IF(status); free(crtdata); crtdata = read_full_file(cacrtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cacert); WARN_AND_RETURN_IF(status); free(crtdata); status = cryptKeysetOpen(&privkeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, kpfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); status = cryptGetPrivateKey(privkeys, &privkey, CRYPT_KEYID_NAME, DEFAULT_PRIVKEY_LABEL, DEFAULT_PASSWORD); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(privkeys); WARN_AND_RETURN_IF(status); status = cryptCreateCert(&revreq, CRYPT_UNUSED, CRYPT_CERTTYPE_REQUEST_REVOCATION); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CERTIFICATE, cert); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CRLREASON, CRYPT_CRLREASON_AFFILIATIONCHANGED); WARN_AND_RETURN_IF(status); #if 0 status = cryptSignCert(revreq, privkey); WARN_AND_RETURN_IF(status); #endif status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_REVOCATION); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, privkey); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_REQUEST, revreq); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CACERTIFICATE, cacert); WARN_AND_RETURN_IF(status); #if 0 status = cryptSetAttributeString(session, CRYPT_SESSINFO_USERNAME, uid, strlen(uid)); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_PASSWORD, rpwd, strlen(rpwd)); WARN_AND_RETURN_IF(status); #endif status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1); if (!cryptStatusOK(status)) { CRYPT_ERRTYPE_TYPE errtype; CRYPT_ATTRIBUTE_TYPE locus; char *errstring; int errstringlen; cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "session errtype %d locus %d\n", errtype, locus); cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "revreq errtype %d locus %d\n", errtype, locus); cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "cert errtype %d locus %d\n", errtype, locus); cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "cacert errtype %d locus %d\n", errtype, locus); cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, NULL, &errstringlen); errstring = malloc(errstringlen + 10); cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, errstring, &errstringlen); errstring[errstringlen] = 0; fprintf(stderr, "session errmsg: %s\n", errstring); free(errstring); } WARN_AND_RETURN_IF(status); status = cryptDestroyContext(privkey); WARN_AND_RETURN_IF(status); status = cryptDestroySession(session); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cacert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(revreq); WARN_AND_RETURN_IF(status); return 0; }