static void prf_set(httpsrv_client_t *hcl) { if (hcl->readbody == NULL) { if (hcl->headers.content_length == 0) { djb_error(hcl, 400, "Setting preferences requires a length"); return; } if (httpsrv_readbody_alloc(hcl, 0, 0) < 0) { log_wrn("httpsrv_readbody_alloc() failed"); } /* Let httpsrv read */ return; } log_dbg("prefs = %s", hcl->readbody); mutex_lock(l_mutex); if (l_current_preferences != NULL) free(l_current_preferences); l_current_preferences = (hcl->readbody == NULL ? NULL : strdup(hcl->readbody)); if (prf_parse_preferences()) { #if DEBUGHANDLE /* this block is just for testing */ unsigned int argc = 0, i; char **argv = NULL; for (i = 0; i < PRF_MAX; i++) { if (l_keys[i] == NULL) continue; if (l_values[i] == NULL) continue; log_dbg("%s => %s\n", l_keys[i], l_values[i]); } argc = prf_get_argv(&argv); log_wrn("argc = %u", argc); for (i = 0; i < argc; i++) { log_dbg("argv[%u] = %s\n", i, argv[i]); } #endif djb_result(hcl, DJB_OK, "Preferences OK"); } else { djb_result(hcl, DJB_OK, "Preferences broken"); } mutex_unlock(l_mutex); }
static void rdv_image_reset(void) { log_dbg("..."); if (l_current_image_path != NULL) { if (unlink(l_current_image_path) == -1) { log_wrn("unlink(%s) failed: %s", l_current_image_path, strerror(errno)); }; if (rmdir(l_current_image_dir) == -1) { log_wrn("rmdir(%s) failed: %s", l_current_image_dir, strerror(errno)); }; free((void *)l_current_image_path); free((void *)l_current_image_dir); l_current_image_path = NULL; l_current_image_dir = NULL; } }
static const char * rdv_peel_signed(void) { int errcode; const char *r; const char *dpkp; FILE *public_key_fp; log_dbg("..."); dpkp = getenv("DEFIANCE_PUBLIC_KEY_PATH"); if (dpkp == NULL) { r = "The server needs to know the DEFIANCE_PUBLIC_KEY_PATH, so " "that the signature can be VERIFIED!"; } else { public_key_fp = fopen(dpkp, "r"); if(public_key_fp == NULL){ log_wrn("Could not open public key file %s: %s\n", dpkp, strerror(errno)); r = "The server can't open the DEFIANCE_PUBLIC_KEY_PATH, so " "that the signature can be VERIFIED!"; } else { errcode = verify_onion(public_key_fp, l_current_onion); fclose(public_key_fp); if (errcode == DEFIANT_OK) { onion_t inner_onion = NULL; errcode = peel_signed_onion(l_current_onion, &inner_onion); if (errcode == DEFIANT_OK) { free_onion(l_current_onion); l_current_onion = inner_onion; r = "The server returned an onion whose " "signature we VERIFIED!"; } else { r = "Peeling it went wrong, very odd."; } } else { r = "The server returned an onion whose signature " "we COULD NOT verify -- try again?"; } } } return (rdv_make_peel_response("", r)); }
int main(int argc, char** argv) { int i, usealt; const char * pin, * label; #ifdef CTAPI void* mutex; #endif /* Check args */ if (argc < 4) { fprintf(stderr, "Usage: [-a] pin label path...\n"); fprintf(stderr, "Signs the specified file(s) and/or files within the specified directory(ies).\n"); fprintf(stderr, " -a use :p7s instead of .p7s extension (alternate data stream on Windows)\n"); return 1; } usealt = strcmp(argv[1], "-a") == 0; pin = !usealt ? argv[1] : argv[2]; label = !usealt ? argv[2] : argv[3]; sig_ext = !usealt ? ".p7s" : ":p7s"; /* Disable buffering on stdout/stderr to prevent mixing the order of messages to stdout/stderr when redirected to the same log file */ setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); /* Log the args */ log_inf("pin=****; label='%s'", label); #ifdef CTAPI /* Create a mutex/sem/lock for controlling access to token. CTAPI implementations must NOT allow simultaneous access to token. */ mutex = create_lock(MUTEX_KEY); if ((int)mutex < 0) { log_wrn( "couldn't create mutex; another inst. of '%s' is likely running", argv[0]); return -1; } #endif /* For each path arg, sign either the specified file or all the files in the specified directory */ for (i = !usealt ? 3 : 4; i < argc; i++) { int err; struct stat info; char* path = argv[i]; /* Trim trailing slashes from path (required for Windows stat) */ int j = strlen(path); while (--j >= 0 && (path[j] == '/' || path[j] == '\\')) path[j] = 0; /* Log the path */ log_inf("path='%s'", path); /* Verify the specified path exists */ err = stat(path, &info); if (err) { int e = errno; log_err("error accessing path '%s': %s", path, strerror(e)); continue; } if (S_ISDIR(info.st_mode)) /* DIRECTORY */ sign_files(path, pin, label); /* Sign all files in the specified directory */ else /* FILE */ sign_file(path, pin, label); /* Sign the specified file */ } /* Clean up */ release_template(); #ifdef CTAPI /* Release mutex/sem/lock here. */ release_lock(mutex); #endif #if defined(_WIN32) && defined(DEBUG) _CrtDumpMemoryLeaks(); #endif return 0; }
/** * Determine if the file at the specified path needs to be signed. * Signing only occurs if the file is new (i.e. not yet signed), * OR if the file has been appended since the last signing as * determined by reading the hcl ("total") from the metadata stored * at the end of the associated signature file and comparing with the * current size of the specified file. * If a new signature is necessary, the sign function above will be * called with the specified pin and label. */ void sign_file(const char* path, const char* pin, const char* label) { int n, err; struct stat entry_info; char sig_path[PATH_MAX] = ""; FILE* fp; /* Stat the entry */ err = stat(path, &entry_info); if (err) { int e = errno; log_err("error accessing file '%s': %s", path, strerror(e)); return; } /* Only sign files */ if (S_ISDIR(entry_info.st_mode)) return; /* Skip empty files */ if (entry_info.st_size <= 0) { log_inf("'%s' empty", path); return; } /* Build associated sig file path (i.e. <path>/<filename><sig_ext>) */ n = snprintf(sig_path, sizeof(sig_path), "%s%s", path, sig_ext); if (n < 0 || n >= sizeof(sig_path)) { log_err("error building sig file path '%s%s'", path, sig_ext); return; } /* Try to open the sig file to see if one exists yet */ fp = fopen(sig_path, "rb"); err = errno; if (fp) fclose(fp); if (!err) { /* Sig file found => figure out if we need to re-create it */ /* Read the metadata from the sig file */ metadata_t md; err = read_metadata(sig_path, &md); if (err) { log_err("error reading metadata from sig file '%s'; will be re-created", sig_path); } else { /* Figure out if we need to re-create the sig file */ offset_t hcl = sizeof(hcl) == 4 ? md.cll : (offset_t)md.clh << 32 | md.cll; if (entry_info.st_size == hcl) { /* Unmodified so skip */ log_inf("'%s' unmodified", path); return; } else if (entry_info.st_size < hcl) { /* Shrunk so re-sign */ log_wrn("'%s' shrunk", path); err = 1; /* force re-sign from beginning of file */ } else { /* Modified so re-sign the file using the hash state saved in the metatdata */ log_inf("'%s' modified", path); } } /* Create/re-create sig file */ sign(path, pin, label, err ? 0 : &md); } else { /* No sig file found (or err reading it) => create/re-create */ int e = errno; if (e == ENOENT) /* A sig file doesn't yet exist, assume file is new */ log_inf("'%s' not yet signed", path); else /* Error accessing an existing sig file */ log_err("error accessing sig file '%s': %s; will be re-created", sig_path, strerror(e)); /* Create/re-create sig file */ sign(path, pin, label, 0); } }