Beispiel #1
0
static void
dosum (const char *file)
{
  FILE *f;
  unsigned char result[16];
  int i;
  
  f = fopen (file, "rb");
  if (!f)
    {
      fprintf (stderr, "opening %s: %s\n", file, xstrerror (errno));
      exit (1);
    }
  
  /* Some executable formats have timestamps in the first 16 bytes, yuck.  */
  if (fseek (f, 16, SEEK_SET) != 0)
     {
      fprintf (stderr, "seeking in %s: %s\n", file, xstrerror (errno));
      exit (1);
    }
  
  if (md5_stream (f, result) != 0
      || fclose (f) != 0)
     {
      fprintf (stderr, "reading %s: %s\n", file, xstrerror (errno));
      exit (1);
    }

  fputs ("const unsigned char executable_checksum[16] = { ", stdout);
  for (i = 0; i < 16; i++)
    printf ("%#02x%s", result[i], i == 15 ? " };\n" : ", ");
}
Beispiel #2
0
char *file_md5sum_alloc(const char *file_name)
{
    static const int md5sum_bin_len = 16;
    static const int md5sum_hex_len = 32;

    static const unsigned char bin2hex[16] = {
        '0', '1', '2', '3',
        '4', '5', '6', '7',
        '8', '9', 'a', 'b',
        'c', 'd', 'e', 'f'
    };

    int i, err;
    FILE *file;
    char *md5sum_hex;
    unsigned char md5sum_bin[md5sum_bin_len];

    md5sum_hex = xcalloc(1, md5sum_hex_len + 1);

    file = fopen(file_name, "r");
    if (file == NULL) {
        opkg_perror(ERROR, "Failed to open file %s", file_name);
        free(md5sum_hex);
        return NULL;
    }

    err = md5_stream(file, md5sum_bin);
    if (err) {
        opkg_msg(ERROR, "Could't compute md5sum for %s.\n", file_name);
        fclose(file);
        free(md5sum_hex);
        return NULL;
    }

    fclose(file);

    for (i = 0; i < md5sum_bin_len; i++) {
        md5sum_hex[i * 2] = bin2hex[md5sum_bin[i] >> 4];
        md5sum_hex[i * 2 + 1] = bin2hex[md5sum_bin[i] & 0xf];
    }

    md5sum_hex[md5sum_hex_len] = '\0';

    return md5sum_hex;
}
Beispiel #3
0
static int
lmd5(lua_State *L) {
  char buff[16];
  char tmp[32];
  size_t l;
  int i;
  int t = lua_type(L, 1);
  if (t == LUA_TSTRING) {
    const char *message = luaL_checklstring(L, 1, &l);
    md5(message, l, buff);
  } else if (t == LUA_TFUNCTION) {
	  md5_stream(L, buff);
  } else {
	  return luaL_error(L, "Invalid type %s, should be string or function", lua_typename(L, lua_type(L, 1)));
  }
  for (i=0;i<16;i++) {
    sprintf(tmp+2*i,"%02x",(unsigned char)buff[i]);
  }
  lua_pushlstring(L, tmp, 32);
  return 1;
}
Beispiel #4
0
char *file_md5sum_alloc(const char *file_name)
{
    int err;
    FILE *file;
    unsigned char md5sum_bin[16];

    file = fopen(file_name, "r");
    if (file == NULL) {
        opkg_perror(ERROR, "Failed to open file %s", file_name);
        return NULL;
    }

    err = md5_stream(file, md5sum_bin);
    if (err) {
        opkg_msg(ERROR, "Could't compute md5sum for %s.\n", file_name);
        fclose(file);
        return NULL;
    }

    fclose(file);

    return md5_to_string(md5sum_bin);
}
Beispiel #5
0
/* .Call so manages R_alloc stack */
SEXP Rmd5(SEXP files)
{
    SEXP ans;
    int i, j, nfiles = length(files), res;
    const char *path;
    char out[33];
    FILE *fp;
    unsigned char resblock[16];

    if(!isString(files)) error(_("argument 'files' must be character"));
    PROTECT(ans = allocVector(STRSXP, nfiles));
    for(i = 0; i < nfiles; i++) {
	path = translateChar(STRING_ELT(files, i));
#ifdef WIN32
	fp = fopen(path, "rb");
#else
	fp = fopen(path, "r");
#endif
	if(!fp) {
	    SET_STRING_ELT(ans, i, NA_STRING);
	} else {
	    res = md5_stream(fp, &resblock);
	    if(res) {
		warning(_("md5 failed on file '%s'"), path);
		SET_STRING_ELT(ans, i, NA_STRING);
	    } else {
		for(j = 0; j < 16; j++)
		    sprintf (out+2*j, "%02x", resblock[j]);
		SET_STRING_ELT(ans, i, mkChar(out));
	    }
	    fclose(fp);
	}
    }
    UNPROTECT(1);
    return ans;
}
Beispiel #6
0
int main (int argc, char **argv)
{
    FILE *fp, *fp2;
    int j, wrong = 0, miss = 0, res;
    char *p, fname[500], line[500]; /* < MAX_PATH + 32+ some */
    char onfile[33], out[33];
    unsigned char resblock[16];

    if(argc < 2) strcpy(fname, "../MD5"); else strcpy(fname, argv[1]);
    fp = fopen(fname, "r");
    if(!fp) {
	fprintf(stderr, "Cannot open file %s\n", fname);
	exit(2);
    }
    chdir(dirname(fname));

    if(access("unins000.dat", 4) == 0) read_unist_file("unins000.dat");

    onfile[32] = '\0';
    while(fgets(line, 500, fp)) {
	p = line + (strlen(line) - 1);
	if(*p == '\n') *p = '\0';
#ifdef DEBUG
	printf("%s: ", line+34);
#endif
	/* the next two files get altered during installation */
	if(strcmp(line+34, "etc/Rconsole") == 0) continue;
	if(strcmp(line+34, "etc/Rprofile.site") == 0) continue;	
	if(line[33] == '*')
	    fp2 = fopen(line+34, "rb");
	else
	    fp2 = fopen(line+34, "r");
	if(!fp2) {
	    int i, found = 0;
	    for(i = 0; i < nnames; i++) {
		if(strcmp(line+34, nameList[i]) == 0) {
		    found = 1;
		    break;
		}
	    }
	    
#ifdef DEBUG
	    printf("missing\n");
#endif
	    if(found || nnames == 0) {
		fprintf(stderr, "file %s: missing\n", line+34);
		miss++;
	    }
	    continue;
	}
	strncpy(onfile, line, 32);
	res = md5_stream(fp2, &resblock);
	if(res) {
#ifdef DEBUG
	    printf("md5 failed\n");
#endif
	    continue;
	} else {
	    for(j = 0; j < 16; j++) snprintf (out+2*j, 3, "%02x", resblock[j]);
	    out[32] = '\0';
	    if(strcmp(onfile, out) == 0) {
#ifdef DEBUG
		printf("OK\n");
#endif
	    } else {
#ifdef DEBUG
		printf("changed\n");
		printf("  %s vs %s\n", onfile, out);
#endif
		fprintf(stderr, "file %s: changed\n", line+34);
		wrong++;
	    }
	}
	fclose(fp2);
    }
    fclose(fp);
    if(miss) fprintf(stderr, "WARNING: %d files missing\n", miss);
    if(wrong) fprintf(stderr, "WARNING: %d files changed\n", wrong);
    if(wrong || miss) {
	fprintf(stderr, "Press ENTER to finish");
	getc(stdin);
	exit(10);
    }

    fprintf(stderr, "No errors detected\n");
    exit(0);
}
Beispiel #7
0
/* Decompress an open file. Call fatal_return(() on error
   return the number of bytes that have been retrieved
 */
i64 runzip_fd(rzip_control *control, int fd_in, int fd_out, int fd_hist, i64 expected_size)
{
	uchar md5_stored[MD5_DIGEST_SIZE];
	struct timeval start,end;
	i64 total = 0, u;
	double tdiff;

	if (!NO_MD5)
		md5_init_ctx (&control->ctx);
	gettimeofday(&start,NULL);

	do {
		u = runzip_chunk(control, fd_in, expected_size, total);
		if (unlikely(u == -1)) {
			print_err("Failed to runzip_chunk in runzip_fd\n");
			return -1;
		}
		total += u;
		if (TMP_OUTBUF) {
			if (unlikely(!flush_tmpoutbuf(control))) {
				print_err("Failed to flush_tmpoutbuf in runzip_fd\n");
				return -1;
			}
		} else if (STDOUT) {
			if (unlikely(!dump_tmpoutfile(control, fd_out))) {
				print_err("Failed to dump_tmpoutfile in runzip_fd\n");
				return -1;
			}
		}
		if (TMP_INBUF)
			clear_tmpinbuf(control);
		else if (STDIN && !DECOMPRESS) {
			if (unlikely(!clear_tmpinfile(control))) {
				print_err("Failed to clear_tmpinfile in runzip_fd\n");
				return -1;
			}
		}
	} while (total < expected_size || (!expected_size && !control->eof));

	gettimeofday(&end,NULL);
	if (!ENCRYPT) {
		tdiff = end.tv_sec - start.tv_sec;
		if (!tdiff)
			tdiff = 1;
		print_progress("\nAverage DeCompression Speed: %6.3fMB/s\n",
			       (total / 1024 / 1024) / tdiff);
	}

	if (!NO_MD5) {
		int i,j;

		md5_finish_ctx (&control->ctx, control->md5_resblock);
		if (HAS_MD5) {
			i64 fdinend = seekto_fdinend(control);

			if (unlikely(fdinend == -1))
				failure_return(("Failed to seekto_fdinend in rzip_fd\n"), -1);
			if (unlikely(seekto_fdin(control, fdinend - MD5_DIGEST_SIZE) == -1))
				failure_return(("Failed to seekto_fdin in rzip_fd\n"), -1);

			if (unlikely(read_1g(control, fd_in, md5_stored, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE))
				fatal_return(("Failed to read md5 data in runzip_fd\n"), -1);
			if (ENCRYPT)
				if (unlikely(!lrz_decrypt(control, md5_stored, MD5_DIGEST_SIZE, control->salt_pass)))
					return -1;
			for (i = 0; i < MD5_DIGEST_SIZE; i++)
				if (md5_stored[i] != control->md5_resblock[i]) {
					print_output("MD5 CHECK FAILED.\nStored:");
					for (j = 0; j < MD5_DIGEST_SIZE; j++)
						print_output("%02x", md5_stored[j] & 0xFF);
					print_output("\nOutput file:");
					for (j = 0; j < MD5_DIGEST_SIZE; j++)
						print_output("%02x", control->md5_resblock[j] & 0xFF);
					failure_return(("\n"), -1);
				}
		}

		if (HASH_CHECK || MAX_VERBOSE) {
			print_output("MD5: ");
			for (i = 0; i < MD5_DIGEST_SIZE; i++)
				print_output("%02x", control->md5_resblock[i] & 0xFF);
			print_output("\n");
		}

		if (CHECK_FILE) {
			FILE *md5_fstream;
			int i, j;

			if (TMP_OUTBUF)
				close_tmpoutbuf(control);
			memcpy(md5_stored, control->md5_resblock, MD5_DIGEST_SIZE);
			if (unlikely(seekto_fdhist(control, 0) == -1))
				fatal_return(("Failed to seekto_fdhist in runzip_fd\n"), -1);
			if (unlikely((md5_fstream = fdopen(fd_hist, "r")) == NULL))
				fatal_return(("Failed to fdopen fd_hist in runzip_fd\n"), -1);
			if (unlikely(md5_stream(md5_fstream, control->md5_resblock)))
				fatal_return(("Failed to md5_stream in runzip_fd\n"), -1);
			/* We don't close the file here as it's closed in main */
			for (i = 0; i < MD5_DIGEST_SIZE; i++)
				if (md5_stored[i] != control->md5_resblock[i]) {
					print_output("MD5 CHECK FAILED.\nStored:");
					for (j = 0; j < MD5_DIGEST_SIZE; j++)
						print_output("%02x", md5_stored[j] & 0xFF);
					print_output("\nOutput file:");
					for (j = 0; j < MD5_DIGEST_SIZE; j++)
						print_output("%02x", control->md5_resblock[j] & 0xFF);
					failure_return(("\n"), -1);
				}
			print_output("MD5 integrity of written file matches archive\n");
			if (!HAS_MD5)
				print_output("Note this lrzip archive did not have a stored md5 value.\n"
				"The archive decompression was validated with crc32 and the md5 hash was "
				"calculated on decompression\n");
		}
	}

	return total;
}
Beispiel #8
0
/* Return Digest authentication credentials header value for the given
 * session. */
static char *request_digest(http_auth_session *sess) 
{
    struct md5_ctx a2, rdig;
    unsigned char a2_md5[16], rdig_md5[16];
    char a2_md5_ascii[33], rdig_md5_ascii[33];
    char nc_value[9] = {0}, *ret;
    const char *qop_value; /* qop-value */
    size_t retlen;

    /* Increase the nonce-count */
    if (sess->qop != http_auth_qop_none) {
	sess->nonce_count++;
	snprintf(nc_value, 9, "%08x", sess->nonce_count);
	DEBUG(DEBUG_HTTPAUTH, "Nonce count is %d, nc is [%s]\n", 
	       sess->nonce_count, nc_value);
    }
    qop_value = qop_values[sess->qop];

    /* Calculate H(A2). */
    md5_init_ctx(&a2);
    md5_process_bytes(sess->method, strlen(sess->method), &a2);
    md5_process_bytes(":", 1, &a2);
    md5_process_bytes(sess->uri, strlen(sess->uri), &a2);
    if (sess->qop == http_auth_qop_auth_int) {
	/* Calculate H(entity-body) */
	if (sess->got_body) {
	    char tmp_md5_ascii[33];
	    unsigned char tmp_md5[16];
	    if (sess->body_stream != NULL) {
		DEBUG(DEBUG_HTTPAUTH, "Digesting body stream.\n");
		md5_stream(sess->body_stream, tmp_md5);
		rewind(sess->body_stream); /* leave it at the beginning */
	    } else if (sess->body_buffer) {
		DEBUG(DEBUG_HTTPAUTH, "Digesting body buffer.\n");
		md5_buffer(sess->body_buffer, strlen(sess->body_buffer), 
			    tmp_md5);
	    }
	    md5_to_ascii(tmp_md5, tmp_md5_ascii);
	    DEBUG(DEBUG_HTTPAUTH, "H(entity-body) is [%s]\n", tmp_md5_ascii);
	    /* Append to A2 */
	    md5_process_bytes(":", 1, &a2);
	    md5_process_bytes(tmp_md5_ascii, 32, &a2);
	} else {
	    /* No entity-body. */
	    DEBUG(DEBUG_HTTPAUTH, "Digesting empty entity-body.\n");
	    md5_process_bytes(":" DIGEST_MD5_EMPTY, 33, &a2);
	}
    }
    md5_finish_ctx(&a2, a2_md5);
    md5_to_ascii(a2_md5, a2_md5_ascii);
    DEBUG(DEBUG_HTTPAUTH, "H(A2): %s\n", a2_md5_ascii);

    DEBUG(DEBUG_HTTPAUTH, "Calculating Request-Digest.\n");
    /* Now, calculation of the Request-Digest.
     * The first section is the regardless of qop value
     *     H(A1) ":" unq(nonce-value) ":" */
    md5_init_ctx(&rdig);

    /* Use the calculated H(A1) */
    md5_process_bytes(sess->h_a1, 32, &rdig);

    md5_process_bytes(":", 1, &rdig);
    md5_process_bytes(sess->unq_nonce, strlen(sess->unq_nonce), &rdig);
    md5_process_bytes(":", 1, &rdig);
    if (sess->qop != http_auth_qop_none) {
	/* Add on:
	 *    nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":"
	 */
	DEBUG(DEBUG_HTTPAUTH, "Have qop directive, digesting: [%s:%s:%s]\n",
	       nc_value, sess->unq_cnonce, qop_value);
	md5_process_bytes(nc_value, 8, &rdig);
	md5_process_bytes(":", 1, &rdig);
	md5_process_bytes(sess->unq_cnonce, strlen(sess->unq_cnonce), &rdig);
	md5_process_bytes(":", 1, &rdig);
	/* Store a copy of this structure (see note below) */
	sess->stored_rdig = rdig;
	md5_process_bytes(qop_value, strlen(qop_value), &rdig);
	md5_process_bytes(":", 1, &rdig);
    } else {
	/* Store a copy of this structure... we do this because the
	 * calculation of the rspauth= field in the Auth-Info header 
	 * is the same as this digest, up to this point. */
	sess->stored_rdig = rdig;
    }
    /* And finally, H(A2) */
    md5_process_bytes(a2_md5_ascii, 32, &rdig);
    md5_finish_ctx(&rdig, rdig_md5);
    md5_to_ascii(rdig_md5, rdig_md5_ascii);
    
    /* Buffer size calculation. */
    
    retlen = 
	6                                      /* Digest */
	+ 1 + 8 + 1 + 2 + strlen(sess->username)  /*  username="******" */
	+ 2 + 5 + 1 + 2 + strlen(sess->unq_realm) /* , realm="..." */
	+ 2 + 5 + 1 + 2 + strlen(sess->unq_nonce) /* , nonce="..." */
	+ 2 + 3 + 1 + 2 + strlen(sess->uri)       /* , uri="..." */
	+ 2 + 8 + 1 + 2 + 32                      /* , response="..." */
	+ 2 + 9 + 1 + 2 + strlen(algorithm_names[sess->alg]) /* 
						   , algorithm="..." */
	;

    if (sess->opaque != NULL)
	retlen += 2 + 6 + 1 + strlen(sess->opaque);   /* , opaque=... */

    if (sess->qop != http_auth_qop_none)
	retlen += 
	    2 + 6 + 2 + 1 + strlen(sess->unq_cnonce) +   /* , cnonce="..." */
	    2 + 2 + 1 + 8 +                       /* , nc=... */
	    2 + 3 + 1 + 2 + strlen(qop_values[sess->qop]) /* , qop="..." */
	    ;

    retlen += 2;   /* \r\n */

    DEBUG(DEBUG_HTTPAUTH, "Calculated length of buffer: %d\n", retlen);

    ret = ne_calloc(retlen + 1);

    sprintf(ret,
	      "Digest username=\"%s\", realm=\"%s\""
	      ", nonce=\"%s\", uri=\"%s\", response=\"%s\""
	      ", algorithm=\"%s\"",
	      sess->username, sess->unq_realm, 
	      sess->unq_nonce, sess->uri, rdig_md5_ascii,
	      algorithm_names[sess->alg]);
    
    if (sess->opaque != NULL) {
	/* We never unquote it, so it's still quoted here */
	strcat(ret, ", opaque=");
	strcat(ret, sess->opaque);
    }

    if (sess->qop != http_auth_qop_none) {
	/* Add in cnonce and nc-value fields */
	strcat(ret, ", cnonce=\"");
	strcat(ret, sess->unq_cnonce);
	strcat(ret, "\", nc=");
	strcat(ret, nc_value);
	strcat(ret, ", qop=\"");
	strcat(ret, qop_values[sess->qop]);
	strcat(ret, "\"");
    }

    DEBUG(DEBUG_HTTPAUTH, "Digest header field value:\n%s\n", ret);

    strcat(ret, "\r\n");

    DEBUG(DEBUG_HTTPAUTH, "Calculated length: %d, actual length: %d\n", 
	   retlen, strlen(ret));
    
    return ret;
}
Beispiel #9
0
std::string Authenticity::Assay
    (calendar_date const& candidate
    ,fs::path const&      data_path
    )
{
    // The cached date is valid unless it's the peremptorily-invalid
    // default value of JDN zero.
    if
        (  calendar_date(jdn_t(0)) != Instance().CachedDate_
        && candidate               == Instance().CachedDate_
        )
        {
        return "cached";
        }

    ResetCache();

    std::ostringstream oss;

    // Read the passkey and valid-date-range files each time
    // because they might change while the program is running.
    // They'll be validated against validated md5sums a fraction
    // of a second later, to guard against fraudulent manipulation.

    // Read saved passkey from file.
    std::string passkey;
    {
    fs::path passkey_path(data_path / "passkey");
    fs::ifstream is(passkey_path);
    if(!is)
        {
        oss
            << "Unable to read passkey file '"
            << passkey_path
            << "'. Try reinstalling."
            ;
        return oss.str();
        }

    is >> passkey;
    if(!is.eof())
        {
        oss
            << "Error reading passkey file '"
            << passkey_path
            << "'. Try reinstalling."
            ;
        return oss.str();
        }

    if(passkey.size() != chars_per_formatted_hex_byte * md5len)
        {
        oss
            << "Length of passkey '"
            << passkey
            << "' is "
            << passkey.size()
            << " but should be "
            << chars_per_formatted_hex_byte * md5len
            << ". Try reinstalling."
            ;
        return oss.str();
        }
    }

    // Read valid date range [begin, end) from file.
    calendar_date begin(last_yyyy_date ());
    calendar_date end  (gregorian_epoch());
    {
    fs::path expiry_path(data_path / "expiry");
    fs::ifstream is(expiry_path);
    if(!is)
        {
        oss
            << "Unable to read expiry file '"
            << expiry_path
            << "'. Try reinstalling."
            ;
        return oss.str();
        }

    is >> begin >> end;
    if(!is || !is.eof())
        {
        oss
            << "Error reading expiry file '"
            << expiry_path
            << "'. Try reinstalling."
            ;
        return oss.str();
        }
    }

    // Make sure candidate date is within valid range.
    if(candidate < begin)
        {
        oss
            << "Current date "
            << candidate.str()
            << " is invalid: this system cannot be used before "
            << begin.str()
            << ". Contact the home office."
            ;
        return oss.str();
        }
    if(end <= candidate)
        {
        oss
            << "Current date "
            << candidate.str()
            << " is invalid: this system cannot be used after "
            << (-1 + end).str()
            << ". Contact the home office."
            ;
        return oss.str();
        }

    // Validate all data files.
    fs::path original_path(fs::current_path());
    if(0 != chdir(data_path.string().c_str()))
        {
        oss
            << "Unable to change directory to '"
            << data_path
            << "'. Try reinstalling."
            ;
        return oss.str();
        }
    try
        {
        system_command("md5sum --check --status " + std::string(md5sum_file()));
        }
    catch(...)
        {
        report_exception();
        oss
            << "At least one required file is missing, altered, or invalid."
            << " Try reinstalling."
            ;
        return oss.str();
        }
    if(0 != chdir(original_path.string().c_str()))
        {
        oss
            << "Unable to restore directory to '"
            << original_path
            << "'. Try reinstalling."
            ;
        return oss.str();
        }

    // The passkey must match the md5 sum of the md5 sum of the file
    // of md5 sums of secured files.

    char c_passkey[md5len];
    unsigned char u_passkey[md5len];
    std::FILE* md5sums_file = std::fopen
        ((data_path / md5sum_file()).string().c_str()
        ,"rb"
        );
    md5_stream(md5sums_file, u_passkey);
    std::fclose(md5sums_file);
    std::memcpy(c_passkey, u_passkey, md5len);
    md5_buffer(c_passkey, md5len, u_passkey);
    std::memcpy(c_passkey, u_passkey, md5len);
    md5_buffer(c_passkey, md5len, u_passkey);
    std::string expected = md5_hex_string
        (std::vector<unsigned char>(u_passkey, u_passkey + md5len)
        );
    if(passkey != expected)
        {
        oss
            << "Passkey is incorrect for this version."
            << " Contact the home office."
            ;
        return oss.str();
        }
    // Cache the validated date.
    Instance().CachedDate_ = candidate;
    return "validated";
}