// Check the user's password, return 1 if OK static int check_password(const char *method, const char *ha1, const char *uri, const char *nonce, const char *nc, const char *cnonce, const char *qop, const char *response) { char ha2[32 + 1], expected_response[32 + 1]; // Some of the parameters may be NULL if (method == NULL || nonce == NULL || nc == NULL || cnonce == NULL || qop == NULL || response == NULL) { return 0; } // NOTE(lsm): due to a bug in MSIE, we do not compare the URI // TODO(lsm): check for authentication timeout if (// strcmp(dig->uri, c->ouri) != 0 || strlen(response) != 32 // || now - strtoul(dig->nonce, NULL, 10) > 3600 ) { return 0; } mg_md5(ha2, method, ":", uri, NULL); mg_md5(expected_response, ha1, ":", nonce, ":", nc, ":", cnonce, ":", qop, ":", ha2, NULL); return mg_strcasecmp(response, expected_response) == 0; }
END_TEST START_TEST(test_mg_md5) { char buf[33]; char *ret; const char *long_str = "_123456789A123456789B123456789C123456789D123456789E123456789F123456789" "G123456789H123456789I123456789J123456789K123456789L123456789M123456789" "N123456789O123456789P123456789Q123456789R123456789S123456789T123456789" "U123456789V123456789W123456789X123456789Y123456789Z"; memset(buf, 77, sizeof(buf)); ret = mg_md5(buf, NULL); ck_assert_str_eq(buf, "d41d8cd98f00b204e9800998ecf8427e"); ck_assert_str_eq(ret, "d41d8cd98f00b204e9800998ecf8427e"); ck_assert_ptr_eq(ret, buf); memset(buf, 77, sizeof(buf)); ret = mg_md5(buf, "The quick brown fox jumps over the lazy dog.", NULL); ck_assert_str_eq(buf, "e4d909c290d0fb1ca068ffaddf22cbd0"); ck_assert_str_eq(ret, "e4d909c290d0fb1ca068ffaddf22cbd0"); ck_assert_ptr_eq(ret, buf); memset(buf, 77, sizeof(buf)); ret = mg_md5(buf, "", "The qu", "ick bro", "", "wn fox ju", "m", "ps over the la", "", "", "zy dog.", "", NULL); ck_assert_str_eq(buf, "e4d909c290d0fb1ca068ffaddf22cbd0"); ck_assert_str_eq(ret, "e4d909c290d0fb1ca068ffaddf22cbd0"); ck_assert_ptr_eq(ret, buf); memset(buf, 77, sizeof(buf)); ret = mg_md5(buf, long_str, NULL); ck_assert_str_eq(buf, "1cb13cf9f16427807f081b2138241f08"); ck_assert_str_eq(ret, "1cb13cf9f16427807f081b2138241f08"); ck_assert_ptr_eq(ret, buf); memset(buf, 77, sizeof(buf)); ret = mg_md5(buf, long_str + 1, NULL); ck_assert_str_eq(buf, "cf62d3264334154f5779d3694cc5093f"); ck_assert_str_eq(ret, "cf62d3264334154f5779d3694cc5093f"); ck_assert_ptr_eq(ret, buf); }
/* * Edit the passwords file. */ static int mg_edit_passwords(const char *fname, const char *domain, const char *user, const char *pass) { int ret = EXIT_SUCCESS, found = 0; char line[512], u[512], d[512], ha1[33], tmp[FILENAME_MAX]; FILE *fp = NULL, *fp2 = NULL; (void) snprintf(tmp, sizeof(tmp), "%s.tmp", fname); /* Create the file if does not exist */ if ((fp = fopen(fname, "a+")) != NULL) (void) fclose(fp); /* Open the given file and temporary file */ if ((fp = fopen(fname, "r")) == NULL) { fprintf(stderr, "Cannot open %s: %s", fname, strerror(errno)); exit(EXIT_FAILURE); } else if ((fp2 = fopen(tmp, "w+")) == NULL) { fprintf(stderr, "Cannot open %s: %s", tmp, strerror(errno)); exit(EXIT_FAILURE); } /* Copy the stuff to temporary file */ while (fgets(line, sizeof(line), fp) != NULL) { if (sscanf(line, "%[^:]:%[^:]:%*s", u, d) != 2) continue; if (!strcmp(u, user) && !strcmp(d, domain)) { found++; mg_md5(ha1, user, ":", domain, ":", pass, NULL); (void) fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); } else { (void) fprintf(fp2, "%s", line); } } /* If new user, just add it */ if (!found) { mg_md5(ha1, user, ":", domain, ":", pass, NULL); (void) fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); } /* Close files */ (void) fclose(fp); (void) fclose(fp2); /* Put the temp file in place of real file */ (void) remove(fname); (void) rename(tmp, fname); return (ret); }
// Return 1 if username/password is allowed, 0 otherwise. int Ntop::checkUserPassword(const char *user, const char *password) { char key[64], val[64]; char password_hash[33]; if(user == NULL) return(false); snprintf(key, sizeof(key), "user.%s.password", user); if(ntop->getRedis()->get(key, val, sizeof(val)) < 0) { return(false); } else { mg_md5(password_hash, password, NULL); return(strcmp(password_hash, val) == 0); } }
int Ntop::addUser(char *username, char *full_name, char *password) { char key[64]; char password_hash[33]; // FIX add a seed mg_md5(password_hash, password, NULL); snprintf(key, sizeof(key), "user.%s.full_name", username); ntop->getRedis()->set(key, full_name, 0); snprintf(key, sizeof(key), "user.%s.group", username); ntop->getRedis()->set(key, (char*) "administrator" /* TODO */, 0); snprintf(key, sizeof(key), "user.%s.password", username); return(ntop->getRedis()->set(key, password_hash, 0) >= 0); }
int Ntop::resetUserPassword(char *username, char *old_password, char *new_password) { char key[64]; char password_hash[33]; if (!checkUserPassword(username, old_password)) return(false); snprintf(key, sizeof(key), "user.%s.password", username); mg_md5(password_hash, new_password, NULL); if(ntop->getRedis()->set(key, password_hash, 0) < 0) return(false); return(true); }
void generate_htpasswd(char* password) { char *strBuff; char digest[33]; int len; FILE *pFile; if(strlen(password) == 0) { printf("\n"); return; } // Generate the digest to hash len = strlen(username) + strlen(realm) + strlen(password) + 2 + 1; // we need 2 : characters, plus null strBuff = (char*)malloc(len * sizeof(char)); strcpy(strBuff, username); strcat(strBuff, ":"); strcat(strBuff, realm); strcat(strBuff, ":"); strcat(strBuff, password); // Calculate the digest mg_md5(digest, strBuff, NULL); // Clear the undigested string from memory free(strBuff); // Write the digest file pFile = fopen("resources/.htpasswd", "w"); if(pFile != NULL) { len = strlen(username) + strlen(realm) + 2 + 32 + 1; // 2 for the :, 32 for the md5 hash, 1 for null strBuff = (char*)malloc(len * sizeof(char)); strcpy(strBuff, username); strcat(strBuff, ":"); strcat(strBuff, realm); strcat(strBuff, ":"); strcat(strBuff, digest); fwrite(strBuff, sizeof(char), len-1, pFile); fwrite("\r\n", sizeof(char), 2, pFile); fclose(pFile); // Clear the digested string from memory free(strBuff); printf(".htpasswd generated successfully!\n\nUsername: \t\t%s\nPassword: \t\t%s\n", username, password); } else { printf("Failed to generate .htpasswd!\n"); return; } }
bool Ntop::resetUserPassword(char *username, char *old_password, char *new_password) { char key[64]; char password_hash[33]; if((old_password != NULL) && (old_password[0] != '\0')) { if(!checkUserPassword(username, old_password)) return(false); } snprintf(key, sizeof(key), CONST_STR_USER_PASSWORD, username); mg_md5(password_hash, new_password, NULL); if(ntop->getRedis()->set(key, password_hash, 0) < 0) return(false); return(true); }
// Return 1 if username/password is allowed, 0 otherwise. bool Ntop::checkUserPassword(const char *user, const char *password) { char key[64], val[64]; if((user == NULL) || (user[0] == '\0')) return(false); snprintf(key, sizeof(key), CONST_STR_USER_PASSWORD, user); if(ntop->getRedis()->get(key, val, sizeof(val)) < 0) { return(false); } else { char password_hash[33]; mg_md5(password_hash, password, NULL); return((strcmp(password_hash, val) == 0) ? true : false); } }
bool Ntop::addUser(char *username, char *full_name, char *password, char *host_role, char *allowed_networks) { char key[64]; char password_hash[33]; // FIX add a seed mg_md5(password_hash, password, NULL); snprintf(key, sizeof(key), CONST_STR_USER_FULL_NAME, username); ntop->getRedis()->set(key, full_name, 0); snprintf(key, sizeof(key), CONST_STR_USER_GROUP, username); ntop->getRedis()->set(key, (char*) host_role /* TODO: done Paola */, 0); snprintf(key, sizeof(key), CONST_STR_USER_PASSWORD, username); ntop->getRedis()->set(key, password_hash, 0); snprintf(key, sizeof(key), CONST_STR_USER_NETS, username); ntop->getRedis()->set(key, allowed_networks, 0); return(true); // TODO add check return return(ntop->getRedis()->set(key, password_hash, 0) >= 0); }
int modify_passwords_file(const char *fname, const char *domain, const char *user, const char *pass) { int found; char line[512], u[512], d[512], ha1[33], tmp[PATH_MAX]; FILE *fp, *fp2; found = 0; fp = fp2 = NULL; // Regard empty password as no password - remove user record. if (pass != NULL && pass[0] == '\0') { pass = NULL; } (void) snprintf(tmp, sizeof(tmp), "%s.tmp", fname); // Create the file if does not exist if ((fp = fopen(fname, "a+")) != NULL) { fclose(fp); } // Open the given file and temporary file if ((fp = fopen(fname, "r")) == NULL) { return 0; } else if ((fp2 = fopen(tmp, "w+")) == NULL) { fclose(fp); return 0; } // Copy the stuff to temporary file while (fgets(line, sizeof(line), fp) != NULL) { if (sscanf(line, "%[^:]:%[^:]:%*s", u, d) != 2) { continue; } if (!strcmp(u, user) && !strcmp(d, domain)) { found++; if (pass != NULL) { mg_md5(ha1, user, ":", domain, ":", pass, NULL); fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); } } else { fprintf(fp2, "%s", line); } } // If new user, just add it if (!found && pass != NULL) { mg_md5(ha1, user, ":", domain, ":", pass, NULL); fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); } // Close files fclose(fp); fclose(fp2); // Put the temp file in place of real file remove(fname); rename(tmp, fname); return 1; }
// Generate session ID. buf must be 33 bytes in size. // Note that it is easy to steal session cookies by sniffing traffic. // This is why all communication must be SSL-ed. static void generate_session_id(char *buf, const char *random, const char *user) { mg_md5(buf, random, user, NULL); }
static void generate_ssid(const char *user_name, const char *expiration_date, char *ssid, size_t ssid_size) { char hash[33]; mg_md5(hash, user_name, ":", expiration_date, ":", s_secret, NULL); snprintf(ssid, ssid_size, "%s|%s|%s", user_name, expiration_date, hash); }