char_t *websCalcDigest(webs_t wp) { #ifdef DIGEST_ACCESS_SUPPORT char_t *digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method; a_assert(wp); digest = NULL; /* * Calculate first portion of digest H(A1) */ a1 = NULL; fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password); a_assert(a1); a1prime = websMD5(a1); bfreeSafe(B_L, a1); /* * Calculate second portion of digest H(A2) */ method = websGetVar(wp, T("REQUEST_METHOD"), NULL); a_assert(method); a2 = NULL; fmtAlloc(&a2, 255, T("%s:%s"), method, wp->uri); a_assert(a2); a2prime = websMD5(a2); bfreeSafe(B_L, a2); /* * Construct final digest KD(H(A1):nonce:H(A2)) */ a_assert(a1prime); a_assert(a2prime); a_assert(wp->nonce); preDigest = NULL; if (!wp->qop) { fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime); } else { fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"), a1prime, wp->nonce, wp->nc, wp->cnonce, wp->qop, a2prime); } a_assert(preDigest); digest = websMD5(preDigest); /* * Now clean up */ bfreeSafe(B_L, a1prime); bfreeSafe(B_L, a2prime); bfreeSafe(B_L, preDigest); return digest; #else return NULL; #endif /* DIGEST_ACCESS_SUPPORT */ }
char_t *websCalcUrlDigest(webs_t wp) { char_t *digest, *a1, *a1prime, *a2, *a2prime, *preDigest, *method; a_assert(wp); digest = NULL; /* * Calculate first portion of digest H(A1) */ a1 = NULL; fmtAlloc(&a1, 255, T("%s:%s:%s"), wp->userName, wp->realm, wp->password); a_assert(a1); a1prime = websMD5(a1); bfreeSafe(B_L, a1); /* * Calculate second portion of digest H(A2) */ method = websGetVar(wp, T("REQUEST_METHOD"), NULL); a_assert(method); /* Fixes by Richard Laing, 2003/7/15 */ a2 = balloc(B_L, (gstrlen(method) +2 + gstrlen(wp->url) ) * sizeof(char_t)); a_assert(a2); gsprintf(a2, T("%s:%s"), method, wp->url); a2prime = websMD5(a2); bfreeSafe(B_L, a2); /* * Construct final digest KD(H(A1):nonce:H(A2)) */ a_assert(a1prime); a_assert(a2prime); a_assert(wp->nonce); preDigest = NULL; if (!wp->qop) { fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime); } else { fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"), a1prime, wp->nonce, wp->nc, wp->cnonce, wp->qop, a2prime); } a_assert(preDigest); digest = websMD5(preDigest); /* * Now clean up */ bfreeSafe(B_L, a1prime); bfreeSafe(B_L, a2prime); bfreeSafe(B_L, preDigest); return digest; }
PUBLIC bool websVerifyPassword(Webs *wp) { char passbuf[BIT_LIMIT_PASSWORD * 3 + 3]; bool success; assure(wp); if (!wp->encoded) { fmt(passbuf, sizeof(passbuf), "%s:%s:%s", wp->username, BIT_REALM, wp->password); wfree(wp->password); wp->password = websMD5(passbuf); wp->encoded = 1; } if (!wp->user && (wp->user = websLookupUser(wp->username)) == 0) { trace(5, "verifyUser: Unknown user \"%s\"", wp->username); return 0; } /* Verify the password */ if (wp->digest) { success = smatch(wp->password, wp->digest); } else { success = smatch(wp->password, wp->user->password); } if (success) { trace(5, "User \"%s\" authenticated", wp->username); } else { trace(5, "Password for user \"%s\" failed to authenticate", wp->username); } return success; }
PUBLIC bool websVerifyPasswordFromFile(Webs *wp) { char passbuf[ME_GOAHEAD_LIMIT_PASSWORD * 3 + 3]; bool success; assert(wp); if (!wp->user && (wp->user = websLookupUser(wp->username)) == 0) { trace(5, "verifyUser: Unknown user \"%s\"", wp->username); return 0; } /* Verify the password. If using Digest auth, we compare the digest of the password. Otherwise we encode the plain-text password and compare that */ if (!wp->encoded) { fmt(passbuf, sizeof(passbuf), "%s:%s:%s", wp->username, ME_GOAHEAD_REALM, wp->password); wfree(wp->password); wp->password = websMD5(passbuf); wp->encoded = 1; } if (wp->digest) { success = smatch(wp->password, wp->digest); } else { success = smatch(wp->password, wp->user->password); } if (success) { trace(5, "User \"%s\" authenticated", wp->username); } else { trace(5, "Password for user \"%s\" failed to authenticate", wp->username); } return success; }
PUBLIC int websOpenAuth(int minimal) { char sbuf[64]; assert(minimal == 0 || minimal == 1); if ((users = hashCreate(-1)) < 0) { return -1; } if ((roles = hashCreate(-1)) < 0) { return -1; } if (!minimal) { fmt(sbuf, sizeof(sbuf), "%x:%x", rand(), OSTimeGet()); secret = websMD5(sbuf); #if ME_GOAHEAD_JAVASCRIPT && FUTURE websJsDefine("can", jsCan); #endif websDefineAction("login", loginServiceProc); websDefineAction("logout", logoutServiceProc); } if (smatch(ME_GOAHEAD_AUTH_STORE, "file")) { verifyPassword = websVerifyPasswordFromFile; #if ME_COMPILER_HAS_PAM } else if (smatch(ME_GOAHEAD_AUTH_STORE, "pam")) { verifyPassword = websVerifyPasswordFromPam; #endif } return 0; }
/* Get a Digest value using the MD5 algorithm -- See RFC 2617 to understand this code. */ static char *calcDigest(Webs *wp, char *username, char *password) { char a1Buf[256], a2Buf[256], digestBuf[256]; char *ha1, *ha2, *method, *result; assure(wp); assure(username && *username); assure(password); /* Compute HA1. If username == 0, then the password is already expected to be in the HA1 format (MD5(username:realm:password). */ if (username == 0) { ha1 = sclone(password); } else { fmt(a1Buf, sizeof(a1Buf), "%s:%s:%s", username, wp->realm, password); ha1 = websMD5(a1Buf); } /* HA2 */ method = wp->method; fmt(a2Buf, sizeof(a2Buf), "%s:%s", method, wp->digestUri); ha2 = websMD5(a2Buf); /* H(HA1:nonce:HA2) */ if (scmp(wp->qop, "auth") == 0) { fmt(digestBuf, sizeof(digestBuf), "%s:%s:%s:%s:%s:%s", ha1, wp->nonce, wp->nc, wp->cnonce, wp->qop, ha2); } else if (scmp(wp->qop, "auth-int") == 0) { fmt(digestBuf, sizeof(digestBuf), "%s:%s:%s:%s:%s:%s", ha1, wp->nonce, wp->nc, wp->cnonce, wp->qop, ha2); } else { fmt(digestBuf, sizeof(digestBuf), "%s:%s:%s", ha1, wp->nonce, ha2); } result = websMD5(digestBuf); wfree(ha1); wfree(ha2); return result; }
char_t *websCalcNonce(webs_t wp) { char_t *nonce, *prenonce; time_t longTime; #if defined(WIN32) char_t buf[26]; errno_t error; struct tm newtime; #else struct tm *newtime; #endif a_assert(wp); /* * Get time as long integer. */ time(&longTime); /* * Convert to local time. */ #if !defined(WIN32) newtime = localtime(&longTime); #else error = localtime_s(&newtime, &longTime); #endif /* * Create prenonce string. */ #if !defined(WIN32) prenonce = NULL; fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime), wp->realm); #else asctime_s(buf, elementsof(buf), &newtime); fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, buf, RANDOMKEY); #endif a_assert(prenonce); /* * Create the nonce */ nonce = websMD5(prenonce); /* * Cleanup */ bfreeSafe(B_L, prenonce); return nonce; }
char_t *websCalcNonce(webs_t wp) { char_t *nonce, *prenonce; struct tm *newtime; time_t longTime; a_assert(wp); /* * Get time as long integer. */ time(&longTime); /* * Convert to local time. */ newtime = localtime(&longTime); /* * Create prenonce string. */ prenonce = NULL; #ifdef DIGEST_ACCESS_SUPPORT fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime), wp->realm); #else fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime), RANDOMKEY); #endif a_assert(prenonce); /* * Create the nonce */ nonce = websMD5(prenonce); /* * Cleanup */ bfreeSafe(B_L, prenonce); return nonce; }
PUBLIC int websOpenAuth(int minimal) { char sbuf[64]; assure(minimal == 0 || minimal == 1); if ((users = hashCreate(-1)) < 0) { return -1; } if ((roles = hashCreate(-1)) < 0) { return -1; } if (!minimal) { fmt(sbuf, sizeof(sbuf), "%x:%x", rand(), time(0)); secret = websMD5(sbuf); #if BIT_JAVASCRIPT && FUTURE websJsDefine("can", jsCan); #endif websDefineAction("login", loginServiceProc); websDefineAction("logout", logoutServiceProc); } return 0; }
int main(int argc, char *argv[]) { WebsBuf buf; char *password, *authFile, *username, *encodedPassword, *realm, *cp, *roles; int i, errflg, create, nextArg; username = 0; create = errflg = 0; password = 0; for (i = 1; i < argc && !errflg; i++) { if (argv[i][0] != '-') { break; } for (cp = &argv[i][1]; *cp && !errflg; cp++) { if (*cp == 'c') { create++; } else if (*cp == 'p') { if (++i == argc) { errflg++; } else { password = argv[i]; break; } } else { errflg++; } } } nextArg = i; if ((nextArg + 3) > argc) { errflg++; } if (errflg) { printUsage(); exit(2); } authFile = argv[nextArg++]; realm = argv[nextArg++]; username = argv[nextArg++]; bufCreate(&buf, 0, 0); for (i = nextArg; i < argc; ) { bufPutStr(&buf, argv[i]); if (++i < argc) { bufPutc(&buf, ','); } } roles = sclone(buf.servp); websOpenAuth(1); if (!create) { if (websLoad(authFile) < 0) { exit(2); } if (access(authFile, W_OK) < 0) { error("Can't write to %s", authFile); exit(4); } } else if (access(authFile, R_OK) < 0) { error("Can't create %s, already exists", authFile); exit(5); } if (!password && (password = getPassword()) == 0) { exit(1); } encodedPassword = websMD5(sfmt("%s:%s:%s", username, realm, password)); websRemoveUser(username); if (websAddUser(username, encodedPassword, roles) < 0) { exit(7); } if (writeAuthFile(authFile) < 0) { exit(6); } websCloseAuth(); return 0; }