Certificate/Source/ServerCertificates/Get-IMAPCertificate.cs

using System;
using System.Management.Automation;
using System.IO;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
 
namespace CPolydorou.Exchange.ServerCertificates
{
    [Cmdlet("Get", "IMAPCertificate")]
    public class GetIMAPCertificate : PSCmdlet
    {
        //region Variables
        // Private variables for parameters
        private string server;
        private int port;
        private bool export = false;
        private string path;
        private bool showerrors = false;
        //endregion
 
        //region Parameters
        [Parameter(
            Mandatory = true,
            Position = 0,
            HelpMessage = "The name of the server.",
            ParameterSetName = "Basic"
        )]
        [Parameter(
            Mandatory = true,
            Position = 0,
            HelpMessage = "The name of the server.",
            ParameterSetName = "Export"
        )]
        [Parameter(
            Mandatory = true,
            Position = 0,
            HelpMessage = "The name of the server.",
            ParameterSetName = "ShowErrors"
        )]
        public string Server
        {
            get { return this.server; }
            set { this.server = value; }
        }
 
        [Parameter(
            Mandatory = true,
            Position = 1,
            HelpMessage = "The port of the server.",
            ParameterSetName = "Basic"
        )]
        [Parameter(
            Mandatory = true,
            Position = 1,
            HelpMessage = "The port of the server.",
            ParameterSetName = "ShowErrors"
        )]
        [Parameter(
            Mandatory = true,
            Position = 1,
            HelpMessage = "The port of the server.",
            ParameterSetName = "Export"
        )]
        public int Port
        {
            get { return this.port; }
            set { this.port = value; }
        }
 
        [Parameter(
            Mandatory = true,
            HelpMessage = "Export the certificate.",
            ParameterSetName = "Export"
        )]
        public SwitchParameter Export
        {
            get { return this.export; }
            set { this.export = value; }
        }
 
        [Parameter(
            Mandatory = true,
            HelpMessage = "The path of the exported file.",
            ParameterSetName = "Export"
        )]
        public string Path
        {
            get { return this.path; }
            set { this.path = value; }
        }
 
        [Parameter(
            Mandatory = true,
            HelpMessage = "Show the errors of the certificate.",
            ParameterSetName = "ShowErrors"
        )]
        public SwitchParameter ShowCertificateErrors
        {
            get { return this.showerrors; }
            set { this.showerrors = value; }
        }
        //endregion
 
        //region Overrides
        protected override void ProcessRecord()
        {
            TcpClient client = new TcpClient(this.server, this.port);
            // Create an SSL stream that will close the client's stream.
            SslStream sslStream = new SslStream(
                client.GetStream(),
                false,
                new RemoteCertificateValidationCallback(RemoteServerCertificateValidationCallback),
                null
                );
            // The server name must match the name on the server certificate.
            try
            {
                sslStream.AuthenticateAsClient(this.server);
            }
            catch (AuthenticationException e)
            {
            }
            client.Close();
        }
        //endregion
 
        //region Helper functions
        private bool RemoteServerCertificateValidationCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            // if the ShowErrors parameter has been entered
            if (this.showerrors == true)
            {
                // Check if the policy errors are not "None"
                if (sslPolicyErrors != SslPolicyErrors.None)
                {
                    CertificateError err = new CertificateError();
                    err.Server = this.server;
                    err.Port = this.port;
                    err.Error = sslPolicyErrors.ToString();
 
                    WriteObject(err);
                }
 
                // Return the result based on the policy errors
                if (sslPolicyErrors == SslPolicyErrors.None)
                    return true;
                else
                    return false;
            }
 
            // if the Export parameter has not been entered
            if (this.export == false)
            {
                Certificate cert = new CPolydorou.Exchange.ServerCertificates.Certificate();
                cert.Subject = certificate.Subject;
                cert.Issuer = certificate.Issuer;
                cert.ExpirationDate = certificate.GetExpirationDateString();
                cert.EffectiveDate = certificate.GetEffectiveDateString();
                cert.Hash = certificate.GetCertHashString();
                cert.PublicKey = certificate.GetPublicKeyString();
                cert.Format = certificate.GetFormat();
                cert.KeyAlgorithm = certificate.GetKeyAlgorithm();
                cert.SerialNumber = certificate.GetSerialNumberString();
                cert.Type = certificate.GetType();
                cert.Server = this.server;
                cert.port = this.port;
 
                WriteObject(cert);
            }
            else
            {
                // Write the certificate to file
                // Resolve the path
                SessionState ss = new SessionState();
                Directory.SetCurrentDirectory(ss.Path.CurrentFileSystemLocation.Path);
 
                // Export the certificate
                string fullPath = System.IO.Path.GetFullPath(path);
                byte[] cert = certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert);
                System.IO.File.WriteAllBytes(this.path, cert);
 
            }
 
            // Return based on the policy errors
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;
            else
                return false;
        }
        //endregion
    }
}