]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
fix http_reply_access with authentication, delay_access with authentication, persiste...
authorrobertc <>
Thu, 26 Sep 2002 19:33:07 +0000 (19:33 +0000)
committerrobertc <>
Thu, 26 Sep 2002 19:33:07 +0000 (19:33 +0000)
src/acl.cc
src/authenticate.cc
src/client_side.cc
src/client_side_reply.cc
src/protos.h
src/store_client.cc
src/structs.h

index 2ea7f13407caf98b0b5832502224d328d6d31c6c..1aa73c4b067f671308b57e99c376bfe6aee17896 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.cc,v 1.285 2002/09/15 06:40:56 robertc Exp $
+ * $Id: acl.cc,v 1.286 2002/09/26 13:33:07 robertc Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -1405,7 +1405,7 @@ aclAuthenticated(aclCheck_t * checklist)
     }
     /* get authed here */
     /* Note: this fills in checklist->auth_user_request when applicable */
-    switch (authenticateAuthenticate(&checklist->auth_user_request, headertype, checklist->request, checklist->conn, checklist->src_addr)) {
+    switch (authenticateTryToAuthenticateAndSetAuthUser(&checklist->auth_user_request, headertype, checklist->request, checklist->conn, checklist->src_addr)) {
     case AUTH_ACL_CANNOT_AUTHENTICATE:
        debug(28, 4) ("aclMatchAcl: returning  0 user authenticated but not authorised.\n");
        return 0;
index 09a2aa79c26b1d9c9128584e7164fae666e4a1dc..f44bc41f7682c6492a1a9373340c0ae085ba5c57 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: authenticate.cc,v 1.39 2002/07/15 22:13:27 hno Exp $
+ * $Id: authenticate.cc,v 1.40 2002/09/26 13:33:08 robertc Exp $
  *
  * DEBUG: section 29    Authenticator
  * AUTHOR: Duane Wessels
@@ -44,6 +44,7 @@ CBDATA_TYPE(auth_user_ip_t);
 
 static void
      authenticateDecodeAuth(const char *proxy_auth, auth_user_request_t * auth_user_request);
+static auth_acl_t authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type headertype, request_t * request, ConnStateData * conn, struct in_addr src_addr);
 
 /*
  *
@@ -424,6 +425,7 @@ authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type
 {
     const char *proxy_auth;
     assert(headertype != 0);
+
     proxy_auth = httpHeaderGetStr(&request->header, headertype);
 
     if (conn == NULL) {
@@ -571,6 +573,27 @@ authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type
     return AUTH_AUTHENTICATED;
 }
 
+auth_acl_t
+authenticateTryToAuthenticateAndSetAuthUser(auth_user_request_t ** auth_user_request, http_hdr_type headertype, request_t * request, ConnStateData * conn, struct in_addr src_addr)
+{
+    /* If we have already been called, return the cached value */
+    auth_user_request_t *t = *auth_user_request ? *auth_user_request : conn->auth_user_request;
+    auth_acl_t result;
+    if (t && t->lastReply != AUTH_ACL_CANNOT_AUTHENTICATE
+       && t->lastReply != AUTH_ACL_HELPER) {
+       if (!*auth_user_request)
+           *auth_user_request = t;
+       return t->lastReply;
+    }
+    /* ok, call the actual authenticator routine. */
+    result = authenticateAuthenticate(auth_user_request, headertype, request, conn, src_addr);
+    t = *auth_user_request ? *auth_user_request : conn->auth_user_request;
+    if (t && result != AUTH_ACL_CANNOT_AUTHENTICATE &&
+       result != AUTH_ACL_HELPER)
+       t->lastReply = result;
+    return result;
+}
+
 
 /* authenticateUserUsername: return a pointer to the username in the */
 char *
@@ -733,6 +756,8 @@ authenticateFixHeader(HttpReply * rep, auth_user_request_t * auth_user_request,
     if ((auth_user_request != NULL) && (auth_user_request->auth_user->auth_module > 0)
        && (authscheme_list[auth_user_request->auth_user->auth_module - 1].AddHeader))
        authscheme_list[auth_user_request->auth_user->auth_module - 1].AddHeader(auth_user_request, rep, accelerated);
+    if (auth_user_request != NULL)
+       auth_user_request->lastReply = AUTH_ACL_CANNOT_AUTHENTICATE;
 }
 
 /* call the active auth module and allow it to add a trailer to the request */
index 16cabb77c1bfe99a91b1e91723736437e6d3976d..041dc8c9b9863b208b08e0abf1255b40ad0f68e6 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.594 2002/09/24 11:31:19 robertc Exp $
+ * $Id: client_side.cc,v 1.595 2002/09/26 13:33:08 robertc Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -171,7 +171,7 @@ static void connNoteUseOfBuffer(ConnStateData * conn, int byteCount);
 static int connKeepReadingIncompleteRequest(ConnStateData * conn);
 static void connCancelIncompleteRequests(ConnStateData * conn);
 static ConnStateData *connStateCreate(struct sockaddr_in peer, struct sockaddr_in me, int fd);
-static clientStreamNode * getClientReplyContext(clientSocketContext * context);
+static clientStreamNode *getClientReplyContext(clientSocketContext * context);
 static int connAreAllContextsForThisConnection(ConnStateData * connState);
 static void connFreeAllContexts(ConnStateData * connState);
 static void clientPullData(clientSocketContext * context);
@@ -412,14 +412,14 @@ httpRequestFree(void *data)
     assert(http != NULL);
     request = http->request;
     debug(33, 3) ("httpRequestFree: %s\n", http->uri);
-    /* FIXME: This needs to use the stream */
-    if (!clientCheckTransferDone(http)) {
-       if (request && request->body_connection)
-           clientAbortBody(request);   /* abort body transter */
-       /* the ICP check here was erroneous
-        * - storeReleaseRequest was always called if entry was valid 
-        */
-    }
+    /* if body_connection !NULL, then ProcessBody has not
+     * found the end of the body yet
+     */
+    if (request && request->body_connection)
+       clientAbortBody(request);       /* abort body transter */
+    /* the ICP check here was erroneous
+     * - storeReleaseRequest was always called if entry was valid 
+     */
     assert(http->logType < LOG_TYPE_MAX);
     clientLogRequest(http);
     if (request)
@@ -608,6 +608,8 @@ contextSendStartOfMessage(clientSocketContext * context, HttpReply * rep, StoreI
     /* init mb; put status line and headers if any */
     if (rep) {
        mb = httpReplyPack(rep);
+       /* Save length of headers for persistent conn checks */
+       context->http->out.headers_sz = mb.size;
 #if HEADERS_LOG
        headersLog(0, 0, context->http->request->method, rep);
 #endif
index ca6061a28e37c100efb9a188c264b38c87860310..3cba46658368fb3918fbea441e4f4fb71c817f03 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side_reply.cc,v 1.8 2002/09/24 12:09:24 robertc Exp $
+ * $Id: client_side_reply.cc,v 1.9 2002/09/26 13:33:08 robertc Exp $
  *
  * DEBUG: section 88    Client-side Reply Routines
  * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c)
@@ -90,7 +90,7 @@ extern ErrorState *clientBuildError(err_type, http_status, char const *,
 
 static void startError(clientReplyContext * context, clientHttpRequest * http, ErrorState * err);
 static void triggerStoreReadWithClientParameters(clientReplyContext * context, clientHttpRequest * http);
-
+static int clientCheckTransferDone(clientReplyContext * context);
 
 /* The clientReply clean interface */
 /* privates */
@@ -886,8 +886,9 @@ clientTraceReply(clientStreamNode * node, clientReplyContext * context)
 #define SENDING_BODY 0
 #define SENDING_HDRSONLY 1
 int
-clientCheckTransferDone(clientHttpRequest const *http)
+clientCheckTransferDone(clientReplyContext * context)
 {
+    clientHttpRequest *http = context->http;
     int sending = SENDING_BODY;
     StoreEntry *entry = http->entry;
     MemObject *mem;
@@ -905,9 +906,10 @@ clientCheckTransferDone(clientHttpRequest const *http)
      * Handle STORE_OK objects.
      * objectLen(entry) will be set proprely.
      * RC: Does objectLen(entry) include the Headers? 
+     * RC: Yes.
      */
     if (entry->store_status == STORE_OK) {
-       if (http->out.offset >= objectLen(entry))
+       if (http->out.offset >= objectLen(entry) - context->headers_sz)
            return 1;
        else
            return 0;
@@ -918,8 +920,9 @@ clientCheckTransferDone(clientHttpRequest const *http)
     mem = entry->mem_obj;
     assert(mem != NULL);
     assert(http->request != NULL);
+    /* mem->reply was wrong because it uses the UPSTREAM header length!!! */
     reply = mem->reply;
-    if (reply->hdr_sz == 0)
+    if (context->headers_sz == 0)
        return 0;               /* haven't found end of headers yet */
     else if (reply->sline.status == HTTP_OK)
        sending = SENDING_BODY;
@@ -938,16 +941,15 @@ clientCheckTransferDone(clientHttpRequest const *http)
      * If we are sending a body and we don't have a content-length,
      * then we must wait for the object to become STORE_OK.
      */
-    if (sending == SENDING_HDRSONLY)
-       sendlen = reply->hdr_sz;
-    else if (reply->content_length < 0)
+    sendlen = http->out.headers_sz;
+    if (reply->content_length < 0)
        return 0;
     else
-       sendlen = reply->content_length + reply->hdr_sz;
+       sendlen += reply->content_length;
     /*
      * Now that we have the expected length, did we send it all?
      */
-    if (http->out.offset < sendlen)
+    if (http->out.size < sendlen)
        return 0;
     else
        return 1;
@@ -1026,27 +1028,33 @@ clientReplyStatus(clientStreamNode * this, clientHttpRequest * http)
         * complete. Should we tcp reset such connections ?
         */
        return STREAM_FAILED;
-    if ((done = clientCheckTransferDone(http)) != 0 || context->flags.complete) {
+    if ((done = clientCheckTransferDone(context)) != 0 || context->flags.complete) {
        debug(88, 5) ("clientReplyStatus: transfer is DONE\n");
        /* Ok we're finished, but how? */
        if (httpReplyBodySize(http->request->method,
                http->entry->mem_obj->reply) < 0) {
-           debug(88, 5) ("clientWriteComplete: closing, content_length < 0\n");
+           debug(88, 5) ("clientReplyStatus: closing, content_length < 0\n");
            return STREAM_FAILED;
-       } else if (!done) {
-           debug(88, 5) ("clientWriteComplete: closing, !done, but read 0 bytes\n");
+       }
+       if (!done) {
+           debug(88, 5) ("clientReplyStatus: closing, !done, but read 0 bytes\n");
            return STREAM_FAILED;
-       } else if (clientGotNotEnough(http)) {
-           debug(88, 5) ("clientWriteComplete: client didn't get all it expected\n");
+       }
+       if (clientGotNotEnough(http)) {
+           debug(88, 5) ("clientReplyStatus: client didn't get all it expected\n");
            return STREAM_UNPLANNED_COMPLETE;
-       } else if (http->request->flags.proxy_keepalive) {
+       }
+       if (http->request->flags.proxy_keepalive) {
+           debug(88, 5) ("clientReplyStatus: stream complete and can keepalive\n");
            return STREAM_COMPLETE;
        }
+       debug(88, 5) ("clientReplyStatus: stream was not expected to complete!\n");
        return STREAM_UNPLANNED_COMPLETE;
-
     }
-    if (clientReplyBodyTooLarge(http->entry->mem_obj->reply, http->out.offset))
+    if (clientReplyBodyTooLarge(http->entry->mem_obj->reply, http->out.offset)) {
+       debug(88, 5) ("clientReplyStatus: client reply body is too large\n");
        return STREAM_FAILED;
+    }
     return STREAM_NONE;
 }
 
@@ -1496,6 +1504,8 @@ clientSendMoreData(void *data, StoreIOBuffer result)
            (int) body_size, rep->hdr_sz);
        ch = aclChecklistCreate(Config.accessList.reply, http->request, NULL);
        ch->reply = rep;
+       if (http->conn)
+           ch->conn = cbdataReference(http->conn);     /* acl.c frees */
        rv = aclCheckFast(Config.accessList.reply, ch);
        aclChecklistFree(ch);
        ch = NULL;
index 6ad0c1d0bb8e13063f4022461112e9fa42f66bac..f9ec8550ade768bd4ee0404a78caa5636a49aaa0 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.447 2002/09/24 10:46:42 robertc Exp $
+ * $Id: protos.h,v 1.448 2002/09/26 13:33:08 robertc Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -145,7 +145,6 @@ extern int clientAbortBody(request_t * req);
 extern void httpRequestFree(void *);
 
 /* client_side_reply.c - client side reply related routines (pure logic, no comms) */
-extern int clientCheckTransferDone(clientHttpRequest const *);
 extern void *clientReplyNewContext(clientHttpRequest *);
 extern int clientHttpRequestStatus(int fd, clientHttpRequest const *http);
 extern void clientSetReplyToError(void *, err_type, http_status, method_t, char const *, struct in_addr *, request_t *, char *, auth_user_request_t * auth_user_request);
@@ -755,7 +754,7 @@ extern void authenticateInit(authConfig *);
 extern void authenticateShutdown(void);
 extern void authenticateFixHeader(HttpReply *, auth_user_request_t *, request_t *, int, int);
 extern void authenticateAddTrailer(HttpReply *, auth_user_request_t *, request_t *, int);
-extern auth_acl_t authenticateAuthenticate(auth_user_request_t **, http_hdr_type, request_t *, ConnStateData *, struct in_addr);
+extern auth_acl_t authenticateTryToAuthenticateAndSetAuthUser(auth_user_request_t **, http_hdr_type, request_t *, ConnStateData *, struct in_addr);
 extern void authenticateAuthUserUnlock(auth_user_t * auth_user);
 extern void authenticateAuthUserLock(auth_user_t * auth_user);
 extern void authenticateAuthUserRequestUnlock(auth_user_request_t *);
index 9f9ef31f830e626d5555786aa7e4670962c13808..a606bcdbce11312a5df35811a005f7a5de1cf829 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_client.cc,v 1.113 2002/09/24 10:46:42 robertc Exp $
+ * $Id: store_client.cc,v 1.114 2002/09/26 13:33:08 robertc Exp $
  *
  * DEBUG: section 20    Storage Manager Client-Side Interface
  * AUTHOR: Duane Wessels
@@ -191,7 +191,7 @@ storeClientCopy(store_client * sc,
     assert(!EBIT_TEST(e->flags, ENTRY_ABORTED));
     debug(20, 3) ("storeClientCopy: %s, from %lu, for length %d, cb %p, cbdata %p\n",
        storeKeyText(e->hash.key),
-       copyInto.offset,
+       (unsigned long) copyInto.offset,
        copyInto.length,
        callback,
        data);
@@ -275,7 +275,7 @@ storeClientCopy3(StoreEntry * e, store_client * sc)
     MemObject *mem = e->mem_obj;
     size_t sz;
 
-    debug(33, 5) ("co: %lu, hi: %ld\n", sc->copyInto.offset, (long int) mem->inmem_hi);
+    debug(33, 5) ("co: %lu, hi: %ld\n", (unsigned long) sc->copyInto.offset, (long int) mem->inmem_hi);
 
     if (storeClientNoMoreToSend(e, sc)) {
        /* There is no more to send! */
@@ -695,7 +695,7 @@ storeClientDumpStats(store_client * thisClient, StoreEntry * output, int clientN
        return;
     storeAppendPrintf(output, "\tClient #%d, %p\n", clientNumber, thisClient->callback_data);
     storeAppendPrintf(output, "\t\tcopy_offset: %lu\n",
-       thisClient->copyInto.offset);
+       (unsigned long) thisClient->copyInto.offset);
     storeAppendPrintf(output, "\t\tcopy_size: %d\n",
        (int) thisClient->copyInto.length);
     storeAppendPrintf(output, "\t\tflags:");
index 763663c7113b93788fdcdce4e54ba47969c395fd..ee1b466528c38f7cdc9ce8b631d2839cd2bef139 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.431 2002/09/24 10:46:42 robertc Exp $
+ * $Id: structs.h,v 1.432 2002/09/26 13:33:08 robertc Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -138,6 +138,11 @@ struct _auth_user_request_t {
     void *scheme_data;
     /* how many 'processes' are working on this data */
     size_t references;
+    /* We only attempt authentication once per http request. This 
+     * is to allow multiple auth acl references from different _access areas
+     * when using connection based authentication
+     */
+    auth_acl_t lastReply;
 };
 
 
@@ -1056,6 +1061,7 @@ struct _clientHttpRequest {
     struct {
        off_t offset;
        size_t size;
+       size_t headers_sz;
     } out;
     HttpHdrRangeIter range_iter;       /* data for iterating thru range specs */
     size_t req_sz;             /* raw request size on input, not current request size */