On Fri, Jan 20, 2023 at 10:08:46PM +0000, Matthew John Cheetham via GitGitGadget wrote: > +struct auth_module { > + char *scheme; > + char *challenge_params; > + struct string_list *tokens; > +}; This is a really minor nit, but: why is "tokens" a pointer? It's always initialized, so you never need or want to test it for NULL. That would make this: > + if (create) { > + struct auth_module *mod = xmalloc(sizeof(struct auth_module)); > + mod->scheme = xstrdup(scheme); > + mod->challenge_params = NULL; > + ALLOC_ARRAY(mod->tokens, 1); > + string_list_init_dup(mod->tokens); simplify to: string_list_init_dup(&mod->tokens); and one does not have to wonder why we use ALLOC_ARRAY() there, but not when allocating the module itself. :) Likewise you could skip freeing it, but since the memory is held until program end anyway, that doesn't happen either way. Certainly what you have won't behave wrong; I'd consider this more like a coding style thing. > + cat >auth.config <<-EOF && > + [auth] > + challenge = no-params > + challenge = with-params:foo=\"bar\" p=1 > + challenge = with-params:foo=\"replaced\" q=1 > + > + token = no-explicit-challenge:valid-token > + token = no-explicit-challenge:also-valid > + token = reset-tokens:these-tokens > + token = reset-tokens:will-be-reset > + token = reset-tokens: > + token = reset-tokens:the-only-valid-one > + > + allowAnonymous = false > + EOF > + > + cat >OUT.expected <<-EOF && > + WWW-Authenticate: no-params > + WWW-Authenticate: with-params foo="replaced" q=1 > + WWW-Authenticate: no-explicit-challenge > + WWW-Authenticate: reset-tokens > + > + Error: 401 Unauthorized > + EOF OK, so I think now we are getting to the interesting part of what your custom http-server does compared to something like apache. And the answer so far is: custom WWW-Authenticate lines. I think we could do that with mod_headers pretty easily. But presumably we also want to check that we are getting the correct tokens, generate a 401, etc. I suspect this could all be done as a CGI wrapping git-http-backend. You can influence the HTTP response code by sending: Status: 401 Authorization Required WWW-Authenticate: whatever you want And likewise you can see what the client sends by putting something like this in apache.conf: SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 and then reading $HTTP_AUTHORIZATION as you like. At that point, it feels like a simple shell or perl script could then decide whether to return a 401 or not (and if not, then just exec git-http-backend to do the rest). And the scripts would be simple enough that you could have individual scripts to implement various schemes, rather than implementing this configuration scheme. You can control which script is run based on the URL; see the way we match /broken_smart/, etc, in t/lib-httpd/apache.conf. -Peff