iCepa/Tor.framework

Collaboration request

Closed this issue · 11 comments

Hi, I have developed a Bitcoin app that allows users to connect to their node via SSH. I would very much like to enable the ability to connect to a bitcoind hidden service using this framework. I am a total Tor newb though. If anyone would be willing to help me or submit a PR to my open sourced app that is 100% free that would be really cool. If not do you know of any apps written in swift that uses this framework that I could use as a reference to help me?

https://github.com/FontaineDenton/FullyNoded

AFAIK, http://github.com/OnionBrowser/OnionBrowser/ is the current reference implementation.

I'm happy to help, if you show, that you tried to find out for yourself, first.

Just ask questions here.

Cool, I will be working on it actively soon. If I hit road blocks I will reach out here, thanks for the response

Hi, trying to build with xcode 10.2. When I run carthage update --platform iOS I get:

Build Failed
	Task failed with exit code 65:
	/usr/bin/xcrun xcodebuild -project /Users/peter/Desktop/MyStuff/BitSense/BitSense/Carthage/Checkouts/Tor.framework/Tor.xcodeproj -scheme Tor-iOS -configuration Release -derivedDataPath /Users/peter/Library/Caches/org.carthage.CarthageKit/DerivedData/10.2.1_10E1001/Tor.framework/64266b031211bcd10b79025f7c809bfe485d96e9 -sdk iphoneos ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES archive -archivePath /var/folders/3d/jzth48_15_g1mrhgr2pkkwcm0000gn/T/Tor.framework SKIP_INSTALL=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO CLANG_ENABLE_CODE_COVERAGE=NO STRIP_INSTALLED_PRODUCT=NO (launched in /Users/peter/Desktop/MyStuff/BitSense/BitSense/Carthage/Checkouts/Tor.framework)

This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/3d/jzth48_15_g1mrhgr2pkkwcm0000gn/T/carthage-xcodebuild.WUs5UD.log

The output of that log file is really long. I followed the instructions and have downloaded the dependencies and added them to my path.

Any advice on how to troubleshoot?

One thing to add, when I go to install the dependencies (autoconf, automake, gettext, libtool) via brew they are all already installed but not linked, i try and force link them but I get a circular error where I can't link them, delete them or use root privileges to try and do it.

Any advice on how to troubleshoot?

Yes. Follow the instructions:

Please check the xcodebuild log for more details: /var/folders/3d/jzth48_15_g1mrhgr2pkkwcm0000gn/T/carthage-xcodebuild.WUs5UD.log

The log showed I had issues with how the dependencies were installed, I had to give permissions to some files in /usr/local/bin then linked everything with brew and it is now building into my project successfully.

I have Tor running successfully on my app however I am not sure how to go about connecting to my bitcoind hidden service. Ive got the bitcoind hidden service running successfully and have the host info (.onion, port #, and cookie). The goal is to make commands to the RPC interface via the hidden service.

Here is my code for getting Tor connected (which is working):

let conf = TorConfiguration()
    
    func startTor() {
        
        let filemgr = FileManager.default
        let dirPaths = filemgr.urls(for: .cachesDirectory, in: .userDomainMask)
        let docsDir = dirPaths[0].path
        
        let dataDir = URL(fileURLWithPath: docsDir, isDirectory: true).appendingPathComponent("tor", isDirectory: true)
        
        // Create tor data directory if it does not yet exist
        do {
            try FileManager.default.createDirectory(atPath: dataDir.path, withIntermediateDirectories: true, attributes: nil)
        } catch let error as NSError {
            print("error=\(error.localizedDescription))")
        }
        // Create tor v3 auth directory if it does not yet exist
        let authDir = URL(fileURLWithPath: dataDir.path, isDirectory: true).appendingPathComponent("auth", isDirectory: true)
        do {
            try FileManager.default.createDirectory(atPath: authDir.path, withIntermediateDirectories: true, attributes: nil)
        } catch let error as NSError {
            print("error=\(error.localizedDescription))")
        }
        
        conf.cookieAuthentication = true
        conf.dataDirectory = dataDir
        
        let config_args = [
            "--allow-missing-torrc",
            "--ignore-missing-torrc",
            "--clientonly", "1",
            "--socksport", "39050",
            "--controlport", "127.0.0.1:39060",
            "--ClientOnionAuthDir", authDir.path
        ]
        
        conf.arguments = config_args
        
        let thread = TorThread.init(configuration: conf)
        thread.start()
        
     }

How would I then go about connecting to my hidden service? Do I add the cookie and hidden service onion address to config_args?

I tried something like this (which is obviously not correct):

        let cookie = Data("myCookie".utf8)
        
        let controller = TorController.init(socketHost: "127.0.0.1", port: 39060)
        
        controller.authenticate(with: cookie) { (success, error) in
            
            if error != nil {
                
                print("error authenticating tor = \(error!.localizedDescription)")
                
            } else {
                
                print("successfully authenticated tor")
                
                controller.addObserver(forCircuitEstablished: { (established) in
                    
                    if !established {
                        
                        print("circuit failed to establish")
                        
                    } else {
                        
                        print("circuit established")
                        
                        controller.getSessionConfiguration({ (configuration) in
                            
                            if let session = URLSession.init(configuration: configuration!) as? URLSession {
                                
                                print("session established")
                                
                                
                            }
                            
                        })
                        
                    }
                    
                })
                
            }
            
        }

Any guidance in the right direction would be great appreciated.

Are we talking HTTP cookie now? That, you will add to your HTTP request, of course.
The .onion address is used like any domain. Just do a web request. It will be resolved, when the Tor thread is properly configured and a circuit fully established.

The following code:


func startTor() {
        
        let conf = TorConfiguration()
        
        let filemgr = FileManager.default
        let dirPaths = filemgr.urls(for: .cachesDirectory, in: .userDomainMask)
        let docsDir = dirPaths[0].path
        
        let dataDir = URL(fileURLWithPath: docsDir, isDirectory: true).appendingPathComponent("tor", isDirectory: true)
        
        // Create tor data directory if it does not yet exist
        do {
            
            try FileManager.default.createDirectory(atPath: dataDir.path, withIntermediateDirectories: true, attributes: nil)
            
        } catch let error as NSError {
            
            print("error creating tor data directory = \(error.localizedDescription))")
            
        }
        
        conf.cookieAuthentication = true
        conf.dataDirectory = dataDir
        
        let config_args = [
            "--allow-missing-torrc",
            "--ignore-missing-torrc",
            "--clientonly", "1",
            "--socksport", "39050",
            "--controlport", "127.0.0.1:39060"
        ]
        
        conf.arguments = config_args
        
        let thread = TorThread.init(configuration: conf)
        thread.start()
        
    }

Outputs this into my xcode console:

Jun 10 11:49:48.213 [notice] Tor 0.3.5.8 running on Darwin with Libevent 2.1.8-stable, OpenSSL 1.1.0i, Zlib 1.2.11, Liblzma N/A, and Libzstd N/A.
Jun 10 11:49:48.213 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning
Jun 10 11:49:48.214 [notice] Configuration file "/private/var/mobile/Containers/Data/Application/05EAE74B-BC77-426B-8CFC-7E735CB84972/.torrc" not present, using reasonable defaults.
Jun 10 11:49:48.222 [notice] Opening Socks listener on 127.0.0.1:39050
Jun 10 11:49:48.222 [notice] Opened Socks listener on 127.0.0.1:39050
Jun 10 11:49:48.222 [notice] Opening Control listener on 127.0.0.1:39060
Jun 10 11:49:48.222 [notice] Opened Control listener on 127.0.0.1:39060
Jun 10 11:49:48.000 [notice] Bootstrapped 0%: Starting
Jun 10 11:49:48.000 [notice] Starting with guard context "default"
Jun 10 11:49:49.000 [notice] Bootstrapped 10%: Finishing handshake with directory server
Jun 10 11:49:49.000 [notice] Bootstrapped 80%: Connecting to the Tor network
Jun 10 11:49:50.000 [notice] Bootstrapped 90%: Establishing a Tor circuit
Jun 10 11:49:51.000 [notice] Bootstrapped 100%: Done

I then try and make a URL call:


let url = URL(string: "http://explorernuoc63nb.onion")!
            
            let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
                
                print("response = \(String(describing: response))")
                
                print("error = \(String(describing: error))")
                
                guard let data = data else { return }
                
                print(String(data: data, encoding: .utf8)!)
                
            }
            
            task.resume()

Which fails and gives me the following output in the console:


2019-06-10 11:49:58.837117+0800 BitSense[2927:1323404] TIC TCP Conn Failed [2:0x282f6a280]: 1:50 Err(50)
2019-06-10 11:49:58.840367+0800 BitSense[2927:1323404] Task <D5A540FA-9330-41F6-9803-858860CF72D4>.<2> HTTP load failed (error code: -1009 [1:50])
2019-06-10 11:49:58.840991+0800 BitSense[2927:1323425] Task <D5A540FA-9330-41F6-9803-858860CF72D4>.<2> finished with error - code: -1009
response = nil
error = Optional(Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSUnderlyingError=0x2815d4450 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=http://explorernuoc63nb.onion/, NSErrorFailingURLKey=http://explorernuoc63nb.onion/, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=50, NSLocalizedDescription=The Internet connection appears to be offline.})

It seems like it's connecting to Tor circuit fine, but the HTTP call doesn't connect to the internet, any ideas why? (thank you very much for your assistance it is highly appreciated)

I think what I need to do is follow his objective-c "Usage" example which seems to manually convert the TorConfiguration to a NSURL Session configuration. Unfortunately my Objective-C is terrible... But I think I know what to do, I did try that but unfortunately when I create the tor data directory and append the "control_socket" path I get an error saying something like "unix error path name too long for socket". Am thinking I can add the tor datadir as a folder in my bundle.main to get around this error.

closing to create a specific issue