65: def open(host, port)
66: socket = TCPSocket.new(proxy_host, proxy_port)
67:
68: methods = [METHOD_NO_AUTH]
69: methods << METHOD_PASSWD if options[:user]
70:
71: packet = [VERSION, methods.size, *methods].pack("C*")
72: socket.send packet, 0
73:
74: version, method = socket.recv(2).unpack("CC")
75: if version != VERSION
76: socket.close
77: raise Net::SSH::Proxy::Error, "invalid SOCKS version (#{version})"
78: end
79:
80: if method == METHOD_NONE
81: socket.close
82: raise Net::SSH::Proxy::Error, "no supported authorization methods"
83: end
84:
85: negotiate_password(socket) if method == METHOD_PASSWD
86:
87: packet = [VERSION, CMD_CONNECT, 0].pack("C*")
88:
89: if host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
90: packet << [ATYP_IPV4, $1.to_i, $2.to_i, $3.to_i, $4.to_i].pack("C*")
91: else
92: packet << [ATYP_DOMAIN, host.length, host].pack("CCA*")
93: end
94:
95: packet << [port].pack("n")
96: socket.send packet, 0
97:
98: version, reply, = socket.recv(2).unpack("C*")
99: socket.recv(1)
100: address_type = socket.recv(1).getbyte(0)
101: case address_type
102: when 1
103: socket.recv(4)
104: when 3
105: len = socket.recv(1).getbyte(0)
106: hostname = socket.recv(len)
107: when 4
108: ipv6addr hostname = socket.recv(16)
109: else
110: socket.close
111: raise ConnectionError, "Illegal response type"
112: end
113: portnum = socket.recv(2)
114:
115: unless reply == SUCCESS
116: socket.close
117: raise ConnectError, "#{reply}"
118: end
119:
120: return socket
121: end