Hello,

I've made some changes to the auth process to (optionally) support a
different realm for each protected uri.

Example:
shttpd_protect_uri(ctx, "/secret", "passfile", NULL); /* use the server
realm */
shttpd_protect_uri(ctx, "/secret2", "passfile", "secret2"); /* use the same
password file but with server2 realm */

Note: The put/delete authentication still use the server realm

Patch attached.

Best regards.

Gaƫl Chardon.
Index: auth.c
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/auth.c,v
retrieving revision 1.2
diff -u -r1.2 auth.c
--- auth.c      12 Nov 2006 03:29:17 -0000      1.2
+++ auth.c      10 Jan 2008 16:52:18 -0000
@@ -230,7 +230,7 @@
  * Authorize against the opened passwords file. Return 1 if authorized.
  */
 static int
-authorize(struct conn *c, FILE *fp)
+authorize(struct conn *c, FILE *fp, const char *realm)
 {
        struct vec      *auth_vec = &c->ch.auth.v_vec;
        struct vec      *user_vec = &c->ch.user.v_vec;
@@ -253,7 +253,7 @@
                        DBG(("[%.*s] [%.*s] [%.*s]", user.len, user.ptr,
                            domain.len, domain.ptr, ha1.len, ha1.ptr));
 
-                       if (vcmp(user_vec, &user) && !memcmp(c->ctx->auth_realm,
+                       if (vcmp(user_vec, &user) && !memcmp(realm,
                            domain.ptr, domain.len)) {
                                ok = check_password(c->method, &ha1, &digest);
                                break;
@@ -264,11 +264,12 @@
        return (ok);
 }
 
-int
+const char*
 check_authorization(struct conn *c, const char *path)
 {
        FILE                    *fp = NULL;
        int                     authorized = 1;
+       const char                      *realm = c->ctx->auth_realm;
        
 #ifdef EMBEDDED
        struct llhead   *lp;
@@ -279,6 +280,8 @@
                auth = LL_ENTRY(lp, struct uri_auth, link);
                if (!strncmp(c->uri, auth->uri, auth->uri_len)) {
                        fp = fopen(auth->file_name, "r");
+                       if (auth->realm != NULL)
+                               realm = auth->realm;
                        break;
                }
        }
@@ -288,11 +291,11 @@
                fp = open_auth_file(c->ctx, path);
 
        if (fp != NULL) {
-               authorized = authorize(c, fp);
+               authorized = authorize(c, fp, realm);
                (void) fclose(fp);
        }
 
-       return (authorized);
+       return (authorized == 1?NULL:realm);
 }
 
 int
@@ -302,7 +305,7 @@
        int     ret = 0;
 
        if ((fp = fopen(c->ctx->put_auth_file, "r")) != NULL) {
-               ret = authorize(c, fp);
+               ret = authorize(c, fp, c->ctx->auth_realm);
                (void) fclose(fp);
        }
 
@@ -310,13 +313,13 @@
 }
 
 void
-send_authorization_request(struct conn *c)
+send_authorization_request(struct conn *c, const char *realm)
 {
        char    buf[512];
 
        (void) my_snprintf(buf, sizeof(buf), "Unauthorized\r\n"
            "WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", "
-           "nonce=\"%lu\"", c->ctx->auth_realm, (unsigned long) current_time);
+           "nonce=\"%lu\"", realm, (unsigned long) current_time);
 
        send_server_error(c, 401, buf);
 }
Index: defs.h
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/defs.h,v
retrieving revision 1.12
diff -u -r1.12 defs.h
--- defs.h      10 Jul 2007 09:45:55 -0000      1.12
+++ defs.h      10 Jan 2008 16:48:43 -0000
@@ -132,6 +132,7 @@
        struct llhead   link;
        const char      *uri;
        const char      *file_name;
+       const char      *realm;
        size_t          uri_len;
 };
 
@@ -440,9 +441,9 @@
 /*
  * auth.c
  */
-extern int     check_authorization(struct conn *c, const char *path);
+extern const char      *check_authorization(struct conn *c, const char *path);
 extern int     is_authorized_for_put(struct conn *c);
-extern void    send_authorization_request(struct conn *c);
+extern void    send_authorization_request(struct conn *c, const char *realm);
 extern int     edit_passwords(const char *fname, const char *domain,
                const char *user, const char *pass);
 
Index: io_emb.c
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/io_emb.c,v
retrieving revision 1.8
diff -u -r1.8 io_emb.c
--- io_emb.c    27 Aug 2007 16:11:20 -0000      1.8
+++ io_emb.c    10 Jan 2008 16:37:40 -0000
@@ -197,7 +197,7 @@
 #endif
 
 void
-shttpd_protect_uri(struct shttpd_ctx *ctx, const char *uri, const char *file)
+shttpd_protect_uri(struct shttpd_ctx *ctx, const char *uri, const char *file, 
const char *realm)
 {
        struct uri_auth *auth;
 
@@ -205,6 +205,10 @@
                auth->uri       = my_strdup(uri);
                auth->file_name = my_strdup(file);
                auth->uri_len   = strlen(uri);
+               if (realm)
+                       auth->realm = my_strdup(realm);
+               else
+                       auth->realm = NULL;
                LL_ADD(&ctx->uri_auths, &auth->link);
        }
 }
Index: shttpd.c
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/shttpd.c,v
retrieving revision 1.18
diff -u -r1.18 shttpd.c
--- shttpd.c    10 Jan 2008 11:01:21 -0000      1.18
+++ shttpd.c    10 Jan 2008 16:43:22 -0000
@@ -431,6 +431,10 @@
 #ifdef EMBEDDED
        struct registered_uri   *ruri;
 #endif /* EMBEDDED */
+#if !defined(NO_AUTH)
+       const char *realm;
+#endif /* EMBEDDED */
+
 
        DBG(("decide_what_to_do: [%s]", c->uri));
 
@@ -457,8 +461,8 @@
        }
 
 #if !defined(NO_AUTH)
-       if (check_authorization(c, path) != 1) {
-               send_authorization_request(c);
+       if ((realm = check_authorization(c, path)) != NULL) {
+               send_authorization_request(c, realm);
        } else
 #endif /* NO_AUTH */
 #ifdef EMBEDDED
@@ -473,7 +477,7 @@
 #if !defined(NO_AUTH)
        if ((c->method == METHOD_PUT || c->method == METHOD_DELETE) &&
            (c->ctx->put_auth_file == NULL || !is_authorized_for_put(c))) {
-               send_authorization_request(c);
+               send_authorization_request(c, c->ctx->auth_realm);
        } else
 #endif /* NO_AUTH */
        if (c->method == METHOD_PUT) {
@@ -1164,6 +1168,8 @@
 
        free((void *) auth->file_name);
        free((void *) auth->uri);
+       if (auth->realm != NULL)
+               free((void *)auth->realm);
        free(auth);
 }
 
Index: shttpd.h
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/shttpd.h,v
retrieving revision 1.5
diff -u -r1.5 shttpd.h
--- shttpd.h    27 Jul 2007 11:15:53 -0000      1.5
+++ shttpd.h    10 Jan 2008 16:31:53 -0000
@@ -98,7 +98,7 @@
 void shttpd_register_uri(struct shttpd_ctx *ctx,
                const char *uri, shttpd_callback_t callback, void *user_data);
 void shttpd_protect_uri(struct shttpd_ctx *ctx,
-               const char *uri, const char *file);
+               const char *uri, const char *file, const char *realm);
 void shttpd_poll(struct shttpd_ctx *, int milliseconds);
 const char *shttpd_version(void);
 int shttpd_get_var(const char *var, const char *buf, int buf_len,
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
shttpd-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/shttpd-general

Reply via email to