void ne_forget_auth(ne_session *sess) { auth_session *as; if ((as = ne_get_session_private(sess, HOOK_SERVER_ID)) != NULL) clean_session(as); if ((as = ne_get_session_private(sess, HOOK_PROXY_ID)) != NULL) clean_session(as); }
static void tls_sasl_connect_ok(user_session_t * c_session, struct client_connection * client) { struct nu_srv_message msg; /* Success place */ if (nuauthconf->log_users_without_realm) { gchar *username = get_rid_of_domain(c_session->user_name); g_free(c_session->user_name); c_session->user_name = username; } if (c_session->proto_version < PROTO_VERSION_V24) { /* send mode to client */ msg.type = SRV_TYPE; if (nuauthconf->push) { msg.option = SRV_TYPE_PUSH; } else { msg.option = SRV_TYPE_POLL; } msg.length = 0; if (nussl_write(c_session->nussl, (char*)&msg, sizeof(msg)) < 0) { log_message(WARNING, DEBUG_AREA_USER, "nussl_write() failure at %s:%d", __FILE__, __LINE__); if (nuauthconf->push) { clean_session(c_session); return; } else { return; } } } c_session->workunits_queue = g_async_queue_new(); /* unlock hash client */ if (nuauthconf->push) { struct internal_message *message = g_new0(struct internal_message, 1); struct tls_insert_data *datas = g_new0(struct tls_insert_data, 1); if ((message == NULL) || (datas == NULL)) { clean_session(c_session); return; } datas->socket = client->socket; datas->data = c_session; c_session->activated = FALSE; message->datas = datas; message->type = INSERT_MESSAGE; g_async_queue_push(nuauthdatas->tls_push_queue, message); } else {
/* Examine a Basic auth challenge. * Returns 0 if an valid challenge, else non-zero. */ static int basic_challenge(auth_session *sess, struct auth_challenge *parms) { char *tmp, password[NE_ABUFSIZ]; /* Verify challenge... must have a realm */ if (parms->realm == NULL) { return -1; } NE_DEBUG(NE_DBG_HTTPAUTH, "Got Basic challenge with realm [%s]\n", parms->realm); clean_session(sess); sess->realm = ne_strdup(parms->realm); if (get_credentials(sess, password)) { /* Failed to get credentials */ return -1; } sess->scheme = auth_scheme_basic; tmp = ne_concat(sess->username, ":", password, NULL); sess->basic = ne_base64((unsigned char *)tmp, strlen(tmp)); ne_free(tmp); /* Paranoia. */ memset(password, 0, sizeof password); return 0; }
/* Examine a Basic auth challenge. * Returns 0 if an valid challenge, else non-zero. */ static int basic_challenge(http_auth_session *sess, struct http_auth_chall *parms) { char *tmp, *password; /* Verify challenge... must have a realm */ if (parms->realm == NULL) { return -1; } DEBUG(DEBUG_HTTPAUTH, "Got Basic challenge with realm [%s]\n", parms->realm); clean_session(sess); sess->unq_realm = shave_string(parms->realm, '"'); if (get_credentials(sess, &password)) { /* Failed to get credentials */ HTTP_FREE(sess->unq_realm); return -1; } sess->scheme = http_auth_scheme_basic; CONCAT3(tmp, sess->username, ":", password?password:""); sess->basic = base64(tmp); free(tmp); HTTP_FREE(password); return 0; }
static void free_auth(void *cookie) { auth_session *sess = cookie; #ifdef HAVE_GSSAPI if (sess->gssname != GSS_C_NO_NAME) { unsigned int major; gss_release_name(&major, &sess->gssname); } #endif clean_session(sess); ne_free(sess); }
static void policy_refuse_user(user_session_t * c_session, int c, policy_refused_reason_t reason) { switch (reason) { case PER_USER_TOO_MANY_LOGINS: log_message(INFO, DEBUG_AREA_USER, "Policy: Too many opened sessions for user \"%s\", closing socket", c_session->user_name); modules_auth_error_log(c_session, AUTH_ERROR_INTERRUPTED, "Too many opened sessions for user"); break; case PER_IP_TOO_MANY_LOGINS: log_message(INFO, DEBUG_AREA_USER, "Policy: User \"%s\" trying to connect from already overused IP, closing socket", c_session->user_name); modules_auth_error_log(c_session, AUTH_ERROR_INTERRUPTED, "Connection from already overused IP"); break; default: log_message(WARNING, DEBUG_AREA_USER, "Policy (bug!): User \"%s\" has to disconnect for UNKNOWN reason, closing socket", c_session->user_name); } /* get rid of client */ clean_session(c_session); }
/* Examine a digest challenge: return 0 if it is a valid Digest challenge, * else non-zero. */ static int digest_challenge(auth_session *sess, struct auth_challenge *parms) { struct ne_md5_ctx tmp; unsigned char tmp_md5[16]; char password[NE_ABUFSIZ]; /* Verify they've given us the right bits. */ if (parms->alg == auth_alg_unknown || (parms->alg == auth_alg_md5_sess && !parms->qop_auth) || parms->realm == NULL || parms->nonce == NULL) { NE_DEBUG(NE_DBG_HTTPAUTH, "Invalid challenge."); return -1; } if (parms->stale) { /* Just a stale response, don't need to get a new username/password */ NE_DEBUG(NE_DBG_HTTPAUTH, "Stale digest challenge.\n"); } else { /* Forget the old session details */ NE_DEBUG(NE_DBG_HTTPAUTH, "In digest challenge.\n"); clean_session(sess); sess->realm = ne_strdup(parms->realm); /* Not a stale response: really need user authentication */ if (get_credentials(sess, password)) { /* Failed to get credentials */ return -1; } } sess->alg = parms->alg; sess->scheme = auth_scheme_digest; sess->nonce = ne_strdup(parms->nonce); sess->cnonce = get_cnonce(); /* TODO: add domain handling. */ if (parms->opaque != NULL) { sess->opaque = ne_strdup(parms->opaque); /* don't strip the quotes */ } if (parms->got_qop) { /* What type of qop are we to apply to the message? */ NE_DEBUG(NE_DBG_HTTPAUTH, "Got qop directive.\n"); sess->nonce_count = 0; sess->qop = auth_qop_auth; } else { /* No qop at all/ */ sess->qop = auth_qop_none; } if (!parms->stale) { /* Calculate H(A1). * tmp = H(unq(username-value) ":" unq(realm-value) ":" passwd) */ NE_DEBUG(NE_DBG_HTTPAUTH, "Calculating H(A1).\n"); ne_md5_init_ctx(&tmp); ne_md5_process_bytes(sess->username, strlen(sess->username), &tmp); ne_md5_process_bytes(":", 1, &tmp); ne_md5_process_bytes(sess->realm, strlen(sess->realm), &tmp); ne_md5_process_bytes(":", 1, &tmp); ne_md5_process_bytes(password, strlen(password), &tmp); memset(password, 0, sizeof password); /* done with that. */ ne_md5_finish_ctx(&tmp, tmp_md5); if (sess->alg == auth_alg_md5_sess) { unsigned char a1_md5[16]; struct ne_md5_ctx a1; char tmp_md5_ascii[33]; /* Now we calculate the SESSION H(A1) * A1 = H(...above...) ":" unq(nonce-value) ":" unq(cnonce-value) */ ne_md5_to_ascii(tmp_md5, tmp_md5_ascii); ne_md5_init_ctx(&a1); ne_md5_process_bytes(tmp_md5_ascii, 32, &a1); ne_md5_process_bytes(":", 1, &a1); ne_md5_process_bytes(sess->nonce, strlen(sess->nonce), &a1); ne_md5_process_bytes(":", 1, &a1); ne_md5_process_bytes(sess->cnonce, strlen(sess->cnonce), &a1); ne_md5_finish_ctx(&a1, a1_md5); ne_md5_to_ascii(a1_md5, sess->h_a1); NE_DEBUG(NE_DBG_HTTPAUTH, "Session H(A1) is [%s]\n", sess->h_a1); } else { ne_md5_to_ascii(tmp_md5, sess->h_a1); NE_DEBUG(NE_DBG_HTTPAUTH, "H(A1) is [%s]\n", sess->h_a1); } } NE_DEBUG(NE_DBG_HTTPAUTH, "I like this Digest challenge.\n"); return 0; }
static int ah_post_send(ne_request *req, void *cookie, const ne_status *status) { auth_session *sess = cookie; struct auth_request *areq = ne_get_request_private(req, sess->spec->id); const char *auth_hdr, *auth_info_hdr; int ret = NE_OK; if (!areq) return NE_OK; auth_hdr = ne_get_response_header(req, sess->spec->resp_hdr); auth_info_hdr = ne_get_response_header(req, sess->spec->resp_info_hdr); if (sess->context == AUTH_CONNECT && status->code == 401 && !auth_hdr) { /* Some broken proxies issue a 401 as a proxy auth challenge * to a CONNECT request; handle this here. */ auth_hdr = ne_get_response_header(req, "WWW-Authenticate"); auth_info_hdr = NULL; } #ifdef HAVE_GSSAPI /* whatever happens: forget the GSSAPI token cached thus far */ if (sess->gssapi_token) { ne_free(sess->gssapi_token); sess->gssapi_token = NULL; } #endif NE_DEBUG(NE_DBG_HTTPAUTH, "ah_post_send (#%d), code is %d (want %d), %s is %s\n", sess->attempt, status->code, sess->spec->status_code, sess->spec->resp_hdr, auth_hdr ? auth_hdr : "(none)"); if (auth_info_hdr && sess->scheme == auth_scheme_digest) { if (verify_digest_response(areq, sess, auth_info_hdr)) { NE_DEBUG(NE_DBG_HTTPAUTH, "Response authentication invalid.\n"); ne_set_error(sess->sess, "%s", _(sess->spec->fail_msg)); ret = NE_ERROR; } } #ifdef HAVE_GSSAPI /* one must wonder... has Mr Brezak actually read RFC2617? */ else if (sess->scheme == auth_scheme_gssapi && (status->klass == 2 || status->klass == 3) && auth_hdr) { char *hdr = ne_strdup(auth_hdr); if (verify_negotiate_response(sess, hdr)) { NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Mutual auth failed.\n"); ret = NE_ERROR; } ne_free(hdr); } #endif /* HAVE_GSSAPI */ else if ((status->code == sess->spec->status_code || (status->code == 401 && sess->context == AUTH_CONNECT)) && auth_hdr) { /* note above: allow a 401 in response to a CONNECT request * from a proxy since some buggy proxies send that. */ NE_DEBUG(NE_DBG_HTTPAUTH, "Got challenge (code %d).\n", status->code); if (!auth_challenge(sess, auth_hdr)) { ret = NE_RETRY; } else { clean_session(sess); ret = sess->spec->fail_code; } } #ifdef HAVE_SSPI else if (sess->sspi_context) { ne_sspi_clear_context(sess->sspi_context); } #endif return ret; }
void do_logout() { clean_session(); fprintf(stdout, "%s", "{\"result\":0}"); }
/* Examine a digest challenge: return 0 if it is a valid Digest challenge, * else non-zero. */ static int digest_challenge(http_auth_session *sess, struct http_auth_chall *parms) { struct md5_ctx tmp; unsigned char tmp_md5[16]; char *password; /* Do we understand this challenge? */ if (parms->alg == http_auth_alg_unknown) { DEBUG(DEBUG_HTTPAUTH, "Unknown algorithm.\n"); return -1; } if ((parms->alg == http_auth_alg_md5_sess) && !(parms->qop_auth || parms->qop_auth_int)) { DEBUG(DEBUG_HTTPAUTH, "Server did not give qop with MD5-session alg.\n"); return -1; } if ((parms->realm==NULL) || (parms->nonce==NULL)) { DEBUG(DEBUG_HTTPAUTH, "Challenge missing nonce or realm.\n"); return -1; } if (parms->stale) { /* Just a stale response, don't need to get a new username/password */ DEBUG(DEBUG_HTTPAUTH, "Stale digest challenge.\n"); } else { /* Forget the old session details */ DEBUG(DEBUG_HTTPAUTH, "In digest challenge.\n"); clean_session(sess); sess->unq_realm = shave_string(parms->realm, '"'); /* Not a stale response: really need user authentication */ if (get_credentials(sess, &password)) { /* Failed to get credentials */ HTTP_FREE(sess->unq_realm); return -1; } } sess->alg = parms->alg; sess->scheme = http_auth_scheme_digest; sess->unq_nonce = shave_string(parms->nonce, '"'); sess->unq_cnonce = get_cnonce(); if (parms->domain) { if (parse_domain(sess, parms->domain)) { /* TODO: Handle the error? */ } } else { sess->domain = NULL; sess->domain_count = 0; } if (parms->opaque != NULL) { sess->opaque = ne_strdup(parms->opaque); /* don't strip the quotes */ } if (parms->got_qop) { /* What type of qop are we to apply to the message? */ DEBUG(DEBUG_HTTPAUTH, "Got qop directive.\n"); sess->nonce_count = 0; if (parms->qop_auth_int) { sess->qop = http_auth_qop_auth_int; } else { sess->qop = http_auth_qop_auth; } } else { /* No qop at all/ */ sess->qop = http_auth_qop_none; } if (!parms->stale) { /* Calculate H(A1). * tmp = H(unq(username-value) ":" unq(realm-value) ":" passwd) */ DEBUG(DEBUG_HTTPAUTH, "Calculating H(A1).\n"); md5_init_ctx(&tmp); md5_process_bytes(sess->username, strlen(sess->username), &tmp); md5_process_bytes(":", 1, &tmp); md5_process_bytes(sess->unq_realm, strlen(sess->unq_realm), &tmp); md5_process_bytes(":", 1, &tmp); if (password != NULL) md5_process_bytes(password, strlen(password), &tmp); md5_finish_ctx(&tmp, tmp_md5); if (sess->alg == http_auth_alg_md5_sess) { unsigned char a1_md5[16]; struct md5_ctx a1; char tmp_md5_ascii[33]; /* Now we calculate the SESSION H(A1) * A1 = H(...above...) ":" unq(nonce-value) ":" unq(cnonce-value) */ md5_to_ascii(tmp_md5, tmp_md5_ascii); md5_init_ctx(&a1); md5_process_bytes(tmp_md5_ascii, 32, &a1); md5_process_bytes(":", 1, &a1); md5_process_bytes(sess->unq_nonce, strlen(sess->unq_nonce), &a1); md5_process_bytes(":", 1, &a1); md5_process_bytes(sess->unq_cnonce, strlen(sess->unq_cnonce), &a1); md5_finish_ctx(&a1, a1_md5); md5_to_ascii(a1_md5, sess->h_a1); DEBUG(DEBUG_HTTPAUTH, "Session H(A1) is [%s]\n", sess->h_a1); } else { md5_to_ascii(tmp_md5, sess->h_a1); DEBUG(DEBUG_HTTPAUTH, "H(A1) is [%s]\n", sess->h_a1); } HTTP_FREE(password); } DEBUG(DEBUG_HTTPAUTH, "I like this Digest challenge.\n"); return 0; }
void http_auth_finish(http_auth_session *sess) { clean_session(sess); }
/** * Log and free structure relative to a user_session_t * * Used as destroy function for #client_conn_hash */ void log_clean_session(user_session_t * c_session) { log_user_session(c_session, SESSION_CLOSE); clean_session(c_session); }