Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/blockchaincommons/bcswifttor

Opinionated pure Swift controller for Tor, including full support for Swift 5.5 and Swift Concurrency.
https://github.com/blockchaincommons/bcswifttor

Last synced: 2 months ago
JSON representation

Opinionated pure Swift controller for Tor, including full support for Swift 5.5 and Swift Concurrency.

Awesome Lists containing this project

README

        

# BCSwiftTor

Opinionated pure Swift controller for [Tor](https://github.com/torproject/tor), including full support for Swift 5.5 and Swift Concurrency.

Inspired by [Tor.framework](https://github.com/iCepa/Tor.framework) but designed to be used seamlessly with [Blockchain Commons]() projects and technologies.

# Dependencies

Depends on [BCSwiftTorBase](https://github.com/BlockchainCommons/BCSwiftTorBase), which is a thin wrapper around Tor that has a new build system for building a universal XCFramework for use with MacOSX, Mac Catalyst, iOS devices, and the iOS simulator across Intel and Apple Silicon (ARM).

# Building

Add to your project like any other Swift Package.

# Usage

```swift
import XCTest
import Tor

class ReadMeTests: XCTestCase {
var controller: TorController!

// Configure the controller. Socket files have length limitations, so find a file system path
// that's short enough to accomodate the socket file we use to communicate with the Tor thread.
static let configuration: TorConfiguration = {
var homeDirectory: URL!
#if targetEnvironment(simulator)
for variable in ["IPHONE_SIMULATOR_HOST_HOME", "SIMULATOR_HOST_HOME"] {
if let p = getenv(variable) {
homeDirectory = URL(fileURLWithPath: String(cString: p))
break
}
}
#else
homeDirectory = URL(fileURLWithPath: NSHomeDirectory())
#endif
precondition(homeDirectory != nil)

let fileManager = FileManager.default

let dataDirectory = fileManager.temporaryDirectory
let socketDirectory = homeDirectory.appendingPathComponent(".tor")
try! fileManager.createDirectory(at: socketDirectory, withIntermediateDirectories: true)
let socketFile = socketDirectory.appendingPathComponent("control_port")

return TorConfiguration(
dataDirectory: dataDirectory,
controlSocket: socketFile,
options: [.ignoreMissingTorrc, .cookieAuthentication]
)
}()

// Run once for every all tests in this suite. Start the Tor thread with logging back to the app.
static override func setUp() {
super.setUp()

let runner = TorRunner(configuration: Self.configuration)
runner.setLogging(minLogSeverity: .notice) { severity, domain, msg in
print("🔵 [\(severity)]: \(domain): \(msg)")
}
runner.run()
}

// Run once for each test this suite. Create a new Tor controller object.
override func setUp() async throws {
try await super.setUp()

controller = try await TorController(socket: Self.configuration.controlSocket)
}

// Authenticate to the Tor process using the cookie that it writes to the file system.
func authenticate() async throws {
guard let cookie = Self.configuration.cookie else {
XCTFail("No cookie file found.")
return
}
try await controller.authenticate(with: cookie)
}

func testRetrieveURL() async throws {
// Authenticate and then wait until a circuit is established
try await authenticate()
try await controller.untilCircuitEstablished()

// Create a URL session that communicates using the socket that's been set up.
let sessionConfiguration = try await controller.getSessionConfiguration()
let session = URLSession(configuration: sessionConfiguration)

// Use the URLSession to retrieve data from an Onion address URL via Tor.

// Blockchain Commons SpotBit instance.
// https://github.com/blockchaincommons/spotbit#test-server
let url = URL(string: "http://h6zwwkcivy2hjys6xpinlnz2f74dsmvltzsd4xb42vinhlcaoe7fdeqd.onion/status")!
let (data, resp) = try await session.data(from: url)
let response = resp as! HTTPURLResponse
XCTAssertEqual(response.statusCode, 200)
XCTAssertEqual(data.utf8, "server is running")
}
}
```