letsencrypt::Client method authorizeDomain (protected)

 <instance of letsencrypt::Client[i]> authorizeDomain auth_url

Defined in /usr/local/ns/tcl/letsencrypt/letsencrypt-procs.tcl

Parameters:
auth_url (required)

Testcases:
No testcase defined.
Source code:
set httpStatus [:send_signed_request $auth_url ""]
:log "$auth_url returned HTTP status $httpStatus<br>"

if {$httpStatus in {400 403}} {
    return [list invalid ""]
}

set authDict [:json2dict ${:replyText}]
set domain [dict get $authDict identifier value]

:log "<br>Authorizing account for domain <strong>$domain</strong>... "
:log "... getting HTTP challenge... "
set :authorization [ns_set iget ${:replyHeaders} "location"]
set challenges [dict get $authDict challenges]
#ns_log notice "... challenges:\n[join $challenges \n]"

#
# Parse HTTP challenge
#
foreach entry $challenges {
    if {[dict filter $entry value "http-01"] ne ""} {
        set challengeURL [dict get $entry url]
        set token [dict get $entry token]
    }
}

#
# Provide HTTP resource to fulfill HTTP challenge
#
file mkdir [ns_server pagedir]/.well-known/acme-challenge
:writeFile [ns_server pagedir]/.well-known/acme-challenge/$token $token.${:thumbprint64}

:log "<pre>keyauthorization: $token.${:thumbprint64}</pre>\n"

#set payload [subst {{"resource": "challenge", "keyAuthorization": "$token.${:thumbprint64}"}}]
:log "challenge was written to [ns_server pagedir]/.well-known/acme-challenge/$token<br>"

#
# Try to obtain the challenge locally. This helps diagnose common
# vhost, redirect, and file-serving problems before contacting
# Let's Encrypt.
#
set wellknown_url "http://$domain/.well-known/acme-challenge/$token"
set flags {}
if {[file exists /scripts/docker-dict.tcl]} {
    source /scripts/docker-dict.tcl
    try {
        #
        # ns_ip might not be available in old versions of
        # NaviServer. For these versions, just skip the
        # rewrite of wellknown_url in docker containers.
        #
        set ip [ns_addrbyhost $domain]

        foreach key [dict keys $::docker::containerMapping] {
            if {[dict get $::docker::containerMapping $key proto] eq "http"} {
                set containerPort [lindex [split $key /] 0]

                if {[dict get $::docker::containerMapping $key host] eq $ip} {
                    :log "... found IP $ip in containerMapping"
                    set wellknown_url "http://127.0.0.1:$containerPort/.well-known/acme-challenge/$token"
                    set flags [list -keep_host_header -headers [ns_set create host $domain]]
                    break

                } elseif {![ns_ip public $ip]} {
                    :log "... IP $ip is not public"
                    set wellknown_url "http://$domain:$containerPort/.well-known/acme-challenge/$token"
                    break
                }
            }
        }
    } on error {errorMsg} {
        :log -severity warning "adjusting wellknown_url in container setups failed: $errorMsg"
    }
}

:log "get challenge locally for $domain via: [list ns_http run -timeout 5s {*}$flags $wellknown_url]"
set d [ns_http run -timeout 5s {*}$flags $wellknown_url]
:log "local test for $domain returned <pre>$d</pre>"

if {[dict get $d status] eq "200"} {
    :log "challenge is available on local server $wellknown_url\n"
} else {
    :log -severity warning "challenge can not retrieved from local server: $wellknown_url\n"
    return "invalid"
}

:log "get challenge for $domain remote via: $challengeURL"
set httpStatus [:send_signed_request $challengeURL "{}"]
:log "challengeURL $challengeURL returned HTTP status $httpStatus<br>"

#
# ----- validate
#
:log "... validating the challenge for $domain ... "
#:log "Reply Headers: [:printHeaders ${:replyHeaders}]<br>"

set status [dict get [:json2dict ${:replyText}] status]
:log "domain $domain status: $status<br>"
#:log "<pre>$result</pre>[:printHeaders ${:replyHeaders}]<br>"

# poll until validation is finished (max 20 attempts)
set count 1
set maxRetry 20
set delay 5
while {$status eq "pending"} {
    :log "... domain $domain retry $count/$maxRetry after ${delay}s... "
    ns_sleep ${delay}s

    set httpStatus [:send_signed_request $auth_url ""]
    :log "$auth_url returned HTTP status $httpStatus<br>"

    set authDict [:json2dict ${:replyText}]
    set status [dict get $authDict status]
    :log "domain $domain status: $status<br>"

    if {$status ni {valid pending}} {
        :log "<pre>${:replyText}</pre>[:printHeaders ${:replyHeaders}]<br>"
        return [list invalid $domain]
    }
    # give up after some time
    if {[incr count] > $maxRetry} {
        :log "domain $domain giving up after $count attempts<br>"
        return [list invalid $domain]
    }
    if {$delay < 15} {
        set delay [expr {$delay + 2}]
    }
}
if {$status eq "valid"} {
    :log "validation of $domain completed after $count attempts<br>"
}
return [list $status $domain]
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: