/// <summary> /// Get the parsed response of a server url /// </summary> /// <param name="postfix">The postfix to attach to the server address</param> /// <param name="appendMAC">If the MAC address of the host should be appended to the URL</param> /// <returns>The parsed response</returns> public static Response GetResponse(string postfix, bool appendMAC) { if (appendMAC) { postfix += ((postfix.Contains(".php?") ? "&" : "?") + "mac=" + Configuration.MACAddresses()); } return(GetResponse(postfix)); }
/// <summary> /// Generate a random AES pass key and securely send it to the server /// </summary> /// <returns>True if successfully authenticated</returns> public static bool HandShake() { try { Log.Entry(LogName, "Waiting for authentication timeout to pass"); CanAuth.WaitOne(); EventTimer.Start(); // Obtain a public key from the server var keyPath = Path.Combine(Settings.Location, "tmp", "public.cer"); if (!Communication.DownloadFile("/management/other/ssl/srvpublic.crt", keyPath)) { return(false); } Log.Debug(LogName, "KeyPath = " + keyPath); var certificate = new X509Certificate2(keyPath); // Ensure the public key came from the pinned server if (!Data.RSA.IsFromCA(Data.RSA.ServerCertificate(), certificate)) { throw new Exception("Certificate is not from FOG CA"); } Log.Entry(LogName, "Cert OK"); // Generate a random AES key var aes = new AesCryptoServiceProvider(); aes.GenerateKey(); Passkey = aes.Key; // Get the security token from the last handshake var tokenPath = Path.Combine(Settings.Location, "token.dat"); try { if (!File.Exists(tokenPath) && File.Exists("token.dat")) { File.Copy("token.dat", tokenPath); } } catch (Exception) { } var token = GetSecurityToken(tokenPath); // Encrypt the security token and AES key using the public key var enKey = Transform.ByteArrayToHexString(RSA.Encrypt(certificate, Passkey)); var enToken = Transform.ByteArrayToHexString(RSA.Encrypt(certificate, token)); // Send the encrypted data to the server and get the response var response = Communication.Post("/management/index.php?sub=requestClientInfo&authorize&newService", $"sym_key={enKey}&token={enToken}&mac={Configuration.MACAddresses()}"); // If the server accepted the token and AES key, save the new token if (!response.Error && response.Encrypted) { Log.Entry(LogName, "Authenticated"); SetSecurityToken(tokenPath, Transform.HexStringToByteArray(response.GetField("token"))); return(true); } // If the server does not recognize the host, register it if (response.ReturnCode.Equals("ih")) { Communication.Contact($"/service/register.php?hostname={Dns.GetHostName()}", true); } } catch (Exception ex) { Log.Error(LogName, "Could not authenticate"); Log.Error(LogName, ex); } return(false); }