]> git.saurik.com Git - apple/security.git/blame - cdsa/cdsa_utilities/socks++4.cpp
Security-54.1.9.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / socks++4.cpp
CommitLineData
bac41a7b
A
1/*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19//
20// socks++int - internal Socks implementation
21//
22#include "socks++4.h"
23#include "hosts.h"
24#include <set>
25
26
27namespace Security {
28namespace IPPlusPlus {
29namespace Socks4 {
30
31
32
33//
34// Socks4 Protocol implementation
35//
36void Server::connect(SocksClientSocket &me, const IPSockAddress &peer)
37{
38 me.Socket::open(SOCK_STREAM);
39 me.Socket::connect(mServerAddress);
40 Message request(socksConnect, peer);
41 request.send(me, "nobody");
42 (Message(me)); // read and check reply message
43 me.mPeerAddress = peer; // best guess, Mr. Sulu
44 debug("socks", "%d socks4 connected to %s", me.fd(), string(peer).c_str());
45}
46
47void Server::connect(SocksClientSocket &me, const Host &host, IPPort port)
48{
49 // Socks4 has no name resolution support. Do it here
50 //@@@ error reporting sucks here
51 set<IPAddress> addrs = host.addresses();
52 for (set<IPAddress>::const_iterator it = addrs.begin(); it != addrs.end(); it++) {
53 try {
54 IPSockAddress addr(*it, port);
55 connect(me, addr);
56 return;
29654253 57 } catch (const UnixError &err) {
bac41a7b
A
58 errno = err.error;
59 }
60 }
61 // exhausted
62 UnixError::throwMe();
63}
64
65
66void Server::bind(SocksServerSocket &me, const IPAddress &peer, IPPort port)
67{
68 me.Socket::open(SOCK_STREAM);
69 me.Socket::connect(mServerAddress);
70 Message request(socksBind, IPSockAddress(peer, port));
71 request.send(me, "nobody");
72 Message reply(me);
73 me.mLocalAddress = reply.address().defaults(mServerAddress.address());
74 debug("socks", "%d socks4 bound to %s", me.fd(), string(me.mLocalAddress).c_str());
75}
76
77void Server::receive(SocksServerSocket &me, SocksClientSocket &receiver)
78{
79 Message reply(me);
80 receiver.setFd(me.fd(), me.mLocalAddress, reply.address());
81 me.clear(); // clear our own (don't close on destruction)
82 debug("socks", "%d socks4 inbound connect", receiver.fd());
83}
84
85
86//
87// Message properties
88//
89Message::Message(Command cmd, const IPSockAddress &address)
90 : version(4), message(cmd), port(htons(address.port())), addr(address.address())
91{
92}
93
94
95void Message::send(Socket &s, const char *userid)
96{
97 if (s.write(this, sizeof(*this)) != sizeof(*this))
98 UnixError::throwMe();
99 // now append zero-terminated userid (what a crock)
100 size_t length = strlen(userid) + 1;
101 if (s.write(userid, length) != length) {
102 s.close();
103 UnixError::throwMe();
104 }
105}
106
107Message::Message(Socket &s)
108{
109 if (s.read(this, sizeof(*this)) != sizeof(*this)) {
110 s.close();
111 UnixError::throwMe();
112 }
113 if (version != 0) {
114 s.close();
115 UnixError::throwMe(EPROTONOSUPPORT);
116 }
117 switch (message) {
118 case requestAccepted:
119 return;
120 default:
121 UnixError::throwMe(ECONNREFUSED); //@@@ hardly any diagnostics here
122 }
123}
124
125
126} // end namespace Socks
127} // end namespace IPPlusPlus
128} // end namespace Security