static void mech_digest_md5_auth_continue(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { struct digest_auth_request *request = (struct digest_auth_request *)auth_request; const char *username, *error; if (parse_digest_response(request, data, data_size, &error)) { if (auth_request->realm != NULL && strchr(request->username, '@') == NULL) { username = t_strconcat(request->username, "@", auth_request->realm, NULL); auth_request->domain_is_realm = TRUE; } else { username = request->username; } if (auth_request_set_username(auth_request, username, &error) && (request->authzid == NULL || auth_request_set_login_username(auth_request, request->authzid, &error))) { auth_request_lookup_credentials(auth_request, "DIGEST-MD5", credentials_callback); return; } } if (error != NULL) auth_request_log_info(auth_request, AUTH_SUBSYS_MECH, "%s", error); auth_request_fail(auth_request); }
static void mech_cram_md5_auth_continue(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { struct cram_auth_request *request = (struct cram_auth_request *)auth_request; const char *error; if (parse_cram_response(request, data, data_size, &error)) { if (auth_request_set_username(auth_request, request->username, &error)) { auth_request_lookup_credentials(auth_request, "CRAM-MD5", credentials_callback); return; } } if (error == NULL) error = "authentication failed"; auth_request_log_info(auth_request, AUTH_SUBSYS_MECH, "%s", error); auth_request_fail(auth_request); }
static void mech_apop_auth_initial(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { struct apop_auth_request *request = (struct apop_auth_request *)auth_request; const unsigned char *tmp, *end, *username = NULL; unsigned long pid, connect_uid, timestamp; const char *error; /* pop3-login handles sending the challenge and getting the response. Our input here is: <challenge> \0 <username> \0 <response> */ if (data_size == 0) { /* Should never happen */ auth_request_log_info(auth_request, "apop", "no initial respone"); auth_request_fail(auth_request); return; } tmp = data; end = data + data_size; /* get the challenge */ while (tmp != end && *tmp != '\0') tmp++; request->challenge = p_strdup_until(request->pool, data, tmp); if (tmp != end) { /* get the username */ username = ++tmp; while (tmp != end && *tmp != '\0') tmp++; } if (tmp + 1 + 16 != end) { /* Should never happen */ auth_request_log_info(auth_request, "apop", "malformed data"); auth_request_fail(auth_request); return; } memcpy(request->response_digest, tmp + 1, sizeof(request->response_digest)); /* the challenge must begin with trusted unique ID. we trust only ourself, so make sure it matches our connection specific UID which we told to client in handshake. Also require a timestamp which is later than this process's start time. */ if (sscanf(request->challenge, "<%lx.%lx.%lx.", &pid, &connect_uid, ×tamp) != 3 || connect_uid != auth_request->connect_uid || pid != (unsigned long)getpid() || (time_t)timestamp < process_start_time) { auth_request_log_info(auth_request, "apop", "invalid challenge"); auth_request_fail(auth_request); return; } if (!auth_request_set_username(auth_request, (const char *)username, &error)) { auth_request_log_info(auth_request, "apop", "%s", error); auth_request_fail(auth_request); return; } auth_request_lookup_credentials(auth_request, "PLAIN", apop_credentials_callback); }