/** * 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); }
/* 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; }