예제 #1
0
/**
 * Authenticates a connection
 *
 * Returns 1 when it worked, or 0 when it didn't - with the error_message set.
 */
int mongo_connection_authenticate(mongo_con_manager *manager, mongo_connection *con, char *database, char *username, char *password, char *nonce, char **error_message)
{
	mcon_str      *packet;
	char          *data_buffer, *errmsg;
	double         ok;
	char          *ptr;
	char          *salted;
	int            length;
	char          *hash, *key;

	mongo_manager_log(manager, MLOG_CON, MLOG_INFO, "authenticate: start");

	/* Calculate hash=md5(${username}:mongo:${password}) */
	length = strlen(username) + 7 + strlen(password) + 1;
	salted = malloc(length);
	snprintf(salted, length, "%s:mongo:%s", username, password);
	hash = mongo_util_md5_hex(salted, length - 1); /* -1 to chop off \0 */
	free(salted);
	mongo_manager_log(manager, MLOG_CON, MLOG_FINE, "authenticate: hash=md5(%s:mongo:%s) = %s", username, password, hash);

	/* Calculate key=md5(${nonce}${username}${hash}) */
	length = strlen(nonce) + strlen(username) + strlen(hash) + 1;
	salted = malloc(length);
	snprintf(salted, length, "%s%s%s", nonce, username, hash);
	key = mongo_util_md5_hex(salted, length - 1); /* -1 to chop off \0 */
	free(salted);
	mongo_manager_log(manager, MLOG_CON, MLOG_FINE, "authenticate: key=md5(%s%s%s) = %s", nonce, username, hash, key);

	packet = bson_create_authenticate_packet(con, database, username, nonce, key);

	free(hash);
	free(key);

	if (!mongo_connect_send_packet(manager, con, packet, &data_buffer, error_message)) {
		free(data_buffer);
		return 0;
	}

	/* Find data fields */
	ptr = data_buffer + sizeof(int32_t); /* Skip the length */

	/* Find errmsg */
	if (bson_find_field_as_double(ptr, "ok", &ok)) {
		if (ok > 0) {
			mongo_manager_log(manager, MLOG_CON, MLOG_INFO, "authentication successful");
		} else {
			mongo_manager_log(manager, MLOG_CON, MLOG_WARN, "authentication failed");
		}
	}
	if (bson_find_field_as_string(ptr, "errmsg", &errmsg)) {
		*error_message = malloc(256);
		snprintf(*error_message, 256, "Authentication failed on database '%s' with username '%s': %s", database, username, errmsg);
		free(data_buffer);
		return 0;
	}

	free(data_buffer);

	return 1;
}
/**
 * Authenticates a connection using MONGODB-CR
 *
 * Returns:
 * 0: when it didn't work - with the error_message set.
 * 1: when it worked
 */
int mongo_connection_authenticate_mongodb_cr(mongo_con_manager *manager, mongo_connection *con, mongo_server_options *options, char *database, char *username, char *password, char *nonce, char **error_message)
{
	mcon_str      *packet;
	char          *salted;
	int            length;
	char          *hash, *key;

	mongo_manager_log(manager, MLOG_CON, MLOG_INFO, "authenticate: start");

	/* Calculate hash=md5(${username}:mongo:${password}) */
	length = strlen(username) + 7 + strlen(password) + 1;
	salted = malloc(length);
	snprintf(salted, length, "%s:mongo:%s", username, password);
	hash = mongo_util_md5_hex(salted, length - 1); /* -1 to chop off \0 */
	free(salted);
	mongo_manager_log(manager, MLOG_CON, MLOG_FINE, "authenticate: hash=md5(%s:mongo:%s) = %s", username, password, hash);

	/* Calculate key=md5(${nonce}${username}${hash}) */
	length = strlen(nonce) + strlen(username) + strlen(hash) + 1;
	salted = malloc(length);
	snprintf(salted, length, "%s%s%s", nonce, username, hash);
	key = mongo_util_md5_hex(salted, length - 1); /* -1 to chop off \0 */
	free(salted);
	mongo_manager_log(manager, MLOG_CON, MLOG_FINE, "authenticate: key=md5(%s%s%s) = %s", nonce, username, hash, key);

	/* BC: Do not send MONGODB-CR as mechanism, won't work on older mongod */
	packet = bson_create_authenticate_packet(con, NULL, database, username, nonce, key);

	free(hash);
	free(key);

	return mongo_connection_authenticate_cmd(manager, con, options, database, username, packet, error_message);
}
예제 #3
0
/* Creates a hash out of the password so that we can store it in the connection hash.
 * The format of this hash is md5(PID,PASSWORD,USERNAME). */
char *mongo_server_create_hashed_password(char *username, char *password)
{
	int salt_length, length;
	char *hash, *salt;

	/* First we create a hash for the password to store (md5(pid,password,username)) */
	salt_length = strlen(password) + strlen(username) + 10 + 1; /* 10 for the 32bit int at max size */
	salt = malloc(salt_length);
	length = snprintf(salt, salt_length, "%d%s%s", getpid(), password, username);
	hash = mongo_util_md5_hex(salt, length);
	free(salt);

	return hash;
}