コード例 #1
0
ファイル: ocsp.c プロジェクト: eworm-de/ipxe
/**
 * Build OCSP request
 *
 * @v ocsp		OCSP check
 * @ret rc		Return status code
 */
static int ocsp_request ( struct ocsp_check *ocsp ) {
	struct digest_algorithm *digest = &ocsp_digest_algorithm;
	struct asn1_builder *builder = &ocsp->request.builder;
	struct asn1_cursor *cert_id_tail = &ocsp->request.cert_id_tail;
	uint8_t digest_ctx[digest->ctxsize];
	uint8_t name_digest[digest->digestsize];
	uint8_t pubkey_digest[digest->digestsize];
	int rc;

	/* Generate digests */
	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx, ocsp->cert->issuer.raw.data,
			ocsp->cert->issuer.raw.len );
	digest_final ( digest, digest_ctx, name_digest );
	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx,
			ocsp->issuer->subject.public_key.raw_bits.data,
			ocsp->issuer->subject.public_key.raw_bits.len );
	digest_final ( digest, digest_ctx, pubkey_digest );

	/* Construct request */
	if ( ( rc = ( asn1_prepend_raw ( builder, ocsp->cert->serial.raw.data,
					 ocsp->cert->serial.raw.len ),
		      asn1_prepend ( builder, ASN1_OCTET_STRING,
				     pubkey_digest, sizeof ( pubkey_digest ) ),
		      asn1_prepend ( builder, ASN1_OCTET_STRING,
				     name_digest, sizeof ( name_digest ) ),
		      asn1_prepend ( builder, ASN1_SEQUENCE,
				     ocsp_algorithm_id,
				     sizeof ( ocsp_algorithm_id ) ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ),
		      asn1_wrap ( builder, ASN1_SEQUENCE ) ) ) != 0 ) {
		DBGC ( ocsp, "OCSP %p \"%s\" could not build request: %s\n",
		       ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
		return rc;
	}
	DBGC2 ( ocsp, "OCSP %p \"%s\" request is:\n",
		ocsp, x509_name ( ocsp->cert ) );
	DBGC2_HDA ( ocsp, 0, builder->data, builder->len );

	/* Parse certificate ID for comparison with response */
	cert_id_tail->data = builder->data;
	cert_id_tail->len = builder->len;
	if ( ( rc = ( asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
		      asn1_skip ( cert_id_tail, ASN1_SEQUENCE ) ) ) != 0 ) {
		DBGC ( ocsp, "OCSP %p \"%s\" could not locate certID: %s\n",
		       ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
		return rc;
	}

	return 0;
}
コード例 #2
0
ファイル: digest_test.c プロジェクト: pipcet/ipxe
/**
 * Test digest algorithm
 *
 * @v digest		Digest algorithm
 * @v fragments		Digest test fragment list, or NULL
 * @v data		Test data
 * @v len		Length of test data
 * @v expected		Expected digest value
 * @ret ok		Digest value is as expected
 */
int digest_test ( struct digest_algorithm *digest,
		  struct digest_test_fragments *fragments,
		  void *data, size_t len, void *expected ) {
	uint8_t ctx[digest->ctxsize];
	uint8_t out[digest->digestsize];
	size_t frag_len = 0;
	unsigned int i;

	/* Initialise digest */
	digest_init ( digest, ctx );

	/* Update digest fragment-by-fragment */
	for ( i = 0 ; len && ( i < ( sizeof ( fragments->len ) /
				     sizeof ( fragments->len[0] ) ) ) ; i++ ) {
		if ( fragments )
			frag_len = fragments->len[i];
		if ( ( frag_len == 0 ) || ( frag_len < len ) )
			frag_len = len;
		digest_update ( digest, ctx, data, frag_len );
		data += frag_len;
		len -= frag_len;
	}

	/* Finalise digest */
	digest_final ( digest, ctx, out );

	/* Compare against expected output */
	return ( memcmp ( expected, out, sizeof ( out ) ) == 0 );
}
コード例 #3
0
ファイル: digest_test.c プロジェクト: pipcet/ipxe
/**
 * Calculate digest algorithm cost
 *
 * @v digest		Digest algorithm
 * @ret cost		Cost (in cycles per byte)
 */
unsigned long digest_cost ( struct digest_algorithm *digest ) {
	static uint8_t random[8192]; /* Too large for stack */
	uint8_t ctx[digest->ctxsize];
	uint8_t out[digest->digestsize];
	struct profiler profiler;
	unsigned long cost;
	unsigned int i;

	/* Fill buffer with pseudo-random data */
	srand ( 0x1234568 );
	for ( i = 0 ; i < sizeof ( random ) ; i++ )
		random[i] = rand();

	/* Profile digest calculation */
	memset ( &profiler, 0, sizeof ( profiler ) );
	for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
		profile_start ( &profiler );
		digest_init ( digest, ctx );
		digest_update ( digest, ctx, random, sizeof ( random ) );
		digest_final ( digest, ctx, out );
		profile_stop ( &profiler );
	}

	/* Round to nearest whole number of cycles per byte */
	cost = ( ( profile_mean ( &profiler ) + ( sizeof ( random ) / 2 ) ) /
		 sizeof ( random ) );

	return cost;
}
コード例 #4
0
ファイル: xymondigest.c プロジェクト: osvaldsson/xymon
int main(int argc, char *argv[])
{
	FILE *fd;
	char buf[8192];
	int buflen;
	digestctx_t *ctx;

	if (argc < 2) {
		printf("Usage: %s digestmethod [filename]\n", argv[0]);
		printf("\"digestmethod\" is \"md5\", \"sha1\", \"sha256\", \"sha512\" or \"rmd160\"\n");
		return 1;
	}

	if ((ctx = digest_init(argv[1])) == NULL) {
		printf("Unknown message digest method %s\n", argv[1]);
		return 1;
	}

	if (argc > 2) fd = fopen(argv[2], "r"); else fd = stdin;

	if (fd == NULL) {
		printf("Cannot open file %s\n", argv[2]);
		return 1;
	}

	while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) {
		digest_data(ctx, buf, buflen);
	}

	printf("%s\n", digest_done(ctx));

	return 0;
}
コード例 #5
0
ファイル: ocsp.c プロジェクト: eworm-de/ipxe
/**
 * Compare responder's certificate public key hash
 *
 * @v ocsp		OCSP check
 * @v cert		Certificate
 * @ret difference	Difference as returned by memcmp()
 */
static int ocsp_compare_responder_key_hash ( struct ocsp_check *ocsp,
					     struct x509_certificate *cert ) {
	struct ocsp_responder *responder = &ocsp->response.responder;
	struct asn1_cursor key_hash;
	uint8_t ctx[SHA1_CTX_SIZE];
	uint8_t digest[SHA1_DIGEST_SIZE];
	int difference;

	/* Enter responder key hash */
	memcpy ( &key_hash, &responder->id, sizeof ( key_hash ) );
	asn1_enter ( &key_hash, ASN1_OCTET_STRING );

	/* Sanity check */
	difference = ( sizeof ( digest ) - key_hash.len );
	if ( difference )
		return difference;

	/* Generate SHA1 hash of certificate's public key */
	digest_init ( &sha1_algorithm, ctx );
	digest_update ( &sha1_algorithm, ctx,
			cert->subject.public_key.raw_bits.data,
			cert->subject.public_key.raw_bits.len );
	digest_final ( &sha1_algorithm, ctx, digest );

	/* Compare responder key hash with hash of certificate's public key */
	return memcmp ( digest, key_hash.data, sizeof ( digest ) );
}
コード例 #6
0
ファイル: pccrc_test.c プロジェクト: baloo/ipxe
/**
 * Report server passphrase test result
 *
 * @v test		Content information segment test
 * @v info		Content information
 * @v pass		Server passphrase
 * @v pass_len		Length of server passphrase
 * @v file		Test code file
 * @v line		Test code line
 */
static void
peerdist_info_passphrase_okx ( struct peerdist_info_segment_test *test,
			       const struct peerdist_info *info,
			       uint8_t *pass, size_t pass_len,
			       const char *file, unsigned int line ) {
	struct digest_algorithm *digest = info->digest;
	uint8_t ctx[digest->ctxsize];
	uint8_t secret[digest->digestsize];
	uint8_t expected[digest->digestsize];
	size_t digestsize = info->digestsize;
	size_t secretsize = digestsize;

	/* Calculate server secret */
	digest_init ( digest, ctx );
	digest_update ( digest, ctx, pass, pass_len );
	digest_final ( digest, ctx, secret );

	/* Calculate expected segment secret */
	hmac_init ( digest, ctx, secret, &secretsize );
	assert ( secretsize == digestsize );
	hmac_update ( digest, ctx, test->expected_hash, digestsize );
	hmac_final ( digest, ctx, secret, &secretsize, expected );
	assert ( secretsize == digestsize );

	/* Verify segment secret */
	okx ( memcmp ( test->expected_secret, expected, digestsize ) == 0,
	      file, line );
}
コード例 #7
0
ファイル: hmac.c プロジェクト: Heyvaert/ipxe-1
/**
 * Finalise HMAC
 *
 * @v digest		Digest algorithm to use
 * @v digest_ctx	Digest context
 * @v key		Key
 * @v key_len		Length of key
 * @v hmac		HMAC digest to fill in
 *
 * The length of the key should be less than the block size of the
 * digest algorithm being used.  (If the key length is greater, it
 * will be replaced with its own digest, and key_len will be updated
 * accordingly).
 */
void hmac_final ( struct digest_algorithm *digest, void *digest_ctx,
		  void *key, size_t *key_len, void *hmac ) {
	unsigned char k_opad[digest->blocksize];
	unsigned int i;

	/* Reduce key if necessary */
	if ( *key_len > sizeof ( k_opad ) )
		hmac_reduce_key ( digest, key, key_len );

	/* Construct output pad */
	memset ( k_opad, 0, sizeof ( k_opad ) );
	memcpy ( k_opad, key, *key_len );
	for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) {
		k_opad[i] ^= 0x5c;
	}
	
	/* Finish inner hash */
	digest_final ( digest, digest_ctx, hmac );

	/* Perform outer hash */
	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) );
	digest_update ( digest, digest_ctx, hmac, digest->digestsize );
	digest_final ( digest, digest_ctx, hmac );
}
コード例 #8
0
ファイル: hmac.c プロジェクト: Heyvaert/ipxe-1
/**
 * Reduce HMAC key length
 *
 * @v digest		Digest algorithm to use
 * @v digest_ctx	Digest context
 * @v key		Key
 * @v key_len		Length of key
 */
static void hmac_reduce_key ( struct digest_algorithm *digest,
			      void *key, size_t *key_len ) {
	uint8_t digest_ctx[digest->ctxsize];

	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx, key, *key_len );
	digest_final ( digest, digest_ctx, key );
	*key_len = digest->digestsize;
}
コード例 #9
0
ファイル: digest_cmd.c プロジェクト: 1stMaster/syslinux
/**
 * The "digest" command
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @v digest		Digest algorithm
 * @ret rc		Exit code
 */
static int digest_exec ( int argc, char **argv,
			 struct digest_algorithm *digest ) {
	const char *image_name;
	struct image *image;
	uint8_t digest_ctx[digest->ctxsize];
	uint8_t digest_out[digest->digestsize];
	uint8_t buf[128];
	size_t offset;
	size_t len;
	size_t frag_len;
	int i;
	unsigned j;

	if ( argc < 2 ||
	     !strcmp ( argv[1], "--help" ) ||
	     !strcmp ( argv[1], "-h" ) ) {
		digest_syntax ( argv );
		return 1;
	}

	for ( i = 1 ; i < argc ; i++ ) {
		image_name = argv[i];

		/* find image */
		image = find_image ( image_name );
		if ( ! image ) {
			printf ( "No such image: %s\n", image_name );
			continue;
		}
		offset = 0;
		len = image->len;

		/* calculate digest */
		digest_init ( digest, digest_ctx );
		while ( len ) {
			frag_len = len;
			if ( frag_len > sizeof ( buf ) )
				frag_len = sizeof ( buf );
			copy_from_user ( buf, image->data, offset, frag_len );
			digest_update ( digest, digest_ctx, buf, frag_len );
			len -= frag_len;
			offset += frag_len;
		}
		digest_final ( digest, digest_ctx, digest_out );

		for ( j = 0 ; j < sizeof ( digest_out ) ; j++ )
			printf ( "%02x", digest_out[j] );

		printf ( "  %s\n", image->name );
	}

	return 0;
}
コード例 #10
0
ファイル: ocsp.c プロジェクト: eworm-de/ipxe
/**
 * Check OCSP response signature
 *
 * @v ocsp		OCSP check
 * @v signer		Signing certificate
 * @ret rc		Return status code
 */
static int ocsp_check_signature ( struct ocsp_check *ocsp,
				  struct x509_certificate *signer ) {
	struct ocsp_response *response = &ocsp->response;
	struct digest_algorithm *digest = response->algorithm->digest;
	struct pubkey_algorithm *pubkey = response->algorithm->pubkey;
	struct x509_public_key *public_key = &signer->subject.public_key;
	uint8_t digest_ctx[ digest->ctxsize ];
	uint8_t digest_out[ digest->digestsize ];
	uint8_t pubkey_ctx[ pubkey->ctxsize ];
	int rc;

	/* Generate digest */
	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx, response->tbs.data,
			response->tbs.len );
	digest_final ( digest, digest_ctx, digest_out );

	/* Initialise public-key algorithm */
	if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
				  public_key->raw.len ) ) != 0 ) {
		DBGC ( ocsp, "OCSP %p \"%s\" could not initialise public key: "
		       "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
		goto err_init;
	}

	/* Verify digest */
	if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
				    response->signature.data,
				    response->signature.len ) ) != 0 ) {
		DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: "
		       "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
		goto err_verify;
	}

	DBGC2 ( ocsp, "OCSP %p \"%s\" signature is correct\n",
		ocsp, x509_name ( ocsp->cert ) );

 err_verify:
	pubkey_final ( pubkey, pubkey_ctx );
 err_init:
	return rc;
}
コード例 #11
0
ファイル: hmac.c プロジェクト: Heyvaert/ipxe-1
/**
 * Initialise HMAC
 *
 * @v digest		Digest algorithm to use
 * @v digest_ctx	Digest context
 * @v key		Key
 * @v key_len		Length of key
 *
 * The length of the key should be less than the block size of the
 * digest algorithm being used.  (If the key length is greater, it
 * will be replaced with its own digest, and key_len will be updated
 * accordingly).
 */
void hmac_init ( struct digest_algorithm *digest, void *digest_ctx,
		 void *key, size_t *key_len ) {
	unsigned char k_ipad[digest->blocksize];
	unsigned int i;

	/* Reduce key if necessary */
	if ( *key_len > sizeof ( k_ipad ) )
		hmac_reduce_key ( digest, key, key_len );

	/* Construct input pad */
	memset ( k_ipad, 0, sizeof ( k_ipad ) );
	memcpy ( k_ipad, key, *key_len );
	for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) {
		k_ipad[i] ^= 0x36;
	}
	
	/* Start inner hash */
	digest_init ( digest, digest_ctx );
	digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) );
}
コード例 #12
0
char *filesum(char *fn, char *dtype)
{
	static char *result = NULL;
	digestctx_t *ctx;
	FILE *fd;
	unsigned char buf[8192];
	int openerr, buflen;

        if ((ctx = digest_init(dtype)) == NULL) return "";

	fd = fileopen(fn, &openerr); 
	if (fd == NULL) return "";
	while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) digest_data(ctx, buf, buflen);
	fclose(fd);

	if (result) xfree(result);
	result = strdup(digest_done(ctx));

	return result;
}
コード例 #13
0
ファイル: e_devcrypto.c プロジェクト: ciz/openssl
static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
    struct digest_ctx *digest_from =
        (struct digest_ctx *)EVP_MD_CTX_md_data(from);
    struct digest_ctx *digest_to =
        (struct digest_ctx *)EVP_MD_CTX_md_data(to);
    struct cphash_op cphash;

    if (digest_from == NULL || digest_from->init_called != 1)
        return 1;

    if (!digest_init(to)) {
        SYSerr(SYS_F_IOCTL, errno);
        return 0;
    }

    cphash.src_ses = digest_from->sess.ses;
    cphash.dst_ses = digest_to->sess.ses;
    if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
        SYSerr(SYS_F_IOCTL, errno);
        return 0;
    }
    return 1;
}
コード例 #14
0
void add_http_test(testitem_t *t)
{
	http_data_t *httptest;

	char *dnsip = NULL;
	ssloptions_t *sslopt = NULL;
	char *sslopt_ciphers = NULL;
	int sslopt_version = SSLVERSION_DEFAULT;
	char *sslopt_clientcert = NULL;
	int  httpversion = HTTPVER_11;
	cookielist_t *ck = NULL;
	int firstcookie = 1;
	char *decodedurl;
	strbuffer_t *httprequest = newstrbuffer(0);

	/* Allocate the private data and initialize it */
	httptest = (http_data_t *) calloc(1, sizeof(http_data_t));
	t->privdata = (void *) httptest;

	decodedurl = decode_url(t->testspec, &httptest->weburl);
	if (!decodedurl) {
		errprintf("Invalid URL for http check: %s\n", t->testspec);
		return;
	}

	httptest->url = strdup(decodedurl);
	httptest->contlen = -1;
	httptest->parsestatus = (httptest->weburl.proxyurl ? httptest->weburl.proxyurl->parseerror : httptest->weburl.desturl->parseerror);

	/* If there was a parse error in the URL, dont run the test */
	if (httptest->parsestatus) return;


	if (httptest->weburl.proxyurl && (httptest->weburl.proxyurl->ip == NULL)) {
		dnsip = dnsresolve(httptest->weburl.proxyurl->host);
		if (dnsip) {
			httptest->weburl.proxyurl->ip = strdup(dnsip);
		}
		else {
			dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.proxyurl->host);
		}
	}
	else if (httptest->weburl.desturl->ip == NULL) {
		dnsip = dnsresolve(httptest->weburl.desturl->host);
		if (dnsip) {
			httptest->weburl.desturl->ip = strdup(dnsip);
		}
		else {
			dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.desturl->host);
		}
	}

	switch (httptest->weburl.testtype) {
	  case WEBTEST_PLAIN:
	  case WEBTEST_STATUS:
		httptest->contentcheck = CONTENTCHECK_NONE;
		break;

	  case WEBTEST_CONTENT:
		{
			FILE *contentfd;
			char contentfn[PATH_MAX];
			sprintf(contentfn, "%s/content/%s.substring", xgetenv("XYMONHOME"), commafy(t->host->hostname));
			contentfd = fopen(contentfn, "r");
			if (contentfd) {
				char l[MAX_LINE_LEN];
				char *p;

				if (fgets(l, sizeof(l), contentfd)) {
					p = strchr(l, '\n'); if (p) { *p = '\0'; };
					httptest->weburl.expdata = strdup(l);
				}
				else {
					httptest->contstatus = STATUS_CONTENTMATCH_NOFILE;
				}
				fclose(contentfd);
			}
			else {
				httptest->contstatus = STATUS_CONTENTMATCH_NOFILE;
			}
			httptest->contentcheck = CONTENTCHECK_REGEX;
		}
		break;

	  case WEBTEST_CONT:
		httptest->contentcheck = ((*httptest->weburl.expdata == '#') ?  CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX);
		break;

	  case WEBTEST_NOCONT:
		httptest->contentcheck = CONTENTCHECK_NOREGEX;
		break;

	  case WEBTEST_POST:
	  case WEBTEST_SOAP:
		if (httptest->weburl.expdata == NULL) {
			httptest->contentcheck = CONTENTCHECK_NONE;
		}
		else {
			httptest->contentcheck = ((*httptest->weburl.expdata == '#') ?  CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX);
		}
		break;

	  case WEBTEST_NOPOST:
	  case WEBTEST_NOSOAP:
		if (httptest->weburl.expdata == NULL) {
			httptest->contentcheck = CONTENTCHECK_NONE;
		}
		else {
			httptest->contentcheck = CONTENTCHECK_NOREGEX;
		}
		break;

	  case WEBTEST_TYPE:
		httptest->contentcheck = CONTENTCHECK_CONTENTTYPE;
		break;
	}

	/* Compile the hashes and regex's for those tests that use it */
	switch (httptest->contentcheck) {
	  case CONTENTCHECK_DIGEST:
		{
			char *hashfunc;

			httptest->exp = (void *) strdup(httptest->weburl.expdata+1);
			hashfunc = strchr(httptest->exp, ':');
			if (hashfunc) {
				*hashfunc = '\0';
				httptest->digestctx = digest_init(httptest->exp);
				*hashfunc = ':';
			}
		}
		break;

	  case CONTENTCHECK_REGEX:
	  case CONTENTCHECK_NOREGEX:
		{
			int status;

			httptest->exp = (void *) malloc(sizeof(regex_t));
			status = regcomp((regex_t *)httptest->exp, httptest->weburl.expdata, REG_EXTENDED|REG_NOSUB);
			if (status) {
				errprintf("Failed to compile regexp '%s' for URL %s\n", httptest->weburl.expdata, httptest->url);
				httptest->contstatus = STATUS_CONTENTMATCH_BADREGEX;
			}
		}
		break;

	  case CONTENTCHECK_CONTENTTYPE:
		httptest->exp = httptest->weburl.expdata;
		break;
	}

	if (httptest->weburl.desturl->schemeopts) {
		if      (strstr(httptest->weburl.desturl->schemeopts, "3"))      sslopt_version = SSLVERSION_V3;
		else if (strstr(httptest->weburl.desturl->schemeopts, "2"))      sslopt_version = SSLVERSION_V2;

		if      (strstr(httptest->weburl.desturl->schemeopts, "h"))      sslopt_ciphers = ciphershigh;
		else if (strstr(httptest->weburl.desturl->schemeopts, "m"))      sslopt_ciphers = ciphersmedium;

		if      (strstr(httptest->weburl.desturl->schemeopts, "10"))     httpversion    = HTTPVER_10;
		else if (strstr(httptest->weburl.desturl->schemeopts, "11"))     httpversion    = HTTPVER_11;
	}

	/* Get any cookies */
	load_cookies();

	/* Generate the request */
	addtobuffer(httprequest, (httptest->weburl.postdata ? "POST " : "GET "));
	switch (httpversion) {
		case HTTPVER_10: 
			addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl));
			addtobuffer(httprequest, " HTTP/1.0\r\n"); 
			break;

		case HTTPVER_11: 
			/*
			 * Experience shows that even though HTTP/1.1 says you should send the
			 * full URL, some servers (e.g. SunOne App server 7) choke on it.
			 * So just send the good-old relative URL unless we're proxying.
			 */
			addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl));
			addtobuffer(httprequest, " HTTP/1.1\r\n"); 
			addtobuffer(httprequest, "Connection: close\r\n"); 
			break;
	}

	addtobuffer(httprequest, "Host: ");
	addtobuffer(httprequest, httptest->weburl.desturl->host);
	if ((httptest->weburl.desturl->port != 80) && (httptest->weburl.desturl->port != 443)) {
		char hostporthdr[20];

		sprintf(hostporthdr, ":%d", httptest->weburl.desturl->port);
		addtobuffer(httprequest, hostporthdr);
	}
	addtobuffer(httprequest, "\r\n");

	if (httptest->weburl.postdata) {
		char hdr[100];
		int contlen = strlen(httptest->weburl.postdata);

		if (strncmp(httptest->weburl.postdata, "file:", 5) == 0) {
			/* Load the POST data from a file */
			FILE *pf = fopen(httptest->weburl.postdata+5, "r");
			if (pf == NULL) {
				errprintf("Cannot open POST data file %s\n", httptest->weburl.postdata+5);
				xfree(httptest->weburl.postdata);
				httptest->weburl.postdata = strdup("");
				contlen = 0;
			}
			else {
				struct stat st;

				if (fstat(fileno(pf), &st) == 0) {
					int n;

					xfree(httptest->weburl.postdata);
					httptest->weburl.postdata = (char *)malloc(st.st_size + 1); *(httptest->weburl.postdata) = '\0';
					n = fread(httptest->weburl.postdata, 1, st.st_size, pf);
					if (n == st.st_size) {
						*(httptest->weburl.postdata+n) = '\0';
						contlen = n;
					}
					else {
						errprintf("Cannot read file %s: %s\n", httptest->weburl.postdata+5, strerror(errno));
						contlen = 0;
					}
				}
				else {
					errprintf("Cannot stat file %s\n", httptest->weburl.postdata+5);
					httptest->weburl.postdata = strdup("");
					contlen = 0;
				}

				fclose(pf);
			}
		}

		addtobuffer(httprequest, "Content-type: ");
		if      (httptest->weburl.postcontenttype) 
			addtobuffer(httprequest, httptest->weburl.postcontenttype);
		else if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) 
			addtobuffer(httprequest, "application/soap+xml; charset=utf-8");
		else 
			addtobuffer(httprequest, "application/x-www-form-urlencoded");
		addtobuffer(httprequest, "\r\n");

		sprintf(hdr, "Content-Length: %d\r\n", contlen);
		addtobuffer(httprequest, hdr);
	}
	{
		char useragent[100];
		void *hinfo;
		char *browser = NULL;

		hinfo = hostinfo(t->host->hostname);
		if (hinfo) browser = xmh_item(hinfo, XMH_BROWSER);

		if (browser) {
			sprintf(useragent, "User-Agent: %s\r\n", browser);
		}
		else {
			sprintf(useragent, "User-Agent: Xymon xymonnet/%s\r\n", VERSION);
		}

		addtobuffer(httprequest, useragent);
	}
	if (httptest->weburl.desturl->auth) {
		if (strncmp(httptest->weburl.desturl->auth, "CERT:", 5) == 0) {
			sslopt_clientcert = httptest->weburl.desturl->auth+5;
		}
		else {
			addtobuffer(httprequest, "Authorization: Basic ");
			addtobuffer(httprequest, base64encode(httptest->weburl.desturl->auth));
			addtobuffer(httprequest, "\r\n");
		}
	}
	if (httptest->weburl.proxyurl && httptest->weburl.proxyurl->auth) {
		addtobuffer(httprequest, "Proxy-Authorization: Basic ");
		addtobuffer(httprequest, base64encode(httptest->weburl.proxyurl->auth));
		addtobuffer(httprequest, "\r\n");
	}
	for (ck = cookiehead; (ck); ck = ck->next) {
		int useit = 0;

		if (ck->tailmatch) {
			int startpos = strlen(httptest->weburl.desturl->host) - strlen(ck->host);

			if (startpos > 0) useit = (strcmp(httptest->weburl.desturl->host+startpos, ck->host) == 0);
		}
		else useit = (strcmp(httptest->weburl.desturl->host, ck->host) == 0);
		if (useit) useit = (strncmp(ck->path, httptest->weburl.desturl->relurl, strlen(ck->path)) == 0);

		if (useit) {
			if (firstcookie) {
				addtobuffer(httprequest, "Cookie: ");
				firstcookie = 0;
			}
			addtobuffer(httprequest, ck->name);
			addtobuffer(httprequest, "=");
			addtobuffer(httprequest, ck->value);
			addtobuffer(httprequest, "\r\n");
		}
	}

	/* Some standard stuff */
	addtobuffer(httprequest, "Accept: */*\r\n");
	addtobuffer(httprequest, "Pragma: no-cache\r\n");

	if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) {
		/* Must provide a SOAPAction header */
		addtobuffer(httprequest, "SOAPAction: ");
		addtobuffer(httprequest, httptest->url);
		addtobuffer(httprequest, "\r\n");
	}
	
	/* The final blank line terminates the headers */
	addtobuffer(httprequest, "\r\n");

	/* Post data goes last */
	if (httptest->weburl.postdata) addtobuffer(httprequest, httptest->weburl.postdata);

	/* Pickup any SSL options the user wants */
	if (sslopt_ciphers || (sslopt_version != SSLVERSION_DEFAULT) || sslopt_clientcert){
		sslopt = (ssloptions_t *) malloc(sizeof(ssloptions_t));
		sslopt->cipherlist = sslopt_ciphers;
		sslopt->sslversion = sslopt_version;
		sslopt->clientcert = sslopt_clientcert;
	}

	/* Add to TCP test queue */
	if (httptest->weburl.proxyurl == NULL) {
		httptest->tcptest = add_tcp_test(httptest->weburl.desturl->ip, 
						 httptest->weburl.desturl->port, 
						 httptest->weburl.desturl->scheme,
						 sslopt, t->srcip,
						 t->testspec, t->silenttest, grabstrbuffer(httprequest), 
						 httptest, tcp_http_data_callback, tcp_http_final_callback);
	}
	else {
		httptest->tcptest = add_tcp_test(httptest->weburl.proxyurl->ip, 
						 httptest->weburl.proxyurl->port, 
						 httptest->weburl.proxyurl->scheme,
						 sslopt, t->srcip,
						 t->testspec, t->silenttest, grabstrbuffer(httprequest), 
						 httptest, tcp_http_data_callback, tcp_http_final_callback);
	}
}
コード例 #15
0
ファイル: hash_df.c プロジェクト: Heyvaert/ipxe-1
/**
 * Distribute entropy throughout a buffer
 *
 * @v hash		Underlying hash algorithm
 * @v input		Input data
 * @v input_len		Length of input data, in bytes
 * @v output		Output buffer
 * @v output_len	Length of output buffer, in bytes
 *
 * This is the Hash_df function defined in ANS X9.82 Part 3-2007
 * Section 10.5.2 (NIST SP 800-90 Section 10.4.1).
 *
 * The number of bits requested is implicit in the length of the
 * output buffer.  Requests must be for an integral number of bytes.
 *
 * The output buffer is filled incrementally with each iteration of
 * the central loop, rather than constructing an overall "temp" and
 * then taking the leftmost(no_of_bits_to_return) bits.
 *
 * There is no way for the Hash_df function to fail.  The returned
 * status SUCCESS is implicit.
 */
void hash_df ( struct digest_algorithm *hash, const void *input,
	       size_t input_len, void *output, size_t output_len ) {
	uint8_t context[hash->ctxsize];
	uint8_t digest[hash->digestsize];
	size_t frag_len;
	struct {
		uint8_t pad[3];
		uint8_t counter;
		uint32_t no_of_bits_to_return;
	} __attribute__ (( packed )) prefix;
	void *temp;
	size_t remaining;

	DBGC ( &hash_df, "HASH_DF input:\n" );
	DBGC_HDA ( &hash_df, 0, input, input_len );

	/* Sanity checks */
	assert ( input != NULL );
	assert ( output != NULL );

	/* 1.  temp = the Null string
	 * 2.  len = ceil ( no_of_bits_to_return / outlen )
	 *
	 * (Nothing to do.  We fill the output buffer incrementally,
	 * rather than constructing the complete "temp" in-memory.
	 * "len" is implicit in the number of iterations required to
	 * fill the output buffer, and so is not calculated
	 * explicitly.)
	 */

	/* 3.  counter = an 8-bit binary value representing the integer "1" */
	prefix.counter = 1;

	/* 4.  For i = 1 to len do */
	for ( temp = output, remaining = output_len ; remaining > 0 ; ) {

		/* Comment: in step 5.1 (sic), no_of_bits_to_return is
		 * used as a 32-bit string.
		 *
		 * 4.1  temp = temp || Hash ( counter || no_of_bits_to_return
		 *                            || input_string )
		 */
		prefix.no_of_bits_to_return = htonl ( output_len * 8 );
		digest_init ( hash, context );
		digest_update ( hash, context, &prefix.counter,
				( sizeof ( prefix ) -
				  offsetof ( typeof ( prefix ), counter ) ) );
		digest_update ( hash, context, input, input_len );
		digest_final ( hash, context, digest );

		/* 4.2  counter = counter + 1 */
		prefix.counter++;

		/* 5.    requested_bits = Leftmost ( no_of_bits_to_return )
		 *       of temp
		 *
		 * (We fill the output buffer incrementally.)
		 */
		frag_len = sizeof ( digest );
		if ( frag_len > remaining )
			frag_len = remaining;
		memcpy ( temp, digest, frag_len );
		temp += frag_len;
		remaining -= frag_len;
	}

	/* 6.  Return SUCCESS and requested_bits */
	DBGC ( &hash_df, "HASH_DF output:\n" );
	DBGC_HDA ( &hash_df, 0, output, output_len );
	return;
}
コード例 #16
0
ファイル: setup-newfiles.c プロジェクト: Kotty666/xymon
int main(int argc, char *argv[])
{
	char srcfn[PATH_MAX];
	char destfn[PATH_MAX];
	char *p;
	struct stat st;
	unsigned char *sumbuf = NULL;

	if (argc > 2) {
		if (stat(argv[2], &st) == 0) {
			FILE *sumfd;
			printf("Loading md5-data ... ");
			sumfd = fopen(argv[2], "r");
			if (sumfd) {
				sumbuf = (char *)malloc(st.st_size + 1);
				if (fread(sumbuf, 1, st.st_size, sumfd) == st.st_size) {
					printf("OK\n");
				}
				else {
					printf("failed\n");
					free(sumbuf);
					sumbuf = NULL;
				}
				fclose(sumfd);
			}
			else {
				printf("failed\n");
			}
		}
	}

	while (fgets(srcfn, sizeof(srcfn), stdin)) {
		FILE *fd;
		unsigned char buf[8192];
		size_t buflen;
		digestctx_t *ctx;
		char srcmd5[40];
		char *md5sum;

		p = strchr(srcfn, '\n'); if (p) *p = '\0';

		strcpy(destfn, argv[1]);
		p = srcfn;
		if (strcmp(srcfn, ".") == 0) p = "";
		else if (strncmp(p, "./", 2) == 0) p += 2;
		strcat(destfn, p);

		*srcmd5 = '\0';
		if (((fd = fopen(srcfn, "r")) != NULL) && ((ctx = digest_init("md5")) != NULL)) {
			while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) digest_data(ctx, buf, buflen);
			strcpy(srcmd5, digest_done(ctx));
			fclose(fd);
		}

		if (stat(destfn, &st) == 0) {
			/* Destination file exists, see if it's a previous version */

			if (sumbuf == NULL) continue; /* No md5-data, don't overwrite an existing file */
			if (!S_ISREG(st.st_mode)) continue;

			fd = fopen(destfn, "r"); if (fd == NULL) continue;
			if ((ctx = digest_init("md5")) == NULL) continue;
			while ((buflen = fread(buf, 1, sizeof(buf), fd)) > 0) digest_data(ctx, buf, buflen);
			md5sum = digest_done(ctx);
			fclose(fd);

			if (strstr(sumbuf, md5sum) == NULL) continue;  /* Not one of our known versions */
			if (strcmp(srcmd5, md5sum) == 0) continue; /* Already installed */

			/* We now know the destination that exists is just one of our old files */
			printf("Updating old standard file %s\n", destfn);
			unlink(destfn);
		}
		else {
			printf("Installing new file %s\n", destfn);
		}

		if (lstat(srcfn, &st) != 0) {
			printf("Error - cannot lstat() %s\n", srcfn);
			return 1;
		}

		if (S_ISREG(st.st_mode)) {
			FILE *infd, *outfd;
			char buf[16384];
			int n;

			infd = fopen(srcfn, "r");
			if (infd == NULL) {
				/* Don't know how this can happen, but .. */
				fprintf(stderr, "Cannot open input file %s: %s\n", srcfn, strerror(errno));
				return 1;
			}
			outfd = fopen(destfn, "w");
			if (outfd == NULL) {
				/* Don't know how this can happen, but .. */
				fprintf(stderr, "Cannot create output file %s: %s\n", destfn, strerror(errno));
				return 1;
			}
			fchmod(fileno(outfd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
			while ( (n = fread(buf, 1, sizeof(buf), infd)) > 0) fwrite(buf, 1, n, outfd);
			fclose(infd); fclose(outfd);
		}
		else if (S_ISDIR(st.st_mode)) {
			struct stat tmpst;

			/* Create upper-lying directories */
			if (*destfn == '/') p = strchr(destfn+1, '/'); else p = strchr(destfn, '/');
			while (p) {
				*p = '\0';
				if ((stat(destfn, &tmpst) == 0) || (mkdir(destfn, st.st_mode) == 0)) { 
					*p = '/'; 
					p = strchr(p+1, '/');
				}
				else p = NULL;
			}

			/* Create the directory itself */
			if (stat(destfn, &tmpst) == -1) mkdir(destfn, st.st_mode);
			chmod(destfn, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
		}
		else if (S_ISLNK(st.st_mode)) {
			char ldest[PATH_MAX + 1];

			memset(ldest, 0, sizeof(ldest));
			if ((readlink(srcfn, ldest, sizeof(ldest)-1) != -1) && (symlink(ldest, destfn) == 0)) {};
		}
	}

	return 0;
}
コード例 #17
0
/**
 * Initialise HTTP Digest
 *
 * @v ctx		Digest context
 * @v string		Initial string
 */
static void http_digest_init ( struct md5_context *ctx ) {

	/* Initialise MD5 digest */
	digest_init ( &md5_algorithm, ctx );
}