001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.proxy.handlers.socks;
021
022import java.net.InetSocketAddress;
023
024import org.apache.mina.proxy.handlers.ProxyRequest;
025
026/**
027 * SocksProxyRequest.java - Wrapper class for SOCKS requests.
028 * 
029 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
030 * @since MINA 2.0.0-M3
031 */
032public class SocksProxyRequest extends ProxyRequest {
033
034    /**
035     * The SOCKS protocol version.
036     */
037    private byte protocolVersion;
038
039    /**
040     * The command code.
041     */
042    private byte commandCode;
043
044    /**
045     * The user name used when authenticating to the proxy server. 
046     */
047    private String userName;
048
049    /**
050     * The user's password used when authenticating to the proxy server.
051     */
052    private String password;
053
054    /**
055     * The SOCKS server host name.
056     */
057    private String host;
058
059    /**
060     * The SOCKS server port.
061     */
062    private int port;
063
064    /**
065     * The Kerberos service name used in GSSAPI authentication mode.
066     */
067    private String serviceKerberosName;
068
069    /**
070     * Constructor used when building a SOCKS4 request.
071     * 
072     * @param protocolVersion the protocol version
073     * @param commandCode the command code
074     * @param endpointAddress the endpoint address
075     * @param userName the user name
076     */
077    public SocksProxyRequest(byte protocolVersion, byte commandCode, InetSocketAddress endpointAddress, String userName) {
078        super(endpointAddress);
079        this.protocolVersion = protocolVersion;
080        this.commandCode = commandCode;
081        this.userName = userName;
082    }
083
084    /**
085     * Constructor used when building a SOCKS4a request.
086     * 
087     * @param commandCode the command code
088     * @param host the server host name
089     * @param port the server port
090     * @param userName the user name
091     */
092    public SocksProxyRequest(byte commandCode, String host, int port, String userName) {
093        this.protocolVersion = SocksProxyConstants.SOCKS_VERSION_4;
094        this.commandCode = commandCode;
095        this.userName = userName;
096        this.host = host;
097        this.port = port;
098    }
099
100    /**
101     * @return the endpoint address resulting from the {@link #getEndpointAddress()}. 
102     * If not set, it will return the {@link SocksProxyConstants#FAKE_IP} constant 
103     * value which will be ignored in a SOCKS v4 request.
104     */
105    public byte[] getIpAddress() {
106        if (getEndpointAddress() == null) {
107            return SocksProxyConstants.FAKE_IP;
108        }
109
110        return getEndpointAddress().getAddress().getAddress();
111    }
112
113    /**
114     * Return the server port as a byte array.
115     * 
116     * @return the server port
117     */
118    public byte[] getPort() {
119        byte[] port = new byte[2];
120        int p = (getEndpointAddress() == null ? this.port : getEndpointAddress().getPort());
121        port[1] = (byte) p;
122        port[0] = (byte) (p >> 8);
123        return port;
124    }
125
126    /**
127     * Return the command code.
128     * 
129     * @return the command code
130     */
131    public byte getCommandCode() {
132        return commandCode;
133    }
134
135    /**
136     * Return the protocol version.
137     * 
138     * @return the protocol version
139     */
140    public byte getProtocolVersion() {
141        return protocolVersion;
142    }
143
144    /**
145     * Return the user name.
146     * 
147     * @return the user name
148     */
149    public String getUserName() {
150        return userName;
151    }
152
153    /**
154     * Return the server host name.
155     * 
156     * @return the server host name
157     */
158    public synchronized final String getHost() {
159        if (host == null) {
160            InetSocketAddress adr = getEndpointAddress();
161
162            if (adr != null && !adr.isUnresolved()) {
163                host = getEndpointAddress().getHostName();
164            }
165        }
166
167        return host;
168    }
169
170    /**
171     * Return the user password.
172     * 
173     * @return the user password
174     */
175    public String getPassword() {
176        return password;
177    }
178
179    /**
180     * Set the user password
181     * 
182     * @param password the user password value
183     */
184    public void setPassword(String password) {
185        this.password = password;
186    }
187
188    /**
189     * Return the Kerberos service name.
190     * 
191     * @return the Kerberos service name
192     */
193    public String getServiceKerberosName() {
194        return serviceKerberosName;
195    }
196
197    /**
198     * Set the Kerberos service name.
199     * 
200     * @param serviceKerberosName the Kerberos service name
201     */
202    public void setServiceKerberosName(String serviceKerberosName) {
203        this.serviceKerberosName = serviceKerberosName;
204    }
205}