1
0
mirror of https://github.com/httpie/cli.git synced 2025-08-10 22:42:05 +02:00

Implement support for private key passphrases

This commit is contained in:
Batuhan Taskaya
2022-03-01 17:16:37 +03:00
parent 98688b2f2d
commit 15013fd609
10 changed files with 223 additions and 13 deletions

View File

@@ -10,7 +10,8 @@ from urllib.parse import urlsplit
from requests.utils import get_netrc_auth
from .argtypes import (
AuthCredentials, KeyValueArgType, PARSED_DEFAULT_FORMAT_OPTIONS,
AuthCredentials, SSLCredentials, KeyValueArgType,
PARSED_DEFAULT_FORMAT_OPTIONS,
parse_auth,
parse_format_options,
)
@@ -148,6 +149,7 @@ class HTTPieArgumentParser(BaseHTTPieArgumentParser):
self._parse_items()
self._process_url()
self._process_auth()
self._process_ssl_cert()
if self.args.raw is not None:
self._body_from_input(self.args.raw)
@@ -236,6 +238,19 @@ class HTTPieArgumentParser(BaseHTTPieArgumentParser):
self.env.stdout = self.env.devnull
self.env.apply_warnings_filter()
def _process_ssl_cert(self):
from httpie.ssl_ import _is_key_file_encrypted
if self.args.cert_key_pass is None:
self.args.cert_key_pass = SSLCredentials(None)
if (
self.args.cert_key is not None
and self.args.cert_key_pass.value is None
and _is_key_file_encrypted(self.args.cert_key)
):
self.args.cert_key_pass.prompt_password(self.args.cert_key)
def _process_auth(self):
# TODO: refactor & simplify this method.
self.args.auth_plugin = None

View File

@@ -130,16 +130,11 @@ class KeyValueArgType:
return tokens
class AuthCredentials(KeyValueArg):
"""Represents parsed credentials."""
def has_password(self) -> bool:
return self.value is not None
def prompt_password(self, host: str):
prompt_text = f'http: password for {self.key}@{host}: '
class PromptMixin:
def _prompt_password(self, prompt: str) -> str:
prompt_text = f'http: {prompt}: '
try:
self.value = self._getpass(prompt_text)
return self._getpass(prompt_text)
except (EOFError, KeyboardInterrupt):
sys.stderr.write('\n')
sys.exit(0)
@@ -150,6 +145,26 @@ class AuthCredentials(KeyValueArg):
return getpass.getpass(str(prompt))
class SSLCredentials(PromptMixin):
"""Represents the passphrase for the certificate's key."""
def __init__(self, value: Optional[str]) -> None:
self.value = value
def prompt_password(self, key_file: str) -> None:
self.value = self._prompt_password(f'passphrase for {key_file}')
class AuthCredentials(KeyValueArg, PromptMixin):
"""Represents parsed credentials."""
def has_password(self) -> bool:
return self.value is not None
def prompt_password(self, host: str) -> None:
self.value = self._prompt_password(f'password for {self.key}@{host}:')
class AuthCredentialsArgType(KeyValueArgType):
"""A key-value arg type that parses credentials."""

View File

@@ -8,7 +8,7 @@ from textwrap import dedent, wrap
from .. import __doc__, __version__
from .argparser import HTTPieArgumentParser
from .argtypes import (
KeyValueArgType, SessionNameValidator,
KeyValueArgType, SessionNameValidator, SSLCredentials,
readable_file_arg, response_charset_type, response_mime_type,
)
from .constants import (
@@ -803,6 +803,17 @@ ssl.add_argument(
'''
)
ssl.add_argument(
'--cert-key-pass',
default=None,
type=SSLCredentials,
help='''
The passphrase to be used to with the given private key. Only needed if --cert-key
is given and the key file requires a passphrase.
'''
)
#######################################################################
# Troubleshooting
#######################################################################