RE: Dynamicly insert 'require' into request
Okay, so upon further inspection, it appears that there may not be an equivalent function for mod_perls set_handlers(). This leads me to a problem: how do I turn off a hook, especially, as the check_user() hook expects the r-user property to contain the username, meaning that the sending of a 403 happens before the check_user() hook is called. Whatever it is I need to do, I need to do in the access() hook. I was hoping it might be something as simple as removing my require entry from the require array. Has anyone had any experience with this? If so, could you comment on techniques? Cheers, Ben -Original Message- From: Ben Davies [mailto:bdav...@stickyeyes.com] Sent: 21 July 2009 14:49 To: modules-dev@httpd.apache.org Subject: RE: Dynamicly insert 'require' into request mod_perl just exposes the API to Perl programmers. Translate their example to C and it'll work without mod_perl. Excellent! Just what I was hoping for! Any clues as to the C equivalent of set_handler()? I've been looking in the apache header files and not found anything yet that matches. You want C, my book takes you through developing a custom authentication/authorization handler. I know. I've been doing exactly that :) Great book by the way :) If I understood your original question (... conditional authentication ... if public access is granted??) I could perhaps say something more specific. A quick overview of what I want: if user requests a resource with a particular method, and that method is in a list of public accessible methods, then auth is not required. If not, then authn/authz is required. Simple as. I know there are other ways of doing this with Limit, for example, but my module adds a few bits and bobs to make management a bit easier (and extensible). I would however, appreciate your comments on the subject :) Cheers for confirming, Ben -Original Message- From: Nick Kew [mailto:n...@apache.org] Sent: 21 July 2009 14:36 To: modules-dev@httpd.apache.org Subject: Re: Dynamicly insert 'require' into request On 21 Jul 2009, at 13:44, Ben Davies wrote: I've just found something that does pretty much what I want but with mod_perl. For an example, see 13.5 in the following chapter (warning: link is a PDF) mod_perl just exposes the API to Perl programmers. Translate their example to C and it'll work without mod_perl. You want C, my book takes you through developing a custom authentication/authorization handler. If I understood your original question (... conditional authentication ... if public access is granted??) I could perhaps say something more specific. -- Nick Kew
RE: Dynamicly insert 'require' into request
On Wed, 2009-07-22 at 10:43 +0100, Ben Davies wrote: Okay, so upon further inspection, it appears that there may not be an equivalent function for mod_perls set_handlers(). This leads me to a problem: how do I turn off a hook, especially, as the check_user() hook expects the r-user property to contain the username, meaning that the sending of a 403 happens before the check_user() hook is called. Whatever it is I need to do, I need to do in the access() hook. I was hoping it might be something as simple as removing my require entry from the require array. Has anyone had any experience with this? If so, could you comment on techniques? Cheers, Ben One solution would be to set a note for your hook in an earlier stage, and then return DECLINED from your handler when you detect that note. There may be a better way :) Cheers Tom
Re: Dynamicly insert 'require' into request
This leads me to a problem: how do I turn off a hook, Whatever it is I need to do, I need to do in the access() hook. In access, set a variable. Call it skipauth. Set it to 1 if you need to skip authorization. In auth, first check skipauth. If it's true, skip your authorization and return OK. Okay, so upon further inspection, it appears that there may not be an equivalent function for mod_perls set_handlers(). You don't need it for your simple case, of course, but think how it easy it would be write. What exactly does it need to do? You want to call different functions, so clearly you need some variabe that tells which function(s) to call, then later you call whichever function designated by the variable. It would be maybe four or five lines added to the typical hook code. There may well be a simpler or better way - I've only just started learning about Apache internals myself and I'm not even a C programer - I'm a Perl guy. But here's the simple implementation that came immediately to mind for me: typedef struct { int (*uid_function_pointer)(request_rec *r); } my_module_conf; static int check_user_id_1(request_rec *r) __attribute__((cdecl)); static int check_user_id_2(request_rec *r) __attribute__((cdecl)); static int my_access_hook(request_rec *r) { if (one) { cfg-uid_function_pointer = check_user_id_1; } else { cfg-uid_function_pointer = check_user_id_2; } } static int my_check_user (request_rec *r) { return cfg-uid_function_pointer(r); } The code dynamically assigns ONE function to be called in a later hook, of course. Better would be for uid_function_pointer to be an array, list, or table of some kind. Implementing that is left as an exercise for the reader. If you're wanting to do the same thing as an existing function in mod_perl, you could look at the source of mod_perl to see how they did it. That might give you some ideas. -- Ray Morris supp...@bettercgi.com Strongbox - The next generation in site security: http://www.bettercgi.com/strongbox/ Throttlebox - Intelligent Bandwidth Control http://www.bettercgi.com/throttlebox/ Strongbox / Throttlebox affiliate program: http://www.bettercgi.com/affiliates/user/register.php On 07/22/2009 04:43:08 AM, Ben Davies wrote: Okay, so upon further inspection, it appears that there may not be an equivalent function for mod_perls set_handlers(). This leads me to a problem: how do I turn off a hook, especially, as the check_user() hook expects the r-user property to contain the username, meaning that the sending of a 403 happens before the check_user() hook is called. Whatever it is I need to do, I need to do in the access() hook. I was hoping it might be something as simple as removing my require entry from the require array. Has anyone had any experience with this? If so, could you comment on techniques? Cheers, Ben -Original Message- From: Ben Davies [mailto:bdav...@stickyeyes.com] Sent: 21 July 2009 14:49 To: modules-dev@httpd.apache.org Subject: RE: Dynamicly insert 'require' into request mod_perl just exposes the API to Perl programmers. Translate their example to C and it'll work without mod_perl. Excellent! Just what I was hoping for! Any clues as to the C equivalent of set_handler()? I've been looking in the apache header files and not found anything yet that matches. You want C, my book takes you through developing a custom authentication/authorization handler. I know. I've been doing exactly that :) Great book by the way :) If I understood your original question (... conditional authentication ... if public access is granted??) I could perhaps say something more specific. A quick overview of what I want: if user requests a resource with a particular method, and that method is in a list of public accessible methods, then auth is not required. If not, then authn/authz is required. Simple as. I know there are other ways of doing this with Limit, for example, but my module adds a few bits and bobs to make management a bit easier (and extensible). I would however, appreciate your comments on the subject :) Cheers for confirming, Ben -Original Message- From: Nick Kew [mailto:n...@apache.org] Sent: 21 July 2009 14:36 To: modules-dev@httpd.apache.org Subject: Re: Dynamicly insert 'require' into request On 21 Jul 2009, at 13:44, Ben Davies wrote: I've just found something that does pretty much what I want but with mod_perl. For an example, see 13.5 in the following chapter (warning: link is a PDF) mod_perl just exposes the API to Perl programmers. Translate their example to C and it'll work without mod_perl. You want C, my book takes you through developing a custom authentication/authorization handler. If I understood your original question (... conditional authentication ... if public
RE: Dynamicly insert 'require' into request
One solution would be to set a note for your hook in an earlier stage, and then return DECLINED from your handler when you detect that note. Ah, but from what I can work out, before the check_user() hook fires, the 403 is sent to the client because of the presence of the require. I can't have the check_user() hook return DECLINED because its too late: the 403 has been sent back automatically. But additionally, I can't return DECLINED from the access() hook (which fires before the check_user() hook) because if the resource requested is publicly accessible, then the access() hook should return OK :) So, to me, the only solution is: In the access() hook, if the resource is NOT publicly accessible, return OK. This will make apache recognise the require directive, return a 403, and then fire the check_user() and auth() hooks. If the resource IS publicly available, I need to somehow remove the require directive from the request, and then return OK from the access() hook. This means that the 403 won't be returns (as there is no require directive set anymore) which means no authentication (check_user()) hook is fired and subsequently no authorization (auth()) hook either. From what I can make out, this is how Apache would handle the process. No to see if I can actually modify the request-requires array, and if so, if that will affect the request processing after exiting the access() hook so that the 403 and the check_user() and auth() hooks don't fire. Fun fun fun! Can someone with a deeper knowledge of Apache than me comment if this sounds like crazy talk? Have I made a massive assumption regarding the returning of the 403 header before check_user(), for example? Cheers! Ben -Original Message- From: Tom Evans [mailto:tevans...@googlemail.com] Sent: 22 July 2009 12:24 To: modules-dev@httpd.apache.org Subject: RE: Dynamicly insert 'require' into request On Wed, 2009-07-22 at 10:43 +0100, Ben Davies wrote: Okay, so upon further inspection, it appears that there may not be an equivalent function for mod_perls set_handlers(). This leads me to a problem: how do I turn off a hook, especially, as the check_user() hook expects the r-user property to contain the username, meaning that the sending of a 403 happens before the check_user() hook is called. Whatever it is I need to do, I need to do in the access() hook. I was hoping it might be something as simple as removing my require entry from the require array. Has anyone had any experience with this? If so, could you comment on techniques? Cheers, Ben One solution would be to set a note for your hook in an earlier stage, and then return DECLINED from your handler when you detect that note. There may be a better way :) Cheers Tom
RE: Dynamicly insert 'require' into request
First of all, thank you to everyone who has replied. Every reply has been enlightening and helpful. I'm clearly a novice to module development, and I only ever post when I am truly stuck and need help, and only when I have exhausted all possible avenues (I own all of the books mentioned regularly on this list and each has a pretty broken spine and is scribbled with notes :) I'm not a novice programmer, but am a novice to C. And C is a very intimidating language when you've only programmed in 'safer' languages for 15 years :) On top of that, the documentation for the Apache API and APR stuff really consists of an API listing and not much else. Nicks book is pretty much the only documentation I've read that was actually any help. Saying that, I have personally learnt more from this mailing list than most, so please consider my multiple postings a compliment. Saying that, I will reduce my postings in future to a few succinct questions. Cheers! Ben Davies -Original Message- From: Ray Morris [mailto:supp...@bettercgi.com] Sent: 22 July 2009 14:36 To: modules-dev@httpd.apache.org Subject: Re: Dynamicly insert 'require' into request Have I made a massive assumption regarding the returning of the 403 header before check_user(), for example? That's exactly what I first thought about when I read your email. I think the 401 authorization required is sent only AFTER check_user_id() is run. Remember there's more than one way to authenticate a client - basic auth and digest auth are two that come standard. In order for mod_auth and mod_auth_digest to send two different headers with the 401, their hooks have to run BEFORE the 401 is sent to the client. I would definitely test that if I were the OP, because I think you're making way more work for yourself than you need to. I think you can simply return OK from check_user_id for publicly accessible resources. Also think carefully about satisfy any. Satisfy any means it has to pass EITHER a) access or b) authentication, which may be just what you're trying to do. Lastly, let me mention that I'd like the the OP to be able to get help when needed. This series of questions has gone on a bit longer than most on this list. Soon, I'm sure, knowledeable people on the list will get tired of answering and think to themselves you can either read the book and look at other modules to learn how to write this yourself, or you can hire me to write it for you. I'm not going to write your module for you on the list, by answering dozens of questions that are all clearly answered in chapter 7 of the book. I'm guessing you probably have one or two questions left before people get tired of answering - use them wisely, when you actually need them. -- Ray Morris supp...@bettercgi.com Strongbox - The next generation in site security: http://www.bettercgi.com/strongbox/ Throttlebox - Intelligent Bandwidth Control http://www.bettercgi.com/throttlebox/ Strongbox / Throttlebox affiliate program: http://www.bettercgi.com/affiliates/user/register.php On 07/22/2009 07:28:05 AM, Ben Davies wrote: One solution would be to set a note for your hook in an earlier stage, and then return DECLINED from your handler when you detect that note. Ah, but from what I can work out, before the check_user() hook fires, the 403 is sent to the client because of the presence of the require. I can't have the check_user() hook return DECLINED because its too late: the 403 has been sent back automatically. But additionally, I can't return DECLINED from the access() hook (which fires before the check_user() hook) because if the resource requested is publicly accessible, then the access() hook should return OK :) So, to me, the only solution is: In the access() hook, if the resource is NOT publicly accessible, return OK. This will make apache recognise the require directive, return a 403, and then fire the check_user() and auth() hooks. If the resource IS publicly available, I need to somehow remove the require directive from the request, and then return OK from the access() hook. This means that the 403 won't be returns (as there is no require directive set anymore) which means no authentication (check_user()) hook is fired and subsequently no authorization (auth()) hook either. From what I can make out, this is how Apache would handle the process. No to see if I can actually modify the request-requires array, and if so, if that will affect the request processing after exiting the access() hook so that the 403 and the check_user() and auth() hooks don't fire. Fun fun fun! Can someone with a deeper knowledge of Apache than me comment if this sounds like crazy talk? Have I made a massive assumption regarding the returning of the 403 header before check_user(), for example? Cheers! Ben -Original Message- From: Tom Evans [mailto:tevans...@googlemail.com] Sent: 22 July 2009 12:24
RE: Dynamicly insert 'require' into request
I've just found something that does pretty much what I want but with mod_perl. For an example, see 13.5 in the following chapter (warning: link is a PDF) http://www.modperlcookbook.org/chapters/ch13.pdf I thought that I might be able to control the flow from within the access hook! Anyone know if there is a similar method as set_handlers in the perl example? Cheers! Ben
Re: Dynamicly insert 'require' into request
On 21 Jul 2009, at 13:44, Ben Davies wrote: I've just found something that does pretty much what I want but with mod_perl. For an example, see 13.5 in the following chapter (warning: link is a PDF) mod_perl just exposes the API to Perl programmers. Translate their example to C and it'll work without mod_perl. You want C, my book takes you through developing a custom authentication/authorization handler. If I understood your original question (... conditional authentication ... if public access is granted??) I could perhaps say something more specific. -- Nick Kew
RE: Dynamicly insert 'require' into request
mod_perl just exposes the API to Perl programmers. Translate their example to C and it'll work without mod_perl. Excellent! Just what I was hoping for! Any clues as to the C equivalent of set_handler()? I've been looking in the apache header files and not found anything yet that matches. You want C, my book takes you through developing a custom authentication/authorization handler. I know. I've been doing exactly that :) Great book by the way :) If I understood your original question (... conditional authentication ... if public access is granted??) I could perhaps say something more specific. A quick overview of what I want: if user requests a resource with a particular method, and that method is in a list of public accessible methods, then auth is not required. If not, then authn/authz is required. Simple as. I know there are other ways of doing this with Limit, for example, but my module adds a few bits and bobs to make management a bit easier (and extensible). I would however, appreciate your comments on the subject :) Cheers for confirming, Ben -Original Message- From: Nick Kew [mailto:n...@apache.org] Sent: 21 July 2009 14:36 To: modules-dev@httpd.apache.org Subject: Re: Dynamicly insert 'require' into request On 21 Jul 2009, at 13:44, Ben Davies wrote: I've just found something that does pretty much what I want but with mod_perl. For an example, see 13.5 in the following chapter (warning: link is a PDF) mod_perl just exposes the API to Perl programmers. Translate their example to C and it'll work without mod_perl. You want C, my book takes you through developing a custom authentication/authorization handler. If I understood your original question (... conditional authentication ... if public access is granted??) I could perhaps say something more specific. -- Nick Kew