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