Add a basic execution check to SimpleHTTP

This commit is contained in:
xenolf 2015-06-13 18:37:30 +02:00
parent 5045c7a614
commit fcd0fba9c7
3 changed files with 38 additions and 7 deletions

View file

@ -35,7 +35,7 @@ type User interface {
// Interface for all challenge solvers to implement. // Interface for all challenge solvers to implement.
type solver interface { type solver interface {
CanSolve() bool CanSolve(domain string) bool
Solve(challenge challenge, domain string) error Solve(challenge challenge, domain string) error
} }
@ -150,7 +150,7 @@ func (c *Client) solveChallenges(challenges []*authorizationResource) error {
// loop through the resources, basically through the domains. // loop through the resources, basically through the domains.
for _, authz := range challenges { for _, authz := range challenges {
// no solvers - no solving // no solvers - no solving
if solvers := c.chooseSolvers(authz.Body); solvers != nil { if solvers := c.chooseSolvers(authz.Body, authz.Domain); solvers != nil {
for i, solver := range solvers { for i, solver := range solvers {
// TODO: do not immediately fail if one domain fails to validate. // TODO: do not immediately fail if one domain fails to validate.
err := solver.Solve(authz.Body.Challenges[i], authz.Domain) err := solver.Solve(authz.Body.Challenges[i], authz.Domain)
@ -168,11 +168,11 @@ func (c *Client) solveChallenges(challenges []*authorizationResource) error {
// Checks all combinations from the server and returns an array of // Checks all combinations from the server and returns an array of
// solvers which should get executed in series. // solvers which should get executed in series.
func (c *Client) chooseSolvers(auth authorization) map[int]solver { func (c *Client) chooseSolvers(auth authorization, domain string) map[int]solver {
for _, combination := range auth.Combinations { for _, combination := range auth.Combinations {
solvers := make(map[int]solver) solvers := make(map[int]solver)
for _, idx := range combination { for _, idx := range combination {
if solver, ok := c.Solvers[auth.Challenges[idx].Type]; ok { if solver, ok := c.Solvers[auth.Challenges[idx].Type]; ok && solver.CanSolve(domain) {
solvers[idx] = solver solvers[idx] = solver
} else { } else {
logger().Printf("Could not find solver for: %s", auth.Challenges[idx].Type) logger().Printf("Could not find solver for: %s", auth.Challenges[idx].Type)

View file

@ -2,7 +2,7 @@ package acme
type dvsniChallenge struct{} type dvsniChallenge struct{}
func (s *dvsniChallenge) CanSolve() bool { func (s *dvsniChallenge) CanSolve(domain string) bool {
return false return false
} }

View file

@ -10,6 +10,7 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"math/big" "math/big"
"net" "net"
"net/http" "net/http"
@ -21,9 +22,39 @@ type simpleHTTPChallenge struct {
optPort string optPort string
} }
func (s *simpleHTTPChallenge) CanSolve() bool { // SimpleHTTPS checks for DNS, public IP and port bindings
func (s *simpleHTTPChallenge) CanSolve(domain string) bool {
// determine public ip
resp, err := http.Get("https://icanhazip.com/")
if err != nil {
logger().Printf("Could not get public IP -> %v", err)
return false
}
ip, err := ioutil.ReadAll(resp.Body)
if err != nil {
logger().Printf("Could not get public IP -> %v", err)
return false
}
ipStr := string(ip)
// resolve domain we should solve for
resolvedIPs, err := net.LookupHost(domain)
if err != nil {
logger().Printf("Could not lookup DNS A record for %s", domain)
return false
}
// if the resolve does not resolve to our public ip, we can't solve.
for _, resolvedIP := range resolvedIPs {
if resolvedIP == ipStr {
return true return true
} }
}
logger().Printf("SimpleHTTPS: Domain %s does not resolve to the public ip of this server. Determined ip: %s", domain, ipStr)
return false
}
func (s *simpleHTTPChallenge) Solve(chlng challenge, domain string) error { func (s *simpleHTTPChallenge) Solve(chlng challenge, domain string) error {