Пример #1
0
def check_ssh_up(host, port):
    """
    Return True if SSH connectivity exists.

    First checks if port is open, then tries to see if it response to SSH connectivity.
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(2)
        try:
            s.connect((host, port))
        except socket.error as e:
            if e.errno in (61,):
                return False
            else:
                raise
        else:
            # Basic connectivity works, try SSH
            t = Transport(s)
            # Shut up paramiko logging
            plog = logging.getLogger('paramiko.transport')
            plog.disabled = True
            try:
                t.start_client()
                return True
            except paramiko.SSHException as e:
                return False
            finally:
                t.close()
                s.close()
                plog.disabled = False
    except Exception as e:
        raise SshError('Error while checking %s:%d for SSH: %s' % (host, port, e))
Пример #2
0
class RepoWriteLock:
    def __init__(self, url):
        self.url = url
        self.transport = None
        self.client = None
        self.socket = socket()

    def __enter__(self):
        self.socket.connect((interpret_urlish(self.url)[1], 22))
        self.transport = Transport(self.socket)
        self.transport.start_client()
        authenticate_transport(self.transport)
        self.client = self.transport.open_sftp_client()
        self.client.chdir(interpret_urlish(self.url)[2])

        self._lock()

    def _lock(self):
        target_locks = self.client.listdir("locks")
        target_locks.sort()

        if target_locks:
            raise RuntimeError("repo is locked; try again later")
        else:
            self.client.mkdir("locks/write_lock")

    def _unlock(self):
        self.client.rmdir("locks/write_lock")

    def __exit__(self, *args):
        self._unlock()

        self.client.close()
        self.transport.close()
        self.socket.close()
Пример #3
0
def restore(path):

    dbinfo = choicedb(path+'/conf/db_info.yaml')
    editData(dbinfo, [['reset master;']])
    if sys.platform == 'win32':
        t = Transport(dbinfo[0], 22)
        t.connect(username=dbinfo[5], password=dbinfo[6])
        sftp = SFTPClient.from_transport(t)
        src = '/home/mysql/basedata/initdata.sql'
        des = path + '/database/initdata.sql'
        sftp.put(des,src )
        t.close()
    else:
        child = spawn(
            'scp '+path+'/database/initdata.sql '+ dbinfo[5]+'@'+dbinfo[0]+':/home/mysql/basedata/')
        child.expect("password:"******"'"+dbinfo[3]+"'"' '+dbinfo[4]+' </home/mysql/basedata/initdata.sql')
    return stderr.read().decode('gbk', errors='ignore')
Пример #4
0
def dbbackup(path):
    dbinfo = choicedb(path + '/conf/db_info.yaml')
    s = sshconnect(hostname=dbinfo[0], port=dbinfo[7], username=dbinfo[5], password=dbinfo[6])
    st, std, stde = s.exec_command('cd /home/mysql/backup'+'\n' 'ls')
    filelist = std.read().decode('gbk',errors='ignore').split('\n')
    if 'databackup.sql' in filelist:
        s.exec_command('cd /home/mysql/backup'+'\n' 'rm -rf databackup1.sql')
    stdin, stdout, stderr = s.exec_command('mysqldump -t -u'+dbinfo[2]+' -p'+dbinfo[3]+' '+dbinfo[4]+' >/home/mysql/backup/databackup.sql')
    if 'error' not in stderr.read().decode('gbk', errors='ignore'):
        t1,t2,t3=s.exec_command('du -b /home/mysql/databackup.sql')
        if sys.platform == 'win32':
            t = Transport(dbinfo[0], 22)
            t.connect(username=dbinfo[5], password=dbinfo[6])
            sftp = SFTPClient.from_transport(t)
            src = '/home/mysql/backup/databackup.sql'
            des = path + '/database/databackup.sql'
            sftp.get(src, des)
            t.close()
        else:
            child = spawn(
                'scp ' + dbinfo[5] + '@' + dbinfo[0] + ':/home/mysql/backup/databackup.sql ' + path + '/database/')
            child.expect("password:")
            child.sendline(dbinfo[6])
            child.read()
        with zipfile.ZipFile(path + '/database/backupdatabase.zip', 'w') as z:
            z.write(path + '/database/databackup.sql')
        return t2.read().decode('gbk',errors='ignore').split('\t')[0].strip()
    else:
        return False
    s.close
Пример #5
0
def fx_authorized_sftp(fx_sftpd, fx_authorized_keys):
    port, (thread, path, ev) = fx_sftpd.popitem()
    thread.start()
    key = RSAKey.generate(1024)
    dot_ssh = path.mkdir('.ssh')
    with dot_ssh.join('authorized_keys').open('w') as f:
        print(format_openssh_pubkey(key), file=f)
        for authorized_key in fx_authorized_keys:
            print(format_openssh_pubkey(authorized_key), file=f)
    transport = Transport(('127.0.0.1', port))
    transport.connect(username='******', pkey=key)
    sftp_client = SFTPClient.from_transport(transport)
    yield sftp_client, path, [key] + fx_authorized_keys
    sftp_client.close()
    transport.close()
Пример #6
0
def authorize(public_keys: collections.abc.Set,
              master_key: PKey,
              remote: Remote,
              timeout: datetime.timedelta) -> datetime.datetime:
    """Make an one-time authorization to the ``remote``, and then revokes
    it when ``timeout`` reaches soon.

    :param public_keys: the set of public keys (:class:`paramiko.pkey.PKey`)
                        to authorize
    :type public_keys: :class:`collections.abc.Set`
    :param master_key: the master key (*not owner's key*)
    :type master_key: :class:`paramiko.pkey.PKey`
    :param remote: a remote to grant access permission
    :type remote: :class:`~.remote.Remote`
    :param timeout: the time an authorization keeps alive
    :type timeout: :class:`datetime.timedelta`
    :return: the expiration time
    :rtype: :class:`datetime.datetime`

    """
    transport = Transport((remote.host, remote.port))
    transport.connect(username=remote.user, pkey=master_key)
    try:
        sftp_client = SFTPClient.from_transport(transport)
        try:
            authorized_keys = AuthorizedKeyList(sftp_client)
            authorized_keys.extend(public_keys)
        except:
            sftp_client.close()
            raise
    except:
        transport.close()
        raise

    def rollback():
        time.sleep(timeout.total_seconds())
        authorized_keys[:] = [master_key]
        sftp_client.close()
        transport.close()
    timer = threading.Thread(target=rollback)
    expires_at = datetime.datetime.now(datetime.timezone.utc) + timeout
    timer.start()
    return expires_at
Пример #7
0
def get_host_key(host, port=22):
    logger.debug("Connecting to host %s to get ssh public host key" % host)
    INTERVAL = 15
    MAX_RETRY = 60 / INTERVAL * 5
    c = 0
    while 1:
        try:
            sock = create_connection((host, port))

            transport = Transport(sock)
            transport.start_client()
            key = transport.get_remote_server_key()
            transport.close()
            break
        except error, e:
            if type(e) is timeout:
                log = logger.warn
            else:
                log = logger.error
            log('socket %s: errno=%r, error msg=%s for server %s' % (e.__class__.__name__, e.errno, e.strerror, host))
        except SSHException, e:
            logger.exception("attempt %s - error while attempting to connect to %s" % (c, host))
Пример #8
0
def sftp_push_file(host, user, password, to_, from_):
    """
    上传文件,注意:不支持文件夹
    :param host: 主机名
    :param user: 用户名
    :param password: 密码
    :param from_: 远程路径,比如:/home/sdn/tmp.txt
    :param to_: 本地路径,比如:D:/text.txt
    :param timeout: 超时时间(默认),必须是int类型
    :return: bool
    """
    logging.debug('SSH FILE PUSH')
    try:
        t = Transport((host, 22))
        t.connect(username=user, password=password)
        sftp = paramiko.SFTPClient.from_transport(t)
        sftp.put(to_, from_)
        t.close()
        logging.info('SSH FILE PUSH SUCCESS')
        return True
    except Exception as e:
        logging.error(str(type(e)) + ' ' + e.strerror)
        logging.error('SSH FILE PUSH FAIL')
        return False
Пример #9
0
def get_host_keys(address, port=22, types=None):
    if types is None:
        types = Transport._preferred_keys

    af, sock_type, proto, name, addr = socket.getaddrinfo(
        address, port, 0,0, socket.IPPROTO_TCP)[0]

    keys = []
    for key_type in types:
        try:
            sock = socket.socket(af, sock_type, proto)
            sock.connect(addr)

            t = Transport(sock)
            t.get_security_options().key_types = [key_type]
            t.start_client()
            keys.append(t.get_remote_server_key())
        except Exception:
            pass
        finally:
            t.close()
            sock.close()

    return keys
 def checkUsername(self, username, tried=0):
     sock = socket.socket()
     sock.connect((self.hostname, self.port))
     # instantiate transport
     transport = Transport(sock)
     try:
         transport.start_client()
     except paramiko.ssh_exception.SSHException:
         # server was likely flooded, retry up to 3 times
         transport.close()
         if tried < 4:
             tried += 1
             return self.checkUsername(username, tried)
         else:
             print("[-] Failed to negotiate SSH transport")
     try:
         transport.auth_publickey(username, paramiko.RSAKey.generate(1024))
     except BadUsername:
         return (username, False)
     except paramiko.ssh_exception.AuthenticationException:
         return (username, True)
     #Successful auth(?)
     raise Exception(
         "There was an error. Is this the correct version of OpenSSH?")
Пример #11
0
class Repository:
    def __init__(self, url):
        self.url = url
        self.index = {}

        self.read_lock = RepoReadLock(url)
        self.write_lock = RepoWriteLock(url)

        self.client = None
        self.transport = None
        self.socket = socket()

        self.opened = False

    def open(self):
        """
        Opens the connection
        """

        self.socket.connect((interpret_urlish(self.url)[1], 22))
        self.transport = Transport(self.socket)
        self.transport.start_client()
        authenticate_transport(self.transport)
        self.client = self.transport.open_sftp_client()
        target_path = interpret_urlish(self.url)[2]
        try:
            self.client.stat(target_path)
        except IOError:
            self.client.mkdir(target_path)
        self.client.chdir(target_path)
        self.opened = True

    def close(self):
        """
        Closes the connection
        """

        if not self.opened:
            return
        self.client.close()
        self.transport.close()
        self.socket.close()
        self.opened = False

    def update(self):
        """
        Update the information in this class to match that of the remote.

        Raises exceptions if remote is invalid or in an invalid state
        """

        if not self.opened:
            self.open()

        with self.read_lock:
            with self.client.open("index.json") as f:
                self.index = json.load(f)

    def get_script(self, hname=None):
        """
        Get the script object
        """
        if hname is None:
            hname = self.index["start"]
        return self.index["scripts"][hname]

    def download_script(self, hname=None):
        if hname is None:
            hname = self.index["start"]
        with self.read_lock:
            with self.client.open("scripts/" + hname + ".py", "r") as f:
                return f.read()

    def get_revision(self):
        return self.index["revision"]

    def append_script(self, script_obj, script_contents):
        h = sha512()
        h.update(script_contents.encode("utf-7"))
        hname = h.hexdigest()
        script_obj["prev"] = self.index["end"]

        with self.write_lock:
            self.index["revision"] += 1
            if self.index["end"]:
                self.index["scripts"][self.index["end"]]["next"] = hname
            self.index["end"] = hname
            self.index["scripts"][hname] = script_obj

            if self.index["start"] == "":
                self.index["start"] = hname

            self._write()
            with self.client.open("scripts/" + hname + ".py", "w") as f:
                f.write(script_contents)

    def _write(self):
        with self.client.open("index.json", "w") as f:
            json.dump(self.index, f)

    def write(self):
        with self.write_lock:
            self._write()

    def __iter__(self):
        return FollowChainIterator(self, self.index["start"])

    def iterate_from(self, pos):
        return FollowChainIterator(self, pos)

    def new(self):
        if not self.opened:
            self.open()

        try:
            self.client.stat("index.json")
            raise RuntimeError(
                "already init-ed, manually delete the folder to re-init")
        except IOError:
            pass

        # create the skeleton fs
        self.client.mkdir("locks")
        self.client.mkdir("scripts")

        # create a basic index.json
        self.index = {
            "version": 1,
            "revision": 0,
            "start": "",
            "end": "",
            "scripts": {}
        }

        self.write()
Пример #12
0
class Communicator(drm4g.communicators.Communicator):
    """
    Create a SSH session to remote resources.
    """
    _lock = __import__('threading').Lock()
    _sem = __import__('threading').Semaphore(SFTP_CONNECTIONS)
    _trans = None

    def connect(self):
        try:
            with self._lock:
                if not self._trans or not self._trans.is_authenticated():
                    logger.debug("Opening ssh connection ... ")
                    keys = None
                    logger.debug("Trying ssh-agent ... ")
                    drm4g_agent = drm4g.commands.Agent()
                    drm4g_agent.start()
                    drm4g_agent.update_agent_env()
                    # paramiko agent
                    agent = Agent()
                    keys = agent.get_keys()
                    if not keys:
                        logger.debug("Error trying to connect to '%s'" %
                                     self.frontend)
                        logger.debug(
                            "Impossible to load '%s' key from the ssh-agent" %
                            self.private_key)
                        try:
                            status_ssh_agent = agent._conn
                        except Exception as err:
                            logger.warning(
                                "Probably you are using paramiko version <= 1.7.7.2 : %s "
                                % err)
                            status_ssh_agent = agent.conn
                        if not status_ssh_agent:
                            logger.warning("'ssh-agent' is not running")
                        else:
                            if agent.get_keys():
                                logger.warning(
                                    "ssh-agent is running but none of the keys have been accepted"
                                    "by remote frontend %s." % self.frontend)
                            else:
                                logger.debug(
                                    "'ssh-agent' is running but without any keys"
                                )
                    if self.private_key:
                        logger.debug("Trying '%s' key ... " % self.private_key)
                        private_key_path = expanduser(self.private_key)
                        if (not exists(private_key_path)) and (
                                not 'PRIVATE KEY' in self.private_key):
                            output = "'%s'key does not exist" % private_key_path
                            raise ComException(output)
                        for pkey_class in (RSAKey, DSSKey):
                            try:
                                if 'PRIVATE KEY' in self.private_key:
                                    import StringIO
                                    key = pkey_class.from_private_key(
                                        StringIO.StringIO(
                                            self.private_key.strip("'")))
                                else:
                                    key = pkey_class.from_private_key_file(
                                        private_key_path)
                                keys = keys + (key, )
                            except Exception:
                                pass
                    if not keys:
                        output = "Impossible to load any keys"
                        logger.error(output)
                        raise ComException(output)

                    for key in keys:
                        try:
                            sock = socket.socket()
                            try:
                                sock.settimeout(SSH_CONNECT_TIMEOUT)
                            except:
                                output = "Timeout trying to connect to '%s'" % self.frontend
                                raise ComException(output)
                            logger.debug(
                                "Connecting to '%s' as user '%s' port  '%s' ..."
                                % (self.frontend, self.username, self.port))
                            if ':' in self.frontend:
                                self.frontend, self.port = self.frontend.split(
                                    ':')
                            sock.connect((self.frontend, self.port))
                            self._trans = Transport(sock)
                            self._trans.connect(username=self.username,
                                                pkey=key)
                            if self._trans.is_authenticated():
                                break
                        except socket.gaierror:
                            output = "Could not resolve hostname '%s' " % self.frontend
                            raise ComException(output)
                        except Exception as err:
                            logger.warning("Error connecting '%s': %s" %
                                           (self.frontend, str(err)))
                if not self._trans:
                    output = "Authentication failed for '%s'. Try to execute `ssh -vvv -p %d %s@%s` and see the response." % (
                        self.frontend, self.port, self.username, self.frontend)
                    raise ComException(output)
        except ComException:
            raise
        except Exception as err:
            if "No handlers could be found for logger" in str(err):
                raise Exception(
                    "The connect function is the one causing problems : %s" %
                    str(err))
            else:
                raise

    def execCommand(self, command, input=None):
        self.connect()
        with self._lock:
            channel = self._trans.open_session()
        channel.settimeout(SSH_CONNECT_TIMEOUT)
        channel.exec_command(command)
        if input:
            for line in input.split():
                channel.makefile('wb', -1).write('%s\n' % line)
                channel.makefile('wb', -1).flush()
        stdout = ''.join(channel.makefile('rb', -1).readlines())
        stderr = ''.join(channel.makefile_stderr('rb', -1).readlines())
        if channel:
            channel.close()
        return stdout, stderr

    def mkDirectory(self, url):
        to_dir = self._set_dir(urlparse(url).path)
        stdout, stderr = self.execCommand("mkdir -p %s" % to_dir)
        if stderr:
            raise ComException("Could not create %s directory on '%s': %s" %
                               (to_dir, self.frontend, stderr))

    def rmDirectory(self, url):
        to_dir = self._set_dir(urlparse(url).path)
        stdout, stderr = self.execCommand("rm -rf %s" % to_dir)
        if stderr:
            raise ComException("Could not remove %s directory on '%s': %s" %
                               (to_dir, self.frontend, stderr))

    def copy(self, source_url, destination_url, execution_mode=''):
        with self._sem:
            self.connect()
            scp = SCPClient(self._trans)
            if 'file://' in source_url:
                from_dir = urlparse(source_url).path
                to_dir = self._set_dir(urlparse(destination_url).path)
                scp.put(from_dir, to_dir)
                if execution_mode == 'X':
                    stdout, stderr = self.execCommand("chmod +x %s" % to_dir)
            else:
                from_dir = self._set_dir(urlparse(source_url).path)
                to_dir = urlparse(destination_url).path
                logger.warning("%s , %s" % (from_dir, to_dir))
                scp.get(from_dir, to_dir)

    def close(self):
        try:
            if self._trans:
                self._trans.close()
        except Exception as err:
            logger.warning("Could not close the SSH connection to '%s': %s" %
                           (self.frontend, str(err)))

    def __del__(self):
        """
        Attempt to clean up if not explicitly closed.
        """
        self.close()

    #internal
    def _set_dir(self, path):
        work_directory = re.compile(r'^~').sub(self.work_directory, path)
        if work_directory[0] == r'~':
            return ".%s" % work_directory[1:]
        else:
            return work_directory
Пример #13
0
## Let's make an ssh tunnel if we find it in profiles.config
from mr_utils.config import ProfileConfig
from paramiko.transport import Transport
import socket

if __name__ == '__main__':
    profile = ProfileConfig()
    ssh_host = profile.get_config_val('ssh.host')
    ssh_user = profile.get_config_val('ssh.user')
    host = profile.get_config_val('gadgetron.host')
    port = profile.get_config_val('gadgetron.port')

    print(ssh_host, ssh_user)

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ssh_host, 22))
    transport = Transport(sock)
    transport.connect(username=ssh_user, password=None)
    chan = transport.open_channel('session', dest_addr=(host, port))
    print(chan)
    chan.close()
    transport.close()
    sock.close()