static int really_install_package(const char *path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); ui_show_indeterminate_progress(); LOGI("Update location: %s\n", path); if (ensure_path_mounted(path) != 0) { LOGE("Can't mount %s\n", path); return INSTALL_CORRUPT; } ui_print("Opening update package...\n"); int err; if (signature_check_enabled) { int numKeys; RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); if (loadedKeys == NULL) { LOGE("Failed to load keys\n"); return INSTALL_CORRUPT; } LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); // Give verification half the progress bar... ui_print("Verifying update package...\n"); ui_show_progress( VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); err = verify_file(path, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); return INSTALL_CORRUPT; } } /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ ui_print("Installing update...\n"); return try_update_binary(path, &zip); }
extern "C" int TWinstall_zip(const char* path, int* wipe_cache) { int ret_val, zip_verify = 1, md5_return, key_count; twrpDigest md5sum; string strpath = path; ZipArchive Zip; if (strcmp(path, "error") == 0) { LOGERR("Failed to get adb sideload file: '%s'\n", path); return INSTALL_CORRUPT; } gui_print("Installing '%s'...\n", path); if (strlen(path) < 9 || strncmp(path, "/sideload", 9) != 0) { gui_print("Checking for MD5 file...\n"); md5sum.setfn(strpath); md5_return = md5sum.verify_md5digest(); if (md5_return == -2) { // md5 did not match LOGERR("Aborting zip install\n"); return INSTALL_CORRUPT; } } #ifndef TW_OEM_BUILD DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify); #endif DataManager::SetProgress(0); MemMapping map; if (sysMapFile(path, &map) != 0) { LOGERR("Failed to sysMapFile '%s'\n", path); return -1; } if (zip_verify) { gui_print("Verifying zip signature...\n"); ret_val = verify_file(map.addr, map.length); if (ret_val != VERIFY_SUCCESS) { LOGERR("Zip signature verification failed: %i\n", ret_val); sysReleaseMap(&map); return -1; } else { gui_print("Zip signature verified successfully.\n"); } } ret_val = mzOpenZipArchive(map.addr, map.length, &Zip); if (ret_val != 0) { LOGERR("Zip file is corrupt!\n", path); sysReleaseMap(&map); return INSTALL_CORRUPT; } ret_val = Run_Update_Binary(path, &Zip, wipe_cache); sysReleaseMap(&map); return ret_val; }
static int verify_test(void) { int ret = 0; ret = fprintf(stdout, "# Verify file %s in chunks\n", workfile); ret = verify_file(0, log.stream_log, NULL, workfile, file_size); return ret; }
/* try to insert the file into the hashmap download queue * returns 1 if no download is needed * returns 0 if download is needed * returns -1 if error */ static int swupd_curl_hashmap_insert(struct file *file) { struct list *iter; struct file *tmp; char *tar_dotfile; char *targetfile; struct stat stat; int hashmap_index = file->hash[0]; struct swupd_curl_hashbucket *bucket = &swupd_curl_hashmap[hashmap_index]; pthread_mutex_lock(&bucket->mutex); iter = bucket->list; while (iter) { tmp = iter->data; if (hash_equal(tmp->hash, file->hash)) { // hash already in download queue pthread_mutex_unlock(&bucket->mutex); return 1; } iter = iter->next; } // if valid target file is already here, no need to download string_or_die(&targetfile, "%s/staged/%s", state_dir, file->hash); if (lstat(targetfile, &stat) == 0) { if (verify_file(file, targetfile)) { free(targetfile); pthread_mutex_unlock(&bucket->mutex); return 1; } } free(targetfile); // hash not in queue and not present in staged // clean up in case any prior download failed in a partial state string_or_die(&tar_dotfile, "%s/download/.%s.tar", state_dir, file->hash); unlink(tar_dotfile); free(tar_dotfile); // queue the hash for download iter = bucket->list; if ((iter = list_prepend_data(iter, file)) == NULL) { pthread_mutex_unlock(&bucket->mutex); return -1; } bucket->list = iter; pthread_mutex_unlock(&bucket->mutex); return 0; }
int main(int argc, char *argv[]) { if (argc == 4 && strcmp(argv[1], "generate") == 0) { return generate_key(argv[2], argv[3]); } else if (argc == 5 && strcmp(argv[1], "sign") == 0) { return sign_file(argv[2], argv[3], argv[4]); } else if (argc == 4 && strcmp(argv[1], "verify") == 0) { return verify_file(argv[2], argv[3]); } else if (argc == 4 && strcmp(argv[1], "header") == 0) { return convert_public_key_to_header_file(argv[2], argv[3]); } else { return usage(argv[0]); } }
static int really_install_package(const char *path, int* wipe_cache) { ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); ui->Print("Finding update package...\n"); // Give verification half the progress bar... ui->SetProgressType(RecoveryUI::DETERMINATE); ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); LOGI("Update location: %s\n", path); if (ensure_path_mounted(path) != 0) { LOGE("Can't mount %s\n", path); return INSTALL_CORRUPT; } ui->Print("Opening update package...\n"); int numKeys; Certificate* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); if (loadedKeys == NULL) { LOGE("Failed to load keys\n"); return INSTALL_CORRUPT; } LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); ui->Print("Verifying update package...\n"); int err; err = verify_file(path, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); return INSTALL_CORRUPT; } /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ ui->Print("Installing update...\n"); return try_update_binary(path, &zip, wipe_cache); }
int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: %s <package>\n", argv[0]); return 2; } int result = verify_file(argv[1], &test_key, 1); if (result == VERIFY_SUCCESS) { printf("SUCCESS\n"); return 0; } else if (result == VERIFY_FAILURE) { printf("FAILURE\n"); return 1; } else { printf("bad return value\n"); return 3; } }
END_TEST START_TEST(test_protocol1_verify_file_gzip_read_failure) { struct asfd *asfd; struct cntr *cntr; struct sbuf *sb; const char *path="somepath"; const char *datapth="/datapth"; const char *endfile="0:0"; const char *best=BASE "/existent"; const char *plain_text="some plain text"; size_t s; struct fzp *fzp; s=strlen(plain_text); clean(); cntr=setup_cntr(); sb=setup_sbuf(path, datapth, endfile, 1/*compression*/); // Make a corrupt gzipped file. build_path_w(best); fail_unless((fzp=fzp_gzopen(best, "wb"))!=NULL); fail_unless(fzp_write(fzp, plain_text, s)==s); fail_unless(!fzp_close(&fzp)); fail_unless((fzp=fzp_open(best, "r+b"))!=NULL); fail_unless(!fzp_seek(fzp, 10, SEEK_SET)); fail_unless(fzp_write(fzp, "aa", 2)==2); fail_unless(!fzp_close(&fzp)); asfd=asfd_mock_setup(&areads, &awrites); setup_error_while_reading(asfd, best); // Returns 0 so that the parent process continues. fail_unless(!verify_file(asfd, sb, 0 /*patches*/, best, cntr)); fail_unless(cntr->ent[CMD_WARNING]->count==1); tear_down(&sb, &cntr, NULL, &asfd); }
BYTE *temp_filename(BYTE *path) { BYTE *fn; BYTE *fp; UWORD n; fn = (BYTE*) mem_alloc(256L); n = 0; do { fp = fn; if (path != NULL) { strcpy(fp, path); strcat(fp, "\\"); fp = &fn[strlen(fn)]; } else fn[0] = NULL; sprintf(fp, "TEMPFILE.%.03u", n); n = (n + 1) % 1000; } while (verify_file(fn)); return (fn); }
int main(int argc, char *argv[]){ /* Pass a filename which is a softlink (p1) or a long directory path (../../../../../../../../../../../etc/passwd) as argv[1] */ verify_file(argv[1]); }
static int process_data_dir_file(struct asfd *asfd, struct bu *bu, struct bu *b, const char *path, struct sbuf *sb, enum action act, struct sdirs *sdirs, struct conf **cconfs) { int ret=-1; int patches=0; char *dpath=NULL; struct stat dstatp; const char *tmp=NULL; const char *best=NULL; uint64_t bytes=0; static char *tmppath1=NULL; static char *tmppath2=NULL; struct cntr *cntr=NULL; if(cconfs) cntr=get_cntr(cconfs); if((!tmppath1 && !(tmppath1=prepend_s(sdirs->client, "tmp1"))) || (!tmppath2 && !(tmppath2=prepend_s(sdirs->client, "tmp2")))) goto end; best=path; tmp=tmppath1; // Now go down the list, applying any deltas. for(b=b->prev; b && b->next!=bu; b=b->prev) { free_w(&dpath); if(!(dpath=prepend_s(b->delta, sb->protocol1->datapth.buf))) goto end; if(lstat(dpath, &dstatp) || !S_ISREG(dstatp.st_mode)) continue; if(!patches) { // Need to gunzip the first one. if(inflate_or_link_oldfile(asfd, best, tmp, cconfs, sb->compression)) { char msg[256]=""; snprintf(msg, sizeof(msg), "error when inflating %s\n", best); log_and_send(asfd, msg); goto end; } best=tmp; if(tmp==tmppath1) tmp=tmppath2; else tmp=tmppath1; } if(do_patch(asfd, best, dpath, tmp, 0 /* do not gzip the result */, sb->compression /* from the manifest */, cconfs)) { char msg[256]=""; snprintf(msg, sizeof(msg), "error when patching %s\n", path); log_and_send(asfd, msg); goto end; } best=tmp; if(tmp==tmppath1) tmp=tmppath2; else tmp=tmppath1; unlink(tmp); patches++; } switch(act) { case ACTION_RESTORE: if(send_file(asfd, sb, patches, best, &bytes, cntr)) goto end; break; case ACTION_VERIFY: if(verify_file(asfd, sb, patches, best, &bytes, cntr)) goto end; break; default: logp("Unknown action: %d\n", act); goto end; } cntr_add(cntr, sb->path.cmd, 0); cntr_add_bytes(cntr, strtoull(sb->endfile.buf, NULL, 10)); cntr_add_sentbytes(cntr, bytes); ret=0; end: free_w(&dpath); return ret; }
int install_package(const char *root_path) { int err; ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); ui_show_indeterminate_progress(); LOGI("Update location: %s\n", root_path); if (ensure_root_path_mounted(root_path) != 0) { LOGE("Can't mount %s\n", root_path); return INSTALL_CORRUPT; } char path[PATH_MAX] = ""; if (translate_root_path(root_path, path, sizeof(path)) == NULL) { LOGE("Bad path %s\n", root_path); return INSTALL_CORRUPT; } ui_print("Opening update package...\n"); LOGI("Update file path: %s\n", path); if (signature_check_enabled) { int numKeys; RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); if (loadedKeys == NULL) { LOGE("Failed to load keys\n"); return INSTALL_CORRUPT; } LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); // Give verification half the progress bar... ui_print("Verifying update package...\n"); ui_show_progress( VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); err = verify_file(path, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); LOGE("may need to disable signature verification\n"); return INSTALL_CORRUPT; } } /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ int status = handle_update_package(path, &zip); mzCloseZipArchive(&zip); return status; }
int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "Usage: %s [-sha256] [-ec | -f4 | -file <keys>] <package>\n", argv[0]); return 2; } Certificate* certs = NULL; int num_keys = 0; int argn = 1; while (argn < argc) { if (strcmp(argv[argn], "-sha256") == 0) { if (num_keys == 0) { fprintf(stderr, "May only specify -sha256 after key type\n"); return 2; } ++argn; Certificate* cert = &certs[num_keys - 1]; cert->hash_len = SHA256_DIGEST_SIZE; } else if (strcmp(argv[argn], "-ec") == 0) { ++argn; Certificate* cert = add_certificate(&certs, &num_keys, Certificate::EC); cert->ec = &test_ec_key; } else if (strcmp(argv[argn], "-e3") == 0) { ++argn; Certificate* cert = add_certificate(&certs, &num_keys, Certificate::RSA); cert->rsa = &test_key; } else if (strcmp(argv[argn], "-f4") == 0) { ++argn; Certificate* cert = add_certificate(&certs, &num_keys, Certificate::RSA); cert->rsa = &test_f4_key; } else if (strcmp(argv[argn], "-file") == 0) { if (certs != NULL) { fprintf(stderr, "Cannot specify -file with other certs specified\n"); return 2; } ++argn; certs = load_keys(argv[argn], &num_keys); ++argn; } else if (argv[argn][0] == '-') { fprintf(stderr, "Unknown argument %s\n", argv[argn]); return 2; } else { break; } } if (argn == argc) { fprintf(stderr, "Must specify package to verify\n"); return 2; } if (num_keys == 0) { certs = (Certificate*) calloc(1, sizeof(Certificate)); if (certs == NULL) { fprintf(stderr, "Failure allocating memory for default certificate\n"); return 1; } certs->key_type = Certificate::RSA; certs->rsa = &test_key; certs->ec = NULL; certs->hash_len = SHA_DIGEST_SIZE; num_keys = 1; } ui = new FakeUI(); MemMapping map; if (sysMapFile(argv[argn], &map) != 0) { fprintf(stderr, "failed to mmap %s: %s\n", argv[argn], strerror(errno)); return 4; } int result = verify_file(map.addr, map.length, certs, num_keys); if (result == VERIFY_SUCCESS) { printf("VERIFIED\n"); return 0; } else if (result == VERIFY_FAILURE) { printf("NOT VERIFIED\n"); return 1; } else { printf("bad return value\n"); return 3; } }
int main(int argc, char** argv) { R_RSA_PUBLIC_KEY public_key; R_RSA_PRIVATE_KEY private_key; int i, n, retval; bool is_valid; DATA_BLOCK signature, in, out; unsigned char signature_buf[256], buf[256], buf2[256]; FILE *f, *fpriv, *fpub; char cbuf[256]; RSA rsa_key; RSA *rsa_key_; BIO *bio_out=NULL; BIO *bio_err=NULL; char *certpath; bool b2o=false; // boinc key to openssl key ? bool kpriv=false; // private key ? if (argc == 1) { usage(); exit(1); } if (!strcmp(argv[1], "-genkey")) { if (argc < 5) { usage(); exit(1); } printf("creating keys in %s and %s\n", argv[3], argv[4]); n = atoi(argv[2]); srand(random_int()); RSA* rp = RSA_generate_key(n, 65537, 0, 0); openssl_to_keys(rp, n, private_key, public_key); fpriv = fopen(argv[3], "w"); if (!fpriv) die("fopen"); fpub = fopen(argv[4], "w"); if (!fpub) die("fopen"); print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); } else if (!strcmp(argv[1], "-sign")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[3], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); signature.data = signature_buf; signature.len = 256; retval = sign_file(argv[2], private_key, signature); print_hex_data(stdout, signature); } else if (!strcmp(argv[1], "-sign_string")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[3], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); generate_signature(argv[2], cbuf, private_key); puts(cbuf); } else if (!strcmp(argv[1], "-verify")) { if (argc < 5) { usage(); exit(1); } fpub = fopen(argv[4], "r"); if (!fpub) die("fopen"); retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); if (retval) die("read_public_key"); f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); if (retval) die("scan_hex_data"); retval = verify_file(argv[2], public_key, signature, is_valid); if (retval) die("verify_file"); if (is_valid) { printf("file is valid\n"); } else { printf("file is invalid\n"); return 1; } } else if (!strcmp(argv[1], "-test_crypt")) { if (argc < 4) { usage(); exit(1); } fpriv = fopen(argv[2], "r"); if (!fpriv) die("fopen"); retval = scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); if (retval) die("scan_key_hex\n"); fpub = fopen(argv[3], "r"); if (!fpub) die("fopen"); retval = scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); if (retval) die("read_public_key"); strcpy((char*)buf2, "encryption test successful"); in.data = buf2; in.len = strlen((char*)in.data); out.data = buf; encrypt_private(private_key, in, out); in = out; out.data = buf2; decrypt_public(public_key, in, out); printf("out: %s\n", out.data); } else if (!strcmp(argv[1], "-cert_verify")) { if (argc < 6) die("usage: crypt_prog -cert_verify file signature_file certificate_dir ca_dir \n"); f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); if (retval) die("cannot scan_hex_data"); certpath = check_validity(argv[4], argv[2], signature.data, argv[5]); if (certpath == NULL) { die("signature cannot be verfied.\n\n"); } else { printf("siganture verified using certificate '%s'.\n\n", certpath); free(certpath); } // this converts, but an executable signed with sign_executable, // and signature converted to OpenSSL format cannot be verified with // OpenSSL } else if (!strcmp(argv[1], "-convsig")) { if (argc < 5) { usage(); exit(1); } if (strcmp(argv[2], "b2o") == 0) { b2o = true; } else if (strcmp(argv[2], "o2b") == 0) { b2o = false; } else { die("either 'o2b' or 'b2o' must be defined for -convsig\n"); } if (b2o) { f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_hex_data(f, signature); fclose(f); f = fopen(argv[4], "w+"); print_raw_data(f, signature); fclose(f); } else { f = fopen(argv[3], "r"); signature.data = signature_buf; signature.len = 256; retval = scan_raw_data(f, signature); fclose(f); f = fopen(argv[4], "w+"); print_hex_data(f, signature); fclose(f); } } else if (!strcmp(argv[1], "-convkey")) { if (argc < 6) { usage(); exit(1); } if (strcmp(argv[2], "b2o") == 0) { b2o = true; } else if (strcmp(argv[2], "o2b") == 0) { b2o = false; } else { die("either 'o2b' or 'b2o' must be defined for -convkey\n"); } if (strcmp(argv[3], "pub") == 0) { kpriv = false; } else if (strcmp(argv[3], "priv") == 0) { kpriv = true; } else { die("either 'pub' or 'priv' must be defined for -convkey\n"); } OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); ENGINE_load_builtin_engines(); if (bio_err == NULL) { bio_err = BIO_new_fp(stdout, BIO_NOCLOSE); } //enc=EVP_get_cipherbyname("des"); //if (enc == NULL) // die("could not get cypher.\n"); // no encription yet. bio_out=BIO_new(BIO_s_file()); if (BIO_write_filename(bio_out,argv[5]) <= 0) { perror(argv[5]); die("could not create output file.\n"); } if (b2o) { rsa_key_ = RSA_new(); if (kpriv) { fpriv = fopen(argv[4], "r"); if (!fpriv) { die("fopen"); } scan_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); fclose(fpriv); private_to_openssl(private_key, &rsa_key); //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key, // enc, NULL, 0, pass_cb, NULL); // no encryption yet. //i = PEM_write_bio_RSAPrivateKey(bio_out, &rsa_key, // NULL, NULL, 0, pass_cb, NULL); fpriv = fopen(argv[5], "w+"); PEM_write_RSAPrivateKey(fpriv, &rsa_key, NULL, NULL, 0, 0, NULL); fclose(fpriv); //if (i == 0) { // ERR_print_errors(bio_err); // die("could not write key file.\n"); //} } else { fpub = fopen(argv[4], "r"); if (!fpub) { die("fopen"); } scan_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); fclose(fpub); fpub = fopen(argv[5], "w+"); if (!fpub) { die("fopen"); } public_to_openssl(public_key, rsa_key_); i = PEM_write_RSA_PUBKEY(fpub, rsa_key_); if (i == 0) { ERR_print_errors(bio_err); die("could not write key file.\n"); } fclose(fpub); } } else { // o2b rsa_key_ = (RSA *)calloc(1, sizeof(RSA)); memset(rsa_key_, 0, sizeof(RSA)); if (rsa_key_ == NULL) { die("could not allocate memory for RSA structure.\n"); } if (kpriv) { fpriv = fopen (argv[4], "r"); rsa_key_ = PEM_read_RSAPrivateKey(fpriv, NULL, NULL, NULL); fclose(fpriv); if (rsa_key_ == NULL) { ERR_print_errors(bio_err); die("could not load private key.\n"); } openssl_to_private(rsa_key_, &private_key); fpriv = fopen(argv[5], "w"); if (!fpriv) { die("fopen"); } print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); } else { fpub = fopen (argv[4], "r"); rsa_key_ = PEM_read_RSA_PUBKEY(fpub, NULL, NULL, NULL); fclose(fpub); if (rsa_key_ == NULL) { ERR_print_errors(bio_err); die("could not load public key.\n"); } openssl_to_keys(rsa_key_, 1024, private_key, public_key); //openssl_to_public(rsa_key_, &public_key); public_to_openssl(public_key, rsa_key_); // fpub = fopen(argv[5], "w"); if (!fpub) { die("fopen"); } print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); } } } else { usage(); exit(1); } return 0; }
int write_string_file_ts( const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) { _cleanup_fclose_ FILE *f = NULL; int q, r; assert(fn); assert(line); /* We don't know how to verify whether the file contents was already on-disk. */ assert(!((flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE) && (flags & WRITE_STRING_FILE_SYNC))); if (flags & WRITE_STRING_FILE_ATOMIC) { assert(flags & WRITE_STRING_FILE_CREATE); r = write_string_file_atomic(fn, line, flags, ts); if (r < 0) goto fail; return r; } else assert(!ts); if (flags & WRITE_STRING_FILE_CREATE) { f = fopen(fn, "we"); if (!f) { r = -errno; goto fail; } } else { int fd; /* We manually build our own version of fopen(..., "we") that * works without O_CREAT */ fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) { r = -errno; goto fail; } f = fdopen(fd, "we"); if (!f) { r = -errno; safe_close(fd); goto fail; } } (void) __fsetlocking(f, FSETLOCKING_BYCALLER); if (flags & WRITE_STRING_FILE_DISABLE_BUFFER) setvbuf(f, NULL, _IONBF, 0); r = write_string_stream_ts(f, line, flags, ts); if (r < 0) goto fail; return 0; fail: if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE)) return r; f = safe_fclose(f); /* OK, the operation failed, but let's see if the right * contents in place already. If so, eat up the error. */ q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); if (q <= 0) return r; return 0; }
/* This function will break if the same HASH.tar full file is downloaded * multiple times in parallel. */ int untar_full_download(void *data) { struct file *file = data; char *tarfile; char *tar_dotfile; char *targetfile; struct stat stat; int err; char *tarcommand; string_or_die(&tar_dotfile, "%s/download/.%s.tar", state_dir, file->hash); string_or_die(&tarfile, "%s/download/%s.tar", state_dir, file->hash); string_or_die(&targetfile, "%s/staged/%s", state_dir, file->hash); /* If valid target file already exists, we're done. * NOTE: this should NEVER happen given the checking that happens * ahead of queueing a download. But... */ if (lstat(targetfile, &stat) == 0) { if (verify_file(file, targetfile)) { unlink(tar_dotfile); unlink(tarfile); free(tar_dotfile); free(tarfile); free(targetfile); return 0; } else { unlink(tarfile); unlink(targetfile); } } else if (lstat(tarfile, &stat) == 0) { /* remove tar file from possible past failure */ unlink(tarfile); } err = rename(tar_dotfile, tarfile); if (err) { free(tar_dotfile); goto exit; } free(tar_dotfile); err = check_tarfile_content(file, tarfile); if (err) { goto exit; } /* modern tar will automatically determine the compression type used */ string_or_die(&tarcommand, TAR_COMMAND " -C %s/staged/ " TAR_PERM_ATTR_ARGS " -xf %s 2> /dev/null", state_dir, tarfile); err = system(tarcommand); if (WIFEXITED(err)) { err = WEXITSTATUS(err); } free(tarcommand); if (err) { printf("ignoring tar extract failure for fullfile %s.tar (ret %d)\n", file->hash, err); goto exit; /* FIXME: can we respond meaningfully to tar error codes? * symlink untars may have perm/xattr complaints and non-zero * tar return, but symlink (probably?) untarred ok. * * Also getting complaints on some new regular files? * * Either way we verify the hash later, so on error there, * something could try to recover? */ } else { /* Only unlink when tar succeeded, so we can examine the tar file * in the failure case. */ unlink(tarfile); } err = lstat(targetfile, &stat); if (!err && !verify_file(file, targetfile)) { /* Download was successful but the hash was bad. This is fatal*/ printf("Error: File content hash mismatch for %s (bad server data?)\n", targetfile); exit(EXIT_FAILURE); } exit: free(tarfile); free(targetfile); if (err) { unlink_all_staged_content(file); } return err; }
static int really_install_package(const char *path, int* wipe_cache) { ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); #if 0 //wschen 2012-07-10 ui->Print("Finding update package...\n"); #else LOGI("Finding update package...\n"); #endif ui->SetProgressType(RecoveryUI::INDETERMINATE); LOGI("Update location: %s\n", path); if (ensure_path_mounted(path) != 0) { LOGE("Can't mount %s\n", path); #if 0 //wschen 2012-07-10 return INSTALL_CORRUPT; #else reset_mark_block(); return INSTALL_NO_SDCARD; #endif } #if 0 //wschen 2012-07-10 ui->Print("Opening update package...\n"); #else LOGI("Opening update package...\n"); #endif int numKeys; RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); if (loadedKeys == NULL) { LOGE("Failed to load keys\n"); #if 0 //wschen 2012-07-10 return INSTALL_CORRUPT; #else reset_mark_block(); return INSTALL_NO_KEY; #endif } LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); // Give verification half the progress bar... #if 0 //wschen 2012-07-10 ui->Print("Verifying update package...\n"); #else LOGI("Verifying update package...\n"); #endif ui->SetProgressType(RecoveryUI::DETERMINATE); ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); int err; err = verify_file(path, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); #if 0 //wschen 2012-07-10 return INSTALL_CORRUPT; #else reset_mark_block(); return INSTALL_SIGNATURE_ERROR; #endif } /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); #if 1 //wschen 2012-07-10 reset_mark_block(); #endif return INSTALL_CORRUPT; } /* ----------------------------- */ /* SECURE BOOT CHECK */ /* ----------------------------- */ #ifdef SUPPORT_SBOOT_UPDATE if(0 != (err=sec_verify_img_info(&zip,false))) { return INSTALL_SECURE_CHECK_FAIL; } sec_mark_status(false); #endif #ifdef SUPPORT_DATA_BACKUP_RESTORE //wschen 2011-03-09 if (check_part_size(&zip) != 0) { reset_mark_block(); return INSTALL_ERROR; } #endif //SUPPORT_DATA_BACKUP_RESTORE /* Verify and install the contents of the package. */ ui->Print("Installing update...\n"); return try_update_binary(path, &zip, wipe_cache); }
static int really_install_package(const char *path, bool* wipe_cache, bool needs_mount) { ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); ui->Print("Finding update package...\n"); // Give verification half the progress bar... ui->SetProgressType(RecoveryUI::DETERMINATE); ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); LOGI("Update location: %s\n", path); // Map the update package into memory. ui->Print("Opening update package...\n"); if (path && needs_mount) { if (path[0] == '@') { ensure_path_mounted(path+1); } else { ensure_path_mounted(path); } } MemMapping map; if (sysMapFile(path, &map) != 0) { LOGE("failed to map file\n"); return INSTALL_CORRUPT; } int numKeys; Certificate* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); if (loadedKeys == NULL) { LOGE("Failed to load keys\n"); return INSTALL_CORRUPT; } LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); ui->Print("Verifying update package...\n"); int err; err = verify_file(map.addr, map.length, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); sysReleaseMap(&map); return INSTALL_CORRUPT; } /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(map.addr, map.length, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); sysReleaseMap(&map); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ ui->Print("Installing update...\n"); ui->SetEnableReboot(false); int result = try_update_binary(path, &zip, wipe_cache); ui->SetEnableReboot(true); ui->Print("\n"); sysReleaseMap(&map); return result; }
static int one_round_run(int round_no) { int ret = 0, fd = -1, j; unsigned long i, chunk_no = 0; struct write_unit wu; MPI_Request request; MPI_Status status; /* * Root rank creates working file in chunks. */ if (!rank) { rank_printf("Prepare file of %lu bytes\n", file_size); open_rw_flags |= O_DIRECT; open_ro_flags |= O_DIRECT; ret = prep_orig_file_in_chunks(workfile, file_size); should_exit(ret); } MPI_Barrier_Sync(); if (!rank) { fd = open_file(workfile, open_rw_flags); should_exit(fd); } else { /* * Verification at the very beginning doesn't do anything more * than reading the file into pagecache on none-root nodes. */ open_rw_flags &= ~O_DIRECT; open_ro_flags &= ~O_DIRECT; ret = verify_file(1, NULL, remote_wus, workfile, file_size); should_exit(fd); } MPI_Barrier_Sync(); /* * Root ranks write chunks at random serially. */ for (i = 0; i < num_chunks; i++) { MPI_Barrier_Sync(); /* * Root rank generates random write unit, then sends it to * rest of ranks in-memoery after O_DIRECT write into file. */ if (!rank) { chunk_no = get_rand_ul(0, num_chunks - 1); prep_rand_dest_write_unit(&wu, chunk_no); rank_printf("Write #%lu chunk with char(%c)\n", chunk_no, wu.wu_char); ret = do_write_chunk(fd, wu); should_exit(ret); memcpy(&remote_wus[wu.wu_chunk_no], &wu, sizeof(wu)); for (j = 1; j < size; j++) { if (verbose) rank_printf("Send write unit #%lu chunk " "char(%c) to rank %d\n", wu.wu_chunk_no, wu.wu_char, j); ret = MPI_Isend(&wu, sizeof(wu), MPI_BYTE, j, 1, MPI_COMM_WORLD, &request); if (ret != MPI_SUCCESS) abort_printf("MPI_Isend failed: %d\n", ret); MPI_Wait(&request, &status); } } else { MPI_Irecv(&wu, sizeof(wu), MPI_BYTE, 0, 1, MPI_COMM_WORLD, &request); MPI_Wait(&request, &status); if (verbose) rank_printf("Receive write unit #%lu chunk " "char(%c)\n", wu.wu_chunk_no, wu.wu_char); if (wu.wu_timestamp >= remote_wus[wu.wu_chunk_no].wu_timestamp) memcpy(&remote_wus[wu.wu_chunk_no], &wu, sizeof(wu)); } MPI_Barrier_Sync(); if (rank) { /* * All none-root ranks need to verify if O_DIRECT writes * from remote root node can be seen locally. */ rank_printf("Try to verify whole file in chunks.\n"); ret = verify_file(1, NULL, remote_wus, workfile, file_size); should_exit(ret); } } MPI_Barrier_Sync(); if (!rank) if (fd > 0) close(fd); return ret; }
int main(int argc, char **argv) { xmlSecKeysMngrPtr mngr; assert(argv); if(argc < 3) { fprintf(stderr, "Error: wrong number of arguments.\n"); fprintf(stderr, "Usage: %s <xml-file> <key-file1> [<key-file2> [...]]\n", argv[0]); return(1); } /* Init libxml and libxslt libraries */ xmlInitParser(); LIBXML_TEST_VERSION xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; xmlSubstituteEntitiesDefault(1); #ifndef XMLSEC_NO_XSLT xmlIndentTreeOutput = 1; #endif /* XMLSEC_NO_XSLT */ /* Init xmlsec library */ if(xmlSecInit() < 0) { fprintf(stderr, "Error: xmlsec initialization failed.\n"); return(-1); } /* Check loaded library version */ if(xmlSecCheckVersion() != 1) { fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n"); return(-1); } /* Load default crypto engine if we are supporting dynamic * loading for xmlsec-crypto libraries. Use the crypto library * name ("openssl", "nss", etc.) to load corresponding * xmlsec-crypto library. */ #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) { fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n" "that you have it installed and check shared libraries path\n" "(LD_LIBRARY_PATH) envornment variable.\n"); return(-1); } #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ /* Init crypto library */ if(xmlSecCryptoAppInit(NULL) < 0) { fprintf(stderr, "Error: crypto initialization failed.\n"); return(-1); } /* Init xmlsec-crypto library */ if(xmlSecCryptoInit() < 0) { fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n"); return(-1); } /* create keys manager and load keys */ mngr = load_keys(&(argv[2]), argc - 2); if(mngr == NULL) { return(-1); } /* verify file */ if(verify_file(mngr, argv[1]) < 0) { xmlSecKeysMngrDestroy(mngr); return(-1); } /* destroy keys manager */ xmlSecKeysMngrDestroy(mngr); /* Shutdown xmlsec-crypto library */ xmlSecCryptoShutdown(); /* Shutdown crypto library */ xmlSecCryptoAppShutdown(); /* Shutdown xmlsec library */ xmlSecShutdown(); /* Shutdown libxslt/libxml */ #ifndef XMLSEC_NO_XSLT xsltCleanupGlobals(); #endif /* XMLSEC_NO_XSLT */ xmlCleanupParser(); return(0); }
/* * verify that the recycler_cfg_t is valid */ int verify_recycler_cfg( const recycler_cfg_t *cfg) /* cfg to verify */ { node_t *node; sqm_lst_t *libs = NULL; Trace(TR_OPRMSG, "verifying recycler cfg"); if (ISNULL(cfg)) { Trace(TR_OPRMSG, "verifying recycler cfg failed: %s", samerrmsg); return (-1); } if (get_all_libraries(NULL, &libs) == -1) { /* * don't return, let the checking try to pass * it could still pass if there are no robot directives. */ libs = NULL; } if (*cfg->recycler_log != char_array_reset && cfg->change_flag & RC_recycler_log) { if (verify_file(cfg->recycler_log, B_TRUE) == B_FALSE) { samerrno = SE_LOGFILE_CANNOT_BE_CREATED; free_list_of_libraries(libs); /* Logfile %s can not be created */ snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(SE_LOGFILE_CANNOT_BE_CREATED), cfg->recycler_log); Trace(TR_OPRMSG, "verifying recycler cfg failed: %s", samerrmsg); return (-1); } } if (*cfg->script != char_array_reset && cfg->change_flag & RC_script) { if (verify_file(cfg->script, B_FALSE) == B_FALSE) { free_list_of_libraries(libs); samerrno = SE_SCRIPT_DOES_NOT_EXIST; /* Script %s does not exist. */ snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(SE_SCRIPT_DOES_NOT_EXIST), cfg->script); Trace(TR_OPRMSG, "verifying recycler cfg failed: %s", samerrmsg); return (-1); } } for (node = cfg->no_recycle_vsns->head; node != NULL; node = node->next) { if (verify_no_rc_vsns((no_rc_vsns_t *)node->data) != 0) { free_list_of_libraries(libs); /* leave samerrmsg as set */ Trace(TR_OPRMSG, "verifying recycler cfg failed: %s", samerrmsg); return (-1); } } for (node = cfg->rc_robot_list->head; node != NULL; node = node->next) { if (verify_rc_robot_cfg((rc_robot_cfg_t *)node->data, libs) != 0) { free_list_of_libraries(libs); Trace(TR_OPRMSG, "verifying recycler cfg failed: %s", samerrmsg); /* leave samerrmsg as set */ return (-1); } } free_list_of_libraries(libs); Trace(TR_OPRMSG, "verified recycler cfg"); return (0); }
static int sigexec_kld_check_load(struct ucred *cred, struct vnode *vp, struct label *vplabel) { return (verify_file(cred, vp)); }
int header (int argc, char **argv) { if (verify_file (argv[1]) == 1) { return 1; } FILE *stream = fopen (argv[1], "r"); struct mho_header header = mho_read_header (stream); printf ("%s: 0x%x (", _("Magic number"), header.magic); if (mho_is_magic (header.magic)) { if (mho_magic_64 (header.magic)) { printf ("64-bit, "); } else if (mho_magic_fat (header.magic)) { printf ("%s, ", _("universal")); } else { printf ("32-bit, "); } if (mho_magic_littleendian (header.magic)) { if (mho_host_littleendian ()) { printf ("%s", _("little endian")); } else printf ("%s", _("big endian")); } else { if (mho_host_littleendian ()) { printf ("%s", _("big endian")); } else printf ("%s", _("little endian")); } } else { printf (_("invalid")); } if (mho_magic_littleendian (header.magic)) { if (mho_host_bigendian ()) { mho_endian_little = !mho_endian_little; } } else { if (mho_host_littleendian ()) { mho_endian_little = !mho_endian_little; } } printf (")\n"); if (mho_magic_fat (header.magic)) { fseek (stream, -sizeof (struct mho_header), SEEK_CUR); struct mho_fat_header fhdr = mho_read_fhdr (stream); printf ("%s: %u\n", _("Architecture count"), fhdr.nfat_arch); for (uint32_t i = 0; i < fhdr.nfat_arch; i++) { struct mho_fat_arch arch = mho_read_farch (stream); printf ("%s %u:\n", _("Architecture"), i + 1); printf ("\t%s: 0x%x (%s)\n", _("CPU type"), arch.cputype, mho_ct2s (arch.cputype)); printf ("\t%s: 0x%x (%s)\n", _("CPU subtype"), arch.cpusubtype & MHO_CPU_SUBTYPE_MASK, mho_cst2s (arch.cputype, arch.cpusubtype & MHO_CPU_SUBTYPE_MASK)); printf ("\t%s: %u\n", _("Offset"), arch.offset); printf ("\t%s: %u\n", _("Size"), arch.size); printf ("\t%s: %u\n", _("Alignment"), arch.alignment); } return 0; } else { printf ("%s: 0x%x (%s)\n", _("CPU type"), header.cputype, mho_ct2s (header.cputype)); printf ("%s: 0x%x (%s)\n", _("CPU subtype"), header.cpusubtype & MHO_CPU_SUBTYPE_MASK, mho_cst2s (header.cputype, header.cpusubtype & MHO_CPU_SUBTYPE_MASK)); } printf ("%s: %hd (%s)\n", _("File type"), (short) header.filetype, mho_ft2s ((short) header.filetype)); printf ("%s: %d\n", _("Commands count"), header.ncmds); printf ("%s: %d\n", _("Commands sumaric size"), header.sizeofcmds); printf ("%s:", _("Flags")); #define __flag__(x) do { \ if(header.flags & MHO_FLAG_##x) { \ printf(" MH_" #x); \ } \ } while(0) __flag__ (NOUNDEFS); __flag__ (INCRLINK); __flag__ (DYLDLINK); __flag__ (BINDATLOAD); __flag__ (PREBOUND); __flag__ (SPLIT_SEGS); __flag__ (LAZY_INIT); __flag__ (TWOLEVEL); __flag__ (FORCE_FLAT); __flag__ (NOMULTIDEFS); __flag__ (NOFIXPREBINDING); __flag__ (PREBINDABLE); __flag__ (ALLMODSBOUND); __flag__ (SUBSECTIONS_VIA_SYMBOLS); __flag__ (CANONICAL); __flag__ (WEAK_DEFINES); __flag__ (BINDS_TO_WEAK); __flag__ (ALLOW_STACK_EXECUTION); __flag__ (ROOT_SAFE); __flag__ (SETUID_SAFE); __flag__ (NO_REEXPORTED_DYLIBS); __flag__ (PIE); __flag__ (DEAD_STRIPPABLE_DYLIB); #undef __flag__ printf ("\n"); if (mho_magic_64 (header.magic)) { struct mho_header_64 *hdr64 = (struct mho_header_64 *) &header; printf ("%s: 0x%x\n", _("Reserved (no purpose)"), hdr64->reserved); } fclose (stream); return 0; }
/* This function is meant to be called while staging file to fix any missing/incorrect paths. * While staging a file, if its parent directory is missing, this would try to create the path * by breaking it into sub-paths and fixing them top down. * Here, target_MoM is the consolidated manifest for the version you are trying to update/verify. */ int verify_fix_path(char *targetpath, struct manifest *target_MoM) { struct list *path_list = NULL; /* path_list contains the subparts in the path */ char *path; char *tmp = NULL, *target = NULL; char *url = NULL; struct stat sb; int ret = 0; struct file *file; char *tar_dotfile = NULL; struct list *list1 = NULL; /* This shouldn't happen */ if (strcmp(targetpath, "/") == 0) { return ret; } /* Removing trailing '/' from the path */ path = strdup(targetpath); if (path[strlen(path) - 1] == '/') { path[strlen(path) - 1] = '\0'; } /* Breaking down the path into parts. * eg. Path /usr/bin/foo will be broken into /usr,/usr/bin and /usr/bin/foo */ while (strcmp(path, "/") != 0) { path_list = list_prepend_data(path_list, strdup(path)); tmp = strdup(dirname(path)); free(path); path = tmp; } free(path); list1 = list_head(path_list); while (list1) { path = list1->data; list1 = list1->next; target = mk_full_filename(path_prefix, path); /* Search for the file in the manifest, to get the hash for the file */ file = search_file_in_manifest(target_MoM, path); if (file == NULL) { printf("Error: Path %s not found in any of the subscribed manifests" "in verify_fix_path for path_prefix %s\n", path, path_prefix); ret = -1; goto end; } if (file->is_deleted) { printf("Error: Path %s found deleted in verify_fix_path\n", path); ret = -1; goto end; } ret = stat(target, &sb); if (ret == 0) { if (verify_file(file, target)) { continue; } printf("Hash did not match for path : %s\n", path); } else if (ret == -1 && errno == ENOENT) { printf("Path %s is missing on the file system\n", path); } else { goto end; } string_or_die(&tar_dotfile, "%s/download/.%s.tar", state_dir, file->hash); // clean up in case any prior download failed in a partial state unlink(tar_dotfile); string_or_die(&url, "%s/%i/files/%s.tar", content_url, file->last_change, file->hash); ret = swupd_curl_get_file(url, tar_dotfile, NULL, NULL, false); if (ret != 0) { printf("Error: Failed to download file %s in verify_fix_path\n", file->filename); unlink(tar_dotfile); goto end; } if (untar_full_download(file) != 0) { printf("Error: Failed to untar file %s\n", file->filename); ret = -1; goto end; } ret = do_staging(file, target_MoM); if (ret != 0) { printf("Error: Path %s failed to stage in verify_fix_path\n", path); goto end; } } end: if (target) { free(target); } if (tar_dotfile) { free(tar_dotfile); } if (url) { free(url); } list_free_list_and_data(path_list, free_path_data); return ret; }
int verify_options (struct silo_options *o) { int rc = 0; int dev = 0; int crc = 0; if (!o->ipldevice || !o->image || !o->bootsect) { if (!o->ipldevice) fprintf(stderr,"ipldevice\n"); if (!o->image) fprintf(stderr,"image\n"); if (!o->bootsect) fprintf(stderr,"bootsect\n"); usage (); exit (1); } PRINT_LEVEL (1, "Testlevel is set to %d\n",o->testlevel); PRINT_LEVEL (1, "IPL device is: '%s'", o->ipldevice); ITRY (dev = verify_device (o->ipldevice)); PRINT_LEVEL (2, "...ok...(%d/%d)", (unsigned short) MAJOR (dev), (unsigned short) MINOR (dev)); PRINT_LEVEL (1, "\n"); PRINT_LEVEL (0, "bootsector is: '%s'", o->bootsect); ITRY (verify_file (o->bootsect, dev)); PRINT_LEVEL (1, "...ok..."); PRINT_LEVEL (0, "\n"); if ( o -> testlevel > 0 && ! strncmp( o->bootmap, SILO_BOOTMAP,strlen(SILO_BOOTMAP) )) { NTRY( o -> bootmap = tempnam(NULL,"boot.")); } PRINT_LEVEL (0, "bootmap is set to: '%s'", o->bootmap); if ( access ( o->bootmap, O_RDWR ) == -1 ) { if ( errno == ENOENT ) { ITRY (creat ( o-> bootmap, O_RDWR )); } else { PRINT_LEVEL(1,"Cannot acces bootmap file '%s': %s\n",o->bootmap, strerror(errno)); } } ITRY (verify_file (o->bootmap, dev)); PRINT_LEVEL (1, "...ok..."); PRINT_LEVEL (0, "\n"); PRINT_LEVEL (0, "Kernel image is: '%s'", o->image); ITRY (verify_file (o->image, dev)); PRINT_LEVEL (1, "...ok..."); PRINT_LEVEL (0, "\n"); PRINT_LEVEL (0, "original parameterfile is: '%s'", o->parmfile); ITRY (verify_file (o->parmfile, dev)); PRINT_LEVEL (1, "...ok..."); o->parmfile = gen_tmpparm(o->parmfile); PRINT_LEVEL (0, "final parameterfile is: '%s'", o->parmfile); ITRY (verify_file (o->parmfile, dev)); PRINT_LEVEL (1, "...ok..."); PRINT_LEVEL (0, "\n"); if (o->ramdisk) { PRINT_LEVEL (0, "initialramdisk is: '%s'", o->ramdisk); ITRY (verify_file (o->ramdisk, dev)); PRINT_LEVEL (1, "...ok..."); PRINT_LEVEL (0, "\n"); } return crc; }
/* This function is meant to be called while staging file to fix any missing/incorrect paths. * While staging a file, if its parent directory is missing, this would try to create the path * by breaking it into sub-paths and fixing them top down. * Here, target_MoM is the consolidated manifest for the version you are trying to update/verify. */ int verify_fix_path(char *targetpath, struct manifest *target_MoM) { struct list *path_list = NULL; /* path_list contains the subparts in the path */ char *path; char *tmp = NULL, *target = NULL; char *url = NULL; struct stat sb; int ret = 0; struct file *file; char *tar_dotfile = NULL; struct list *list1 = NULL; /* This shouldn't happen */ if (strcmp(targetpath, "/") == 0) { return ret; } /* Removing trailing '/' from the path */ path = strdup_or_die(targetpath); if (path[strlen(path) - 1] == '/') { path[strlen(path) - 1] = '\0'; } /* Breaking down the path into parts. * eg. Path /usr/bin/foo will be broken into /usr,/usr/bin and /usr/bin/foo */ while (strcmp(path, "/") != 0) { path_list = list_prepend_data(path_list, strdup_or_die(path)); tmp = strdup_or_die(dirname(path)); free_string(&path); path = tmp; } free_string(&path); list1 = list_head(path_list); while (list1) { path = list1->data; list1 = list1->next; free_string(&target); free_string(&tar_dotfile); free_string(&url); target = mk_full_filename(path_prefix, path); /* Search for the file in the manifest, to get the hash for the file */ file = search_file_in_manifest(target_MoM, path); if (file == NULL) { fprintf(stderr, "Error: Path %s not found in any of the subscribed manifests" "in verify_fix_path for path_prefix %s\n", path, path_prefix); ret = -1; goto end; } if (file->is_deleted) { fprintf(stderr, "Error: Path %s found deleted in verify_fix_path\n", path); ret = -1; goto end; } ret = stat(target, &sb); if (ret == 0) { if (verify_file(file, target)) { continue; } fprintf(stderr, "Hash did not match for path : %s ... fixing\n", path); } else if (ret == -1 && errno == ENOENT) { fprintf(stderr, "Path %s is missing on the file system ... fixing\n", path); } else { goto end; } /* In some circumstances (Docker using layers between updates/bundle adds, * corrupt staging content) we could have content which fails to stage. * In order to avoid this causing failure in verify_fix_path, remove the * staging content before proceeding. This also cleans up in case any prior * download failed in a partial state. */ unlink_all_staged_content(file); string_or_die(&tar_dotfile, "%s/download/.%s.tar", state_dir, file->hash); string_or_die(&url, "%s/%i/files/%s.tar", content_url, file->last_change, file->hash); ret = swupd_curl_get_file(url, tar_dotfile); if (ret != 0) { fprintf(stderr, "Error: Failed to download file %s in verify_fix_path\n", file->filename); unlink(tar_dotfile); goto end; } if (untar_full_download(file) != 0) { fprintf(stderr, "Error: Failed to untar file %s\n", file->filename); ret = -1; goto end; } ret = do_staging(file, target_MoM); if (ret != 0) { fprintf(stderr, "Error: Path %s failed to stage in verify_fix_path\n", path); goto end; } } end: free_string(&target); free_string(&tar_dotfile); free_string(&url); list_free_list_and_data(path_list, free_path_data); return ret; }
/* Compares the hash for BUNDLE with that listed in the Manifest.MoM. If the * hash check fails, we should assume the bundle manifest is incorrect and * discard it. A retry should then force redownloading of the bundle manifest. */ int verify_bundle_hash(struct manifest *manifest, struct file *bundle) { struct list *iter = list_head(manifest->manifests); struct file *current; char *local = NULL; int ret = 0; while (iter) { struct stat sb; current = iter->data; iter = iter->next; if (strcmp(current->filename, bundle->filename) != 0) { continue; } string_or_die(&local, "%s/%i/Manifest.%s", state_dir, current->last_change, current->filename); if (stat(local, &sb) != 0) { /* missing bundle manifest - attempt to download it */ char *filename; char *url; char *tar; printf("Warning: Downloading missing manifest for bundle %s version %d.\n", current->filename, current->last_change); string_or_die(&filename, "%s/%i/Manifest.%s", state_dir, current->last_change, current->filename); string_or_die(&url, "%s/%i/Manifest.%s.tar", content_url, current->last_change, current->filename); ret = swupd_curl_get_file(url, filename, NULL, NULL, false); free(url); if (ret != 0) { printf("Error: download of %s failed\n", filename); unlink(filename); free(filename); break; } free(filename); string_or_die(&tar, TAR_COMMAND " -C %s/%i -xf %s/%i/Manifest.%s.tar 2> /dev/null", state_dir, current->last_change, state_dir, current->last_change, current->filename); ret = system(tar); free(tar); if (WIFEXITED(ret)) { ret = WEXITSTATUS(ret); } if (ret != 0) { break; } } if (!verify_file(bundle, local)) { printf("Warning: hash check failed for Manifest.%s for version %i. Deleting it.\n", current->filename, manifest->version); unlink(local); ret = 1; } break; } free(local); return ret; }
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) { _cleanup_fclose_ FILE *f = NULL; int q, r; assert(fn); assert(line); if (flags & WRITE_STRING_FILE_ATOMIC) { assert(flags & WRITE_STRING_FILE_CREATE); r = write_string_file_atomic(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); if (r < 0) goto fail; return r; } if (flags & WRITE_STRING_FILE_CREATE) { f = fopen(fn, "we"); if (!f) { r = -errno; goto fail; } } else { int fd; /* We manually build our own version of fopen(..., "we") that * works without O_CREAT */ fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) { r = -errno; goto fail; } f = fdopen(fd, "we"); if (!f) { r = -errno; safe_close(fd); goto fail; } } r = write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); if (r < 0) goto fail; return 0; fail: if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE)) return r; f = safe_fclose(f); /* OK, the operation failed, but let's see if the right * contents in place already. If so, eat up the error. */ q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); if (q <= 0) return r; return 0; }
KMF_RETURN genkeypair_file(KMF_HANDLE_T kmfhandle, KMF_KEY_ALG keyAlg, int keylen, KMF_ENCODE_FORMAT fmt, char *outkey, KMF_KEY_HANDLE *outPriKey, KMF_KEY_HANDLE *outPubKey) { KMF_RETURN kmfrv; KMF_KEY_HANDLE pubk, prik; char *fullkeypath = NULL; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; KMF_ATTRIBUTE attrlist[10]; int numattr = 0; KMF_KEY_ALG keytype; uint32_t keylength; KMF_ENCODE_FORMAT format; if (EMPTYSTRING(outkey)) { cryptoerror(LOG_STDERR, gettext("No output file was specified for " "the key\n")); return (PK_ERR_USAGE); } fullkeypath = strdup(outkey); if (verify_file(fullkeypath)) { cryptoerror(LOG_STDERR, gettext("Cannot write the indicated output " "key file (%s).\n"), fullkeypath); free(fullkeypath); return (PK_ERR_USAGE); } keylength = keylen; /* bits */ keytype = keyAlg; format = fmt; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, &keytype, sizeof (keytype)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength)); numattr++; if (fullkeypath != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, fullkeypath, strlen(fullkeypath)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE)); numattr++; kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); if (kmfrv != KMF_OK) { goto cleanup; } cleanup: if (fullkeypath != NULL) free(fullkeypath); if (kmfrv == KMF_OK) { if (outPriKey != NULL) *outPriKey = prik; if (outPubKey != NULL) *outPubKey = pubk; } return (kmfrv); }
// a = length of struct bu array // i = position to restore from static int restore_file(struct bu *arr, int a, int i, const char *datapth, const char *fname, const char *tmppath1, const char *tmppath2, int act, const char *endfile, char cmd, int64_t winattr, int compression, struct cntr *cntr, struct config *cconf) { int x=0; char msg[256]=""; // Go up the array until we find the file in the data directory. for(x=i; x<a; x++) { char *path=NULL; struct stat statp; if(!(path=prepend_s(arr[x].data, datapth, strlen(datapth)))) { log_and_send_oom(__FUNCTION__); return -1; } //logp("server file: %s\n", path); if(lstat(path, &statp) || !S_ISREG(statp.st_mode)) { free(path); continue; } else { int patches=0; struct stat dstatp; const char *tmp=NULL; const char *best=NULL; unsigned long long bytes=0; best=path; tmp=tmppath1; // Now go down the array, applying any deltas. for(x-=1; x>=i; x--) { char *dpath=NULL; if(!(dpath=prepend_s(arr[x].delta, datapth, strlen(datapth)))) { log_and_send_oom(__FUNCTION__); free(path); return -1; } if(lstat(dpath, &dstatp) || !S_ISREG(dstatp.st_mode)) { free(dpath); continue; } if(!patches) { // Need to gunzip the first one. if(inflate_or_link_oldfile(best, tmp, compression)) { logp("error when inflating %s\n", best); free(path); free(dpath); return -1; } best=tmp; if(tmp==tmppath1) tmp=tmppath2; else tmp=tmppath1; } if(do_patch(best, dpath, tmp, FALSE /* do not gzip the result */, compression /* from the manifest */, cntr, cconf)) { char msg[256]=""; snprintf(msg, sizeof(msg), "error when patching %s\n", path); log_and_send(msg); free(path); free(dpath); return -1; } best=tmp; if(tmp==tmppath1) tmp=tmppath2; else tmp=tmppath1; unlink(tmp); patches++; } if(act==ACTION_RESTORE) { if(send_file(fname, patches, best, datapth, &bytes, cmd, winattr, compression, cntr, cconf)) { free(path); return -1; } else { do_filecounter(cntr, cmd, 0); do_filecounter_bytes(cntr, strtoull(endfile, NULL, 10)); } } else if(act==ACTION_VERIFY) { if(verify_file(fname, patches, best, datapth, &bytes, endfile, cmd, compression, cntr)) { free(path); return -1; } else { do_filecounter(cntr, cmd, 0); do_filecounter_bytes(cntr, strtoull(endfile, NULL, 10)); } } do_filecounter_sentbytes(cntr, bytes); free(path); return 0; } } logw(cntr, "restore could not find %s (%s)\n", fname, datapth); //return -1; return 0; }