def rename_lineage(config: configuration.NamespaceConfig) -> None: """Rename the specified lineage to the new name. :param config: Configuration. :type config: :class:`certbot._internal.configuration.NamespaceConfig` """ certname = get_certnames(config, "rename")[0] new_certname = config.new_certname if not new_certname: code, new_certname = display_util.input_text( "Enter the new name for certificate {0}".format(certname), force_interactive=True) if code != display_util.OK or not new_certname: raise errors.Error("User ended interaction.") lineage = lineage_for_certname(config, certname) if not lineage: raise errors.ConfigurationError("No existing certificate with name " "{0} found.".format(certname)) storage.rename_renewal_config(certname, new_certname, config) display_util.notification("Successfully renamed {0} to {1}.".format( certname, new_certname), pause=False)
def get_email(invalid: bool = False, optional: bool = True) -> str: """Prompt for valid email address. :param bool invalid: True if an invalid address was provided by the user :param bool optional: True if the user can use --register-unsafely-without-email to avoid providing an e-mail :returns: e-mail address :rtype: str :raises errors.Error: if the user cancels """ invalid_prefix = "There seem to be problems with that address. " msg = "Enter email address (used for urgent renewal and security notices)\n" unsafe_suggestion = ( "\n\nIf you really want to skip this, you can run " "the client with --register-unsafely-without-email " "but you will then be unable to receive notice about " "impending expiration or revocation of your " "certificates or problems with your Certbot " "installation that will lead to failure to renew.\n\n") if optional: if invalid: msg += unsafe_suggestion suggest_unsafe = False else: suggest_unsafe = True else: suggest_unsafe = False while True: try: code, email = display_util.input_text(invalid_prefix + msg if invalid else msg, force_interactive=True) except errors.MissingCommandlineFlag: msg = ("You should register before running non-interactively, " "or provide --agree-tos and --email <email_address> flags.") raise errors.MissingCommandlineFlag(msg) if code != display_util.OK: if optional: raise errors.Error( "An e-mail address or " "--register-unsafely-without-email must be provided.") raise errors.Error("An e-mail address must be provided.") if util.safe_email(email): return email if suggest_unsafe: msg = unsafe_suggestion + msg suggest_unsafe = False # add this message at most once invalid = bool(email)
def _choose_names_manually(prompt_prefix: str = "") -> List[str]: """Manually input names for those without an installer. :param str prompt_prefix: string to prepend to prompt for domains :returns: list of provided names :rtype: `list` of `str` """ code, input_ = display_util.input_text( prompt_prefix + "Please enter the domain name(s) you would like on your certificate " "(comma and/or space separated)", cli_flag="--domains", force_interactive=True) if code == display_util.OK: invalid_domains = {} retry_message = "" try: domain_list = internal_display_util.separate_list_input(input_) except UnicodeEncodeError: domain_list = [] retry_message = ( "Internationalized domain names are not presently " "supported.{0}{0}Would you like to re-enter the " "names?{0}").format(os.linesep) for i, domain in enumerate(domain_list): try: domain_list[i] = util.enforce_domain_sanity(domain) except errors.ConfigurationError as e: invalid_domains[domain] = str(e) if invalid_domains: retry_message = ( "One or more of the entered domain names was not valid:" "{0}{0}").format(os.linesep) for invalid_domain, err in invalid_domains.items(): retry_message = retry_message + "{1}: {2}{0}".format( os.linesep, invalid_domain, err) retry_message = retry_message + ( "{0}Would you like to re-enter the names?{0}").format( os.linesep) if retry_message: # We had error in input retry = display_util.yesno(retry_message, force_interactive=True) if retry: return _choose_names_manually() else: return domain_list return []
def _perform_emailreply00(self, achall): response, _ = achall.challb.response_and_validation(achall.account_key) text = 'A challenge request for S/MIME certificate has been sent. In few minutes, ACME server will send a challenge e-mail to requested recipient {}. Please, copy the ENTIRE subject and paste it below. The subject starts with the label ACME: '.format(achall.domain) display_util.notification(text,pause=False) code,subject = display_util.input_text('Subject: ', force_interactive=True) token64 = subject.split(' ')[-1] token1 = jose.b64.b64decode(token64) full_token = token1+achall.chall.token # We reconstruct the ChallengeBody challt = messages.ChallengeBody.from_json({ 'type': 'email-reply-00', 'token': jose.b64.b64encode(bytes(full_token)).decode('ascii'), 'url': achall.challb.uri, 'status': achall.challb.status.to_json(), 'from': achall.challb.chall.from_addr }) response, validation = challt.response_and_validation(achall.account_key) digest = hashes.Hash(hashes.SHA256()) digest.update(validation.encode()) thumbprint = jose.b64encode(digest.finalize()).decode() display_util.notification('A challenge response has been generated. Please, copy the following text, reply the e-mail you have received from ACME server and paste this text in the TOP of the message\'s body: ',pause=False) print('\n-----BEGIN ACME RESPONSE-----\n' '{}\n' '-----END ACME RESPONSE-----\n'.format(thumbprint)) return response