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) } } } }
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) st, controller, reg := command_base.OpenStorageFromFlags(UI) var newContact []string var newAgreementURL *string if nil != reg { if !no_refresh { UI.Message("Using existing registration") if err := reg.Refresh(); nil != err { utils.Errorf("Couldn't refresh the registration: %s", err) } } if modify { var err error if newContact, err = EnterNewContact(UI); nil != err { utils.Fatalf("Couldn't get new contact information: %s", err) } if reflect.DeepEqual(newContact, reg.Registration().Resource.Contact) { UI.Messagef("Entered contact information is the same we already have, ignoring update") newContact = nil // no changes } } } else { UI.Message("Creating new registration") dir, err := controller.GetDirectory(demoDirectoryURL, false) if nil != err { utils.Fatalf("Couldn't fetch directory for '%s': %s", demoDirectoryURL, err) } UI.Message("Generating private key, might take some time") signingKey, err := types.CreateSigningKey(keyType, curve, &rsabits) if nil != err { utils.Fatalf("Couldn't create private key for registration: %s", err) } contact, err := EnterNewContact(UI) if nil != err { utils.Fatalf("Couldn't get contact information for registration: %s", err) } if password, err := UI.NewPasswordPrompt("Enter new password for account", "Enter password again"); nil != err { utils.Fatalf("Couldn't read new password for storage file: %s", err) } else { st.SetPassword(password) } if reg, err = dir.NewRegistration(command_base.FlagsStorageRegistrationName, signingKey, contact); nil != err { utils.Fatalf("Couldn't create registration: %s", err) } } regData := reg.Registration() if 0 != len(regData.LinkTermsOfService) && (show_tos || 0 == len(regData.Resource.AgreementURL)) { if regData.Resource.AgreementURL == regData.LinkTermsOfService { UI.Messagef("The terms of service at %s are marked as already agreed to.", regData.LinkTermsOfService) } else if agree_tos { UI.Messagef("Automatically accepting the terms of service at %s as requested:", regData.LinkTermsOfService) newAgreementURL = ®Data.LinkTermsOfService } else { var title string if 0 == len(regData.Resource.AgreementURL) { title = "The server asks for confirmation of the terms of service at %s" } else { title = "There are new terms of service at %s" } ack, err := UI.YesNoDialog(fmt.Sprintf(title, regData.LinkTermsOfService), "", "Agree?", false) if err != nil { utils.Fatalf("Couldn't read acknowledge for terms of service: %s", err) } if ack { newAgreementURL = ®Data.LinkTermsOfService } else if 0 == len(regData.Resource.AgreementURL) { utils.Infof("Terms of service not accepted") } else { utils.Infof("New terms of service not accepted") } } } if err := reg.Update(newContact, newAgreementURL); err != nil { utils.Fatalf("Couldn't update registration: %s", err) } regData = reg.Registration() UI.Messagef("Your registration URL is %s", regData.Location) UI.Messagef("Your registered contact information is: %v", regData.Resource.Contact) if 0 != len(regData.Resource.AgreementURL) { UI.Messagef("You agreed to the terms of service at %s", regData.Resource.AgreementURL) } else { UI.Messagef("You didn't agree to the terms of service at %s", regData.LinkTermsOfService) } UI.Messagef("Your recovery token is: %s", regData.RecoveryToken) }