コード例 #1
0
bool_t check_encoding_zbase32(void) {

	stringer_t *zb32, *binary;
	byte_t buffer[ZBASE32_CHECK_SIZE];

	for (uint64_t i = 0; status() && i < ZBASE32_CHECK_ITERATIONS; i++) {

		// Fill the buffer with random data and convert the buffer to hex.
		if (rand_write(PLACER(buffer, ZBASE32_CHECK_SIZE)) != ZBASE32_CHECK_SIZE) {
			return false;
		}
		else if (!(zb32 = zbase32_encode(PLACER(buffer, ZBASE32_CHECK_SIZE)))) {
			return false;
		}

		//log_pedantic("zb32 = %.*s", st_length_int(zb32), st_char_get(zb32));

		// Convert the buffer back to binary and compare it with the original array.
		if (!(binary = zbase32_decode(zb32))) {
			st_free(zb32);
			return false;
		}
		else if (st_cmp_cs_eq(binary, PLACER(buffer, ZBASE32_CHECK_SIZE))) {
			st_free(binary);
			st_free(zb32);
			return false;
		}

		st_free(binary);
		st_free(zb32);
	}

	return true;
}
コード例 #2
0
ファイル: mode_fix.c プロジェクト: alexkhmara/shntool
static bool reopen_input_file(int i,progress_info *proginfo)
{
  unsigned char *header;

  if (!open_input_stream(files[i])) {
    prog_error(proginfo);
    st_warning("could not reopen input file: [%s]",files[i]->filename);
    return FALSE;
  }

  if (NULL == (header = malloc(files[i]->header_size * sizeof(unsigned char)))) {
    prog_error(proginfo);
    st_warning("could not allocate %d-byte WAVE header",files[i]->header_size);
    return FALSE;
  }

  if (read_n_bytes(files[i]->input,header,files[i]->header_size,NULL) != files[i]->header_size) {
    prog_error(proginfo);
    st_warning("error while reading %d-byte WAVE header",files[i]->header_size);
    st_free(header);
    return FALSE;
  }

  st_free(header);

  return TRUE;
}
コード例 #3
0
ファイル: bzip.c プロジェクト: 503serviceunavailable/magma
/**
 * @brief	Decompress data using the bzip engine.
 * @param	compressed	a pointer to the head of the compressed data.
 * @return	NULL on failure, or a managed string containing the uncompressed data on success.
 */
stringer_t * decompress_bzip(compress_t *compressed) {

	int ret;
	void *bptr;
	uint64_t hash, rlen, blen;
	stringer_t *result = NULL;
	compress_head_t *head;

	if (!(head = (compress_head_t *)compressed)) {
		log_info("Invalid compression header. {compress_head = NULL}");
		return NULL;
	} else if (head->engine != COMPRESS_ENGINE_BZIP) {
		log_info("The buffer passed in was not compressed using the BZIP engine. {engine = %hhu}", head->engine);
		return NULL;
	} else if (!(bptr = compress_body_data(compressed)) || !(blen = head->length.compressed) || !(rlen = head->length.original) || head->hash.compressed != (hash = hash_adler32(bptr, blen))) {
		log_info("The compressed has been corrupted. {expected = %lu / input = %lu}", head->hash.compressed, hash);
		return NULL;
	} else if (!(result = st_alloc(head->length.original + 1))) {
		log_info("Could not allocate a block of %lu bytes for the uncompressed data.", head->length.original);
		return NULL;
	} else if ((ret = BZ2_bzBuffToBuffDecompress_d(st_data_get(result), (unsigned int *)&rlen, bptr, blen, 0, 0)) != BZ_OK) {
		log_info("Unable to decompress the buffer. {BZ2_bzBuffToBuffDecompress = %i}", ret);
		st_free(result);
		return NULL;
	} else if (head->length.original != rlen || head->hash.original != (hash = hash_adler32(st_data_get(result), rlen))) {
		log_info("The uncompressed data is corrupted. {input = %lu != %lu / hash = %lu != %lu}", head->length.original, rlen, head->hash.original, hash);
		st_free(result);
		return NULL;
	}

	st_length_set(result, rlen);
	return result;
}
コード例 #4
0
ファイル: main.c プロジェクト: 503serviceunavailable/magma
bool_t check_string_dupe(char *type, uint32_t check) {

	size_t len;
	stringer_t *s, *d;

	if (!(s = st_alloc(check, st_length_int(constant)))) {
		return false;
	}

	len = snprintf(st_char_get(s), st_length_int(constant) + 1, "%.*s", st_length_int(constant), st_char_get(constant));
	if (check & MAPPED_T || check & MANAGED_T) {
		st_length_set(s, len);
	}

	if (!(d = st_dupe(s))) {
		st_free(s);
		return false;
	}

	log_print("%28.28s = %.*s", type, st_length_int(d), st_char_get(d));

	if (memcmp(st_char_get(d), st_char_get(s), st_length_get(s))) {
		st_free(s);
		st_free(d);
		return false;
	}

	st_free(s);
	st_free(d);

	return true;
}
コード例 #5
0
ファイル: string_check.c プロジェクト: lavabit/magma
bool_t check_string_dupe(uint32_t check) {

	size_t len;
	stringer_t *s, *d;

	if (!(s = st_alloc_opts(check, st_length_int(string_check_constant)))) {
		return false;
	}

	len = snprintf(st_char_get(s), st_length_int(string_check_constant) + 1, "%.*s", st_length_int(string_check_constant), st_char_get(string_check_constant));
	if ((check & MAPPED_T) || (check & MANAGED_T)) {
		st_length_set(s, len);
	}

	if (!(d = st_dupe(s))) {
		st_free(s);
		return false;
	}

	if (memcmp(st_char_get(d), st_char_get(s), st_length_get(s))) {
		st_free(s);
		st_free(d);
		return false;
	}

	st_free(s);
	st_free(d);

	return true;
}
コード例 #6
0
ファイル: qp_check.c プロジェクト: lavabit/magma
bool_t check_encoding_qp(void) {

	stringer_t *qp, *binary;
	byte_t buffer[QP_CHECK_SIZE];

	for (uint64_t i = 0; status() && i < QP_CHECK_ITERATIONS; i++) {

		// Fill the buffer with random data and convert the buffer to hex.
		if (rand_write(PLACER(buffer, QP_CHECK_SIZE)) != QP_CHECK_SIZE) {
			return false;
		}
		else if (!(qp = qp_encode(PLACER(buffer, QP_CHECK_SIZE)))) {
			return false;
		}

		//log_pedantic("qp = %.*s", st_length_int(qp), st_char_get(qp));

		// Convert the buffer back to binary and compare it with the original array.
		if (!(binary = qp_decode(qp))) {
			st_free(qp);
			return false;
		}
		else if (st_cmp_cs_eq(binary, PLACER(buffer, QP_CHECK_SIZE))) {
			st_free(binary);
			st_free(qp);
			return false;
		}

		st_free(binary);
		st_free(qp);
	}

	return true;
}
コード例 #7
0
ファイル: st-input.c プロジェクト: va1erian/panda-smalltalk
void
st_input_destroy (st_input *input)
{
    st_assert (input != NULL);

    st_free (input->text);
    st_free (input);
}
コード例 #8
0
ファイル: mime.c プロジェクト: 503serviceunavailable/magma
/**
 * @brief	Get the subtype of the Content-Type header value from a mime header.
 * @note	For example in the case of a Content-Type of 'text/plain', "plain" would be the subtype.
 * @param	header	a placer pointing to the mime header to be parsed.
 * @return	a managed string containing the content subtype of the header, with "plain" as the default.
 */
stringer_t * mail_mime_type_sub(placer_t header) {

	chr_t *stream;
	stringer_t *line, *result;
	size_t remaining, characters = 0;

	if (!(line = mail_header_fetch_cleaned(&header, PLACER("Content-Type", 12)))) {
		return st_import("plain", 5);
	}

	stream = st_char_get(line);
	remaining = st_length_get(line);

	// Advance past any garbage.
	while (remaining && (*stream == '\n' || *stream == '\r' || *stream == ' ' || *stream == '\t' || *stream == '"')) {
		stream++;
		remaining--;
	}

	// Count how many characters are in the group. Based on RFC4288, section 4.2.
	while (remaining && ((*stream >= 'a' && *stream <= 'z') || (*stream >= 'A' && *stream <= 'Z') || (*stream >= '0' && *stream <= '9') ||
		*stream == '!' || *stream == '#' || *stream == '$' || *stream == '&' || *stream == '.' || *stream == '+' || *stream == '-' ||
		*stream == '^' || *stream == '_')) {
		stream++;
		remaining--;
	}

	// Make sure we got something back. Use a default value of plain.
	if (!remaining || *stream != '/') {
		st_free(line);
		return st_import("plain", 5);
	}

	// Advance past the separator.
	stream++;
	remaining--;

	// Count how many characters are in the subtype. Based on RFC4288, section 4.2.
	while (remaining != 0 && ((*stream >= 'a' && *stream <= 'z') || (*stream >= 'A' && *stream <= 'Z') || (*stream >= '0' && *stream <= '9') ||
		*stream == '!' || *stream == '#' || *stream == '$' || *stream == '&' || *stream == '.' || *stream == '+' || *stream == '-' ||
		*stream == '^' || *stream == '_')) {
		stream++;
		remaining--;
		characters++;
	}

	// Make sure we got something back. Use a default value of text.
	if (!characters) {
		st_free(line);
		return st_import("plain", 5);
	}

	result = st_import(stream - characters, characters);
	st_free(line);

	return result;
}
コード例 #9
0
ファイル: main.c プロジェクト: 503serviceunavailable/magma
// Check that we can't specify a length greater than the available buffer.
bool_t check_string_logic(uint32_t check) {

	stringer_t *s;

	if (!(s = st_alloc(check, 128)) || st_length_set(s, st_avail_get(s) * 2) != st_avail_get(s)) {
		if (s)
			st_free(s);
		return false;
	}

	st_free(s);
	return true;
}
コード例 #10
0
// QUESTION: Why are we using managed strings here? It makes no sense, especially since we have expectations as to where they point.
// QUESTION: And why even have message? It seems like we could make do with just having part.
size_t mail_discover_insertion_point(stringer_t *message, stringer_t *part, int_t type) {

	chr_t *stream;
	size_t length;
	stringer_t *tag;

	// If the message is not HTML, return the end of the part as the insertion point.
	if (type != MESSAGE_TYPE_HTML) {
		return st_char_get(part) - st_char_get(message) + st_length_get(part);
	}

	// Get setup.
	length = st_length_get(part);
	stream = st_data_get(part) + length - 1;

	while (length) {

		// Reverse until we find a character that is not whitespace.
		while (length && (*stream == ' ' || *stream == '\r' || *stream == '\n' || *stream == '\t')) {
			length--;
			stream--;
		}

		if (!(tag = mail_extract_tag(stream, length))) {
			return (st_char_get(part) - st_char_get(message)) + length;
		}

		// What tag is it?
		if (st_cmp_ci_eq(tag, PLACER("</body>", 7)) != 0 && st_cmp_ci_eq(tag, PLACER("</html>", 7)) != 0) {
			st_free(tag);
			return (st_char_get(part) - st_char_get(message)) + length;
		}

		st_free(tag);

		// Advance past this tag.
		while (length && *stream != '<') {
			length--;
			stream--;
		}

		if (length && *stream == '<') {
			length--;
			stream--;
		}

	}

	return (st_char_get(part) - st_char_get(message)) + length;
}
コード例 #11
0
ファイル: st-input.c プロジェクト: va1erian/panda-smalltalk
char *
st_input_next_chunk (st_input *input)
{
    char *chunk_filtered, *chunk = NULL;
    st_uint start;

    start = st_input_index (input);

    while (st_input_look_ahead (input, 1) != ST_INPUT_EOF) {

	if (st_input_look_ahead (input, 1) != '!') {
	    st_input_consume (input);
	    continue;
	}
	
	/* skip past doubled bangs */
	if (st_input_look_ahead (input, 1) == '!'
	    && st_input_look_ahead (input, 2) == '!') {
	    st_input_consume (input);
	    st_input_consume (input);
	    continue;
	}

	chunk = st_input_range (input, start, st_input_index (input));	
	chunk_filtered = filter_double_bangs (chunk);
	st_input_consume (input);
	st_free (chunk);	

	return chunk_filtered;
    }

    return NULL;
}
コード例 #12
0
ファイル: hex.c プロジェクト: lavabit/magma
/**
 * @brief	Allocates an output string of appropriate size with specified opts for hex decoding of input
 * @param	input	Input stringer to be decoded.
 * @return	NULL on failure, otherwise allocated stringer with decoded data.
 */
stringer_t * hex_decode_opts(stringer_t *input, uint32_t opts) {

	stringer_t *result = NULL;
	size_t insize;

	if(st_empty(input)) {
		log_pedantic("Empty stringer was passed in.");
	}

	if(!opts) {
		log_pedantic("Invalid stringer options were passed in.");
		goto error;
	}

	insize = st_length_get(input);

	if(!(result = st_alloc_opts(opts, (insize % 2) ? ((insize + 1) / 2) : (insize / 2) ))) {
		log_error("Failed to allocate memory for hex-encoded output.");
		goto error;
	}

	if(result != hex_decode_st(input, result)) {
		log_error("Failed to encode data.");
		goto cleanup_result;
	}

	return result;

cleanup_result:
	st_free(result);
error:
	return NULL;
}
コード例 #13
0
ファイル: pop.c プロジェクト: 503serviceunavailable/magma
/**
 * @brief	Accept a username for POP3 authentication.
 * @note	This command is only allowed for sessions which have not yet been authenticated.
 * 			If the username has already been supplied pre-authentication, the old value will be overwritten with the new one.
 * @param	con		the POP3 client connection issuing the command.
 * @brief	This function returns no value.
 */
void pop_user(connection_t *con) {

	stringer_t *username, *clean;

	if (con->pop.session_state != 0) {
		pop_invalid(con);
		return;
	}

	// If they didn't pass in a valid username.
	if (!(username = pop_user_parse(con)) || !(clean = credential_address(username))) {
		con_write_bl(con, "-ERR Invalid USER command.\r\n", 28);
		st_cleanup(username);
		return;
	}

	// Check for a previously provided value and free it.
	st_cleanup(con->pop.username);
	st_free(username);

	// Store the value we were given. Until authentication, this will be the fully qualified username.
	con->pop.username = clean;

	// Tell the client everything worked.
	con_write_bl(con, "+OK Username accepted.\r\n", 24);

	return;
}
コード例 #14
0
/**
 * @brief	Insert a spam signature training link into a plain text message part.
 * @see		mail_discover_insertion_point()
 * @param	server		the server object of the web server where the teacher application is hosted.
 * @param	message		a managed string containing the message body to be parsed.
 * @param	part		a managed string (placer) containing the part of the message where the signature should be inserted.
 * @param	signum		the spam signature number referenced by the teacher url.
 * @param	sigkey		the spam signature key for client verification in the teacher app.
 * @param	disposition	if 0, the message disposition is "innocent"; otherwise, the disposition specifies "spam".
 * @param	type		the encoding type of the message (MESSAGE_TYPE_HTML or other).
 * @param	encoding	if MESSAGE_ENCODING_QUOTED_PRINTABLE, set the encoding type to qp.
 * @return	NULL on failure or a managed string containing the message with the inserted signature training link on success.
 */
stringer_t * mail_insert_chunk_text(server_t *server, stringer_t *message, stringer_t *part, uint64_t signum, uint64_t sigkey, int_t disposition, int_t type, int_t encoding) {

	size_t point;
	stringer_t *pretext;
	stringer_t *posttext;
	stringer_t *result;
	stringer_t *signature;

	if (st_empty(part)) {
		return NULL;
	}

	// Start at the end of the chunk and search for where to insert the signature.
	if (!(signature = mail_build_signature(server, type, encoding, signum, sigkey, disposition))) {
		return NULL;
	}

	// Figure out the insertion point_t and create the new message.
	point = mail_discover_insertion_point(message, part, type);
	pretext = PLACER(st_char_get(message), point);
	posttext = PLACER(st_char_get(message) + point, st_length_get(message) - point);
	result = st_merge("sss", pretext, signature, posttext);

	st_free(signature);

	if (!result) {
		log_pedantic("Unable to merge the strings together.");
	}

	return result;
}
コード例 #15
0
ファイル: bitwise_check.c プロジェクト: lavabit/magma
bool_t check_bitwise_simple(void) {

	stringer_t *a, *b, *outcome, *check;
	unsigned char    a_buf[] = {0x00, 0xFF, 0x88, 0x44, 0x22};
	unsigned char    b_buf[] = {0x11, 0x33, 0xF0, 0x0F, 0x3C};
	unsigned char  xor_buf[] = {0x11, 0xCC, 0x78, 0x4B, 0x1E};
	unsigned char  and_buf[] = {0x00, 0x33, 0x80, 0x04, 0x20};
	unsigned char   or_buf[] = {0x11, 0xFF, 0xF8, 0x4F, 0x3E};
	unsigned char nota_buf[] = {0xFF, 0x00, 0x77, 0xBB, 0xDD};

	a = PLACER(a_buf, 5);
	b = PLACER(b_buf, 5);
	check = PLACER(xor_buf, 5);

	if(!(outcome = st_xor(a, b, NULL)) || st_cmp_cs_eq(outcome, check)) {
		st_cleanup(outcome);
		return false;
	}

	check = PLACER(and_buf, 5);
	st_free(outcome);

	if(!(outcome = st_and(a, b, NULL)) || st_cmp_cs_eq(outcome, check)) {
		st_cleanup(outcome);
		return false;
	}

	check = PLACER(or_buf, 5);
	st_free(outcome);

	if(!(outcome = st_or(a, b, NULL)) || st_cmp_cs_eq(outcome, check)) {
		st_cleanup(outcome);
		return false;
	}

	check = PLACER(nota_buf, 5);
	st_free(outcome);

	if(!(outcome = st_not(a, NULL)) || st_cmp_cs_eq(outcome,check)) {
		st_cleanup(outcome);
		return false;
	}

	st_free(outcome);

	return true;
}
コード例 #16
0
END_TEST

START_TEST(test_folder_exists__nonexistent) {
	stringer_t *nonex = mkstringer("/nonexistent");
	ck_assert_int_eq(-1, folder_exists(nonex, false));
	ck_assert_int_eq(-1, folder_exists(nonex, true));
	st_free(nonex);
}
コード例 #17
0
ファイル: plugin.c プロジェクト: AriaAsuka/deadbeef
void
st_close (ddb_dsp_context_t *_src) {
    ddb_soundtouch_t *st = (ddb_soundtouch_t *)_src;
    if (st->st) {
        st_free (st->st);
    }
    free (st);
}
コード例 #18
0
END_TEST

START_TEST(test_folder_exists__nested) {
	stringer_t *deepdir = mkstringer("/tmp/deeply/nested/dir");
	ck_assert_int_eq(-1, folder_exists(deepdir, false));
	ck_assert_int_eq(-1, folder_exists(deepdir, true));
	st_free(deepdir);
}
コード例 #19
0
ファイル: string_check.c プロジェクト: lavabit/magma
bool_t check_string_import(void) {

	stringer_t *s;

	if (!(s = st_import(st_data_get(string_check_constant), st_length_int(string_check_constant)))) {
		return false;
	}

	if (memcmp(st_char_get(s), st_char_get(string_check_constant), st_length_get(string_check_constant))) {
		st_free(s);
		return false;
	}

	st_free(s);

	return true;
}
コード例 #20
0
ファイル: orgs.c プロジェクト: lavabit/magma
/**
 * @brief	Derive an organizational signet from the corresponding private key structures.
 */
prime_org_signet_t * org_signet_generate(prime_org_key_t *org) {

	prime_org_signet_t *signet = NULL;
	stringer_t *signing = NULL, *encryption = NULL, *cryptographic = MANAGEDBUF(69);

	// Ensure the org structure contains the necessary private keys.
	if (!org || !org->encryption || !org->signing || org->signing->type != ED25519_PRIV) {
		return NULL;
	}
	else if (!(signet = mm_alloc(sizeof(prime_org_signet_t)))) {
		return NULL;
	}
	// Store the public singing, and encryption keys.
	else if (!(signing = ed25519_public_get(org->signing, NULL)) ||
		!(encryption = secp256k1_public_get(org->encryption, NULL))) {
		log_pedantic("PRIME organizational signet generation failed, the public keys could not be derived from the provided private keys.");
		org_signet_free(signet);
		st_cleanup(signing);
		return NULL;
	}

	// Generate a serialized signet with the cryptographic fields.
	else if (st_write(cryptographic, prime_field_write(PRIME_ORG_SIGNET, 1, ED25519_KEY_PUB_LEN, signing, MANAGEDBUF(34)),
		prime_field_write(PRIME_ORG_SIGNET, 3, SECP256K1_KEY_PUB_LEN, encryption, MANAGEDBUF(35))) != 69) {
		log_pedantic("PRIME organizational signet generation failed, the serialized cryptographic signet could not be derived.");
		org_signet_free(signet);
		st_free(encryption);
		st_free(signing);
		return NULL;
	}

	// Generate a signature using the serialized cryptographic fields.
	else if (!(signet->signature = ed25519_sign(org->signing, cryptographic, NULL))) {
		log_pedantic("PRIME organizational signet generation failed, the cryptographic signet signature could not be derived.");
		org_signet_free(signet);
		st_free(encryption);
		st_free(signing);
		return NULL;
	}

	// Finally, convert the serialized public keys into usable structures.
	else if (!(signet->signing = ed25519_public_set(signing)) || !(signet->encryption = secp256k1_public_set(encryption))) {
		log_pedantic("PRIME organizational signet generation failed, the serialized public keys could not be parsed.");
		org_signet_free(signet);
		st_free(encryption);
		st_free(signing);
		return NULL;
	}

	// We no longer need the serialized public keys.
	st_free(encryption);
	st_free(signing);

	return signet;
}
コード例 #21
0
ファイル: global.c プロジェクト: 503serviceunavailable/magma
/**
 * @brief	Free all loaded magma configuration options.
 * @note	First all magma config keys will be freed, then the cache servers, relay servers, and magma servers.
 * @return	This function returns no value.
 */
void config_free(void) {

	for (uint64_t i = 0; i < sizeof(magma_keys) / sizeof(magma_keys_t); i++) {
		switch (magma_keys[i].norm.type) {

		case (M_TYPE_BLOCK):
			if (*((void **)(magma_keys[i].store))) {
				mm_free(*((void **)(magma_keys[i].store)));
			}
			break;
		case (M_TYPE_NULLER):
			if (*((char **)(magma_keys[i].store))) {
				ns_free(*((char **)(magma_keys[i].store)));
			}
			break;
		case (M_TYPE_STRINGER):

			// Intercept the blacklist config key.
			if (!st_cmp_cs_eq(NULLER(magma_keys[i].name), PLACER("magma.smtp.blacklist", 20))) {
				for (uint32_t j = 0; j < magma.smtp.blacklists.count; j++) {
					st_free(magma.smtp.blacklists.domain[j]);
				}
			}
			else if (*((stringer_t **)(magma_keys[i].store))) {
				st_free(*((stringer_t **)(magma_keys[i].store)));
			}
			break;
		default:
#ifdef MAGMA_PEDANTIC
			if (magma_keys[i].norm.type != M_TYPE_BOOLEAN && magma_keys[i].norm.type != M_TYPE_DOUBLE && magma_keys[i].norm.type != M_TYPE_FLOAT &&
					magma_keys[i].norm.type != M_TYPE_INT16 && magma_keys[i].norm.type != M_TYPE_INT32 && magma_keys[i].norm.type != M_TYPE_INT64 &&
					magma_keys[i].norm.type != M_TYPE_INT8 && magma_keys[i].norm.type != M_TYPE_UINT8 && magma_keys[i].norm.type != M_TYPE_UINT16 &&
					magma_keys[i].norm.type != M_TYPE_UINT32 && magma_keys[i].norm.type != M_TYPE_UINT64 && magma_keys[i].norm.type != M_TYPE_ENUM) {
				log_pedantic("Unexpected type. {type = %s = %u}", type(magma_keys[i].norm.type), magma_keys[i].norm.type);
			}
#endif
			break;
		}
	}

	cache_free();
	relay_free();
	servers_free();
	return;
}
コード例 #22
0
ファイル: asn1.c プロジェクト: JaegarSarauer/DCOMM-Assign2
void
st_asn1_free_context(st_asn1_context* pContext) {
  if ((pContext == NULL) || (*pContext == NULL))
    return;
  
  if (((unsigned char*)*pContext)[0])
    st_free(*pContext);
  *pContext = NULL;
}  
コード例 #23
0
ファイル: mime.c プロジェクト: 503serviceunavailable/magma
/**
 * @brief	Generate a MIME boundary string that is unique to a collection of content.
 * @param	parts	a pointer to an array of managed strings containing the MIME children data to be separated by the boundary.
 * @return	NULL on failure, or a pointer to a managed string containing the generated boundary on success.
 */
stringer_t * mail_mime_generate_boundary (array_t *parts) {

	stringer_t *result, *cmp;
	chr_t *ptr;
	size_t blen = 16;
	int_t rnd;

	if (!parts) {
		log_pedantic("Cannot generate mime boundary with empty input data.");
		return NULL;
	}

	if (!(result = st_alloc(blen))) {
		log_error("Unable to allocate space for boundary string.");
		return NULL;
	}

	// Keep generating boundary strings until one of them is unique... we don't expect collisions to happen that often.
	while (1) {
		srand(rand_get_uint64());
		ptr = st_char_get (result);

		// Generate blen's worth of random bytes, each being either a random digit or lowercase letter.
		for (size_t i = 0; i < blen; i++) {
			rnd = rand();

			if (rnd % 2) {
				*ptr++ = '0' + (rnd % 10);
			} else {
				*ptr ++ = 'a' + (rnd % 26);
			}

		}

		st_length_set(result, blen);

		// Now make sure it's not found in any of the parts.
		for (size_t i = 0; i < ar_length_get(parts); i++) {

			if (!(cmp = (stringer_t *) ar_field_ptr(parts, i))) {
				log_pedantic("Could not generate mime boundary for null content.");
				st_free(result);
				return NULL;
			}

			if (st_search_ci(cmp, result, NULL)) {
				continue;
			}

		}

		// If we made it this far, the boundary string was not found in any of the supplied content.
		break;
	}

	return result;
}
コード例 #24
0
ファイル: request.c プロジェクト: desertsky/wonder
void req_free(HTTPRequest *req)
{
   if (req->headers) {
      st_free(req->headers);
   }
   if (req->request_str)		WOFREE(req->request_str);
   if (req->content)			WOFREE(req->content);
   WOFREE(req);
}
コード例 #25
0
ファイル: xmlparse.c プロジェクト: ATLTed/wonder
/*
 * This function cleans up all the lists and dictionaries created while parsing the config.
 */
static void freeWOXMLEdits(WOXMLEdits *config)
{
   int i;

   for (i=0; i<wolist_count(config->new_apps); i++)
      st_free(wolist_elementAt(config->new_apps, i));
   wolist_dealloc(config->new_apps);

   for (i=0; i<wolist_count(config->new_app_instances); i++)
   {
      int j;
      list *instances = wolist_elementAt(config->new_app_instances, i);
      for (j=0; j<wolist_count(instances); j++)
         st_free(wolist_elementAt(instances, j));
      wolist_dealloc(instances);
   }
   wolist_dealloc(config->new_app_instances);
}
コード例 #26
0
END_TEST

START_TEST(test_folder_exists__tmpdir) {
	stringer_t *tmpdir = mkstringer("/tmp/check_host_folder.d");
	ck_assert_int_eq(-1, folder_exists(tmpdir, false));
	ck_assert_int_eq(1, folder_exists(tmpdir, true));
	rmdir(st_data_get(tmpdir));
	st_free(tmpdir);
}
コード例 #27
0
ファイル: mime.c プロジェクト: 503serviceunavailable/magma
/**
 * @brief	Encode a MIME part for a provided block of data (file attachment) with the specified filename.
 * @note	This function will look up the media type based on the supplied filename, and use that media type as a determination
 * 			of whether the content is to be encoded as either quoted-printable or base64.
 * @param	data		a pointer to a managed string containing the body of the data to be encoded.
 * @param	filename	a pointer to a managed string containing the filename of the attachment for which the data was provided.
 * @param	boundary	a pointer to a managed string containing the boundary that will be used to separate the individual MIME parts.
 * @return	NULL on failure, or a pointer to a managed string containing the file attachment encoded as a MIME part on success.
 */
stringer_t * mail_mime_encode_part(stringer_t *data, stringer_t *filename, stringer_t *boundary) {

	stringer_t *result, *encoded;
	media_type_t *mtype;
	chr_t *fstart, *extptr = NULL, *ctype;
	size_t flen;

	if (!data) {
		return NULL;
	}

	// First get the extension of the filename so we can look up the media type.
	if (!st_empty_out(filename, (uchr_t **)&fstart, &flen)) {
		extptr = fstart + flen + 1;

		while (extptr >= fstart) {

			if (*extptr == '.') {
				break;
			}

			extptr--;
		}

		if (extptr < fstart) {
			extptr = NULL;
		}

	}

	mtype = mail_mime_get_media_type (extptr);

	if (mtype->bin) {
		encoded = base64_encode(data, NULL);
		ctype = "base64";
	} else {
		encoded = qp_encode(data);
		ctype = "quoted-printable";
	}

	if (!encoded) {
		log_pedantic("Unable to encode MIME part data.");
		return NULL;
	}

	// What we return is: boundary/CRLF, Content-Type/CRLF, Content-Transfer-Encoding/CRLF, Content-Disposition/CRLF, data/CRLF
	if (!(result = st_merge("nsnnnnnnnsns", "--------------", boundary, "\r\n", "Content-Type: ", mtype->name, ";\r\n", "Content-Transfer-Encoding: ", ctype,
			"\r\nContent-Disposition: attachment; filename=\"", filename, "\"\r\n\r\n", encoded))) {
		log_pedantic("Unable to generate MIME part data.");
		return NULL;
	}

	st_free(encoded);

	return result;
}
コード例 #28
0
ファイル: main.c プロジェクト: 503serviceunavailable/magma
bool_t check_string_import(void) {

	stringer_t *s;

	if (!(s = st_import(st_data_get(constant), st_length_int(constant)))) {
		return false;
	}

	log_print("%28.28s = %.*s", "duplicate", st_length_int(s), st_char_get(s));

	if (memcmp(st_char_get(s), st_char_get(constant), st_length_get(constant))) {
		st_free(s);
		return false;
	}

	st_free(s);

	return true;
}
コード例 #29
0
ファイル: mime.c プロジェクト: 503serviceunavailable/magma
/**
 * @brief	Get an array of the key/value pairs of parameters passed to the value of the mime Content-Type header.
 * @note	The parameters of the Content-Type header value will be examined, and each found parameter will result in the addition of
 * 			TWO managed strings to the returned array: the first containing the parameter key name, and the second with the parameter value.
 * @param	header	a placer pointing to the mime header to be parsed.
 * @return	NULL on failure, or on success, an array of managed strings structured as the key name followed by the value of each parameter
 * 			passed in the Content-Type header.
 */
array_t * mail_mime_type_parameters(placer_t header) {

	array_t *output;
	stringer_t *key, *holder;
	placer_t parameter;
	unsigned increment, tokens;

	if (!(holder = mail_header_fetch_cleaned(&header, PLACER("Content-Type", 12)))) {
		return NULL;
	}

	if ((tokens = tok_get_count_st(holder, ';')) <= 1) {
		st_free(holder);
		return NULL;
	}

	// Allocate an array.
	if (!(output = ar_alloc((tokens - 1) * 2))) {
		st_free(holder);
		return NULL;
	}

	for (increment = 1; increment < tokens; increment++) {
		tok_get_st(holder, ';', increment, &parameter);

		if ((key = mail_mime_type_parameters_key(&parameter))) {
			upper_st(key);
			ar_append(&output, ARRAY_TYPE_STRINGER, key);
			ar_append(&output, ARRAY_TYPE_STRINGER, mail_mime_type_parameters_value(&parameter));
		}

	}

	st_free(holder);

	if (!ar_length_get(output)) {
		ar_free(output);
		return NULL;
	}

	return output;
}
コード例 #30
0
ファイル: orgs.c プロジェクト: lavabit/magma
// Note that we need 1 extra byte for the 0x04 prefix taken from proposed RFC for adding EdDSA to the OpenPGP schema.
// https://tools.ietf.org/id/draft-koch-eddsa-for-openpgp.txt
void org_signet_free(prime_org_signet_t *org) {

	if (org) {
		if (org->signing) ed25519_free(org->signing);
		if (org->encryption) secp256k1_free(org->encryption);
		if (org->signature) st_free(org->signature);
		mm_free(org);
	}

	return;
}