1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License.
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *     http://www.apache.org/licenses/LICENSE-2.0
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS,
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License.
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smackx.bytestreams.socks5;
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.IOException;
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.net.Socket;
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.TimeoutException;
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.Connection;
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.XMPPException;
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.IQ;
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.util.SyncPacketSend;
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Implementation of a SOCKS5 client used on the initiators side. This is needed because connecting
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to the local SOCKS5 proxy differs form the regular way to connect to a SOCKS5 proxy. Additionally
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * a remote SOCKS5 proxy has to be activated by the initiator before data can be transferred between
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the peers.
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Henning Staib
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenclass Socks5ClientForInitiator extends Socks5Client {
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /* the XMPP connection used to communicate with the SOCKS5 proxy */
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private Connection connection;
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /* the session ID used to activate SOCKS5 stream */
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private String sessionID;
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /* the target JID used to activate SOCKS5 stream */
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private String target;
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Creates a new SOCKS5 client for the initiators side.
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param streamHost containing network settings of the SOCKS5 proxy
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param digest identifying the SOCKS5 Bytestream
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param connection the XMPP connection
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param sessionID the session ID of the SOCKS5 Bytestream
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param target the target JID of the SOCKS5 Bytestream
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Socks5ClientForInitiator(StreamHost streamHost, String digest, Connection connection,
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    String sessionID, String target) {
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        super(streamHost, digest);
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.connection = connection;
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.sessionID = sessionID;
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.target = target;
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Socket getSocket(int timeout) throws IOException, XMPPException, InterruptedException,
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    TimeoutException {
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Socket socket = null;
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // check if stream host is the local SOCKS5 proxy
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (this.streamHost.getJID().equals(this.connection.getUser())) {
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy();
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            socket = socks5Server.getSocket(this.digest);
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (socket == null) {
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw new XMPPException("target is not connected to SOCKS5 proxy");
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        else {
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            socket = super.getSocket(timeout);
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            try {
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                activate();
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            catch (XMPPException e) {
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                socket.close();
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                throw new XMPPException("activating SOCKS5 Bytestream failed", e);
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return socket;
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Activates the SOCKS5 Bytestream by sending a XMPP SOCKS5 Bytestream activation packet to the
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * SOCKS5 proxy.
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void activate() throws XMPPException {
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Bytestream activate = createStreamHostActivation();
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // if activation fails #getReply throws an exception
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        SyncPacketSend.getReply(this.connection, activate);
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns a SOCKS5 Bytestream activation packet.
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return SOCKS5 Bytestream activation packet
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private Bytestream createStreamHostActivation() {
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Bytestream activate = new Bytestream(this.sessionID);
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        activate.setMode(null);
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        activate.setType(IQ.Type.SET);
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        activate.setTo(this.streamHost.getJID());
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        activate.setToActivate(this.target);
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return activate;
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
118