From f379d734a8c1f502481f99dca70e6e997dde93fe Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Thu, 19 Mar 2026 16:16:09 +0800 Subject: [PATCH] =?UTF-8?q?api=E5=A2=9E=E5=8A=A0=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tun/Punchnet/Actors/SDLContextActor.swift | 12 ++++++------ punchnet/Core/SDLAPIClient.swift | 19 +++++++++++++++++- punchnet/Core/SDLUtil.swift | 24 +++++++++++++++++++++++ punchnet/Core/SystemConfig.swift | 6 ++++++ punchnet/Views/UserContext.swift | 4 ++++ 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index a51ac58..c00306d 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -287,7 +287,11 @@ actor SDLContextActor { case .registerAck(let registerAck): await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck) case .data(let data): - try? await self.handleHoleData(data: data) + do { + try await self.handleHoleData(data: data) + } catch let err { + SDLLogger.shared.log("[SDLContext] handleHoleData get err: \(err)") + } case .stunReply(let stunReply): SDLLogger.shared.log("[SDLContext] get a stunReply: \(stunReply)") } @@ -537,11 +541,7 @@ actor SDLContextActor { return } - guard let decyptedData = try? dataCipher.decrypt(cipherText: Data(data.data)) else { - SDLLogger.shared.log("SDLContext use dataCipher: \(dataCipher), decrypt error", level: .warning) - return - } - + let decyptedData = try dataCipher.decrypt(cipherText: Data(data.data)) let layerPacket = try LayerPacket(layerData: decyptedData) self.flowTracer.inc(num: decyptedData.count, type: .inbound) diff --git a/punchnet/Core/SDLAPIClient.swift b/punchnet/Core/SDLAPIClient.swift index 468099a..42c0ada 100644 --- a/punchnet/Core/SDLAPIClient.swift +++ b/punchnet/Core/SDLAPIClient.swift @@ -21,17 +21,21 @@ struct SDLAPIError: Error, Decodable { struct SDLAPIClient { static var baseUrl: String = "https://punchnet.s5s8.com/api" + static private let token: String = "H6p*2RfEu4ITcL" static func doPost(path: String, params: [String: Any], as: T.Type) async throws -> T { let postData = try! JSONSerialization.data(withJSONObject: params) var request = URLRequest(url: URL(string: baseUrl + path)!) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") + request.addValue(sign(params: params), forHTTPHeaderField: "X-sign") request.httpBody = postData let (data, _) = try await URLSession.shared.data(for: request) - NSLog("response is: \(String(bytes: data, encoding: .utf8))") + if let response = String(bytes: data, encoding: .utf8) { + NSLog("response is: \(response)") + } let apiResponse = try JSONDecoder().decode(SDLAPIResponse.self, from: data) if apiResponse.code == 0, let data = apiResponse.data { @@ -48,4 +52,17 @@ struct SDLAPIClient { } } + private static func sign(params: [String: Any]) -> String { + let keys = params.keys.sorted() + + let qs = keys.map { key in + let str = String(describing: params[key] ?? "") + return "\(key)=\(str)" + }.joined(separator: "&") + + NSLog("sign qs is: \(qs), sign: \(SDLUtil.hmacMD5(key: token, data: qs))") + + return SDLUtil.hmacMD5(key: token, data: qs) + } + } diff --git a/punchnet/Core/SDLUtil.swift b/punchnet/Core/SDLUtil.swift index 4eea6d3..ac0988b 100644 --- a/punchnet/Core/SDLUtil.swift +++ b/punchnet/Core/SDLUtil.swift @@ -4,6 +4,8 @@ // // Created by 安礼成 on 2026/3/9. // +import Foundation +import CommonCrypto struct SDLUtil { enum ContactType { @@ -12,6 +14,28 @@ struct SDLUtil { case invalid } + static func hmacMD5(key: String, data: String) -> String { + let keyData = key.data(using: .utf8)! + let dataData = data.data(using: .utf8)! + + var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) + + keyData.withUnsafeBytes { keyBytes in + dataData.withUnsafeBytes { dataBytes in + CCHmac( + CCHmacAlgorithm(kCCHmacAlgMD5), + keyBytes.baseAddress!, + keyBytes.count, + dataBytes.baseAddress!, + dataBytes.count, + &digest + ) + } + } + + return digest.map { String(format: "%02x", $0) }.joined() + } + static func identifyContact(_ input: String) -> ContactType { let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines) // 手机号正则(中国手机号为例,以 1 开头,11 位数字) diff --git a/punchnet/Core/SystemConfig.swift b/punchnet/Core/SystemConfig.swift index 64d5f16..e94732f 100644 --- a/punchnet/Core/SystemConfig.swift +++ b/punchnet/Core/SystemConfig.swift @@ -18,6 +18,12 @@ struct SystemConfig { // stun探测辅助服务器ip static let stunAssistHost = "punchnet.s5s8.com" + // 获取系统信息 + static let systemInfo: String = { + let version = ProcessInfo.processInfo.operatingSystemVersion + return "macOS \(version.majorVersion).\(version.minorVersion)" + }() + static func getOptions(networkId: UInt32, networkDomain: String, ip: String, maskLen: UInt8, accessToken: String, identityId: UInt32, hostname: String, noticePort: Int) -> [String: NSObject]? { guard let serverIp = DNSResolver.resolveAddrInfos(serverHost).first else { return nil diff --git a/punchnet/Views/UserContext.swift b/punchnet/Views/UserContext.swift index 36cd09f..358314c 100644 --- a/punchnet/Views/UserContext.swift +++ b/punchnet/Views/UserContext.swift @@ -62,6 +62,8 @@ class UserContext { var params: [String: Any] = [ "username": username, "password": password, + "system": SystemConfig.systemInfo, + "version": SystemConfig.version_name ] params.merge(baseParams) {$1} @@ -79,6 +81,8 @@ class UserContext { func loginWithToken(token: String) async throws { var params: [String: Any] = [ "token": token, + "system": SystemConfig.systemInfo, + "version": SystemConfig.version_name ] params.merge(baseParams) {$1}