summaryrefslogtreecommitdiff
path: root/src/ne_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ne_auth.c')
-rw-r--r--src/ne_auth.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/src/ne_auth.c b/src/ne_auth.c
index 966d0f4..c7f0267 100644
--- a/src/ne_auth.c
+++ b/src/ne_auth.c
@@ -46,6 +46,10 @@
#include <unistd.h> /* for getpid() */
#endif
+#ifdef WIN32
+#include <windows.h> /* for GetCurrentThreadId() etc */
+#endif
+
#ifdef NEON_SSL
#include <openssl/rand.h>
#endif
@@ -128,6 +132,13 @@ static const struct auth_class {
/* Authentication session state. */
typedef struct {
ne_session *sess;
+
+ /* Which context will auth challenges be accepted? */
+ enum {
+ AUTH_ANY, /* ignore nothing. */
+ AUTH_CONNECT, /* only in response to a CONNECT request. */
+ AUTH_NOTCONNECT /* only in non-CONNECT responsees */
+ } context;
/* Specifics for server/proxy auth. FIXME: need a better field
* name! */
@@ -976,25 +987,31 @@ static void ah_create(ne_request *req, void *session, const char *method,
const char *uri)
{
auth_session *sess = session;
- struct auth_request *areq = ne_calloc(sizeof *areq);
-
- NE_DEBUG(NE_DBG_HTTPAUTH, "ah_create, for %s\n", sess->spec->resp_hdr);
-
- areq->method = method;
- areq->uri = uri;
- areq->request = req;
-
- ne_add_response_header_handler(req, sess->spec->resp_hdr,
- ne_duplicate_header, &areq->auth_hdr);
-
+ int is_connect = strcmp(method, "CONNECT") == 0;
+
+ if (sess->context == AUTH_ANY ||
+ (is_connect && sess->context == AUTH_CONNECT) ||
+ (!is_connect && sess->context == AUTH_NOTCONNECT)) {
+ struct auth_request *areq = ne_calloc(sizeof *areq);
+
+ NE_DEBUG(NE_DBG_HTTPAUTH, "ah_create, for %s\n", sess->spec->resp_hdr);
+
+ areq->method = method;
+ areq->uri = uri;
+ areq->request = req;
+
+ ne_add_response_header_handler(req, sess->spec->resp_hdr,
+ ne_duplicate_header, &areq->auth_hdr);
+
- ne_add_response_header_handler(req, sess->spec->resp_info_hdr,
- ne_duplicate_header,
- &areq->auth_info_hdr);
-
- sess->attempt = 0;
-
- ne_set_request_private(req, sess->spec->id, areq);
+ ne_add_response_header_handler(req, sess->spec->resp_info_hdr,
+ ne_duplicate_header,
+ &areq->auth_info_hdr);
+
+ sess->attempt = 0;
+
+ ne_set_request_private(req, sess->spec->id, areq);
+ }
}
@@ -1003,7 +1020,7 @@ static void ah_pre_send(ne_request *r, void *cookie, ne_buffer *request)
auth_session *sess = cookie;
struct auth_request *req = ne_get_request_private(r, sess->spec->id);
- if (!sess->can_handle) {
+ if (!sess->can_handle || !req) {
NE_DEBUG(NE_DBG_HTTPAUTH, "Not handling session.\n");
} else {
char *value;
@@ -1053,6 +1070,8 @@ static int ah_post_send(ne_request *req, void *cookie, const ne_status *status)
struct auth_request *areq = ne_get_request_private(req, sess->spec->id);
int ret = NE_OK;
+ if (!areq) return NE_OK;
+
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,
@@ -1083,7 +1102,7 @@ static void ah_destroy(ne_request *req, void *session)
{
auth_session *sess = session;
struct auth_request *areq = ne_get_request_private(req, sess->spec->id);
- ne_free(areq);
+ if (areq) ne_free(areq);
}
static void free_auth(void *cookie)
@@ -1094,7 +1113,7 @@ static void free_auth(void *cookie)
ne_free(sess);
}
-static void auth_register(ne_session *sess,
+static void auth_register(ne_session *sess, int isproxy,
const struct auth_class *ahc, const char *id,
ne_auth_creds creds, void *userdata)
{
@@ -1105,6 +1124,11 @@ static void auth_register(ne_session *sess,
ahs->sess = sess;
ahs->spec = ahc;
+ if (strcmp(ne_get_scheme(sess), "https") == 0)
+ ahs->context = isproxy ? AUTH_CONNECT : AUTH_NOTCONNECT;
+ else
+ ahs->context = AUTH_ANY;
+
/* Register hooks */
ne_hook_create_request(sess, ah_create, ahs);
ne_hook_pre_send(sess, ah_pre_send, ahs);
@@ -1117,12 +1141,12 @@ static void auth_register(ne_session *sess,
void ne_set_server_auth(ne_session *sess, ne_auth_creds creds, void *userdata)
{
- auth_register(sess, &ah_server_class, HOOK_SERVER_ID, creds, userdata);
+ auth_register(sess, 0, &ah_server_class, HOOK_SERVER_ID, creds, userdata);
}
void ne_set_proxy_auth(ne_session *sess, ne_auth_creds creds, void *userdata)
{
- auth_register(sess, &ah_proxy_class, HOOK_PROXY_ID, creds, userdata);
+ auth_register(sess, 1, &ah_proxy_class, HOOK_PROXY_ID, creds, userdata);
}
void ne_forget_auth(ne_session *sess)