~ubuntu-branches/ubuntu/maverick/tomcat6/maverick

« back to all changes in this revision

Viewing changes to .pc/0012-Prevent-disclosure-of-host-name-or-IP-address.patch/java/org/apache/catalina/authenticator/BasicAuthenticator.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2010-06-28 21:41:31 UTC
  • mfrom: (2.2.15 sid)
  • Revision ID: james.westby@ubuntu.com-20100628214131-3wktukpb3lgdf83h
Tags: 6.0.26-5
* Convert patches to dep3 format.
* Backport security fix from trunk to fix CVE-2010-1157. (Closes: #587447)
* Set urgency to medium due to the security fix.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements.  See the NOTICE file distributed with
 
4
 * this work for additional information regarding copyright ownership.
 
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
6
 * (the "License"); you may not use this file except in compliance with
 
7
 * the License.  You may obtain a copy of the License at
 
8
 * 
 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
 
10
 * 
 
11
 * Unless required by applicable law or agreed to in writing, software
 
12
 * distributed under the License is distributed on an "AS IS" BASIS,
 
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
 * See the License for the specific language governing permissions and
 
15
 * limitations under the License.
 
16
 */
 
17
 
 
18
 
 
19
package org.apache.catalina.authenticator;
 
20
 
 
21
 
 
22
import java.io.IOException;
 
23
import java.security.Principal;
 
24
 
 
25
import javax.servlet.http.HttpServletResponse;
 
26
 
 
27
import org.apache.catalina.connector.Request;
 
28
import org.apache.catalina.connector.Response;
 
29
import org.apache.catalina.deploy.LoginConfig;
 
30
import org.apache.catalina.util.Base64;
 
31
import org.apache.juli.logging.Log;
 
32
import org.apache.juli.logging.LogFactory;
 
33
import org.apache.tomcat.util.buf.ByteChunk;
 
34
import org.apache.tomcat.util.buf.CharChunk;
 
35
import org.apache.tomcat.util.buf.MessageBytes;
 
36
 
 
37
 
 
38
 
 
39
/**
 
40
 * An <b>Authenticator</b> and <b>Valve</b> implementation of HTTP BASIC
 
41
 * Authentication, as outlined in RFC 2617:  "HTTP Authentication: Basic
 
42
 * and Digest Access Authentication."
 
43
 *
 
44
 * @author Craig R. McClanahan
 
45
 * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (Di, 24. Okt 2006) $
 
46
 */
 
47
 
 
48
public class BasicAuthenticator
 
49
    extends AuthenticatorBase {
 
50
    private static Log log = LogFactory.getLog(BasicAuthenticator.class);
 
51
 
 
52
 
 
53
 
 
54
    /**
 
55
     * Authenticate bytes.
 
56
     */
 
57
    public static final byte[] AUTHENTICATE_BYTES = {
 
58
        (byte) 'W',
 
59
        (byte) 'W',
 
60
        (byte) 'W',
 
61
        (byte) '-',
 
62
        (byte) 'A',
 
63
        (byte) 'u',
 
64
        (byte) 't',
 
65
        (byte) 'h',
 
66
        (byte) 'e',
 
67
        (byte) 'n',
 
68
        (byte) 't',
 
69
        (byte) 'i',
 
70
        (byte) 'c',
 
71
        (byte) 'a',
 
72
        (byte) 't',
 
73
        (byte) 'e'
 
74
    };
 
75
 
 
76
 
 
77
   // ----------------------------------------------------- Instance Variables
 
78
 
 
79
 
 
80
    /**
 
81
     * Descriptive information about this implementation.
 
82
     */
 
83
    protected static final String info =
 
84
        "org.apache.catalina.authenticator.BasicAuthenticator/1.0";
 
85
 
 
86
 
 
87
    // ------------------------------------------------------------- Properties
 
88
 
 
89
 
 
90
    /**
 
91
     * Return descriptive information about this Valve implementation.
 
92
     */
 
93
    public String getInfo() {
 
94
 
 
95
        return (info);
 
96
 
 
97
    }
 
98
 
 
99
 
 
100
    // --------------------------------------------------------- Public Methods
 
101
 
 
102
 
 
103
    /**
 
104
     * Authenticate the user making this request, based on the specified
 
105
     * login configuration.  Return <code>true</code> if any specified
 
106
     * constraint has been satisfied, or <code>false</code> if we have
 
107
     * created a response challenge already.
 
108
     *
 
109
     * @param request Request we are processing
 
110
     * @param response Response we are creating
 
111
     * @param config    Login configuration describing how authentication
 
112
     *              should be performed
 
113
     *
 
114
     * @exception IOException if an input/output error occurs
 
115
     */
 
116
    public boolean authenticate(Request request,
 
117
                                Response response,
 
118
                                LoginConfig config)
 
119
        throws IOException {
 
120
 
 
121
        // Have we already authenticated someone?
 
122
        Principal principal = request.getUserPrincipal();
 
123
        String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
 
124
        if (principal != null) {
 
125
            if (log.isDebugEnabled())
 
126
                log.debug("Already authenticated '" + principal.getName() + "'");
 
127
            // Associate the session with any existing SSO session
 
128
            if (ssoId != null)
 
129
                associate(ssoId, request.getSessionInternal(true));
 
130
            return (true);
 
131
        }
 
132
 
 
133
        // Is there an SSO session against which we can try to reauthenticate?
 
134
        if (ssoId != null) {
 
135
            if (log.isDebugEnabled())
 
136
                log.debug("SSO Id " + ssoId + " set; attempting " +
 
137
                          "reauthentication");
 
138
            /* Try to reauthenticate using data cached by SSO.  If this fails,
 
139
               either the original SSO logon was of DIGEST or SSL (which
 
140
               we can't reauthenticate ourselves because there is no
 
141
               cached username and password), or the realm denied
 
142
               the user's reauthentication for some reason.
 
143
               In either case we have to prompt the user for a logon */
 
144
            if (reauthenticateFromSSO(ssoId, request))
 
145
                return true;
 
146
        }
 
147
 
 
148
        // Validate any credentials already included with this request
 
149
        String username = null;
 
150
        String password = null;
 
151
 
 
152
        MessageBytes authorization = 
 
153
            request.getCoyoteRequest().getMimeHeaders()
 
154
            .getValue("authorization");
 
155
        
 
156
        if (authorization != null) {
 
157
            authorization.toBytes();
 
158
            ByteChunk authorizationBC = authorization.getByteChunk();
 
159
            if (authorizationBC.startsWithIgnoreCase("basic ", 0)) {
 
160
                authorizationBC.setOffset(authorizationBC.getOffset() + 6);
 
161
                // FIXME: Add trimming
 
162
                // authorizationBC.trim();
 
163
                
 
164
                CharChunk authorizationCC = authorization.getCharChunk();
 
165
                Base64.decode(authorizationBC, authorizationCC);
 
166
                
 
167
                // Get username and password
 
168
                int colon = authorizationCC.indexOf(':');
 
169
                if (colon < 0) {
 
170
                    username = authorizationCC.toString();
 
171
                } else {
 
172
                    char[] buf = authorizationCC.getBuffer();
 
173
                    username = new String(buf, 0, colon);
 
174
                    password = new String(buf, colon + 1, 
 
175
                            authorizationCC.getEnd() - colon - 1);
 
176
                }
 
177
                
 
178
                authorizationBC.setOffset(authorizationBC.getOffset() - 6);
 
179
            }
 
180
 
 
181
            principal = context.getRealm().authenticate(username, password);
 
182
            if (principal != null) {
 
183
                register(request, response, principal, Constants.BASIC_METHOD,
 
184
                         username, password);
 
185
                return (true);
 
186
            }
 
187
        }
 
188
        
 
189
 
 
190
        // Send an "unauthorized" response and an appropriate challenge
 
191
        MessageBytes authenticate = 
 
192
            response.getCoyoteResponse().getMimeHeaders()
 
193
            .addValue(AUTHENTICATE_BYTES, 0, AUTHENTICATE_BYTES.length);
 
194
        CharChunk authenticateCC = authenticate.getCharChunk();
 
195
        authenticateCC.append("Basic realm=\"");
 
196
        if (config.getRealmName() == null) {
 
197
            authenticateCC.append(request.getServerName());
 
198
            authenticateCC.append(':');
 
199
            authenticateCC.append(Integer.toString(request.getServerPort()));
 
200
        } else {
 
201
            authenticateCC.append(config.getRealmName());
 
202
        }
 
203
        authenticateCC.append('\"');        
 
204
        authenticate.toChars();
 
205
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
 
206
        //response.flushBuffer();
 
207
        return (false);
 
208
 
 
209
    }
 
210
 
 
211
 
 
212
}