Ticket #1169 (closed defect: wontfix)

Opened 5 years ago

Last modified 1 year ago

HTTPAuth doesn't validate against AccountManager htpasswd file

Reported by: jlevy@srgtampa.com Assigned to: coderanger
Priority: normal Component: HttpAuthPlugin
Severity: normal Keywords:
Cc: Trac Release: 0.10

Description (Last modified by stp)

HTTPAuth dialog comes up, but username & passwords are rejected. Doesn't look like the Accountmanager plugin's password file is being consulted, as per your page's declaration that AccountManagerplugin? is used to check passwords.

Using in conjunction w/XMLRPC plugin so we can use Mylar w/Eclipse & Trac.

Standard form-based login still works. Pop-up dialog appears for /xmlrpc & /xmlrpc/login targets, but username & password doesn't work.

  • Does crypt scheme in passwd file make two-bits of a difference? [using md5]
  • What's with the "Control Panel" name in the login dialog?
  • Is it a misconfiguration on my part?

I'm using trac 10.3, on Debian. I'm using Py-24

Thanks for taking a look.

Attachments

Change History

02/03/07 03:31:54 changed by jlevy@srgtampa.com

my mistake: /xmlrpc & /login/xmlrpc targets work. They both result in a login dialog. But, again, username & password aren't accepted.

02/03/07 03:34:03 changed by jlevy@srgtampa.com

More details yet...

Snooping source, I see log entries... so I check my log: 2007-02-02 22:20:37,117 Trac[init] INFO: HTTPAuthFilter: No/bad authentication data given, returing 403

02/03/07 04:16:47 changed by jlevy@srgtampa.com

get_header('Authorization') always seems to return None... has api changed?

03/29/07 22:58:53 changed by beau@beaugunderson.com

I see this too with a similar setup; 0.10.3, Python 2.4, FreeBSD.

/xmlrpc and /login/xmlrpc targets work but reject all users and passwords.

I also noticed that get_header('Authorization') is returning none.

I added a debug line to print out req._inheaders:

2007-03-29 17:54:36,852 Trac[filter] DEBUG: HTTPAuthFilter: req._inheaders = 
[('cookie', 'trac_form_token=f8938fa4194db5ac822c5260; 
trac_auth=27841af7dce3a81d8a685e62b3f467a0'), ('keep-alive', '300'), 
('accept-charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7'), ('user-agent', 'Mozilla/5.0 
(Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3'), 
('connection', 'keep-alive'), ('host', 'www.redacted.com'), ('cache-control', 
'max-age=0, max-age=0'), ('accept', 
'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'), 
('accept-language', 'en-us,en;q=0.5'), ('accept-encoding', 'gzip,deflate')]

I then double-checked that I was sending the authorization header using 'Live HTTP Headers' for Firefox.

It seems that something (The AccountManager plugin?) is stripping this header.

03/29/07 23:47:31 changed by beau@beaugunderson.com

Thought maybe I was crazy so I tcpdumped this from the server; the Authorization header is definitely received by Apache. Somewhere along the line it must be stripped out but I'm having a devil of a time trying to find where.

05/06/07 19:22:10 changed by chechu

I had the same problem. In my case the problem was that the header "Authorization" doesn't arrive to the cgi (or fcgi). I could get it in the .htaccess file, and I could set rules with this header in this file, but in the trac.cgi I could not see it.

I have my hosting with Dreamhost, maybe it's a server configuration problem.

My solution

First step

I set the next rules in the .htaccess file:

<IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{HTTP:Authorization} ^Basic.*
        RewriteRule ^(.*)$ index.cgi/$1?INTERNAL_AUTH=%{HTTP:Authorization} [L]
</IfModule>

<IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.cgi/$1 [L]
</IfModule>

The second one is the normal rule for Trac. The first one is an special adaption of the second one: when the header "Athorization" is present in a request (and starts with "Basic") I rewrite the url to pass an argument to the cgi. I pass as argument the value of the header Athorization. So, the next step is to get this argument in the cgi.

Second step

In the file trac.cgi (or trac.fcgi) I added the next code in the beginning:

import os, sys
from cgi import escape

valor = os.environ["QUERY_STRING"]
if valor:
    clave, valor = valor.split('=', 1)
    if clave == "INTERNAL_AUTH":
        os.environ["HTTP_AUTHORIZATION"] = valor

QUERY_STRING is an environmen variable with all the variables passed in the URL. We split this value to get the value of INTERNAL_AUTH variable, and only if this variable exists we set and environment variable: HTTP_AUTHORIZATION. This variable will be used then by the HttpAuthPlugin.

08/10/07 06:40:07 changed by yuji.od

That solution overwrite query strings.I changed following.

<IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{HTTP:Authorization} ^Basic.*
        RewriteRule ^(.*)$ index.cgi/$1?INTERNAL_AUTH=%{HTTP:Authorization}&%{QUERY_STRING} [L]
</IfModule>

09/21/07 02:53:37 changed by progrium@gmail.com

If you're using mod_wsgi, auth info is stripped before passing to the app. Turn WSGIPassAuthorization On for it to work. See http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives

(follow-up: ↓ 10 ) 10/22/07 19:00:08 changed by caleb.lyness

I had a lot of trouble with the solution as stated above, eventually I came up with a slightly modified version which suited my environment. Here are the relavent sections of the apache (2.2) config (one still needs to modify the trac.fcgi as above):

<IfModule? alias_module>

AliasMatch? /trac/[/]+/chrome/common/(.*) "/usr/local/share/trac/htdocs/$1" AliasMatch? /trac/([/]+)/chrome/site/(.*) "/usr/local/www/trac/$1/htdocs/$2" ScriptAlias? /trac /usr/local/www/apache22/cgi-bin/trac.fcgi

</IfModule>

<Location /trac>

SetEnv? TRAC_ENV_PARENT_DIR "/usr/local/www/trac" RewriteEngine? on RewriteCond? %{HTTP:Authorization} Basic.* RewriteCond? %{QUERY_STRING} !INTERNAL_AUTH=.* RewriteRule? .*trac\.fcgi/(.*xmlrpc)$ $1?INTERNAL_AUTH=%{HTTP:Authorization}&%{QUERY_STRING} [L]

</Location>

I also came across the following we should have worked but did not:

# http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html <IfModule? mod_fastcgi.c>

AddHandler? fastcgi-script .fcgi FastCgiConfig? -pass-header Authorization

</IfModule> LoadModule? fastcgi_module libexec/apache22/mod_fastcgi.so

(in reply to: ↑ 9 ) 10/22/07 20:54:28 changed by anonymous

Replying to caleb.lyness:

I had a lot of trouble with the solution as stated above, eventually I came up with a slightly modified version which suited my environment. Here are the relavent sections of the apache (2.2) config (one still needs to modify the trac.fcgi as above):

Holy formatting, Batman! Next time please hit preview.

12/22/07 02:03:21 changed by coderanger

  • status changed from new to closed.
  • resolution set to wontfix.

This an Apache issue clearly. I can't do anything about it.

12/22/07 02:12:43 changed by stp

  • description changed.

Please note that Mylyn should support form-based authentication via the AccountManagerPlugin in the latest releases. Please file a bug against Mylyn if it does not work for you:

http://www.eclipse.org/mylyn/bugs/

07/10/08 20:02:23 changed by anonymous

When you use the apache cgi you run in this problem, since the CGI specification told that the apache does not send the "authentication" header to python. I moved from cgi to mod_python and all works fine. When you start trac with its own http server (tracd) also all works fine.

01/06/10 09:50:32 changed by lee.calabrese@gmail.com

I know this is old but I was having lots of troubles with this and couldn't get the above to work. On shared hosting, I didn't have access to the Apache configuration, so I had to use this hack. What I ended up doing was the following:

I changed my .htaccess file with the following RewriteRule (which will then give you the request environment variable "REQUEST_HTTP_AUTHORIZATION":

RewriteRule ^(.*)$ index.fcgi/$1 [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

Note I had a couple of these RewriteRules in there because I was prettying the URL (removing the index.fcgi from the address and accessing it that way). Your mileage may vary but the idea is the same, use E= to pass through an environment variable. The trick that took me so long is it got prepended with "REQUEST_" automatically...

Then I modified the HttpAuthPlugin filter.py _check_password function to look at this variable as a fallback in case the headers weren't passed along properly. The full function became:

    def _check_password(self, req):
        header = req.get_header('Authorization')
        token = None
        if header:
            token = header.split()[1]
        if not token:
            # try the environment variables
            try:
                val = req.environ['REDIRECT_HTTP_AUTHORIZATION']
                if val:
                    token = val.split()[1]
            except KeyError:
                pass

        if token:
            user, passwd = b64decode(token).split(':', 1)
            if AccountManager(self.env).check_password(user, passwd):
                return user

Hope this helps someone else as it was a really tough one to deal with.

11/12/10 16:18:19 changed by anonymous

Here is my filter.py _check_password method :

def _check_password(self, req):
        val = req.environ['QUERY_STRING']
        token = None
        if val:
            token = val.split()[1]
        if token:
            user, passwd = b64decode(token).split(':', 1)
            if AccountManager(self.env).check_password(user, passwd):
                return user

And here is my apache configuration

<IfModule alias_module>
    AliasMatch /trac/[/]+/chrome/common/(.*) "/home/trac/htdocs/$1"
    AliasMatch /trac/([/]+)/chrome/site/(.*) "/home/trac/$1/htdocs/$2"
    ScriptAlias /trac /home/trac/cgi-bin/trac.fcgi/
</IfModule>

<Location /trac>
    SetEnv TRAC_ENV_PARENT_DIR "/home/trac/Prisme"
    RewriteEngine on
    RewriteCond %{HTTP:Authorization} Basic.*
    RewriteCond %{QUERY_STRING} !INTERNAL_AUTH=.*
    RewriteRule .*trac\.fcgi/(.*xmlrpc)$ $1?INTERNAL_AUTH=%{HTTP:Authorization}&%{QUERY_STRING} [L]
</Location>

<IfModule mod_fastcgi.c>
    AddHandler fastcgi-script .fcgi
    FastCgiConfig -pass-header Authorization
</IfModule>

Add/Change #1169 (HTTPAuth doesn't validate against AccountManager htpasswd file)




Change Properties
Action