Public/Revoke-PAAuthorization.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
function Revoke-PAAuthorization {
    [CmdletBinding(SupportsShouldProcess)]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess','')]
    param(
        [Parameter(Mandatory,Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [Alias('authorizations')]
        [string[]]$AuthURLs,
        [Parameter(Position=1)]
        [PSTypeName('PoshACME.PAAccount')]$Account,
        [switch]$Force
    )

    Begin {
        # make sure any account passed in is actually associated with the current server
        # or if no account was specified, that there's a current account.
        if (!$Account) {
            if (!($Account = Get-PAAccount)) {
                throw "No Account parameter specified and no current account selected. Try running Set-PAAccount first."
            }
        } else {
            if ($Account.id -notin (Get-PAAccount -List).id) {
                throw "Specified account id $($Account.id) was not found in the current server's account list."
            }
        }
        # make sure it's valid
        if ($Account.status -ne 'valid') {
            throw "Account status is $($Account.status)."
        }

        # build the header template
        $header = @{
            alg = $Account.alg
            kid = $Account.location
            nonce = $script:Dir.nonce
            url = [String]::Empty
        }

        # build the payload
        $payload = '{"status":"deactivated"}'

        $urls = @()
    }

    Process {

        # Because authorizations are tied to an account and potentially shared between
        # orders, we may end up with duplicate URLs that come in via the pipeline in
        # separate calls of this Process block. So instead of doing the deactivations
        # here, we're just going to collect the URLs and wait to process them in the
        # End block.

        $urls += @($AuthURLs)
    }

    End {
        # Remove any duplicates that might exist
        $urls = $urls | Select-Object -Unique

        $auths = $urls | Get-PAAuthorizations -Account $Account

        # loop through the URLs and request deactivation
        foreach ($auth in $auths) {

            # don't bother with already deactivated ones
            if ('deactivated' -eq $auth.status) {
                Write-Warning "Authorization has already been deactivated for $($auth.fqdn)."
                continue
            }

            if (!$Force) {
                $msg = "Revoking an authorization prevents ordering a certificate for the identifier without proving ownership again on this account."
                $question = "Are you sure you wish to revoke the authorization for $($auth.fqdn)?"
                if (!$PSCmdlet.ShouldContinue($question,$msg)) {
                    Write-Verbose "Aborted authorization revocation for $($auth.fqdn)."
                    continue
                }
            }

            $header.nonce = $script:Dir.nonce
            $header.url = $auth.location

            Write-Verbose "Revoking authorization for $($auth.fqdn)"
            try {
                $response = Invoke-ACME $header $payload $Account -EA Stop
                Write-Debug "Response: $($response.Content)"
            } catch [AcmeException] {
                Write-Error $_.Exception.Data.detail
            }

        }

    }



    <#
    .SYNOPSIS
        Revoke the authorization associated with an ACME identifier.
 
    .DESCRIPTION
        Many ACME server implementations cache succesful authorizations for a certain amount of time to avoid requiring an account to re-authorize identifiers for additional orders submitted during the cache window.
 
        This can make testing authorization challenges in a client more cumbersome by having to create new orders with uncached identifiers. This function allows you to revoke those cached authorizations so that subsequent orders will go through the full challenge validation process.
 
    .PARAMETER AuthURLs
        One or more authorization URLs. You also pipe in one or more PoshACME.PAOrder objects.
 
    .PARAMETER Account
        An existing ACME account object such as the output from Get-PAAccount. If no account is specified, the current account will be used.
 
    .PARAMETER Force
        If specified, no confirmation prompts will be presented.
 
    .EXAMPLE
        Revoke-PAAuthorization https://acme.example.com/authz/1234567
 
        Revoke the authorization for the specified URL using the current account.
 
    .EXAMPLE
        Get-PAOrder | Revoke-PAAuthorization -Force
 
        Revoke all authorizations for the current order on the current account without confirmation prompts.
 
    .EXAMPLE
        Get-PAOrder -List | Revoke-PAAuthorizations
 
        Revoke all authorizations for all orders on the current account.
 
    .LINK
        Project: https://github.com/rmbolger/Posh-ACME
 
    .LINK
        Get-PAAuthorizations
 
    .LINK
        Get-PAOrder
 
    #>

}