}
+static
+DWORD
+make_random_challenge(DWORD *challenge_out) {
+ HCRYPTPROV provider;
+ DWORD status = 0;
+ *challenge_out = 0;
+ if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ status = GetLastError();
+ cci_check_error(status);
+ return status;
+ }
+ if (!CryptGenRandom(provider, sizeof(*challenge_out),
+ (BYTE *)challenge_out)) {
+ status = GetLastError();
+ cci_check_error(status);
+ return status;
+ }
+ if (!CryptReleaseContext(provider, 0)) {
+ /*
+ * Note: even though CryptReleaseContext() failed, we don't really
+ * care since a) we've already successfully obtained our challenge
+ * anyway and b) at least one of the potential errors, "ERROR_BUSY"
+ * does not really seem to be an error at all. So GetLastError() is
+ * logged for informational purposes only and should not be returned.
+ */
+ cci_check_error(GetLastError());
+ }
+ return status;
+}
+
static
DWORD
authenticate_server(Init::InitInfo& info) {
- DWORD challenge = 17; // XXX - maybe use random number
- DWORD desired_response= challenge + 1;
+ DWORD challenge, desired_response;
HANDLE hMap = 0;
LPSTR mem_name = 0;
PDWORD pvalue = 0;
status = alloc_name(&mem_name, "auth", isNT());
cci_check_error(status);
+ if (!status) {
+ status = make_random_challenge(&challenge);
+ desired_response = challenge + 1;
+ cci_check_error(status);
+ }
+
if (!status) {
if (isNT()) {
sa.nLength = sizeof(sa);