mirror of
https://github.com/Grace-Solutions/PSProxmox.git
synced 2026-08-09 23:00:01 +00:00
Initial commit of PSProxmox module
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Security;
|
||||
|
||||
namespace PSProxmox.Session
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a connection to a Proxmox VE server.
|
||||
/// </summary>
|
||||
public class ProxmoxConnection
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the server hostname or IP address.
|
||||
/// </summary>
|
||||
public string Server { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the port number used for the connection.
|
||||
/// </summary>
|
||||
public int Port { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the connection uses HTTPS.
|
||||
/// </summary>
|
||||
public bool UseSSL { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether to skip SSL certificate validation.
|
||||
/// </summary>
|
||||
public bool SkipCertificateValidation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authentication ticket for the Proxmox API.
|
||||
/// </summary>
|
||||
public string Ticket { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CSRF prevention token for the Proxmox API.
|
||||
/// </summary>
|
||||
public string CSRFPreventionToken { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the username used for authentication.
|
||||
/// </summary>
|
||||
public string Username { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the realm used for authentication.
|
||||
/// </summary>
|
||||
public string Realm { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the connection is authenticated.
|
||||
/// </summary>
|
||||
public bool IsAuthenticated => !string.IsNullOrEmpty(Ticket) && !string.IsNullOrEmpty(CSRFPreventionToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base URL for the Proxmox API.
|
||||
/// </summary>
|
||||
public string ApiUrl => $"{(UseSSL ? "https" : "http")}://{Server}:{Port}/api2/json";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ProxmoxConnection"/> class.
|
||||
/// </summary>
|
||||
/// <param name="server">The server hostname or IP address.</param>
|
||||
/// <param name="port">The port number.</param>
|
||||
/// <param name="useSSL">Whether to use HTTPS.</param>
|
||||
/// <param name="skipCertificateValidation">Whether to skip SSL certificate validation.</param>
|
||||
/// <param name="username">The username for authentication.</param>
|
||||
/// <param name="realm">The realm for authentication.</param>
|
||||
public ProxmoxConnection(string server, int port = 8006, bool useSSL = true, bool skipCertificateValidation = false, string username = null, string realm = "pam")
|
||||
{
|
||||
Server = server ?? throw new ArgumentNullException(nameof(server));
|
||||
Port = port;
|
||||
UseSSL = useSSL;
|
||||
SkipCertificateValidation = skipCertificateValidation;
|
||||
Username = username;
|
||||
Realm = realm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of the connection with updated authentication information.
|
||||
/// </summary>
|
||||
/// <param name="ticket">The authentication ticket.</param>
|
||||
/// <param name="csrfPreventionToken">The CSRF prevention token.</param>
|
||||
/// <returns>A new connection object with updated authentication information.</returns>
|
||||
internal ProxmoxConnection WithAuthentication(string ticket, string csrfPreventionToken)
|
||||
{
|
||||
var connection = new ProxmoxConnection(Server, Port, UseSSL, SkipCertificateValidation, Username, Realm)
|
||||
{
|
||||
Ticket = ticket,
|
||||
CSRFPreventionToken = csrfPreventionToken
|
||||
};
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Management.Automation;
|
||||
using Newtonsoft.Json;
|
||||
using PSProxmox.Models;
|
||||
|
||||
namespace PSProxmox.Session
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles authentication and session management for Proxmox VE.
|
||||
/// </summary>
|
||||
public class ProxmoxSession
|
||||
{
|
||||
/// <summary>
|
||||
/// Authenticates with the Proxmox VE API.
|
||||
/// </summary>
|
||||
/// <param name="server">The server hostname or IP address.</param>
|
||||
/// <param name="port">The port number.</param>
|
||||
/// <param name="useSSL">Whether to use HTTPS.</param>
|
||||
/// <param name="skipCertificateValidation">Whether to skip SSL certificate validation.</param>
|
||||
/// <param name="username">The username for authentication.</param>
|
||||
/// <param name="password">The password for authentication.</param>
|
||||
/// <param name="realm">The realm for authentication.</param>
|
||||
/// <param name="cmdlet">The PowerShell cmdlet making the request.</param>
|
||||
/// <returns>A connection object with authentication information.</returns>
|
||||
public static ProxmoxConnection Login(
|
||||
string server,
|
||||
int port,
|
||||
bool useSSL,
|
||||
bool skipCertificateValidation,
|
||||
string username,
|
||||
SecureString password,
|
||||
string realm,
|
||||
PSCmdlet cmdlet)
|
||||
{
|
||||
var connection = new ProxmoxConnection(server, port, useSSL, skipCertificateValidation, username, realm);
|
||||
|
||||
// Create the login URL
|
||||
string loginUrl = $"{connection.ApiUrl}/access/ticket";
|
||||
|
||||
// Log the URL if verbose is enabled
|
||||
if (cmdlet != null)
|
||||
{
|
||||
cmdlet.WriteVerbose($"Authenticating to {loginUrl}");
|
||||
}
|
||||
|
||||
// Create the request
|
||||
var request = (HttpWebRequest)WebRequest.Create(loginUrl);
|
||||
request.Method = "POST";
|
||||
request.ContentType = "application/x-www-form-urlencoded";
|
||||
|
||||
// Skip certificate validation if requested
|
||||
if (skipCertificateValidation && request.RequestUri.Scheme == "https")
|
||||
{
|
||||
request.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
|
||||
}
|
||||
|
||||
// Convert SecureString to plain text (only for sending to API)
|
||||
string plainPassword = new System.Net.NetworkCredential(string.Empty, password).Password;
|
||||
|
||||
// Create the request body
|
||||
string postData = $"username={Uri.EscapeDataString(username)}&password={Uri.EscapeDataString(plainPassword)}&realm={Uri.EscapeDataString(realm)}";
|
||||
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
|
||||
request.ContentLength = byteArray.Length;
|
||||
|
||||
// Send the request
|
||||
using (Stream dataStream = request.GetRequestStream())
|
||||
{
|
||||
dataStream.Write(byteArray, 0, byteArray.Length);
|
||||
}
|
||||
|
||||
// Get the response
|
||||
try
|
||||
{
|
||||
using (var response = (HttpWebResponse)request.GetResponse())
|
||||
using (var reader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
string responseText = reader.ReadToEnd();
|
||||
var loginResponse = JsonConvert.DeserializeObject<ProxmoxResponse<ProxmoxTicket>>(responseText);
|
||||
|
||||
if (loginResponse?.Data == null)
|
||||
{
|
||||
throw new Exception("Invalid response from server");
|
||||
}
|
||||
|
||||
return connection.WithAuthentication(
|
||||
loginResponse.Data.Ticket,
|
||||
loginResponse.Data.CSRFPreventionToken);
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
if (ex.Response != null)
|
||||
{
|
||||
using (var errorResponse = (HttpWebResponse)ex.Response)
|
||||
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
|
||||
{
|
||||
string errorText = reader.ReadToEnd();
|
||||
throw new Exception($"Authentication failed: {errorText}");
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs out from the Proxmox VE API.
|
||||
/// </summary>
|
||||
/// <param name="connection">The connection to log out from.</param>
|
||||
/// <param name="cmdlet">The PowerShell cmdlet making the request.</param>
|
||||
public static void Logout(ProxmoxConnection connection, PSCmdlet cmdlet)
|
||||
{
|
||||
if (connection == null || !connection.IsAuthenticated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the logout URL
|
||||
string logoutUrl = $"{connection.ApiUrl}/access/ticket";
|
||||
|
||||
// Log the URL if verbose is enabled
|
||||
if (cmdlet != null)
|
||||
{
|
||||
cmdlet.WriteVerbose($"Logging out from {logoutUrl}");
|
||||
}
|
||||
|
||||
// Create the request
|
||||
var request = (HttpWebRequest)WebRequest.Create(logoutUrl);
|
||||
request.Method = "DELETE";
|
||||
request.Headers.Add("Cookie", $"PVEAuthCookie={connection.Ticket}");
|
||||
request.Headers.Add("CSRFPreventionToken", connection.CSRFPreventionToken);
|
||||
|
||||
// Skip certificate validation if requested
|
||||
if (connection.SkipCertificateValidation && request.RequestUri.Scheme == "https")
|
||||
{
|
||||
request.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
|
||||
}
|
||||
|
||||
// Send the request and ignore the response
|
||||
try
|
||||
{
|
||||
using (var response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
// Just to ensure the request is completed
|
||||
}
|
||||
}
|
||||
catch (WebException)
|
||||
{
|
||||
// Ignore errors during logout
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user