Ejemplo n.º 1
0
 def save(self, master_key: PKey):
     with io.StringIO() as buffer_:
         master_key.write_private_key(buffer_)
         pem = buffer_.getvalue()
     self.driver.upload_object_via_stream(
         self._countable_iterator([pem]), self.container, self.object_name, {"content_type": "application/x-pem-key"}
     )
Ejemplo n.º 2
0
 def save(self, master_key: PKey):
     with io.StringIO() as buffer_:
         master_key.write_private_key(buffer_)
         pem = buffer_.getvalue()
     self.driver.upload_object_via_stream(
         self._countable_iterator([pem]), self.container, self.object_name,
         {'content_type': 'application/x-pem-key'})
Ejemplo n.º 3
0
def format_openssh_pubkey(key: PKey) -> str:
    """Format the given ``key`` to an OpenSSH public key line, used by
    :file:`authorized_keys`, :file:`id_rsa.pub`, etc.

    :param key: the key object to format
    :type key: :class:`paramiko.pkey.PKey`
    :return: a formatted openssh public key line
    :rtype: :class:`str`

    """
    return '{} {} '.format(key.get_name(), key.get_base64())
Ejemplo n.º 4
0
def format_openssh_pubkey(key: PKey) -> str:
    """Format the given ``key`` to an OpenSSH public key line, used by
    :file:`authorized_keys`, :file:`id_rsa.pub`, etc.

    :param key: the key object to format
    :type key: :class:`paramiko.pkey.PKey`
    :return: a formatted openssh public key line
    :rtype: :class:`str`

    """
    return '{} {} '.format(key.get_name(), key.get_base64())
Ejemplo n.º 5
0
 def test_parse_junk(self):
     """Non-key data is allowed before and after the key itself"""
     key_str = '\n'.join([
         "BLA bla BLA", "Lots of junk",
         self.ecdsa_str.strip(),
         "It's your lucky day, we even have trailing junk!"
     ])
     self.assertEqual(PKey._parse_openssh_pkey(key_str), self.ecdsa_parsed)
Ejemplo n.º 6
0
 def save(self, master_key: PKey):
     extra = {'content_type': 'application/x-pem-key'}
     if isinstance(self.driver, S3StorageDriver):
         # On some cases (altough unknown condition), S3 driver failed to
         # match signature when it uploads object through stream.
         # This is workaround to upload the master key without stream.
         with tempfile.NamedTemporaryFile('w+', encoding='utf-8') as f:
             master_key.write_private_key(f)
             f.file.flush()
             self.driver.upload_object(f.name, self.container,
                                       self.object_name, extra)
         return
     with io.StringIO() as buffer_:
         master_key.write_private_key(buffer_)
         pem = buffer_.getvalue()
     self.driver.upload_object_via_stream(self._countable_iterator([pem]),
                                          self.container, self.object_name,
                                          extra)
Ejemplo n.º 7
0
    def test_parse_old_plain(self):
        key_str = open(_support("test_rsa.key")).read()
        pkformat, typ, headers, data = PKey._parse_openssh_pkey(key_str)

        self.assertEqual(pkformat, PKey.FORMAT_ORIGINAL)
        self.assertEqual(typ, RSAKey.LEGACY_TYPE)
        self.assertEqual(headers, {})
        self.assertIsInstance(data, bytes)
        self.assertEqual(len(data), 606)
Ejemplo n.º 8
0
    def test_parse_new(self):
        """In new format, parsing is same for encryped and un-encrypted."""
        key_str = open(_support("test_ed25519.key")).read()
        pkformat, typ, headers, data = PKey._parse_openssh_pkey(key_str)

        self.assertEqual(pkformat, PKey.FORMAT_OPENSSH)
        self.assertEqual(typ, "OPENSSH")
        self.assertEqual(headers, {})
        self.assertIsInstance(data, bytes)
        self.assertEqual(len(data), 266)
Ejemplo n.º 9
0
 def load(self) -> PKey:
     if os.path.isfile(self.path):
         classes = PKey.__subclasses__()
         last = len(classes) + 1
         for i, cls in enumerate(classes):
             try:
                 return cls.from_private_key_file(self.path)
             except SSHException:
                 if i == last:
                     raise
                 continue
     raise EmptyStoreError()
Ejemplo n.º 10
0
def get_key_fingerprint(key: PKey, glue: str=':') -> str:
    """Get the hexadecimal fingerprint string of the ``key``.

    :param key: the key to get fingerprint
    :type key: :class:`paramiko.pkey.PKey`
    :param glue: glue character to be placed between bytes.
                 ``':'`` by default
    :type glue: :class:`str`
    :return: the fingerprint string
    :rtype: :class:`str`

    """
    return glue.join(map('{:02x}'.format, key.get_fingerprint()))
Ejemplo n.º 11
0
 def save(self, master_key: PKey) -> None:
     extra = {'content_type': 'application/x-pem-key'}
     if isinstance(self.driver, S3StorageDriver):
         # On some cases (altough unknown condition), S3 driver failed to
         # match signature when it uploads object through stream.
         # This is workaround to upload the master key without stream.
         with tempfile.NamedTemporaryFile('w+', encoding='utf-8') as f:
             master_key.write_private_key(f)
             getattr(f, 'file').flush()  # workaround mypy
             self.driver.upload_object(
                 f.name, self.container, self.object_name, extra
             )
         return
     with io.StringIO() as buffer_:
         master_key.write_private_key(buffer_)
         pem = getattr(buffer_, 'getvalue')()  # workaround mypy
     self.driver.upload_object_via_stream(
         type(self)._countable_iterator([pem]),
         self.container,
         self.object_name,
         extra
     )
Ejemplo n.º 12
0
    def test_parse_old_password(self):
        """Old format with headers"""
        pkformat, typ, headers, data = PKey._parse_openssh_pkey(self.ecdsa_str)

        self.assertEqual(pkformat, PKey.FORMAT_ORIGINAL)
        self.assertEqual(typ, ECDSAKey.LEGACY_TYPE)
        self.assertEqual(
            headers, {
                "dek-info": "AES-128-CBC,EEB56BC745EDB2DE04FC3FE1F8DA387E",
                "proc-type": "4,ENCRYPTED"
            })
        self.assertIsInstance(data, bytes)
        self.assertEqual(len(data), 128)
Ejemplo n.º 13
0
def get_key_fingerprint(key: PKey, glue: str=':') -> str:
    """Get the hexadecimal fingerprint string of the ``key``.

    :param key: the key to get fingerprint
    :type key: :class:`paramiko.pkey.PKey`
    :param glue: glue character to be placed between bytes.
                 ``':'`` by default
    :type glue: :class:`str`
    :return: the fingerprint string
    :rtype: :class:`str`

    """
    return glue.join(map('{:02x}'.format, key.get_fingerprint()))
Ejemplo n.º 14
0
 def connect(self):
     try:
         self.remote_client = SSHClient()
         self.remote_client.set_missing_host_key_policy(AutoAddPolicy())
         self.remote_client.connect(
             self.hostname,
             username=self.username,
             password=self.password,
             port=self.port,
             pkey=PKey(self.private_key) if self.private_key else None,
             key_filename=self.private_key_file_path,
         )
     except AuthenticationException as e:
         raise RemoteExecutor.AuthenticationException(str(e))
     except NoValidConnectionsError as e:
         raise RemoteExecutor.NoValidConnectionException(str(e))
     except Exception as e:
         raise RemoteExecutor.ConnectionException(str(e))
Ejemplo n.º 15
0
 def register(self, identity: Identity, public_key: PKey) -> None:
     with self._connect() as connection:
         cursor = connection.cursor()
         try:
             params = (self._get_key_params(public_key) +
                       (public_key.get_base64(),) +
                       self._get_identity_params(identity))
             self._execute(cursor, '''
                 INSERT INTO geofront_public_key (
                     key_type, key_fingerprint, key_base64,
                      team_type, identifier
                 ) VALUES (?, ?, ?, ?, ?)
             ''', params)
             connection.commit()
         except self.integrity_error as e:
             raise DuplicatePublicKeyError(str(e))
         finally:
             cursor.close()
Ejemplo n.º 16
0
def read_private_key_file(file_: io.IOBase) -> PKey:
    """Read a private key file.  Similar to :meth:`PKey.from_private_key()
    <paramiko.pkey.PKey.from_private_key>` except it guess the key type.

    :param file_: a stream of the private key to read
    :type file_: :class:`io.IOBase`
    :return: the read private key
    :rtype: :class:`paramiko.pkey.PKery`
    :raise paramiko.ssh_exception.SSHException: when something goes wrong

    """
    classes = PKey.__subclasses__()
    last = len(classes) + 1
    for i, cls in enumerate(classes):
        try:
            return cls.from_private_key(file_)
        except SSHException:
            if i == last:
                raise
            file_.seek(0)
            continue
Ejemplo n.º 17
0
    def check_auth_publickey(self, username: Text, key: PKey) -> int:
        ssh_pub_key = SSHKey(f"{key.get_name()} {key.get_base64()}")
        ssh_pub_key.parse()
        logging.debug("check_auth_publickey: username=%s, key=%s %s %sbits",
                      username, key.get_name(), ssh_pub_key.hash_sha256(),
                      ssh_pub_key.bits)
        if self.session.session_log_dir:
            os.makedirs(self.session.session_log_dir, exist_ok=True)
            pubkeyfile_path = os.path.join(self.session.session_log_dir,
                                           'publickeys')
            with open(pubkeyfile_path, 'a+') as pubkeyfile:
                pubkeyfile.write(
                    f"{key.get_name()} {key.get_base64()} saved-from-auth-publickey\n"
                )
        if self.args.disable_pubkey_auth:
            logging.debug(
                "Publickey login attempt, but publickey auth was disabled!")
            return paramiko.common.AUTH_FAILED
        if self.args.accept_first_publickey:
            logging.debug('host probing disabled - first key accepted')
            if self.args.disallow_publickey_auth:
                logging.debug(
                    'ignoring argument --disallow-publickey-auth, first key still accepted'
                )
            self.session.authenticator.authenticate(username, key=None)
            self.session.accepted_key = key
            return paramiko.common.AUTH_SUCCESSFUL

        auth_result: int = self.session.authenticator.authenticate(username,
                                                                   key=key)
        if auth_result == paramiko.common.AUTH_SUCCESSFUL:
            self.session.accepted_key = key
        if self.session.accepted_key is not None and self.args.enable_trivial_auth:
            logging.debug("found valid key for trivial authentication")
            return paramiko.common.AUTH_FAILED
        if self.args.disallow_publickey_auth:
            return paramiko.common.AUTH_FAILED
        return auth_result
Ejemplo n.º 18
0
 def save(self, master_key: PKey):
     master_key.write_private_key_file(self.path)
Ejemplo n.º 19
0
 def test_parse_empty(self):
     with self.assertRaises(SSHException) as ctx:
         PKey._parse_openssh_pkey("")
     self.assertEqual(str(ctx.exception), "not a valid private key file")
Ejemplo n.º 20
0
 def test_bad_base64(self):
     with self.assertRaises(SSHException) as ctx:
         PKey._parse_openssh_pkey(INVALID_BASE64_KEY)
     self.assertEqual(str(ctx.exception),
                      "base64 decoding error: Incorrect padding")
Ejemplo n.º 21
0
 def test_parse_end_line(self):
     """END tag must be on a line by itself"""
     key_str = self.ecdsa_str.strip() + "BLA"
     with self.assertRaises(SSHException):
         PKey._parse_openssh_pkey(key_str)
Ejemplo n.º 22
0
 def test_parse_begin_line(self):
     """BEGIN tag must be on a line by itself"""
     key_str = "BLA" + self.ecdsa_str
     with self.assertRaises(SSHException):
         PKey._parse_openssh_pkey(key_str)
Ejemplo n.º 23
0
def main(*margs):
    parser = argparse.ArgumentParser("Netconf Client Utility")
    parser.add_argument("--debug", action="store_true", help="Enable debug logging")
    parser.add_argument('--host', default="localhost", help='Netconf server hostname')
    parser.add_argument(
        '--get',
        const="",
        nargs='?',
        help="Perform <get>. arg value is xpath/xml filter or taken from infile if not specified")
    parser.add_argument(
        '--get-config',
        const="",
        nargs='?',
        help=
        "Perform <get-config>. arg value is xpath/xml filter or taken from infile if not specified")
    parser.add_argument(
        '--hello', action="store_true", help="Do hello and return capabilities of server.")
    parser.add_argument("-i", "--infile", help="File to read from")
    parser.add_argument(
        '-p',
        '--password',
        default=None,
        help='Password (or passphrase) use "env:" or "file:" prefix to specify password source')
    parser.add_argument(
        '-k', '--keyfile', default=None, help='SSH key use password to specify passphrase')
    # Deprecated now parse password args more functional
    parser.add_argument('--passenv', default=None, help=argparse.SUPPRESS)
    parser.add_argument('--port', type=int, default=830, help='Netconf server port')
    parser.add_argument("-q", "--quiet", action="store_true", help="Quiet operation")
    parser.add_argument('--source', default="running", help="Source for get config")
    parser.add_argument('--timeout', type=float, help="Timeout for command in fractional seconds")
    parser.add_argument('-u', '--username', default="admin", help='Netconf username')
    parser.add_argument("-v", "--verbose", action="store_true", help="Verbose logging")
    args = parser.parse_args(*margs)

    if args.passenv and args.password:
        print("Only one of --password and --passenv allowed", file=sys.stderr)
        sys.exit(1)
    if args.passenv:
        args.password = os.environ[args.passenv]
    else:
        args.password = parse_password_arg(args.password)

    if args.keyfile:
        args.password = PKey.from_private_key_file(args.keyfile, password=args.password)

    if args.debug:
        logging.basicConfig(level=logging.DEBUG)
    elif args.verbose:
        logging.basicConfig(level=logging.INFO)
    elif args.quiet:
        logging.basicConfig(level=logging.ERROR)
    else:
        logging.basicConfig(level=logging.WARNING)

    session = client.NetconfSSHSession(
        args.host, args.port, args.username, args.password, debug=args.debug)

    if args.hello:
        result = "\n".join(session.capabilities) + "\n"
    elif args.get is not None:
        result = session.get(args.get, args.timeout)
        result = "  " + etree.tounicode(result, pretty_print=True)
    elif args.get_config is not None:
        result = session.get_config(args.source, args.get_config, args.timeout)
        result = "  " + etree.tounicode(result, pretty_print=True)
    else:
        print("get: {}".format(args.get))
        if args.infile:
            xml = open(args.infile).read()
        else:
            xml = sys.stdin.read()
        if not xml:
            print("Nothing to do.", file=sys.stderr)
            sys.exit(1)
        result = session.send_rpc(xml)[2]
    sys.stdout.write(result)
    session.close()
Ejemplo n.º 24
0
 def test_parse_crlf(self):
     """Test handling of Windows newlines"""
     key_str = self.ecdsa_str
     key_str = key_str.replace("\n", "\r\n")
     self.assertEqual(PKey._parse_openssh_pkey(key_str), self.ecdsa_parsed)
Ejemplo n.º 25
0
 def test_parse_whitespace(self):
     """In some places, extraneous whitespace should not affect parsing"""
     key_str = self.ecdsa_str
     key_str = key_str.replace("\n", "  \t\n")
     key_str = key_str.replace(": ", ": \t ")
     self.assertEqual(PKey._parse_openssh_pkey(key_str), self.ecdsa_parsed)
Ejemplo n.º 26
0
 def _get_key_params(self, public_key: PKey) -> Tuple[str, str]:
     return public_key.get_name(), get_key_fingerprint(public_key, '')
Ejemplo n.º 27
0
 def setUpClass(cls):
     # Several tests rely on these fields.
     cls.ecdsa_str = open(
         _support("test_ecdsa_password_256.key")).read().strip()
     cls.ecdsa_parsed = PKey._parse_openssh_pkey(cls.ecdsa_str)