// // Inception.swift // PrivadoVPN // // Created by Juraldinio on 8/18/20. // Copyright © 2020 Privado LLC. All rights reserved. // import Foundation final class Inception { private enum Constants { static let authenticate = "auth" static let customer = "customer" // static let suffixLength = 5 } // Credentials passed from url private struct Credentials: Decodable { let user: String let pass: String } // privadovpn://auth?yLCUMSNr2bQ5Vq-38Hhw16RhwVGCgMM1ETsYzEXd0P8GBaUGnS65HSfB0Nkm9bz1vQcDw static func handle(url: URL) -> Route? { guard let scheme = url.scheme , scheme.localizedCaseInsensitiveCompare(PrivadoConstants.Application.scheme) == .orderedSame , let host = url.host else { return nil } switch host { case Constants.authenticate: return Self.authenticate(components: URLComponents(url: url, resolvingAgainstBaseURL: false)) case Constants.customer: return .customer default: return nil } /*let encoded = host.replacingOccurrences(of: base64, with: "") guard let data = Data(base64Encoded: encoded) , let credentials = try? JSONDecoder().decode(Credentials.self, from: data) else { return nil } return .login(type: .authenticate(credentials.user, credentials.pass))*/ } // MARK: - Static Private private static func authenticate(components: URLComponents?) -> Route? { guard let components = components , let urlToken = components.queryItems?.first?.name else { return nil } let token = urlToken .replacingOccurrences(of: "-", with: "+") .replacingOccurrences(of: "_", with: "/") guard let encrToken = Data(base64Encoded: String(token.suffix(token.count - Constants.suffixLength))) , let key = PrivadoConstants.Session.key.data(using: .utf8) else { return nil } let blockSize = 16 let iv = encrToken.prefix(upTo: blockSize) let message = encrToken.suffix(encrToken.count - blockSize) guard let decriptedToken = CryptoAES(key: key, iv: iv).decrypt(data: message) else { return nil } let credentials = decriptedToken .split(separator: ":") .map { String($0) } if credentials.count == 2 , let username = credentials.first , let password = credentials.last { return .login(type: .authenticate(username, password, true)) } return nil } }