func (responding *challengeSimpleHttpResponding) ShowInstructions(UI ui.UserInterface) error { if file, err := responding.createVerificationFile(); nil != err { return err } else if _, err := UI.Prompt(fmt.Sprintf( "Make the text on the next line available (without quotes) as %s\n%v\nPress enter when done", responding.WellKnownURL(), file)); nil != err { return err } return nil }
func (responding *challengeDVSNIResponding) ShowInstructions(UI ui.UserInterface) error { text := fmt.Sprintf("%s:443 needs to present a (self-signed) certificate for SNI name (\"vhost\") %s\n", responding.dnsIdentifier, responding.subjectAltName()) if cert, err := responding.makeCertificate(); nil != err { text += fmt.Sprintf("Couldn't generate example certificate (build your own instead): %s\n", err) } else { text += fmt.Sprintf("You can use the following 2048-bit RSA certificate:\n%s", cert) } text += "Press enter when done" _, err := UI.Prompt(text) return err }
func Run(UI ui.UserInterface, args []string) { register_flags.Parse(args) _, _, reg := command_base.OpenStorageFromFlags(UI) if nil == reg { utils.Fatalf("You need to register first") } listValidAuths, err := reg.AuthorizationInfosWithStatus(types.AuthorizationStatus("valid")) if nil != err { utils.Fatalf("Couldn't list valid authorizations: %s", err) } validAuths := make(map[string]bool) var validDomains []string for dnsName, _ := range listValidAuths { validAuths[dnsName] = true validDomains = append(validDomains, dnsName) } if 0 == len(validDomains) { utils.Fatalf("You don't have any valid authorizations.") } var pkey interface{} privateKeyGenerated := false if 0 != len(register_flags.Args()) { pkeyPrompt, _ := UI.PasswordPromptOnce("Enter private key password") if pkeyFile, err := os.Open(register_flags.Arg(0)); nil != err { utils.Fatalf("%s", err) } else if pkey, err = utils.LoadFirstPrivateKey(pkeyFile, pkeyPrompt); nil != err { utils.Fatalf("%s", err) } } else { UI.Message("Generating private key for certificate") privateKeyGenerated = true var err error if pkey, err = utils.CreatePrivateKey(keyType, curve, &rsabits); nil != err { utils.Fatalf("Couldn't create private key for certificate: %s", err) } } UI.Messagef("Available domains: %v", validDomains) markSelectedDomains := make(map[string]bool) var selectedDomains []string for { domain, err := UI.Prompt("Enter domain to add to certificate (empty to end list)") if err != nil { utils.Fatalf("Couldn't read domain: %s", err) } if 0 == len(domain) { break } if markSelectedDomains[domain] { UI.Messagef("Already selected %#v", domain) continue } markSelectedDomains[domain] = true if !validAuths[domain] { UI.Messagef("Unknown domain %#v, not adding - try again", domain) continue } selectedDomains = append(selectedDomains, domain) } if 0 == len(selectedDomains) { UI.Message("No domains entered, aborting") return } csr, err := utils.MakeCertificateRequest(utils.CertificateRequestParameters{ PrivateKey: pkey, DNSNames: selectedDomains, }) if nil != err { utils.Fatalf("Couldn't create certificate request: %s", err) } utils.Debugf("CSR:\n%s", pem.EncodeToMemory(csr)) cert, err := reg.NewCertificate(*csr) if nil != err { utils.Fatalf("Certificate request failed: %s", err) } if privateKeyGenerated { if err := cert.SetPrivateKey(pkey); nil != err { utils.Errorf("Couldn't store private key: %s", err) } } certData := cert.Certificate() UI.Messagef("New certificate is available under: %s (DER encoded)", certData.Location) if 0 != len(certData.LinkIssuer) { UI.Messagef("Issueing certificate available at: %s", certData.LinkIssuer) } UI.Messagef("%s", pem.EncodeToMemory(certData.Certificate)) if nil != certData.PrivateKey { UI.Messagef("%s", pem.EncodeToMemory(certData.PrivateKey)) } }
func Run(UI ui.UserInterface, args []string) { register_flags.Parse(args) _, _, reg := command_base.OpenStorageFromFlags(UI) if nil == reg { utils.Fatalf("You need to register first") } if 1 != len(register_flags.Args()) { auths, err := reg.AuthorizationInfos() if nil != err { utils.Fatalf("Couldn't retrieve list of authorizations: %s", err) } msg := "The following authorizations are available:\n" for dnsName, auth := range auths { msg += fmt.Sprintf("\t%s\n", dnsName) for _, info := range auth { if info.Status == types.AuthorizationStatus("valid") && nil != info.Expires { msg += fmt.Sprintf("\t\t%s (%s till %s)\n", info.Location, info.Status, info.Expires) } else { msg += fmt.Sprintf("\t\t%s (%s)\n", info.Location, info.Status) } } } msg += "Provide the domain (or url) you want to work with as command line parameter" UI.Message(msg) return } locationOrDnsName := register_flags.Arg(0) auth, err := reg.LoadAuthorizationByURL(locationOrDnsName) if nil != err { utils.Fatalf("Couldn't load authorization %v: %v", locationOrDnsName, err) } else if nil != auth { if err := auth.Refresh(); nil != err { utils.Fatalf("Couldn't refresh authorization %v: %v", locationOrDnsName, err) } } else { if auth, err = reg.AuthorizeDNS(locationOrDnsName); nil != err { utils.Fatalf("Couldn't get authorization for %v: %s", locationOrDnsName, err) } } for { // refresh every round authData := auth.Authorization() msg := fmt.Sprintf("Status: %s\n", authData.Resource.Status) if string(authData.Resource.Status) == "valid" { msg += fmt.Sprintf("Expires: %s\n", authData.Resource.Expires) } for ndx, challenge := range authData.Resource.Challenges { if 0 != len(challenge.GetValidated()) { msg += fmt.Sprintf("Challenge: %d (%s, %s, validated on %s)\n", ndx, challenge.GetType(), challenge.GetStatus(), challenge.GetValidated()) } else { msg += fmt.Sprintf("Challenge: %d (%s, %s)\n", ndx, challenge.GetType(), challenge.GetStatus()) } } msg += fmt.Sprintf("Valid combinations: %v", authData.Resource.Combinations) UI.Message(msg) if 0 != len(authData.Resource.Status) { UI.Message("Authorization finished") return } sel, err := UI.Prompt("Enter a challenge number to respond to (or r for refresh and empty string to exit)") if nil != err { utils.Fatalf("Failed reading challenge number: %s", err) } if 0 == len(sel) { break } if sel != "r" { selCh, err := strconv.Atoi(sel) if nil != err { UI.Messagef("Invalid input (%s), try again", err) continue } if selCh < 0 || selCh >= len(authData.Resource.Challenges) { UI.Messagef("Not a valid challenge index, try again", err) continue } chResp, err := authData.Respond(reg.Registration(), selCh) if nil != err { utils.Fatalf("Error trying to create response: %s", err) } if nil == chResp { UI.Messagef("Responding for challenge %d not supported", selCh) continue } if err = chResp.InitializeResponse(UI); nil != err { UI.Messagef("Failed to initialize response: %s", err) } if err = chResp.ShowInstructions(UI); nil != err { UI.Messagef("Failed to complete challenge: %s", err) continue } if err = chResp.Verify(); nil != err { UI.Messagef("Failed to verify challenge: %s", err) if err = auth.SaveChallengeData(chResp); nil != err { utils.Fatalf("Couldn't store challenge data: %s", err) } continue } // update refreshes auth automatically if err = auth.UpdateChallenge(chResp); nil != err { UI.Messagef("Failed to update challenge: %s", err) continue } } else { if err := auth.Refresh(); nil != err { utils.Errorf("Couldn't update authorization: %s", err) } } } }