Beispiel #1
0
    def test_leading_stuff(self):
        orig = RSAKey.from_private_key(StringIO(RSA_PRIVATE_OUT))
        skey = RSAKey.from_private_key(
            StringIO("\n\n" + RSA_PRIVATE_OUT + "\n\n"))
        self.assertEqual(orig.get_fingerprint(), skey.get_fingerprint())

        comment = "Bag Attributes\n    localKeyID: 32 CB FA 64 B9 D8 C5 D3 BC 4B 20 04 3D EC 38 6B 32 2D C4 9A \nKey Attributes: <No Attributes>\n"  # noqa: E501
        ckey = RSAKey.from_private_key(StringIO(comment + RSA_PRIVATE_OUT))
        self.assertEqual(orig.get_fingerprint(), ckey.get_fingerprint())
Beispiel #2
0
 def get_private_keys(self, force=False):
     if force or self._keys is None:
         self._keys = []
         for key_string in ["/root/.ssh/id_rsa", "/root/.ssh/bootstrap.rsa"]:
             with self.get_admin_remote().open(key_string) as f:
                 self._keys.append(RSAKey.from_private_key(f))
     return self._keys
 def _get_keys(self):
     keys = []
     admin_remote = self._get_remote(self.admin_ip)
     key_string = '/root/.ssh/id_rsa'
     with admin_remote.open(key_string) as f:
         keys.append(RSAKey.from_private_key(f))
     return keys
Beispiel #4
0
    def connect(self):
        ip_address = self.ip_address
        logger = self.logger
        key_string = self.key_string

        ssh_client = super(ExtSSHClient, self)
        isinstance(ssh_client, SSHClient)

        f = StringIO(key_string)
        paramiko_key = RSAKey.from_private_key(f)

        #try:
        #    ssh_client.load_system_host_keys()
        #except:
        #    pass

        ssh_client.set_missing_host_key_policy(AutoAddPolicy())

        logger('Connecting via SSH.')
        tries = 0
        while True:
            try:
                ssh_client.connect(ip_address, username='******',
                                   pkey=paramiko_key, timeout=1000)
                break
            except:
                tries = tries + 1
                if tries > 5:
                    self._raise_error('Timed out trying to ssh to host.')

                logger('Waiting on SSH connection.')
                sleep(5)

        ssh_client.invoke_shell()
Beispiel #5
0
def get_connect_args(password, ssh_key):
    connect_kwargs = {"allow_agent": False, "look_for_keys": False}

    if password is not None:
        connect_kwargs["password"] = password

    if ssh_key is not None:

        if isinstance(ssh_key, str):
            private_key = RSAKey.from_private_key(io.StringIO(ssh_key))
        else:
            private_key = RSAKey.from_private_key(ssh_key)

        connect_kwargs["pkey"] = private_key

    return connect_kwargs
Beispiel #6
0
    def __connect(self):
        """Open connection to remote host."""
        try:
            self.client = SSHClient()
            self.client.load_system_host_keys()
            self.client.set_missing_host_key_policy(AutoAddPolicy())
            pk = None
            with open(self.ssh_key_filepath) as keyfile:
                pk = RSAKey.from_private_key(keyfile, password=self.passphrase)

            if pk is None:
                logger.error(f"private key {self.ssh_key_filepath} not found")
                exit(1)
            self.client.connect(
                hostname=self.host,
                username=self.user,
                passphrase=self.passphrase,
                pkey=pk,
                look_for_keys=True,
                auth_timeout=30,
                timeout=60,
            )
            self.scp = SCPClient(self.client.get_transport())
        except AuthenticationException as error:
            logger.exception("Authentication failed")
            raise error
        except SSHException as error:
            logger.exception("SSH exception")
            raise error
        finally:
            return self.client
Beispiel #7
0
 def _get_keys(self):
     keys = []
     admin_remote = self._get_remote(self.admin_ip)
     for key_string in ['/root/.ssh/id_rsa', '/root/.ssh/bootstrap.rsa']:
         with admin_remote.open(key_string) as f:
             keys.append(RSAKey.from_private_key(f))
     return keys
Beispiel #8
0
def sign_certificate(credential, token, url):
    """
    An interface to the OAuth2 SSH certificate signing service
    @type credential: models.Credential
    """
    key_type = credential.key.get_name()
    key_data = credential.key.get_base64()
    headers = {'Authorization': 'Bearer ' + token}
    payload = {'public_key': key_type + ' ' + key_data}

    r = requests.post(url, headers=headers, data=json.dumps(payload))
    cert_response = json.loads(r.text)
    if 'certificate' not in cert_response:
        return False

    # Ignore the certificate comment field
    remote_user_name = cert_response['user']
    cert_type, cert_data = cert_response['certificate'].split()[0:2]
    if cert_type != '*****@*****.**':
        return False  # We only support this certificate type at the moment

    old_key = credential.key
    private_key = StringIO()
    old_key.write_private_key(private_key)
    private_key.seek(0)
    cert = RSAKey.from_private_key(private_key)
    cert.load_certificate(Message(base64.b64decode(cert_data)))
    credential.key = cert
    credential.remote_user = remote_user_name
    credential.save()
    return True
Beispiel #9
0
    def _connect(
        self, hostname=None, port=None, username=None, password=None,
        accept_missing_host_key=None, timeout=None, compress=None, pkey=None,
        look_for_keys=None, allow_agent=None, key_filename=None,
            proxy_type=None, proxy_ip=None, proxy_port=None, sock=None):
        connect_kwargs = dict(self.connect_kwargs)
        connect_kwargs.update({
            k: locals().get(k) for k in self.connect_kwargs
            if locals().get(k) is not None})
        connect_kwargs["port"] = int(connect_kwargs.get("port"))

        ssh = ExtendedParamikoSSHClient()

        if bool(self.accept_missing_host_key or accept_missing_host_key):
            ssh.set_missing_host_key_policy(AutoAddPolicy())

        if connect_kwargs.get("pkey") is not None:
            connect_kwargs["pkey"] = RSAKey.from_private_key(
                io.StringIO(unicode(connect_kwargs["pkey"])))

        proxy_type = proxy_type or self.proxy_type
        proxy_ip = proxy_ip or self.proxy_ip
        proxy_port = proxy_port or self.proxy_port
        if connect_kwargs.get("sock") is not None:
            pass
        elif all([proxy_type, proxy_ip, proxy_port]):
            connect_kwargs["sock"] = create_connection(
                (connect_kwargs.get("hostname"), connect_kwargs.get("port")),
                proxy_type, proxy_ip, int(proxy_port))

        ssh.connect(**connect_kwargs)
        return ssh
Beispiel #10
0
def start_server(host=None, port=None, keyfile=None):
    if host is None:
        current_site = Site.objects.get_current()
        host = current_site.domain
    port = port or getattr(settings, 'SFTP_PORT', 2200)
    host_key_string = getattr(
        settings, 'SFTP_HOST_KEY',
        "-----BEGIN RSA PRIVATE KEY-----\n"
        "MIICXgIBAAKCAIEAl7sAF0x2O/HwLhG68b1uG8KHSOTqe3Cdlj5i/1RhO7E2BJ4B\n"
        "3jhKYDYtupRnMFbpu7fb21A24w3Y3W5gXzywBxR6dP2HgiSDVecoDg2uSYPjnlDk\n"
        "HrRuviSBG3XpJ/awn1DObxRIvJP4/sCqcMY8Ro/3qfmid5WmMpdCZ3EBeC0CAwEA\n"
        "AQKCAIBSGefUs5UOnr190C49/GiGMN6PPP78SFWdJKjgzEHI0P0PxofwPLlSEj7w\n"
        "RLkJWR4kazpWE7N/bNC6EK2pGueMN9Ag2GxdIRC5r1y8pdYbAkuFFwq9Tqa6j5B0\n"
        "GkkwEhrcFNBGx8UfzHESXe/uE16F+e8l6xBMcXLMJVo9Xjui6QJBAL9MsJEx93iO\n"
        "zwjoRpSNzWyZFhiHbcGJ0NahWzc3wASRU6L9M3JZ1VkabRuWwKNuEzEHNK8cLbRl\n"
        "TyH0mceWXcsCQQDLDEuWcOeoDteEpNhVJFkXJJfwZ4Rlxu42MDsQQ/paJCjt2ONU\n"
        "WBn/P6iYDTvxrt/8+CtLfYc+QQkrTnKn3cLnAkEAk3ixXR0h46Rj4j/9uSOfyyow\n"
        "qHQunlZ50hvNz8GAm4TU7v82m96449nFZtFObC69SLx/VsboTPsUh96idgRrBQJA\n"
        "QBfGeFt1VGAy+YTLYLzTfnGnoFQcv7+2i9ZXnn/Gs9N8M+/lekdBFYgzoKN0y4pG\n"
        "2+Q+Tlr2aNlAmrHtkT13+wJAJVgZATPI5X3UO0Wdf24f/w9+OY+QxKGl86tTQXzE\n"
        "4bwvYtUGufMIHiNeWP66i6fYCucXCMYtx6Xgu2hpdZZpFw==\n"
        "-----END RSA PRIVATE KEY-----\n")
    host_key = RSAKey.from_private_key(
        keyfile or StringIO(host_key_string))
    server = MyTSFTPTCPServer((host, port), host_key=host_key)
    try:
        server.serve_forever()
    except (SystemExit, KeyboardInterrupt):
        server.server_close()
Beispiel #11
0
def start_server(host=None, port=None, keyfile=None):
    if host is None:
        current_site = Site.objects.get_current()
        host = current_site.domain
    port = port or getattr(settings, 'SFTP_PORT', 2200)
    host_key_string = getattr(
        settings, 'SFTP_HOST_KEY',
        "-----BEGIN RSA PRIVATE KEY-----\n"
        "MIICXgIBAAKCAIEAl7sAF0x2O/HwLhG68b1uG8KHSOTqe3Cdlj5i/1RhO7E2BJ4B\n"
        "3jhKYDYtupRnMFbpu7fb21A24w3Y3W5gXzywBxR6dP2HgiSDVecoDg2uSYPjnlDk\n"
        "HrRuviSBG3XpJ/awn1DObxRIvJP4/sCqcMY8Ro/3qfmid5WmMpdCZ3EBeC0CAwEA\n"
        "AQKCAIBSGefUs5UOnr190C49/GiGMN6PPP78SFWdJKjgzEHI0P0PxofwPLlSEj7w\n"
        "RLkJWR4kazpWE7N/bNC6EK2pGueMN9Ag2GxdIRC5r1y8pdYbAkuFFwq9Tqa6j5B0\n"
        "GkkwEhrcFNBGx8UfzHESXe/uE16F+e8l6xBMcXLMJVo9Xjui6QJBAL9MsJEx93iO\n"
        "zwjoRpSNzWyZFhiHbcGJ0NahWzc3wASRU6L9M3JZ1VkabRuWwKNuEzEHNK8cLbRl\n"
        "TyH0mceWXcsCQQDLDEuWcOeoDteEpNhVJFkXJJfwZ4Rlxu42MDsQQ/paJCjt2ONU\n"
        "WBn/P6iYDTvxrt/8+CtLfYc+QQkrTnKn3cLnAkEAk3ixXR0h46Rj4j/9uSOfyyow\n"
        "qHQunlZ50hvNz8GAm4TU7v82m96449nFZtFObC69SLx/VsboTPsUh96idgRrBQJA\n"
        "QBfGeFt1VGAy+YTLYLzTfnGnoFQcv7+2i9ZXnn/Gs9N8M+/lekdBFYgzoKN0y4pG\n"
        "2+Q+Tlr2aNlAmrHtkT13+wJAJVgZATPI5X3UO0Wdf24f/w9+OY+QxKGl86tTQXzE\n"
        "4bwvYtUGufMIHiNeWP66i6fYCucXCMYtx6Xgu2hpdZZpFw==\n"
        "-----END RSA PRIVATE KEY-----\n")
    host_key = RSAKey.from_private_key(
        keyfile or StringIO(host_key_string))
    server = MyTSFTPServer((host, port), host_key=host_key)
    try:
        server.serve_forever()
    except (SystemExit, KeyboardInterrupt):
        server.server_close()
Beispiel #12
0
def get_replication_client(dispatcher, remote):
    host = dispatcher.call_sync(
        'peer.query',
        [('address', '=', remote), ('type', '=', 'replication')],
        {'single': True}
    )
    if not host:
        raise TaskException(errno.ENOENT, 'There are no known keys to connect to {0}'.format(remote))

    with open('/etc/replication/key') as f:
        pkey = RSAKey.from_private_key(f)

    credentials = host['credentials']

    try:
        client = Client()
        with tempfile.NamedTemporaryFile('w') as host_key_file:
            host_key_file.write(credentials['hostkey'])
            host_key_file.flush()
            client.connect(
                'ws+ssh://replication@{0}'.format(remote),
                port=credentials['port'],
                host_key_file=host_key_file.name,
                pkey=pkey
            )
        client.login_service('replicator')
        return client

    except (AuthenticationException, SSHException):
        raise TaskException(errno.EAUTH, 'Cannot connect to {0}'.format(remote))
    except (OSError, ConnectionRefusedError):
        raise TaskException(errno.ECONNREFUSED, 'Cannot connect to {0}'.format(remote))
    except IOError:
        raise TaskException(errno.EINVAL, 'Provided host key is not valid')
Beispiel #13
0
    def _connect(
        self, hostname=None, port=None, username=None, password=None,
        accept_missing_host_key=None, timeout=None, compress=None, pkey=None,
        look_for_keys=None, allow_agent=None, key_filename=None,
            proxy_type=None, proxy_ip=None, proxy_port=None, sock=None):
        connect_kwargs = dict(self.connect_kwargs)
        connect_kwargs.update({
            k: locals().get(k) for k in self.connect_kwargs
            if locals().get(k) is not None})
        connect_kwargs["port"] = int(connect_kwargs.get("port"))

        ssh = ExtendedParamikoSSHClient()

        if bool(self.accept_missing_host_key or accept_missing_host_key):
            ssh.set_missing_host_key_policy(AutoAddPolicy())

        if connect_kwargs.get("pkey") is not None:
            connect_kwargs["pkey"] = RSAKey.from_private_key(
                io.StringIO(unicode(connect_kwargs["pkey"])))

        proxy_type = proxy_type or self.proxy_type
        proxy_ip = proxy_ip or self.proxy_ip
        proxy_port = proxy_port or self.proxy_port
        if connect_kwargs.get("sock") is not None:
            pass
        elif all([proxy_type, proxy_ip, proxy_port]):
            connect_kwargs["sock"] = create_connection(
                (connect_kwargs.get("hostname"), connect_kwargs.get("port")),
                proxy_type, proxy_ip, int(proxy_port))

        ssh.connect(**connect_kwargs)
        return ssh
Beispiel #14
0
 def _get_keys(self):
     keys = []
     admin_remote = self._get_remote(self.admin_ip)
     for key_string in ['/root/.ssh/id_rsa', '/root/.ssh/bootstrap.rsa']:
         with admin_remote.open(key_string) as f:
             keys.append(RSAKey.from_private_key(f))
     return keys
Beispiel #15
0
 def __init__(self, database, options, aux=False):
     self.db = database
     self.options = options
     self.aux = aux
     #RG
     self.bbzybo = 1
     self.__start_time = None
     self.__timer_value = 0
     self.ip_address = options.dut_ip_address if not aux \
         else options.aux_ip_address
     self.scp_port = options.dut_scp_port if not aux \
         else options.aux_scp_port
     self.prompt = '{} '.format(options.dut_prompt if not aux or not options
                                .aux_prompt else options.aux_prompt)
     self.username = options.dut_username if not aux \
         else options.aux_username
     self.password = options.dut_password if not aux \
         else options.aux_password
     rsakey_file = StringIO(database.campaign.rsakey)
     self.rsakey = RSAKey.from_private_key(rsakey_file)
     rsakey_file.close()
     self.uboot_command = options.dut_uboot if not aux \
         else options.aux_uboot
     self.login_command = options.dut_login if not aux \
         else options.aux_login
     for message in reversed(self.vxworks_signal_messages if options.
                             vxworks else self.linux_signal_messages):
         self.error_messages.insert(0, message)
     for message in reversed(options.error_messages):
         self.error_messages.insert(0, (message, message))
     self.open()
Beispiel #16
0
    def __init__(self, host, port, tun_host, tun_port, tun_user, tun_password,
                 pkey, pkey_password):
        self.host = host
        self.port = int(port)
        self.tun_host = tun_host
        self.tun_port = int(tun_port)
        self.tun_user = tun_user
        self.tun_password = tun_password

        if pkey:
            private_key_file_obj = io.StringIO()
            private_key_file_obj.write(pkey)
            private_key_file_obj.seek(0)
            self.private_key = RSAKey.from_private_key(private_key_file_obj,
                                                       password=pkey_password)
            self.server = SSHTunnelForwarder(
                ssh_address_or_host=(self.tun_host, self.tun_port),
                ssh_username=self.tun_user,
                ssh_pkey=self.private_key,
                remote_bind_address=(self.host, self.port),
            )
        else:
            self.server = SSHTunnelForwarder(
                ssh_address_or_host=(self.tun_host, self.tun_port),
                ssh_username=self.tun_user,
                ssh_password=self.tun_password,
                remote_bind_address=(self.host, self.port),
            )
        self.server.start()
Beispiel #17
0
 def __init__(self,
              name,
              missionid,
              host,
              port,
              username,
              frequency=1,
              count=30,
              password=None,
              pkeycontent=None,
              **kwargs):
     SSHClient.__init__(self)
     self.name = name
     self.missionid = missionid
     self.frequency = frequency
     self.count = count
     self.homedir = "/home/%s" % username if username != "root" else "/root"
     self.set_missing_host_key_policy(AutoAddPolicy())
     key = StringIO(pkeycontent)
     pkey = RSAKey.from_private_key(key) if pkeycontent else None
     self.connect(hostname=host,
                  port=port,
                  username=username,
                  password=password,
                  pkey=pkey,
                  **kwargs)
     self.sftpclient = self.open_sftp()
Beispiel #18
0
    def connect(self, ip_address, key_string):

        print('Connecting to %s via SSH' % ip_address)
        ssh_client = super(Ext_SSHClient, self)
        isinstance(ssh_client, SSHClient)

        self.ip_address = ip_address

        f = StringIO(key_string)
        paramiko_key = RSAKey.from_private_key(f)

        try:
            ssh_client.load_system_host_keys()
        except:
            pass

        ssh_client.set_missing_host_key_policy(AutoAddPolicy())

        tries = 0
        while True:
            try:
                ssh_client.connect(ip_address,
                                   username='******',
                                   pkey=paramiko_key,
                                   timeout=1000)
                break
            except:
                tries = tries + 1
                if tries > 5:
                    raise BaseException('Timed out trying to ssh to host %s' %
                                        ip_address)
                print('Waiting for SSH to %s' % ip_address)
                sleep(5)

        ssh_client.invoke_shell()
Beispiel #19
0
 def _get_keys(self):
     keys = []
     admin_remote = self._get_remote(self.admin_ip)
     key_string = '/root/.ssh/id_rsa'
     with admin_remote.open(key_string) as f:
         keys.append(RSAKey.from_private_key(f))
     return keys
Beispiel #20
0
    def connect(self, instance, ssh_user, ssh_ports, cmd, ssh_key_name):
        """
        execute a command on instance with ssh and return if cmd param is not None
        connect to ssh if cmd is None
        :param instance:
        :param ssh_user:
        :param ssh_ports:
        :param ssh_key_name:
        :param cmd: execute this command if not None
        :return:
        """

        # get instance public ip
        ssh_ip = instance.ip

        # we need to find the ssh key
        try:
            key_file = open(os.path.join(os.path.expanduser(self._key_path), ssh_key_name), 'r')
        except FileNotFoundError:
            try:
                key_file = open(os.path.join(os.path.expanduser(self._key_path), ssh_key_name + '.pem'), 'r')
            except FileNotFoundError:
                raise CourirSshException('private key %(key_name)s nor %(key_name)s.pem not found' % {
                    'key_name': ssh_key_name
                })

        client = SSHClient()
        client.set_missing_host_key_policy(AutoAddPolicy())

        logger.debug('connecting to %s with port %s and user %s', ssh_ip, ssh_ports[0], ssh_user)
        mykey = RSAKey.from_private_key(key_file)

        # we try with each ssh_port we have
        for count, ssh_port in enumerate(ssh_ports):
            try:
                logger.debug(ssh_ip)
                logger.debug(ssh_port)
                client.connect(hostname=ssh_ip, port=int(ssh_port), username=ssh_user, pkey=mykey, timeout=4)
                if cmd is None:
                    with NamedTemporaryFile(mode='w+') as tmp_key_file:
                        mykey.write_private_key(tmp_key_file, password=None)
                        tmp_key_file.flush()
                        cmd = 'ssh -i %s %s@%s -p %s' % (tmp_key_file.name, ssh_user, ssh_ip, ssh_port)
                        logger.debug(cmd)
                        os.system(cmd)
                else:
                    stdin, stdout, stderr = client.exec_command(command=cmd)
                    out_str = stdout.read()
                    out_err = stderr.read().strip(' \t\n\r')
                    print(out_str)
                    if out_err != '':
                        print(out_err)
                        sys.exit(1)

            except (ConnectionRefusedError, socket.timeout):
                # we will try another tcp port
                if count < len(ssh_ports):
                    continue
                else:
                    raise CourirSshException('connection error')
Beispiel #21
0
 def connect(self):
     """ Get a handle to a remote connection """
     # Check URL
     schema = urlparse(self.url)
     if schema.scheme == 'sftp':
         self.transport = Transport((schema.hostname, int(schema.port)))
     else:
         raise SFTPError('Not a valid sftp url %s, type is %s' %
                         (self.url, schema.scheme))
     # Add authentication to transport
     try:
         if self.password:
             self.transport.connect(username=self.user_name,
                                    password=self.password)
         elif self.private_key:
             self.transport.connect(username=self.user_name,
                                    pkey=RSAKey.from_private_key(
                                        StringIO(self.private_key)))
         else:
             raise SFTPError("No password or private_key defined")
         # Connect
         self.conn = SFTPClient.from_transport(self.transport)
     except (socket.gaierror, error), msg:
         raise SFTPError(
             str(msg) + ' while establishing connection to %s' %
             (self.url, ))
 def admin_keys(self):
     """Return list with private ssh keys from Fuel master node"""
     if self._admin_keys is None:
         self._admin_keys = []
         with self.ssh_admin() as remote:
             with remote.open('/root/.ssh/id_rsa') as f:
                 self._admin_keys.append(RSAKey.from_private_key(f))
     return self._admin_keys
Beispiel #23
0
 def get_private_keys(self, force=False):
     if force or self._keys is None:
         self._keys = []
         for key_string in ['/root/.ssh/id_rsa',
                            '/root/.ssh/bootstrap.rsa']:
             with self.get_admin_remote().open(key_string) as f:
                 self._keys.append(RSAKey.from_private_key(f))
     return self._keys
Beispiel #24
0
    def connect(self, node, attempts=5):
        """Connect to node prior to running exec_command or scp.

        If there already is a connection to the node, this method reuses it.

        :param node: Node in topology.
        :param attempts: Number of reconnect attempts.
        :type node: dict
        :type attempts: int
        :raises IOError: If cannot connect to host.
        """
        self._node = node
        node_hash = self._node_hash(node)
        if node_hash in SSH.__existing_connections:
            self._ssh = SSH.__existing_connections[node_hash]
            if self._ssh.get_transport().is_active():
                logger.debug('Reusing SSH: {ssh}'.format(ssh=self._ssh))
            else:
                if attempts > 0:
                    self._reconnect(attempts - 1)
                else:
                    raise IOError(
                        'Cannot connect to {host}'.format(host=node['host']))
        else:
            try:
                start = time()
                pkey = None
                if 'priv_key' in node:
                    pkey = RSAKey.from_private_key(
                        StringIO.StringIO(node['priv_key']))

                self._ssh = SSHClient()
                self._ssh.set_missing_host_key_policy(AutoAddPolicy())

                self._ssh.connect(node['host'],
                                  username=node['username'],
                                  password=node.get('password'),
                                  pkey=pkey,
                                  port=node['port'])

                self._ssh.get_transport().set_keepalive(10)

                SSH.__existing_connections[node_hash] = self._ssh
                logger.debug(
                    'New SSH to {peer} took {total} seconds: {ssh}'.format(
                        peer=self._ssh.get_transport().getpeername(),
                        total=(time() - start),
                        ssh=self._ssh))
            except SSHException as exc:
                raise_from(
                    IOError(
                        'Cannot connect to {host}'.format(host=node['host'])),
                    exc)
            except NoValidConnectionsError as err:
                raise_from(
                    IOError(
                        'Unable to connect to port {port} on {host}'.format(
                            port=node['port'], host=node['host'])), err)
Beispiel #25
0
 def get_ssh_to_remote_by_key(self, ip, keyfile):
     try:
         with open(keyfile) as f:
             keys = [RSAKey.from_private_key(f)]
     except IOError:
         logger.warning('Loading of SSH key from file failed. Trying to use'
                        ' SSH agent ...')
         keys = Agent().get_keys()
     return SSHClient(ip, private_keys=keys)
Beispiel #26
0
 def admin_keys(self):
     """Return list with private ssh keys from Fuel master node"""
     if self._admin_keys is None:
         self._admin_keys = []
         with self.ssh_admin() as remote:
             for path in ['/root/.ssh/id_rsa', '/root/.ssh/bootstrap.rsa']:
                 with remote.open(path) as f:
                     self._admin_keys.append(RSAKey.from_private_key(f))
     return self._admin_keys
Beispiel #27
0
 def get_ssh_to_remote_by_key(self, ip, keyfile):
     try:
         with open(keyfile) as f:
             keys = [RSAKey.from_private_key(f)]
     except IOError:
         logger.warning('Loading of SSH key from file failed. Trying to use'
                        ' SSH agent ...')
         keys = Agent().get_keys()
     return SSHClient(ip, private_keys=keys)
Beispiel #28
0
    def get_ssh_to_remote(self, ip):
        keys = []
        for key_string in ['/root/.ssh/id_rsa', '/root/.ssh/bootstrap.rsa']:
            with self.get_admin_remote().open(key_string) as f:
                keys.append(RSAKey.from_private_key(f))

        return SSHClient(ip,
                         username=settings.SSH_CREDENTIALS['login'],
                         password=settings.SSH_CREDENTIALS['password'],
                         private_keys=keys)
Beispiel #29
0
 def get_ssh_to_remote_by_key(ip, keyfile):
     warn('LEGACY,  for fuel-qa compatibility', DeprecationWarning)
     try:
         with open(keyfile) as f:
             keys = [RSAKey.from_private_key(f)]
     except IOError:
         logger.warning('Loading of SSH key from file failed. Trying to use'
                        ' SSH agent ...')
         keys = Agent().get_keys()
     return SSHClient(ip, auth=SSHAuth(keys=keys))
Beispiel #30
0
    def __init__(self, kwargs):

        self.key = RSAKey.from_private_key(
            io.StringIO(kwargs['asymKeys']['private']))
        self.ip_address = kwargs['ip_address']
        self.username = kwargs['username']

        self.sshclient = SSHClient()
        self.sshclient.set_missing_host_key_policy(AutoAddPolicy())

        return super().__init__()
Beispiel #31
0
    def get_ssh_to_remote(self, ip):
        keys = []
        for key_string in ['/root/.ssh/id_rsa',
                           '/root/.ssh/bootstrap.rsa']:
            with self.get_admin_remote().open(key_string) as f:
                keys.append(RSAKey.from_private_key(f))

        return SSHClient(ip,
                         username=settings.SSH_CREDENTIALS['login'],
                         password=settings.SSH_CREDENTIALS['password'],
                         private_keys=keys)
def run_ssh_cmd_single(vm, cmd, _async=False, needs_pty=False):
    '''
    sometime /etc/sudoers is configured to require a tty to execute a command with sudo. In this case, set needs_pty to
    True. But if needs_pty is True, you cannot run a command asyncrounously (check if this is really true)
    
    Defaults    !requiretty

    If aysnc is true, return code is 0 and stdout and stderr are both empty strings. That's because the function
    returns before they are available

    :param vm: 
    :param cmd: 
    :param needs_pty: 
    :return: 
    '''

    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        if vm.priv_key:
            pkey = RSAKey.from_private_key(StringIO(
                vm.priv_key))  # assuming it is an RSAKey
            ssh.connect(hostname=vm.ip,
                        port=22,
                        username=vm.username,
                        pkey=pkey)
        else:
            ssh.connect(hostname=vm.ip,
                        port=22,
                        username=vm.username,
                        password=vm.password)

        logger.debug('Executing command on the remote host {0}: {1}'.format(
            vm.benchsuite_name, cmd))
        stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=needs_pty)

        if _async:
            return (0, '', '')

        out = sanitize_output(stdout.read().decode("utf-8"))
        err = sanitize_output(stderr.read().decode("utf-8"))

        exit_status = stdout.channel.recv_exit_status()

        return (exit_status, out, err)

        # chan = ssh.get_transport().open_session()
        # chan.get_pty()
        # chan.exec_command(cmd)
        # print(chan.recv(1024))

    finally:
        ssh.close()
Beispiel #33
0
 def __get_ssh_key(self):
     """Fetch locally stored SSH key."""
     try:
         query_cmd = """SELECT * FROM keys WHERE host='""" + self.host + """'"""
         self.cur.execute(query_cmd)
         key_string = self.cur.fetchone()[1]
         self.key_file_obj = StringIO(key_string)
         self.ssh_key = RSAKey.from_private_key(self.key_file_obj)
     except SSHException as error:
         logger.error(error)
     return self.ssh_key
Beispiel #34
0
    def test_load_rsa(self):
        key = RSAKey.from_private_key_file(_support('test_rsa.key'))
        self.assert_key_values(key, 'ssh-rsa', 1024, PUB_RSA,
                               FINGER_RSA.split()[1], FINGER_SHA256_RSA)

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(RSA_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = RSAKey.from_private_key(s)
        self.assertEqual(key, key2)
Beispiel #35
0
 def __init__(self, miko_param, *args, **kwargs):
     '''
     :param miko_param: 参考paramiko.SSHClient()
     :param args:
     :param kwargs:
     '''
     MyClass.__init__(self, *args, **kwargs)
     # pkey需要转换
     if isinstance(miko_param.get('pkey'), str):
         miko_param['pkey'] = RSAKey.from_private_key(
             StringIO(miko_param['pkey']))
     self.miko_param = miko_param
    def __init__(self,
                 listen_addr="127.0.0.1",
                 port=0,
                 server_key_string=None,
                 user2key=None,
                 user2password=None,
                 fake_device=None,
                 enable_sftp=False,
                 enable_scp=False,
                 *largs,
                 **kwargs):
        """
        SSH server.

        :param listen_addr: str : which local IP to listen on, default 127.0.0.1
        :param port: int : listening port for the SSH server, or 0 to let the
            system choose; if 0 was used, check the .port field for the assigned port
        :param server_key_string: str : private key for the server's identity;
            leave blank to generate
        :param user2key: dict[str, PKey] : mapping from each username to the correct
            public or private PKey
        :param user2password: dict[str, str] : mapping from each username to the
            correct password
        :param fake_device: FakeDevice : an object that responds to commands
        :param enable_sftp: bool : whether to respond to SFTP requests
        :param enable_scp: bool : whether to respond to SCP requests
        :param largs:
        :param kwargs:
        """
        paramiko.ServerInterface.__init__(self)
        self.enable_sftp = enable_sftp
        self.enable_scp = enable_scp
        self.user2key = user2key or {}
        self.user2password = user2password or {}
        self.fake_device = fake_device or DefaultFakeDevice()
        self.server_key = (RSAKey.from_private_key(StringIO(server_key_string))
                           if server_key_string else RSAKey.generate(2048))
        self.reads = {}
        self.filename2stringio = {}
        self.channelid2scpfilename = {}
        self.channelid2subsystem = {}
        self.channels = set()
        self.scpchannelid2command = {}
        self.channelid2event = {}

        self.listensock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listensock.bind((listen_addr, port))
        self.listensock.listen(5)
        self.port = self.listensock.getsockname()[1]

        t = threading.Thread(target=self.sockthread)
        t.setDaemon(True)
        t.start()
 def admin_keys(self):
     """Return list with private ssh keys from Fuel master node"""
     if self._admin_keys is None:
         self._admin_keys = []
         with SSHClient(host=self.admin_ip,
                        username=self.ssh_login,
                        password=self.ssh_password) as remote:
             for path in ['/root/.ssh/id_rsa',
                          '/root/.ssh/bootstrap.rsa']:
                 with remote.open(path) as f:
                     self._admin_keys.append(RSAKey.from_private_key(f))
     return self._admin_keys
Beispiel #38
0
    def connect(self):
        self.transport = None
        try:
            key = RSAKey.from_private_key(StringIO(self.key))
        except SSHException:
            raise CommunicationError("Bad RSA key!")

        sock = socket(AF_INET, SOCK_STREAM)
        try:
            sock.connect((self.host, self.port))
        except (error, gaierror, timeout), e:
            raise CommunicationError(e)
Beispiel #39
0
    def connect(self, node, attempts=5):
        """Connect to node prior to running exec_command or scp.

        If there already is a connection to the node, this method reuses it.

        :param node: Node in topology.
        :param attempts: Number of reconnect attempts.
        :type node: dict
        :type attempts: int
        :raises IOError: If cannot connect to host.
        """
        self._node = node
        node_hash = self._node_hash(node)
        if node_hash in SSH.__existing_connections:
            self._ssh = SSH.__existing_connections[node_hash]
            if self._ssh.get_transport().is_active():
                logger.debug(f"Reusing SSH: {self._ssh}")
            else:
                if attempts > 0:
                    self._reconnect(attempts-1)
                else:
                    raise IOError(f"Cannot connect to {node['host']}")
        else:
            try:
                start = time()
                pkey = None
                if u"priv_key" in node:
                    pkey = RSAKey.from_private_key(StringIO(node[u"priv_key"]))

                self._ssh = SSHClient()
                self._ssh.set_missing_host_key_policy(AutoAddPolicy())

                self._ssh.connect(
                    node[u"host"], username=node[u"username"],
                    password=node.get(u"password"), pkey=pkey,
                    port=node[u"port"]
                )

                self._ssh.get_transport().set_keepalive(10)

                SSH.__existing_connections[node_hash] = self._ssh
                logger.debug(
                    f"New SSH to {self._ssh.get_transport().getpeername()} "
                    f"took {time() - start} seconds: {self._ssh}"
                )
            except SSHException as exc:
                raise IOError(f"Cannot connect to {node[u'host']}") from exc
            except NoValidConnectionsError as err:
                raise IOError(
                    f"Unable to connect to port {node[u'port']} on "
                    f"{node[u'host']}"
                ) from err
Beispiel #40
0
 def load_from_file(self, credentials_path):
     """ Recovers SSHCredentials object from disk file
         * credentials_path (**str**): Path to packed credentials file.
     """
     try:
         file = open(credentials_path, 'rb')
         data = pickle.load(file)
     except IOError as err:
         sys.exit(err)
     self.host = data['host']
     self.userid = data['userid']
     self.look_for_keys = data['look_for_keys']
     self.key = RSAKey.from_private_key(StringIO(data['data'].getvalue()))
Beispiel #41
0
 def start(self):
     """Registers a tunnel with a boring proxy api and starts an ssh tunnel"""
     tunnel_info = self.__register_tunnel__()
     ssh_pkey = RSAKey.from_private_key(
         StringIO(tunnel_info["tunnel_private_key"]))
     super().__init__(hostname=tunnel_info["server_address"],
                      port=tunnel_info["server_port"],
                      username=tunnel_info["username"],
                      pkey=ssh_pkey,
                      server_port=tunnel_info["tunnel_port"],
                      remote_host=self.__client_addr__,
                      remote_port=self.__client_port__)
     super(Tunnel, self).start()
Beispiel #42
0
    def test_load_rsa(self):
        key = RSAKey.from_private_key_file(_support("test_rsa.key"))
        self.assertEqual("ssh-rsa", key.get_name())
        self.assert_key_fingerprints(key, FINGER_RSA)
        self.assertEqual(PUB_RSA.split()[1], key.get_base64())
        self.assertEqual(1024, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(RSA_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = RSAKey.from_private_key(s)
        self.assertEqual(key, key2)
Beispiel #43
0
    def _get_ssh_key(self):
        """Retorna la ssh key para la coneción.

        Returns
        -------
        PKey
            Objeto PKey de paramiko.
        """
        f = open(self.ssh_key, 'r')
        s = f.read()
        keyfile = StringIO(s)
        pkey = RSAKey.from_private_key(keyfile, password=self.password)
        return pkey
Beispiel #44
0
 def __init__(self, host, username, password=None, timeout=300, pkey=None,
              channel_timeout=10, look_for_keys=False, key_filename=None):
     self.host = host
     self.username = username
     self.password = password
     if isinstance(pkey, basestring):
         pkey = RSAKey.from_private_key(StringIO(str(pkey)))
     self.pkey = pkey
     self.look_for_keys = look_for_keys
     self.key_filename = key_filename
     self.timeout = int(timeout)
     self.channel_timeout = float(channel_timeout)
     self.buf_size = 1024
Beispiel #45
0
    def test_2_load_rsa(self):
        key = RSAKey.from_private_key_file('tests/test_rsa.key')
        self.assertEquals('ssh-rsa', key.get_name())
        exp_rsa = FINGER_RSA.split()[1].replace(':', '')
        my_rsa = hexlify(key.get_fingerprint())
        self.assertEquals(exp_rsa, my_rsa)
        self.assertEquals(PUB_RSA.split()[1], key.get_base64())
        self.assertEquals(1024, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEquals(RSA_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = RSAKey.from_private_key(s)
        self.assertEquals(key, key2)
Beispiel #46
0
    def test_2_load_rsa(self):
        key = RSAKey.from_private_key_file(_support("test_rsa.key"))
        self.assertEqual("ssh-rsa", key.get_name())
        exp_rsa = b(FINGER_RSA.split()[1].replace(":", ""))
        my_rsa = hexlify(key.get_fingerprint())
        self.assertEqual(exp_rsa, my_rsa)
        self.assertEqual(PUB_RSA.split()[1], key.get_base64())
        self.assertEqual(1024, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(RSA_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = RSAKey.from_private_key(s)
        self.assertEqual(key, key2)
Beispiel #47
0
    def setup(self):
        LOG.debug('Doing key exchange between %s and %s', self.api.address,
                  self.device.get_address())
        sftp = self.api.sftp()

        # Currently works only with RSA keys (v1)
        f = sftp.open(KeyExchange.IDENTITY_SSH1)
        pk = RSAKey.from_private_key(f)
        with SSHInterface(device=self.device) as sshifc:
            sshifc.api.exchange_key(key=pk, name=self.api.address)

        # Make sure known_hosts is updated
        self.api.run('ssh-keygen -R %s' % self.address)
        self.api.run('ssh -n -o StrictHostKeyChecking=no root@%s /bin/true' % 
                     self.address)
Beispiel #48
0
 def paramiko_connect():
     ssh = client.SSHClient()
     ssh.set_missing_host_key_policy(client.AutoAddPolicy())
     if not form.get('hostname', None):
         return flash_error("Hostname required.")
     else:
         hostname = form['hostname']
     if not form.get('username', None):
         username = None
     else:
         username = form['username']
     if not form.get('port', None):
         port = 22
     else:
         port = int(form.get('port'))
     if not form.get('password', None):
         password = None
     else:
         password = form['password']
     if not request.files.get('keypath', None):
         keypath = None
     else:
         file = request.files['keypath']
         file = io.StringIO(file.read().decode('utf-8'))
         try:
             keypath = RSAKey.from_private_key(file, password)
         except IOError:
             return flash_error("There was an error reading the key.")
         except ssh_exception.PasswordRequiredException:
             return flash_error("The private key file is encrypted, and password is None")
         except ssh_exception.SSHException:
             return flash_error("The key file is invalid.")
     try:
         ssh.connect(hostname=hostname, port=port, username=username, pkey=keypath, password=password)
     except ssh_exception.BadHostKeyException:
         return flash_error("The server’s host key could not be verified")
     except ssh_exception.AuthenticationException:
         return flash_error("Authentication failed")
     except ssh_exception.SSHException:
         return flash_error("There was an error connecting or establishing an SSH session")
     except socket.error:
         return flash_error("There was a socket error while trying to connect.")
     id = add_connection(ssh)
     session['shell'] = id
     return render_template('shell.html', stdin=None, stdout=None, log=log)
Beispiel #49
0
    def get_ssh_to_remote(self, ip,
                          login=settings.SSH_SLAVE_CREDENTIALS['login'],
                          password=settings.SSH_SLAVE_CREDENTIALS['password']):
        warn('LEGACY,  for fuel-qa compatibility', DeprecationWarning)
        keys = []
        remote = self.get_admin_remote()
        for key_string in ['/root/.ssh/id_rsa',
                           '/root/.ssh/bootstrap.rsa']:
            if remote.isfile(key_string):
                with remote.open(key_string) as f:
                    keys.append(RSAKey.from_private_key(f))

        return SSHClient(
            ip,
            auth=SSHAuth(
                username=login,
                password=password,
                keys=keys))
Beispiel #50
0
def get_freenas_peer_client(parent, remote):
    try:
        address = socket.gethostbyname(remote)
    except socket.error as err:
        raise TaskException(err.errno, '{0} is unreachable'.format(remote))

    host = parent.dispatcher.call_sync(
        'peer.query', [
            ('or', [
                ('credentials.address', '=', remote),
                ('credentials.address', '=', address),
            ]),
            ('type', '=', 'freenas')
        ],
        {'single': True}
    )
    if not host:
        raise TaskException(errno.ENOENT, 'There are no known keys to connect to {0}'.format(remote))

    with io.StringIO() as f:
        f.write(parent.configstore.get('peer.freenas.key.private'))
        f.seek(0)
        pkey = RSAKey.from_private_key(f)

    credentials = host['credentials']

    try:
        client = Client()
        with tempfile.NamedTemporaryFile('w') as host_key_file:
            host_key_file.write(remote + ' ' + credentials['hostkey'])
            host_key_file.flush()
            client.connect(
                'ws+ssh://freenas@{0}'.format(wrap_address(remote)),
                port=credentials['port'],
                host_key_file=host_key_file.name,
                pkey=pkey
            )
        client.login_service('replicator')
        return client

    except (AuthenticationException, SSHException):
        raise TaskException(errno.EAUTH, 'Cannot connect to {0}'.format(remote))
    except OSError as err:
        raise TaskException(errno.ECONNREFUSED, 'Cannot connect to {0}: {1}'.format(remote, err))
Beispiel #51
0
def start_server(host=None, port=None, keyfile=None):
    '''
    The SFTP_HOST_KEY setting is required for configuring SFTP access.
    The SFTP_PORT setting defaults to 2200.

    See: tardis/default_settings/sftp.py
    '''
    if host is None:
        current_site = Site.objects.get_current()
        host = current_site.domain
    port = port or getattr(settings, 'SFTP_PORT', 2200)
    host_key_string = settings.SFTP_HOST_KEY
    host_key = RSAKey.from_private_key(
        keyfile or BytesIO(host_key_string))
    server = MyTSFTPTCPServer((host, port), host_key=host_key)
    try:
        server.serve_forever()
    except (SystemExit, KeyboardInterrupt):
        server.server_close()
Beispiel #52
0
    def connect(self, instance, tag_ssh_user, tag_ssh_port, cmd):
        """
        execute a command on instance with ssh and return if cmd param is not None
        connect to ssh if cmd is None
        :param instance:
        :param tag_ssh_user:
        :param tag_ssh_port:
        :param cmd: execute this command if not None
        :return:
        """
        ssh_user = SergentSsh.get_ssh_user(instance, tag_ssh_user)
        ssh_port = SergentSsh.get_ssh_port(instance, tag_ssh_port)

        if self._using_vpn is True:
            ssh_ip = instance.private_ip_address
        else:
            ssh_ip = instance.ip_address

        client = SSHClient()
        client.set_missing_host_key_policy(AutoAddPolicy())

        logger.debug('connecting to %s with port %s and user %s', ssh_ip, ssh_port, ssh_user)
        mykey = RSAKey.from_private_key(self._key_file)

        client.connect(hostname=ssh_ip, port=ssh_port, username=ssh_user, pkey=mykey)

        if cmd is None:
            with NamedTemporaryFile(mode='w+') as tmp_key_file:
                mykey.write_private_key(tmp_key_file, password=None)
                tmp_key_file.flush()
                cmd = 'ssh -i %s %s@%s -p %s' % (tmp_key_file.name, ssh_user, ssh_ip, ssh_port)
                logger.debug(cmd)
                os.system(cmd)
        else:
            stdin, stdout, stderr = client.exec_command(command=cmd)
            out_str = stdout.read()
            out_err = stderr.read().strip(' \t\n\r')
            print(out_str)
            if out_err != '':
                print(out_err)
                sys.exit(1)
 def connect(self):
   """ Get a handle to a remote connection """
   # Check URL
   schema = urlparse(self.url)
   if schema.scheme == 'sftp':
     self.transport = Transport((schema.hostname, int(schema.port)))
   else:
     raise SFTPError('Not a valid sftp url %s, type is %s' %(self.url, schema.scheme))
   # Add authentication to transport
   try:
     if self.password:
       self.transport.connect(username=self.user_name, password=self.password)
     elif self.private_key:
       self.transport.connect(username=self.user_name,
                              pkey=RSAKey.from_private_key(StringIO(self.private_key)))
     else:
       raise SFTPError("No password or private_key defined")
     # Connect
     self.conn = SFTPClient.from_transport(self.transport)
   except (socket.gaierror,error), msg:
     raise SFTPError(str(msg) + ' while establishing connection to %s' % (self.url,))
Beispiel #54
0
 def connect(self):
   """ Get a handle to a remote connection """
   # Check URL
   schema = urlparse(self.url)
   if schema.scheme == 'sftp':
     hostname = schema.hostname
     port = int(schema.port)
     # Socket creation code inspired from paramiko.Transport.__init__
     # with added bind support.
     for family, socktype, _, _, _ in getaddrinfo(
           hostname, port, AF_UNSPEC, SOCK_STREAM,
         ):
       if socktype == SOCK_STREAM:
         sock = socket(family, SOCK_STREAM)
         if self.bind_address:
           # XXX: Expects bind address to be of same family as hostname.
           # May not be easy if name resolution is involved.
           # Try to reconciliate them ?
           sock.bind((self.bind_address, 0))
         retry_on_signal(lambda: sock.connect((hostname, port)))
         break
     else:
       raise SFTPError('No suitable socket family found')
     self.transport = Transport(sock)
   else:
     raise SFTPError('Not a valid sftp url %s, type is %s' %(self.url, schema.scheme))
   # Add authentication to transport
   try:
     if self.password:
       self.transport.connect(username=self.user_name, password=self.password)
     elif self.private_key:
       self.transport.connect(username=self.user_name,
                              pkey=RSAKey.from_private_key(StringIO(self.private_key)))
     else:
       raise SFTPError("No password or private_key defined")
     # Connect
     self.conn = SFTPClient.from_transport(self.transport)
   except (gaierror, error), msg:
     raise SFTPError(str(msg) + ' while establishing connection to %s' % (self.url,))
Beispiel #55
0
    def playbook_on_play_start(self, name):
        play_vars = merge_hash(self.play.vars,
                               getattr(self.play, 'vars_file_vars', {}))
        play_vars = merge_hash(play_vars,
                               getattr(self.playbook, 'extra_vars', {}))
        pem = play_vars.get('creds_ssh_private_key', None)
        if pem is None: return
        key = RSAKey.from_private_key(StringIO.StringIO(pem))

        hexdigest = unpack('16B', key.get_fingerprint())
        hexdigest = ':'.join(['%02x' % x for x in hexdigest])
        display('Loading SSH private key %s' % hexdigest)

        pub = '%s %s %s' % (key.get_name(), key.get_base64(), self.KEY_COMMENT)
        for x in self.play.tasks() + self.play.handlers():
            y = getattr(x, 'module_vars', None)
            if y: y['creds_ssh_public_key'] = pub

        ssh_agent = play_vars.get('creds_ssh_agent', True)
        if not ssh_agent: return

        msg = Message()
        msg.add_byte(chr(self.SSH2_AGENTC_ADD_IDENTITY))
        msg.add_string(key.get_name())
        msg.add_mpint(key.n)
        msg.add_mpint(key.e)
        msg.add_mpint(key.d)
        msg.add_mpint(0)
        msg.add_mpint(key.p)
        msg.add_mpint(key.q)
        msg.add_string(self.KEY_COMMENT)

        agent = Agent()
        if agent._conn:
            agent._send_message(msg)
        else:
            warning('Failed to connect to ssh-agent')
        agent.close()
Beispiel #56
0
def sign_certificate(credential, token, url):
    """
    An interface to the OAuth2 SSH certificate signing service
    @type credential: models.Credential
    """
    key_type = credential.key.get_name()
    key_data = credential.key.get_base64()
    headers = {'Authorization': 'Bearer ' + token}
    payload = {'public_key': key_type + ' ' + key_data}

    # TODO: remote verify=False
    r = requests.post(
        url,
        headers=headers,
        data=json.dumps(payload),
        verify=False)
    cert_response = json.loads(r.text)
    if 'certificate' not in cert_response:
        return False

    # Ignore the certificate comment field
    remote_user_name = cert_response['user']
    cert_type, cert_data = cert_response['certificate'].split()[0:2]
    if cert_type != '*****@*****.**':
        return False  # We only support this certificate type at the moment

    old_key = credential.key
    private_key = StringIO()
    old_key.write_private_key(private_key)
    private_key.seek(0)
    cert = RSAKey.from_private_key(private_key)
    cert.load_certificate(Message(base64.b64decode(cert_data)))
    credential.key = cert
    credential.remote_user = remote_user_name
    credential.save()
    return True
Beispiel #57
0
    def build_pkey(self, private):
        from paramiko import RSAKey

        keyfile = StringIO(private)
        key = mykey = RSAKey.from_private_key(keyfile)
        return key
Beispiel #58
0
    def run(self, peer, initial_credentials):
        hostid = self.dispatcher.call_sync('system.info.host_uuid')
        hostname = self.dispatcher.call_sync('system.general.get_config')['hostname']
        remote_peer_name = hostname
        credentials = peer['credentials']
        remote = credentials.get('address')
        port = credentials.get('port', 22)
        username = initial_credentials.get('username')
        password = initial_credentials.get('password')
        auth_code = initial_credentials.get('auth_code')
        key_auth = initial_credentials.get('key_auth')

        local_ssh_config = self.dispatcher.call_sync('service.sshd.get_config')

        if self.datastore.exists('peers', ('credentials.address', '=', remote), ('type', '=', 'freenas')):
            raise TaskException(
                errno.EEXIST,
                'FreeNAS peer entry for {0} already exists'.format(remote)
            )

        remote_client = Client()

        try:
            if auth_code:
                try:
                    remote_client.connect('ws://{0}'.format(wrap_address(remote)))
                except (AuthenticationException, OSError, ConnectionRefusedError):
                    raise TaskException(errno.ECONNABORTED, 'Cannot connect to {0}:{1}'.format(remote, port))

                try:
                    remote_host_uuid, pubkey = remote_client.call_sync(
                        'peer.freenas.auth_with_code',
                        auth_code,
                        hostname,
                        local_ssh_config['port']
                    )
                except RpcException as err:
                    raise TaskException(err.code, err.message)

                try:
                    self.dispatcher.call_sync('peer.freenas.put_temp_pubkey', pubkey)
                    if not self.dispatcher.test_or_wait_for_event(
                        'peer.changed',
                        lambda ar: ar['operation'] == 'create' and remote_host_uuid in ar['ids'],
                        lambda: self.datastore.exists('peers', ('id', '=', remote_host_uuid)),
                        timeout=30
                    ):
                        raise TaskException(
                            errno.EAUTH,
                            'FreeNAS peer creation failed. Check connection to host {0}.'.format(remote)
                        )
                finally:
                    self.dispatcher.call_sync('peer.freenas.remove_temp_pubkey', pubkey)

            else:
                try:
                    if key_auth:
                        with io.StringIO() as f:
                            f.write(self.configstore.get('peer.freenas.key.private'))
                            f.seek(0)
                            pkey = RSAKey.from_private_key(f)

                        max_tries = 50
                        while True:
                            try:
                                remote_client.connect('ws+ssh://freenas@{0}'.format(
                                    wrap_address(remote)), pkey=pkey, port=port
                                )
                                break
                            except AuthenticationException:
                                if max_tries:
                                    max_tries -= 1
                                    time.sleep(1)
                                else:
                                    raise
                    else:
                        remote_client.connect(
                            'ws+ssh://{0}@{1}'.format(username, wrap_address(remote)),
                            port=port,
                            password=password
                        )

                    remote_client.login_service('replicator')
                except (AuthenticationException, OSError, ConnectionRefusedError):
                    raise TaskException(errno.ECONNABORTED, 'Cannot connect to {0}:{1}'.format(remote, port))

                local_host_key, local_pub_key = self.dispatcher.call_sync('peer.freenas.get_ssh_keys')
                remote_host_key, remote_pub_key = remote_client.call_sync('peer.freenas.get_ssh_keys')
                ip_at_remote_side = remote_client.local_address[0]

                remote_hostname = remote_client.call_sync('system.general.get_config')['hostname']

                remote_host_key = remote_host_key.rsplit(' ', 1)[0]
                local_host_key = local_host_key.rsplit(' ', 1)[0]

                if remote_client.call_sync('peer.query', [('id', '=', hostid)]):
                    raise TaskException(errno.EEXIST, 'Peer entry of {0} already exists at {1}'.format(hostname, remote))

                peer['credentials'] = {
                    '%type': 'freenas-credentials',
                    'pubkey': remote_pub_key,
                    'hostkey': remote_host_key,
                    'port': port,
                    'address': remote_hostname
                }

                local_id = remote_client.call_sync('system.info.host_uuid')
                peer['id'] = local_id
                peer['name'] = remote_hostname
                ip = socket.gethostbyname(remote)

                created_id = self.run_subtask_sync(
                    'peer.freenas.create_local',
                    peer,
                    ip,
                    True
                )

                peer['id'] = hostid
                peer['name'] = remote_peer_name
                peer['credentials'] = {
                    '%type': 'freenas-credentials',
                    'pubkey': local_pub_key,
                    'hostkey': local_host_key,
                    'port': local_ssh_config['port'],
                    'address': hostname
                }

                try:
                    call_task_and_check_state(
                        remote_client,
                        'peer.freenas.create_local',
                        peer,
                        ip_at_remote_side
                    )
                except TaskException:
                    self.datastore.delete('peers', local_id)
                    self.dispatcher.dispatch_event('peer.changed', {
                        'operation': 'delete',
                        'ids': [local_id]
                    })
                    raise

                return created_id
        finally:
            remote_client.disconnect()
Beispiel #59
0
    def apply_config(self, user, timestamp, passphrase):

        """ Apply the configuration

        This will check the Affectedlog and generates proper authorized_keys
         file for each host affected.

        """

        retval = {
            "status": "success",
            "ssh_messages": []
        }

        # Add note about that.

        ActionLog(
            timestamp=timestamp,
            user=user,
            action="APPLY"
        ).save()

        # Do some initialisation

        affected_hosts = self.all()

        public_key = Configuration.objects.get(
            key="sshkey_public"
        )

        private_key_config = Configuration.objects.get(
            key="sshkey_private"
        )

        keytype = Configuration.objects.get(
            key="sshkey_type"
        )

        if not public_key or not private_key_config or not keytype:
            raise _("Invalid configuration. Did you run setup already?")

        if passphrase == "":
            passphrase = None

        private_key = None

        try:

            # Generate private key to use

            private_key_file = StringIO.StringIO(
                str(private_key_config.value)
            )

            if keytype.value == "dsa":

                # noinspection PyTypeChecker
                private_key = DSSKey.from_private_key(
                    private_key_file, passphrase
                )

            else:

                # noinspection PyTypeChecker
                private_key = RSAKey.from_private_key(
                    private_key_file, passphrase
                )

            private_key_file.close()

        except SSHException:

            retval['ssh_messages'].append(_(
                "Cannot open skd private key. Perhaps you specified the "
                "wrong passphrase?"
            ))

            retval['status'] = "error"

        hosts_applied = []

        if private_key:

            client = SSHClient()
            client.load_system_host_keys()
            client.set_missing_host_key_policy(AutoAddPolicy)

            for apply_line in affected_hosts:

                host = apply_line.host

                if host in hosts_applied:
                    continue

                workload = []

                # Find all users, that have access to this host.

                user_keys = UserKey.objects.filter(
                    **{
                        "user__useringroup__group__"
                        "usergroupinhostgroup__hostgroup__"
                        "hostingroup__host__id": host.id
                    }
                )

                if not user_keys:

                    # This seems to be an old entry. Obviously, no one
                    # has access to the host anymore. Skip it.

                    hosts_applied.append(host)
                    retval['ssh_messages'].append(
                        _(
                            "Removing seemingly orphaned host %(host)s "
                            "from workload" %
                            {
                                'host': host.name
                            }
                        )
                    )
                    continue

                if host.user == '*':
                    # This host is a wildcard host.

                    # Build up workload using the usernames of the
                    # assigned users and include optional username mappings

                    assigned_users = User.objects.filter(
                        **{
                            "useringroup__group__usergroupinhostgroup__"
                            "hostgroup__hostingroup__host__id": host.id
                        }
                    )

                    for assigned_user in assigned_users:

                        namemaps = UserMap.objects.filter(
                            user=assigned_user,
                            host=host
                        )

                        assigned_username = assigned_user.name

                        if namemaps:

                            assigned_username = namemaps[0].username

                        # Find all users, that also share this username,
                        # either inside their user data or via a username
                        # mapping.

                        # Namemaps

                        all_users = []

                        same_namemap = UserMap.objects.filter(
                            host=host,
                            username=assigned_username
                        )

                        for mapping in same_namemap:
                            all_users.append(mapping.user)

                        # User data

                        same_users = User.objects.filter(
                            **{
                                "name": assigned_username,
                                "useringroup__group__"
                                "usergroupinhostgroup__hostgroup__"
                                "hostingroup__host__id": host.id
                            }
                        )

                        for found_user in same_users:
                            all_users.append(found_user)

                        user_keys = UserKey.objects.filter(
                            user__in=all_users
                        )

                        workload.append(
                            {
                                'host': host,
                                'user': assigned_username,
                                'user_keys': user_keys
                            }
                        )

                else:

                    # No wildcard host, just us.

                    workload = [
                        {
                            'host': host,
                            'user': host.user,
                            'user_keys': user_keys
                        }
                    ]

                error_in_workload = False

                for step in workload:

                    # Build up authorized_keys-filecontent

                    authorized_keys = []

                    for key in user_keys:
                        authorized_keys.append("# %s (%s)" % (
                            key.user.fullname,
                            key.name
                        ))
                        authorized_keys.append(key.key)

                    # Add our own public key to the keys

                    authorized_keys.append("# Generated by skd")
                    authorized_keys.append(
                        public_key.value
                    )

                    # Connect to the server

                    is_connected = False

                    try:

                        client.connect(
                            hostname=str(step['host'].fqdn),
                            username=str(step['user']),
                            pkey=private_key
                        )

                        is_connected = True

                    except AuthenticationException:

                        retval['ssh_messages'].append(_(
                            "Cannot connect to host %(name)s as user "
                            "%(user)s. Perhaps the skd-key hasn't  been "
                            "added to it's authorized_keys-file" %
                            {
                                "name": step['host'].name,
                                "user": step['user']
                            }
                        ))

                        retval['status'] = "error"

                    except (SSHException, socket.error, socket.gaierror):

                        retval['ssh_messages'].append(_(
                            "System failure connecting to SSH host "
                            "%(host)s as user %(user)s: %(error)s" %
                            {
                                "error": sys.exc_info()[1],
                                "host": step['host'].name,
                                "user": step['user']
                            }
                        ))

                        retval['status'] = "error"

                    if is_connected:

                        try:

                            # Deploy the authorized_keys file onto the
                            # server.

                            def noAscii(k):
                                return ''.join(
                                    [x for x in k if ord(x) < 128]
                                )

                            command = 'echo -e "%s" > ~/' \
                                      '.ssh/authorized_keys' % \
                                      (
                                          noAscii(
                                              "\n".join(authorized_keys)
                                          )
                                      )

                            client.exec_command(command=command)

                            retval['ssh_messages'].append(_(
                                "Host %(host)s with user %(user)s "
                                "completed." %
                                {
                                    "host": step['host'].name,
                                    "user": step['user']
                                }
                            ))

                        except SSHException:

                            retval['ssh_messages'].append(_(
                                "Error deploying the authorized_keys-file "
                                "of host %(host)s / user %(user)s: "
                                "%(error)s" %
                                {
                                    "error": sys.exc_info()[1],
                                    "host": host.name,
                                    "user": host.user
                                }
                            ))

                            retval['status'] = "error"

                            error_in_workload = True

                        if not error_in_workload:

                            # All went well, delete host from apply-Log.

                            hosts_applied.append(host)

                        client.close()

            # Remove succesful hosts from applylog

            self.filter(host__in=hosts_applied).delete()

        return retval
Beispiel #60
0
 def get_private_keys(self):
     keys = []
     for key_string in ['/root/.ssh/id_rsa', '/root/.ssh/bootstrap.rsa']:
         with self.remote().open(key_string) as f:
             keys.append(RSAKey.from_private_key(f))
     return keys