1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2026-03-09 17:59:19 +03:00
Files
SoftEtherVPN/SoftEtherVPN-iOS/SoftEtherVPN-iOS/Protocol/SoftEtherProtocol.swift

184 lines
6.9 KiB
Swift

import Foundation
import Network
import Security
import CryptoKit
/// SoftEtherProtocol manages the communication between iOS client and SoftEther VPN server
class SoftEtherProtocol {
// MARK: - Properties
private var secureConnection: SecureConnection?
private var isConnected = false
private var host: String = ""
private var port: UInt16 = 443
private var nextPacketId: UInt32 = 1
// MARK: - Public Methods
/// Connect to a SoftEther VPN server
/// - Parameters:
/// - host: The server hostname or IP address
/// - port: The server port (default: 443)
/// - completion: Callback with connection result
public func connect(to host: String, port: UInt16 = 443, completion: @escaping (Bool, Error?) -> Void) {
self.host = host
self.port = port
// Create a secure connection
secureConnection = SecureConnection(host: host, port: port)
// Connect using TLS
secureConnection?.connect { [weak self] success, error in
guard let self = self, success else {
completion(false, error ?? NSError(domain: "SoftEtherError", code: 1, userInfo: [NSLocalizedDescriptionKey: "TLS connection failed"]))
return
}
// After successful TLS connection, send the client signature
self.sendClientSignature { success, error in
if success {
self.isConnected = true
}
completion(success, error)
}
}
}
/// Disconnect from the server
public func disconnect() {
secureConnection?.disconnect()
isConnected = false
}
// MARK: - Private Methods
/// Send the SoftEther client signature to identify as a legitimate client
/// - Parameter completion: Callback with result
private func sendClientSignature(completion: @escaping (Bool, Error?) -> Void) {
// Generate client signature using our specialized class
let signatureData = SoftEtherClientSignature.generateSignature()
// Create a packet with the signature data
let packetId = self.nextPacketId
self.nextPacketId += 1
let packet = SoftEtherPacket(type: 0x01, id: packetId, data: signatureData)
let packetData = packet.serialize()
print("Sending client signature packet: \(packetData.count) bytes")
// Send the packet
secureConnection?.send(data: packetData) { [weak self] error in
guard let self = self else { return }
if let error = error {
print("Error sending client signature: \(error)")
completion(false, error)
return
}
// After sending signature, wait for server response
self.receiveServerResponse { success, error in
completion(success, error)
}
}
}
/// Receive and process server response after sending signature
/// - Parameter completion: Callback with result
private func receiveServerResponse(completion: @escaping (Bool, Error?) -> Void) {
secureConnection?.receive { data, error in
if let error = error {
print("Error receiving server response: \(error)")
completion(false, error)
return
}
guard let data = data, data.count > 4 else {
let error = NSError(domain: "SoftEtherError", code: 2, userInfo: [NSLocalizedDescriptionKey: "Invalid server response"])
print("Invalid server response: insufficient data")
completion(false, error)
return
}
print("Received server response: \(data.count) bytes")
// Parse the response packet
guard let packet = SoftEtherPacket(fromData: data) else {
let error = NSError(domain: "SoftEtherError", code: 3, userInfo: [NSLocalizedDescriptionKey: "Invalid packet format"])
print("Could not parse server response packet")
completion(false, error)
return
}
// Verify the response
let packetData = packet.getData()
let isValid = SoftEtherClientSignature.verifyServerResponse(packetData)
if isValid {
print("Server accepted our client signature")
completion(true, nil)
} else {
print("Server rejected our client signature")
let error = NSError(domain: "SoftEtherError", code: 4, userInfo: [NSLocalizedDescriptionKey: "Server rejected client signature"])
completion(false, error)
}
}
}
/// Send a data packet to the server
/// - Parameters:
/// - data: Data to send
/// - completion: Callback with result
func sendData(data: Data, completion: @escaping (Bool, Error?) -> Void) {
guard isConnected else {
completion(false, NSError(domain: "SoftEtherError", code: 5, userInfo: [NSLocalizedDescriptionKey: "Not connected to server"]))
return
}
let packetId = self.nextPacketId
self.nextPacketId += 1
let packet = SoftEtherPacket(type: 0x05, id: packetId, data: data)
let packetData = packet.serialize()
secureConnection?.send(data: packetData) { error in
if let error = error {
completion(false, error)
return
}
completion(true, nil)
}
}
/// Receive data from the server
/// - Parameter completion: Callback with received data and result
func receiveData(completion: @escaping (Data?, Bool, Error?) -> Void) {
guard isConnected else {
completion(nil, false, NSError(domain: "SoftEtherError", code: 5, userInfo: [NSLocalizedDescriptionKey: "Not connected to server"]))
return
}
secureConnection?.receive { data, error in
if let error = error {
completion(nil, false, error)
return
}
guard let data = data, data.count > 4 else {
completion(nil, false, NSError(domain: "SoftEtherError", code: 2, userInfo: [NSLocalizedDescriptionKey: "Invalid server response"]))
return
}
// Parse the packet
guard let packet = SoftEtherPacket(fromData: data) else {
completion(nil, false, NSError(domain: "SoftEtherError", code: 3, userInfo: [NSLocalizedDescriptionKey: "Invalid packet format"]))
return
}
completion(packet.getData(), true, nil)
}
}
}