Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -103,12 +103,10 @@ 4B2B3E80140D430500EC2F7C /* OFDictionary_hashtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E76140D430500EC2F7C /* OFDictionary_hashtable.m */; }; 4B2B3E81140D430500EC2F7C /* OFMutableArray_adjacent.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2B3E77140D430500EC2F7C /* OFMutableArray_adjacent.h */; settings = {ATTRIBUTES = (); }; }; 4B2B3E82140D430500EC2F7C /* OFMutableArray_adjacent.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E78140D430500EC2F7C /* OFMutableArray_adjacent.m */; }; 4B2B3E83140D430500EC2F7C /* OFMutableDictionary_hashtable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2B3E79140D430500EC2F7C /* OFMutableDictionary_hashtable.h */; settings = {ATTRIBUTES = (); }; }; 4B2B3E84140D430500EC2F7C /* OFMutableDictionary_hashtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E7A140D430500EC2F7C /* OFMutableDictionary_hashtable.m */; }; - 4B2B3E85140D430500EC2F7C /* OFSOCKS5Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2B3E7B140D430500EC2F7C /* OFSOCKS5Socket.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4B2B3E86140D430500EC2F7C /* OFSOCKS5Socket.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3E7C140D430500EC2F7C /* OFSOCKS5Socket.m */; }; 4B39844213D3A24600E6F825 /* OFSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B39844013D3A24600E6F825 /* OFSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B39844313D3A24600E6F825 /* OFSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844113D3A24600E6F825 /* OFSet.m */; }; 4B39844713D3AFB400E6F825 /* OFMutableSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B39844513D3AFB400E6F825 /* OFMutableSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B39844813D3AFB400E6F825 /* OFMutableSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844613D3AFB400E6F825 /* OFMutableSet.m */; }; 4B39844A13D3D03000E6F825 /* OFSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B39844913D3D03000E6F825 /* OFSet.m */; }; @@ -285,10 +283,12 @@ 4BB25E89139C388A00F574EA /* OFObject+Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB25E83139C388A00F574EA /* OFObject+Serialization.m */; }; 4BB25E8A139C388A00F574EA /* OFString+Serialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB25E84139C388A00F574EA /* OFString+Serialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BB25E8B139C388A00F574EA /* OFString+Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB25E85139C388A00F574EA /* OFString+Serialization.m */; }; 4BB25E8C139C388A00F574EA /* OFXMLElement+Serialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB25E86139C388A00F574EA /* OFXMLElement+Serialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BB25E8D139C388A00F574EA /* OFXMLElement+Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB25E87139C388A00F574EA /* OFXMLElement+Serialization.m */; }; + 4BD653C5143B8489006182F0 /* OFTCPSocket+SOCKS5.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD653C3143B8489006182F0 /* OFTCPSocket+SOCKS5.h */; }; + 4BD653C6143B8489006182F0 /* OFTCPSocket+SOCKS5.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD653C4143B8489006182F0 /* OFTCPSocket+SOCKS5.m */; }; 4BD98C03133814220048DD5B /* objfw-defs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD98C011338140B0048DD5B /* objfw-defs.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BDF37B51338055600F9A81A /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDF37B41338055600F9A81A /* config.h */; }; 4BE852D213B7671200C00856 /* OFDoubleMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE852CE13B7671200C00856 /* OFDoubleMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BE852D313B7671200C00856 /* OFDoubleMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE852CF13B7671200C00856 /* OFDoubleMatrix.m */; }; 4BE852D413B7671200C00856 /* OFDoubleVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE852D013B7671200C00856 /* OFDoubleVector.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -459,12 +459,10 @@ 4B2B3E76140D430500EC2F7C /* OFDictionary_hashtable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDictionary_hashtable.m; path = src/OFDictionary_hashtable.m; sourceTree = ""; }; 4B2B3E77140D430500EC2F7C /* OFMutableArray_adjacent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableArray_adjacent.h; path = src/OFMutableArray_adjacent.h; sourceTree = ""; }; 4B2B3E78140D430500EC2F7C /* OFMutableArray_adjacent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableArray_adjacent.m; path = src/OFMutableArray_adjacent.m; sourceTree = ""; }; 4B2B3E79140D430500EC2F7C /* OFMutableDictionary_hashtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableDictionary_hashtable.h; path = src/OFMutableDictionary_hashtable.h; sourceTree = ""; }; 4B2B3E7A140D430500EC2F7C /* OFMutableDictionary_hashtable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableDictionary_hashtable.m; path = src/OFMutableDictionary_hashtable.m; sourceTree = ""; }; - 4B2B3E7B140D430500EC2F7C /* OFSOCKS5Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSOCKS5Socket.h; path = src/OFSOCKS5Socket.h; sourceTree = ""; }; - 4B2B3E7C140D430500EC2F7C /* OFSOCKS5Socket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSOCKS5Socket.m; path = src/OFSOCKS5Socket.m; sourceTree = ""; }; 4B39844013D3A24600E6F825 /* OFSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSet.h; path = src/OFSet.h; sourceTree = ""; }; 4B39844113D3A24600E6F825 /* OFSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSet.m; path = src/OFSet.m; sourceTree = ""; }; 4B39844513D3AFB400E6F825 /* OFMutableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFMutableSet.h; path = src/OFMutableSet.h; sourceTree = ""; }; 4B39844613D3AFB400E6F825 /* OFMutableSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFMutableSet.m; path = src/OFMutableSet.m; sourceTree = ""; }; 4B39844913D3D03000E6F825 /* OFSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSet.m; path = tests/OFSet.m; sourceTree = ""; }; @@ -639,10 +637,12 @@ 4BB25E87139C388A00F574EA /* OFXMLElement+Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFXMLElement+Serialization.m"; path = "src/OFXMLElement+Serialization.m"; sourceTree = ""; }; 4BB50DCF12F863C700C9393F /* of_asprintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = of_asprintf.h; path = src/of_asprintf.h; sourceTree = SOURCE_ROOT; }; 4BB50DD012F863C700C9393F /* of_asprintf.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = of_asprintf.m; path = src/of_asprintf.m; sourceTree = SOURCE_ROOT; }; 4BBA36C411406AB700CBA3AC /* atomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = atomic.h; path = src/atomic.h; sourceTree = ""; }; 4BBA36C511406AB700CBA3AC /* macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macros.h; path = src/macros.h; sourceTree = ""; }; + 4BD653C3143B8489006182F0 /* OFTCPSocket+SOCKS5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFTCPSocket+SOCKS5.h"; path = "src/OFTCPSocket+SOCKS5.h"; sourceTree = ""; }; + 4BD653C4143B8489006182F0 /* OFTCPSocket+SOCKS5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFTCPSocket+SOCKS5.m"; path = "src/OFTCPSocket+SOCKS5.m"; sourceTree = ""; }; 4BD86D801237A6C600ED9912 /* OFBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFBlock.h; path = src/OFBlock.h; sourceTree = SOURCE_ROOT; }; 4BD86D811237A6C600ED9912 /* OFBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFBlock.m; path = src/OFBlock.m; sourceTree = SOURCE_ROOT; }; 4BD98C011338140B0048DD5B /* objfw-defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "objfw-defs.h"; path = "src/objfw-defs.h"; sourceTree = SOURCE_ROOT; }; 4BDF37B41338055600F9A81A /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = SOURCE_ROOT; }; 4BE17AD812FD744C002CEB0B /* foundation-compat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "foundation-compat.m"; path = "src/foundation-compat.m"; sourceTree = SOURCE_ROOT; }; @@ -952,12 +952,10 @@ 4B39844113D3A24600E6F825 /* OFSet.m */, 4BA85BC8140ECCE800E91D51 /* OFSet_hashtable.h */, 4BA85BC9140ECCE800E91D51 /* OFSet_hashtable.m */, 4BF1BCC411C9663F0025511F /* OFSHA1Hash.h */, 4BF1BCC511C9663F0025511F /* OFSHA1Hash.m */, - 4B2B3E7B140D430500EC2F7C /* OFSOCKS5Socket.h */, - 4B2B3E7C140D430500EC2F7C /* OFSOCKS5Socket.m */, 4B67997D1099E7C50041064A /* OFStream.h */, 4B67997E1099E7C50041064A /* OFStream.m */, 4BAF5F47123460C900F4E111 /* OFStreamObserver.h */, 4BAF5F48123460C900F4E111 /* OFStreamObserver.m */, 4B83F0F2142FDEFD00E4A821 /* OFStreamObserver_kqueue.h */, @@ -980,10 +978,12 @@ 4BF1BCCB11C9663F0025511F /* OFString+XMLEscaping.m */, 4BF1BCCC11C9663F0025511F /* OFString+XMLUnescaping.h */, 4BF1BCCD11C9663F0025511F /* OFString+XMLUnescaping.m */, 4B6799811099E7C50041064A /* OFTCPSocket.h */, 4B6799821099E7C50041064A /* OFTCPSocket.m */, + 4BD653C3143B8489006182F0 /* OFTCPSocket+SOCKS5.h */, + 4BD653C4143B8489006182F0 /* OFTCPSocket+SOCKS5.m */, 4B6799831099E7C50041064A /* OFThread.h */, 4B6799841099E7C50041064A /* OFThread.m */, 4B4A61F212DF5EA20048F3F2 /* OFURL.h */, 4B4A61F312DF5EA20048F3F2 /* OFURL.m */, 4BF1BCCE11C9663F0025511F /* OFXMLAttribute.h */, @@ -1144,11 +1144,10 @@ 4B3D23D21337FCB000DD29B8 /* OFPlugin.h in Headers */, 4B3D23D31337FCB000DD29B8 /* OFSeekableStream.h in Headers */, 4B989C2F13771A3700109A30 /* OFSerialization.h in Headers */, 4B39844213D3A24600E6F825 /* OFSet.h in Headers */, 4B3D23D41337FCB000DD29B8 /* OFSHA1Hash.h in Headers */, - 4B2B3E85140D430500EC2F7C /* OFSOCKS5Socket.h in Headers */, 4B3D23D51337FCB000DD29B8 /* OFStream.h in Headers */, 4B3D23D61337FCB000DD29B8 /* OFStreamObserver.h in Headers */, 4B3D23D71337FCB000DD29B8 /* OFStreamSocket.h in Headers */, 4B3D23D81337FCB000DD29B8 /* OFString.h in Headers */, 4B3D23D91337FCB000DD29B8 /* OFString+Hashing.h in Headers */, @@ -1239,10 +1238,11 @@ 4BA85BCC140ECCE800E91D51 /* OFMutableSet_hashtable.h in Headers */, 4BA85BCE140ECCE800E91D51 /* OFSet_hashtable.h in Headers */, 4B83F0F4142FDEFD00E4A821 /* OFStreamObserver_kqueue.h in Headers */, 4B64D6EF1425381E007BDFB1 /* OFStreamObserver_poll.h in Headers */, 4B64D6F11425381E007BDFB1 /* OFStreamObserver_select.h in Headers */, + 4BD653C5143B8489006182F0 /* OFTCPSocket+SOCKS5.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ @@ -1431,11 +1431,10 @@ 4B3D23A01337FC0D00DD29B8 /* OFPlugin.m in Sources */, 4B3D23A11337FC0D00DD29B8 /* OFSeekableStream.m in Sources */, 4B39844313D3A24600E6F825 /* OFSet.m in Sources */, 4BA85BCF140ECCE800E91D51 /* OFSet_hashtable.m in Sources */, 4B3D23A21337FC0D00DD29B8 /* OFSHA1Hash.m in Sources */, - 4B2B3E86140D430500EC2F7C /* OFSOCKS5Socket.m in Sources */, 4B3D23A31337FC0D00DD29B8 /* OFStream.m in Sources */, 4B3D23A41337FC0D00DD29B8 /* OFStreamObserver.m in Sources */, 4B83F0F5142FDEFD00E4A821 /* OFStreamObserver_kqueue.m in Sources */, 4B64D6F01425381E007BDFB1 /* OFStreamObserver_poll.m in Sources */, 4B64D6F21425381E007BDFB1 /* OFStreamObserver_select.m in Sources */, @@ -1445,10 +1444,11 @@ 4BB25E8B139C388A00F574EA /* OFString+Serialization.m in Sources */, 4B3D23A81337FC0D00DD29B8 /* OFString+URLEncoding.m in Sources */, 4B3D23A91337FC0D00DD29B8 /* OFString+XMLEscaping.m in Sources */, 4B3D23AA1337FC0D00DD29B8 /* OFString+XMLUnescaping.m in Sources */, 4B3D23AB1337FC0D00DD29B8 /* OFTCPSocket.m in Sources */, + 4BD653C6143B8489006182F0 /* OFTCPSocket+SOCKS5.m in Sources */, 4B3D23AC1337FC0D00DD29B8 /* OFThread.m in Sources */, 4B3D23AD1337FC0D00DD29B8 /* OFURL.m in Sources */, 4B3D23AE1337FC0D00DD29B8 /* OFXMLAttribute.m in Sources */, 4B49EA6E143B3A090005BBC6 /* OFXMLCDATA.m in Sources */, 4B49EA70143B3A090005BBC6 /* OFXMLCharacters.m in Sources */, Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -38,11 +38,10 @@ OFObject+Serialization.m \ ${OFPLUGIN_M} \ OFSeekableStream.m \ OFSet.m \ OFSHA1Hash.m \ - OFSOCKS5Socket.m \ OFStream.m \ OFStreamObserver.m \ OFStreamSocket.m \ OFString.m \ OFString+Hashing.m \ @@ -86,10 +85,11 @@ OFMutableSet_hashtable.m \ OFSet_hashtable.m \ ${OFSTREAMOBSERVER_KQUEUE_M} \ ${OFSTREAMOBSERVER_POLL_M} \ ${OFSTREAMOBSERVER_SELECT_M} \ + OFTCPSocket+SOCKS5.m \ ${ASPRINTF_M} \ ${FOUNDATION_COMPAT_M} \ iso_8859_15.m \ windows_1252.m \ ${OBJC_PROPERTIES_M} \ DELETED src/OFSOCKS5Socket.h Index: src/OFSOCKS5Socket.h ================================================================== --- src/OFSOCKS5Socket.h +++ src/OFSOCKS5Socket.h @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#import "OFTCPSocket.h" - -/** - * \brief A class which provides functions to create and use TCP sockets using a - * SOCKS5 proxy. - */ -@interface OFSOCKS5Socket: OFTCPSocket -{ - OFString *proxyHost; - uint16_t proxyPort; -} - -/** - * \brief Creates a new OFSOCKS5Socket which uses the specified SOCKS5 proxy. - * - * \param proxyHost The host of the SOCKS5 proxy - * \param proxyPort The port of the SOCKS5 proxy - * \return A new, autoreleased OFSOCKS5Socket - */ -+ socketWithProxyHost: (OFString*)proxyHost - port: (uint16_t)proxyPort; - -/** - * \brief Initializes an already allocated OFSOCKS5Socket with the specified - * SOCKS5 proxy. - * - * \param proxyHost The host of the SOCKS5 proxy - * \param proxyPort The port of the SOCKS5 proxy - * \return An initialized OFSOCKS5Socket - */ -- initWithProxyHost: (OFString*)proxyHost - port: (uint16_t)proxyPort; -@end DELETED src/OFSOCKS5Socket.m Index: src/OFSOCKS5Socket.m ================================================================== --- src/OFSOCKS5Socket.m +++ src/OFSOCKS5Socket.m @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#import "OFSOCKS5Socket.h" - -#import "OFConnectionFailedException.h" -#import "OFNotImplementedException.h" - -@implementation OFSOCKS5Socket -+ socketWithProxyHost: (OFString*)host - port: (uint16_t)port -{ - return [[[self alloc] initWithProxyHost: host - port: port] autorelease]; -} - -- init -{ - Class c = isa; - [self release]; - @throw [OFNotImplementedException exceptionWithClass: c - selector: _cmd]; -} - -- initWithProxyHost: (OFString*)host - port: (uint16_t)port -{ - self = [super init]; - - @try { - proxyHost = [host copy]; - proxyPort = port; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)dealloc -{ - [proxyHost release]; - - [super dealloc]; -} - -- (void)connectToHost: (OFString*)host - port: (uint16_t)port -{ - const char request[] = { 5, 1, 0, 3 }; - char reply[256]; - BOOL oldBuffersWrites; - - [super connectToHost: proxyHost - port: proxyPort]; - - /* 5 1 0 -> no authentication */ - [self writeNBytes: 3 - fromBuffer: request]; - - [self readExactlyNBytes: 2 - intoBuffer: reply]; - - if (reply[0] != 5 || reply[1] != 0) { - [self close]; - @throw [OFConnectionFailedException - exceptionWithClass: isa - socket: self - host: proxyHost - port: proxyPort]; - } - - oldBuffersWrites = [self buffersWrites]; - [self setBuffersWrites: YES]; - - /* CONNECT request */ - [self writeNBytes: 4 - fromBuffer: request]; - [self writeInt8: - [host cStringLengthWithEncoding: OF_STRING_ENCODING_NATIVE]]; - [self writeNBytes: [host cStringLengthWithEncoding: - OF_STRING_ENCODING_NATIVE] - fromBuffer: [host cStringWithEncoding: - OF_STRING_ENCODING_NATIVE]]; - [self writeBigEndianInt16: port]; - - [self flushWriteBuffer]; - [self setBuffersWrites: oldBuffersWrites]; - - [self readExactlyNBytes: 4 - intoBuffer: reply]; - - if (reply[0] != 5 || reply[1] != 0 || reply[2] != 0) { - [self close]; - @throw [OFConnectionFailedException exceptionWithClass: isa - socket: self - host: host - port: port]; - } - - /* Skip the rest of the reply */ - switch (reply[3]) { - case 1: /* IPv4 */ - [self readExactlyNBytes: 4 - intoBuffer: reply]; - break; - case 3: /* Domainname */ - [self readExactlyNBytes: [self readInt8] - intoBuffer: reply]; - break; - case 4: /* IPv6 */ - [self readExactlyNBytes: 16 - intoBuffer: reply]; - break; - default: - [self close]; - @throw [OFConnectionFailedException exceptionWithClass: isa - socket: self - host: host - port: port]; - } - - [self readBigEndianInt16]; -} -@end ADDED src/OFTCPSocket+SOCKS5.h Index: src/OFTCPSocket+SOCKS5.h ================================================================== --- src/OFTCPSocket+SOCKS5.h +++ src/OFTCPSocket+SOCKS5.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFTCPSocket.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int _OFTCPSocket_SOCKS5_reference; +#ifdef __cplusplus +} +#endif + +@interface OFTCPSocket (SOCKS5) +/// \cond internal +- (void)_SOCKS5ConnectToHost: (OFString*)host + port: (uint16_t)port; +/// \endcond +@end ADDED src/OFTCPSocket+SOCKS5.m Index: src/OFTCPSocket+SOCKS5.m ================================================================== --- src/OFTCPSocket+SOCKS5.m +++ src/OFTCPSocket+SOCKS5.m @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFTCPSocket+SOCKS5.h" + +#import "OFConnectionFailedException.h" + +/* Reference for static linking */ +int _OFTCPSocket_SOCKS5_reference; + +@implementation OFTCPSocket (SOCKS5) +- (void)_SOCKS5ConnectToHost: (OFString*)host + port: (uint16_t)port +{ + const char request[] = { 5, 1, 0, 3 }; + char reply[256]; + BOOL oldBuffersWrites; + + /* 5 1 0 -> no authentication */ + [self writeNBytes: 3 + fromBuffer: request]; + + [self readExactlyNBytes: 2 + intoBuffer: reply]; + + if (reply[0] != 5 || reply[1] != 0) { + [self close]; + @throw [OFConnectionFailedException + exceptionWithClass: isa + socket: self + host: host + port: port]; + } + + oldBuffersWrites = [self buffersWrites]; + [self setBuffersWrites: YES]; + + /* CONNECT request */ + [self writeNBytes: 4 + fromBuffer: request]; + [self writeInt8: + [host cStringLengthWithEncoding: OF_STRING_ENCODING_NATIVE]]; + [self writeNBytes: [host cStringLengthWithEncoding: + OF_STRING_ENCODING_NATIVE] + fromBuffer: [host cStringWithEncoding: + OF_STRING_ENCODING_NATIVE]]; + [self writeBigEndianInt16: port]; + + [self flushWriteBuffer]; + [self setBuffersWrites: oldBuffersWrites]; + + [self readExactlyNBytes: 4 + intoBuffer: reply]; + + if (reply[0] != 5 || reply[1] != 0 || reply[2] != 0) { + [self close]; + @throw [OFConnectionFailedException exceptionWithClass: isa + socket: self + host: host + port: port]; + } + + /* Skip the rest of the reply */ + switch (reply[3]) { + case 1: /* IPv4 */ + [self readExactlyNBytes: 4 + intoBuffer: reply]; + break; + case 3: /* Domainname */ + [self readExactlyNBytes: [self readInt8] + intoBuffer: reply]; + break; + case 4: /* IPv6 */ + [self readExactlyNBytes: 16 + intoBuffer: reply]; + break; + default: + [self close]; + @throw [OFConnectionFailedException exceptionWithClass: isa + socket: self + host: host + port: port]; + } + + [self readBigEndianInt16]; +} +@end Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -37,16 +37,50 @@ @interface OFTCPSocket: OFStreamSocket { BOOL listening; struct sockaddr_storage *sockAddr; socklen_t sockAddrLen; + OFString *SOCKS5Host; + uint16_t SOCKS5Port; } #ifdef OF_HAVE_PROPERTIES @property (assign, readonly, getter=isListening) BOOL listening; +@property (copy) OFString *SOCKS5Host; +@property (assign) uint16_t SOCKS5Port; #endif +/** + * \brief Sets the host to use as a SOCKS5 proxy. + * + * \param host The host to use as a SOCKS5 proxy + */ +- (void)setSOCKS5Host: (OFString*)host; + +/** + * \brief Returns the host to use as a SOCKS5 proxy. + * + * \return The host to use as a SOCKS5 proxy + */ +- (OFString*)SOCKS5Host; + +/** + * \brief Sets the port to use on the SOCKS5 proxy. + * + * The default port is 1080. + * + * \param port The port to use on the SOCKS5 proxy + */ +- (void)setSOCKS5Port: (uint16_t)port; + +/** + * \brief Returns the port to use on the SOCKS5 proxy. + * + * \return The port to use on the SOCKS5 proxy + */ +- (uint16_t)SOCKS5Port; + /** * \brief Connect the OFTCPSocket to the specified destination. * * \param host The host to connect to * \param port The port on the host to connect to Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -31,10 +31,11 @@ # include # include #endif #import "OFTCPSocket.h" +#import "OFTCPSocket+SOCKS5.h" #import "OFString.h" #import "OFAcceptFailedException.h" #import "OFAlreadyConnectedException.h" #import "OFAddressTranslationFailedException.h" @@ -41,10 +42,11 @@ #import "OFBindFailedException.h" #import "OFConnectionFailedException.h" #import "OFInvalidArgumentException.h" #import "OFListenFailedException.h" #import "OFNotConnectedException.h" +#import "OFNotImplementedException.h" #import "OFSetOptionFailedException.h" #import "macros.h" #ifndef INVALID_SOCKET @@ -59,10 +61,16 @@ #endif #ifdef _WIN32 # define close(sock) closesocket(sock) #endif + +/* References for static linking */ +void _references_to_categories_of_OFTCPSocket(void) +{ + _OFTCPSocket_SOCKS5_reference = 1; +} @implementation OFTCPSocket #if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) + (void)initialize { @@ -75,20 +83,50 @@ { self = [super init]; sock = INVALID_SOCKET; sockAddr = NULL; + SOCKS5Port = 1080; return self; } + +- (void)setSOCKS5Host: (OFString*)host +{ + OF_SETTER(SOCKS5Host, host, YES, YES) +} + +- (OFString*)SOCKS5Host +{ + OF_GETTER(SOCKS5Host, YES) +} + +- (void)setSOCKS5Port: (uint16_t)port +{ + SOCKS5Port = port; +} + +- (uint16_t)SOCKS5Port +{ + return SOCKS5Port; +} - (void)connectToHost: (OFString*)host port: (uint16_t)port { + OFString *destinationHost = host; + uint16_t destinationPort = port; + if (sock != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithClass: isa socket: self]; + + if (SOCKS5Host != nil) { + /* Connect to the SOCKS5 proxy instead */ + host = SOCKS5Host; + port = SOCKS5Port; + } #ifdef HAVE_THREADSAFE_GETADDRINFO struct addrinfo hints, *res, *res0; char portCString[7]; @@ -199,10 +237,14 @@ if (sock == INVALID_SOCKET) @throw [OFConnectionFailedException exceptionWithClass: isa socket: self host: host port: port]; + + if (SOCKS5Host != nil) + [self _SOCKS5ConnectToHost: destinationHost + port: destinationPort]; } - (uint16_t)bindToHost: (OFString*)host port: (uint16_t)port { @@ -215,10 +257,14 @@ if (sock != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithClass: isa socket: self]; + if (SOCKS5Host != nil) + @throw [OFNotImplementedException exceptionWithClass: isa + selector: _cmd]; + #ifdef HAVE_THREADSAFE_GETADDRINFO struct addrinfo hints, *res; char portCString[7]; memset(&hints, 0, sizeof(struct addrinfo)); Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -44,11 +44,10 @@ #import "OFStream.h" #import "OFFile.h" #import "OFStreamSocket.h" #import "OFTCPSocket.h" -#import "OFSOCKS5Socket.h" #import "OFStreamObserver.h" #import "OFHTTPRequest.h" #import "OFHash.h"