Пример #1
0
/*
 * rotn_error --
 *	Display an error from this module in a standard way.
 */
static int
rotn_error(ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err,
    const char *msg)
{
	WT_EXTENSION_API *wtext;

	wtext = encryptor->wtext;
	(void)wtext->err_printf(wtext, session,
	    "rotn encryption: %s: %s", msg, wtext->strerror(wtext, NULL, err));
	return (err);
}
Пример #2
0
/*
 * csv_extract --
 *	WiredTiger CSV extraction.
 */
static int
csv_extract(WT_EXTRACTOR *extractor, WT_SESSION *session,
    const WT_ITEM *key, const WT_ITEM *value, WT_CURSOR *result_cursor)
{
	char *copy, *p, *pend, *valstr;
	const CSV_EXTRACTOR *csv_extractor;
	int i, ret, val;
	size_t len;
	WT_EXTENSION_API *wtapi;

	(void)key;				/* Unused parameters */

	csv_extractor = (const CSV_EXTRACTOR *)extractor;
	wtapi = csv_extractor->wt_api;

	/* Unpack the value. */
	if ((ret = wtapi->struct_unpack(wtapi,
	    session, value->data, value->size, "S", &valstr)) != 0)
		return (ret);

	p = valstr;
	pend = strchr(p, ',');
	for (i = 0; i < csv_extractor->field && pend != NULL; i++) {
		p = pend + 1;
		pend = strchr(p, ',');
	}
	if (i == csv_extractor->field) {
		if (pend == NULL)
			pend = p + strlen(p);
		/*
		 * The key we must return is a null terminated string, but p
		 * is not necessarily NULL-terminated.  So make a copy, just
		 * for the duration of the insert.
		 */
		len = (size_t)(pend - p);
		if ((copy = malloc(len + 1)) == NULL)
			return (errno);
		strncpy(copy, p, len);
		copy[len] = '\0';
		if (csv_extractor->format_isnum) {
			if ((val = atoi(copy)) < 0) {
				free(copy);
				return (EINVAL);
			}
			result_cursor->set_key(result_cursor, val);
		} else
			result_cursor->set_key(result_cursor, copy);
		ret = result_cursor->insert(result_cursor);
		free(copy);
		if (ret != 0)
			return (ret);
	}
	return (0);
}
Пример #3
0
/*
 * rotn_configure --
 *	WiredTiger no-op encryption configuration.
 */
static int
rotn_configure(ROTN_ENCRYPTOR *rotn_encryptor, WT_CONFIG_ARG *config)
{
	WT_CONFIG_ITEM k, v;
	WT_CONFIG_PARSER *config_parser;
	WT_EXTENSION_API *wtext;	/* Extension API */
	int ret, t_ret;

	wtext = rotn_encryptor->wtext;

	/* Get the configuration string. */
	if ((ret = wtext->config_get(wtext, NULL, config, "config", &v)) != 0)
		return (rotn_error(rotn_encryptor, NULL, ret,
		    "WT_EXTENSION_API.config_get"));

	/* Step through the list of configuration options. */
	if ((ret = wtext->config_parser_open(
	    wtext, NULL, v.str, v.len, &config_parser)) != 0)
		return (rotn_error(rotn_encryptor, NULL, ret,
		    "WT_EXTENSION_API.config_parser_open"));

	while ((ret = config_parser->next(config_parser, &k, &v)) == 0) {
		if (strncmp("rotn_force_error", k.str, k.len) == 0 &&
		    strlen("rotn_force_error") == k.len) {
			rotn_encryptor->force_error = v.val == 0 ? 0 : 1;
			continue;
		} else {
			if ((ret = config_parser->close(config_parser)) != 0)
				return (rotn_error(rotn_encryptor,
				    NULL, ret, "WT_CONFIG_PARSER.close"));
			return (rotn_error(rotn_encryptor, NULL, EINVAL,
			    "unknown config key"));
		}
	}
	if ((t_ret = config_parser->close(config_parser)) != 0)
		return (rotn_error(rotn_encryptor, NULL, t_ret,
		    "WT_CONFIG_PARSER.close"));
	if (ret != WT_NOTFOUND)
		return (rotn_error(rotn_encryptor, NULL, ret,
		    "WT_CONFIG_PARSER.next"));

	return (0);
}
Пример #4
0
/*
 * csv_customize --
 *	The customize function creates a customized extractor,
 *	needed to save the field number and format.
 */
static int
csv_customize(WT_EXTRACTOR *extractor, WT_SESSION *session,
    const char *uri, WT_CONFIG_ITEM *appcfg, WT_EXTRACTOR **customp)
{
	const CSV_EXTRACTOR *orig;
	CSV_EXTRACTOR *csv_extractor;
	WT_CONFIG_ITEM field, format;
	WT_CONFIG_PARSER *parser;
	WT_EXTENSION_API *wtapi;
	int ret;
	long field_num;

	(void)session;				/* Unused parameters */
	(void)uri;				/* Unused parameters */

	orig = (const CSV_EXTRACTOR *)extractor;
	wtapi = orig->wt_api;
	if ((ret = wtapi->config_parser_open(wtapi, session, appcfg->str,
	    appcfg->len, &parser)) != 0)
		return (ret);
	if ((ret = parser->get(parser, "field", &field)) != 0 ||
	    (ret = parser->get(parser, "format", &format)) != 0) {
		if (ret == WT_NOTFOUND)
			return (EINVAL);
		return (ret);
	}
	field_num = strtol(field.str, NULL, 10);
	if (field_num < 0 || field_num > INT_MAX)
		return (EINVAL);
	if (format.len != 1 || (format.str[0] != 'S' && format.str[0] != 'i'))
		return (EINVAL);
	if ((csv_extractor = calloc(1, sizeof(CSV_EXTRACTOR))) == NULL)
		return (errno);

	*csv_extractor = *orig;
	csv_extractor->field = field_num;
	csv_extractor->format_isnum = (format.str[0] == 'i');
	*customp = (WT_EXTRACTOR *)csv_extractor;
	return (0);
}
Пример #5
0
/*
 * rotn_customize --
 *	The customize function creates a customized encryptor
 */
static int
rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session,
    WT_CONFIG_ARG *encrypt_config, WT_ENCRYPTOR **customp)
{
	const ROTN_ENCRYPTOR *orig;
	ROTN_ENCRYPTOR *rotn_encryptor;
	WT_CONFIG_ITEM keyid, secret;
	WT_EXTENSION_API *wtext;
	size_t i, len;
	int ret, keyid_val;
	u_char base;

	ret = 0;
	keyid_val = 0;

	orig = (const ROTN_ENCRYPTOR *)encryptor;
	wtext = orig->wtext;

	if ((rotn_encryptor = calloc(1, sizeof(ROTN_ENCRYPTOR))) == NULL)
		return (errno);
	*rotn_encryptor = *orig;
	rotn_encryptor->keyid = rotn_encryptor->secretkey = NULL;

	/*
	 * Stash the keyid from the configuration string.
	 */
	if ((ret = wtext->config_get(wtext, session, encrypt_config,
	    "keyid", &keyid)) == 0 && keyid.len != 0) {
		/*
		 * In this demonstration, we expect keyid to be a number.
		 */
		if ((keyid_val = atoi(keyid.str)) < 0) {
			ret = EINVAL;
			goto err;
		}
		if ((rotn_encryptor->keyid = malloc(keyid.len + 1)) == NULL) {
			ret = errno;
			goto err;
		}
		strncpy(rotn_encryptor->keyid, keyid.str, keyid.len + 1);
		rotn_encryptor->keyid[keyid.len] = '\0';
	}

	/*
	 * In this demonstration, the secret key must be alphabetic characters.
	 * We stash the secret key from the configuration string
	 * and build some shift bytes to make encryption/decryption easy.
	 */
	if ((ret = wtext->config_get(wtext, session, encrypt_config,
	    "secretkey", &secret)) == 0 && secret.len != 0) {
		len = secret.len;
		if ((rotn_encryptor->secretkey = malloc(len + 1)) == NULL ||
		    (rotn_encryptor->shift_forw = malloc(len)) == NULL ||
		    (rotn_encryptor->shift_back = malloc(len)) == NULL) {
			ret = errno;
			goto err;
		}
		for (i = 0; i < len; i++) {
			if ('a' <= secret.str[i] && secret.str[i] <= 'z')
				base = 'a';
			else if ('A' <= secret.str[i] && secret.str[i] <= 'Z')
				base = 'A';
			else {
				ret = EINVAL;
				goto err;
			}
			base -= (u_char)keyid_val;
			rotn_encryptor->shift_forw[i] =
			    (u_char)secret.str[i] - base;
			rotn_encryptor->shift_back[i] =
			    base - (u_char)secret.str[i];
		}
		rotn_encryptor->shift_len = len;
		strncpy(rotn_encryptor->secretkey, secret.str, secret.len + 1);
		rotn_encryptor->secretkey[secret.len] = '\0';
	}

	/*
	 * In a real encryptor, we could use some sophisticated key management
	 * here to map the keyid onto a secret key.
	 */
	rotn_encryptor->rot_N = keyid_val;

	*customp = (WT_ENCRYPTOR *)rotn_encryptor;
	return (0);

err:	free(rotn_encryptor->keyid);
	free(rotn_encryptor->secretkey);
	free(rotn_encryptor->shift_forw);
	free(rotn_encryptor->shift_back);
	free(rotn_encryptor);
	return (ret);
}
Пример #6
0
/*
 * dump_config --
 *	Dump the config for the uri.
 */
static int
dump_config(WT_SESSION *session, const char *uri, int hex)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;
	WT_EXTENSION_API *wtext;
	int tret;
	const char *value;

	/* Dump the config. */
	if (WT_PREFIX_MATCH(uri, "table:")) {
		/* Open a metadata cursor. */
		if ((ret = session->open_cursor(
		    session, "metadata:", NULL, NULL, &cursor)) != 0) {
			fprintf(stderr, "%s: %s: session.open_cursor: %s\n",
			    progname, "metadata:", wiredtiger_strerror(ret));
			return (1);
		}
		/*
		 * Search for the object itself, just to make sure it exists,
		 * we don't want to output a header if the user entered the
		 * wrong name.  This where we find out a table object doesn't
		 * exist, use a simple error message.
		 */
		cursor->set_key(cursor, uri);
		if ((ret = cursor->search(cursor)) == 0) {
			if (dump_prefix(hex) != 0 ||
			    dump_table_config(session, cursor, uri) != 0 ||
			    dump_suffix() != 0)
				ret = 1;
		} else if (ret == WT_NOTFOUND)
			ret = util_err(0, "%s: No such object exists", uri);
		else
			ret = util_err(ret, "%s", uri);

		if ((tret = cursor->close(cursor)) != 0) {
			tret = util_cerr(uri, "close", tret);
			if (ret == 0)
				ret = tret;
		}
	} else {
		/*
		 * We want to be able to dump the metadata file itself, but the
		 * configuration for that file lives in the turtle file.  Reach
		 * down into the library and ask for the file's configuration,
		 * that will work in all cases.
		 *
		 * This where we find out a file object doesn't exist, use a
		 * simple error message.
		 */
		wtext = session->
		    connection->get_extension_api(session->connection);
		if ((ret =
		    wtext->metadata_search(wtext, session, uri, &value)) == 0) {
			if (dump_prefix(hex) != 0 ||
			    print_config(session, uri, value, NULL) != 0 ||
			    dump_suffix() != 0)
				ret = 1;
		} else if (ret == WT_NOTFOUND)
			ret = util_err(0, "%s: No such object exists", uri);
		else
			ret = util_err(ret, "%s", uri);
	}

	return (ret);
}
Пример #7
0
/*
 * rotate_customize --
 *	The customize function creates a customized encryptor
 */
static int
rotate_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session,
    WT_CONFIG_ARG *encrypt_config, WT_ENCRYPTOR **customp)
{
	MY_CRYPTO *my_crypto;
	WT_CONFIG_ITEM keyid, secret;
	WT_EXTENSION_API *extapi;
	int ret;
	const MY_CRYPTO *orig_crypto;

	extapi = session->connection->get_extension_api(session->connection);

	orig_crypto = (const MY_CRYPTO *)encryptor;
	if ((my_crypto = calloc(1, sizeof(MY_CRYPTO))) == NULL) {
		ret = errno;
		goto err;
	}
	*my_crypto = *orig_crypto;
	my_crypto->keyid = my_crypto->password = NULL;

	/*
	 * Stash the keyid and the (optional) secret key from the configuration
	 * string.
	 */
	error_check(extapi->config_get(
	    extapi, session, encrypt_config, "keyid", &keyid));
	if (keyid.len != 0) {
		if ((my_crypto->keyid = malloc(keyid.len + 1)) == NULL) {
			ret = errno;
			goto err;
		}
		strncpy(my_crypto->keyid, keyid.str, keyid.len + 1);
		my_crypto->keyid[keyid.len] = '\0';
	}

	ret = extapi->config_get(
	    extapi, session, encrypt_config, "secretkey", &secret);
	if (ret == 0 && secret.len != 0) {
		if ((my_crypto->password = malloc(secret.len + 1)) == NULL) {
			ret = errno;
			goto err;
		}
		strncpy(my_crypto->password, secret.str, secret.len + 1);
		my_crypto->password[secret.len] = '\0';
	}
	/*
	 * Presumably we'd have some sophisticated key management
	 * here that maps the id onto a secret key.
	 */
	if (ITEM_MATCHES(keyid, "system")) {
		if (my_crypto->password == NULL ||
		    strcmp(my_crypto->password, SYS_PW) != 0) {
			ret = EPERM;
			goto err;
		}
		my_crypto->rot_N = 13;
	} else if (ITEM_MATCHES(keyid, USER1_KEYID))
		my_crypto->rot_N = 4;
	else if (ITEM_MATCHES(keyid, USER2_KEYID))
		my_crypto->rot_N = 19;
	else {
		ret = EINVAL;
		goto err;
	}

	++my_crypto->num_calls;		/* Call count */

	*customp = (WT_ENCRYPTOR *)my_crypto;
	return (0);

err:	free(my_crypto->keyid);
	free(my_crypto->password);
	free(my_crypto);
	return (ret);
}