Files

88 lines
2.7 KiB
Swift

//
// 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
}
}