def gen_keys(key="", key_path_dir=""): """ 在KEY_DIR下创建一个 uuid命名的目录, 并且在该目录下 生产一对秘钥 :return: 返回目录名(uuid) """ key_basename = "key-" + uuid4().hex if not key_path_dir: key_path_dir = os.path.join(KEY_DIR, 'role_key', key_basename) private_key = os.path.join(key_path_dir, 'id_rsa') public_key = os.path.join(key_path_dir, 'id_rsa.pub') mkdir(key_path_dir, mode=0755) if not key: key = RSAKey.generate(2048) key.write_private_key_file(private_key) else: key_file = os.path.join(key_path_dir, 'id_rsa') with open(key_file, 'w') as f: f.write(key) f.close() with open(key_file) as f: try: key = RSAKey.from_private_key(f) except SSHException, e: shutil.rmtree(key_path_dir, ignore_errors=True) raise SSHException(e)
def gen_keys(key="", key_path_dir=""): """ 在KEY_DIR下创建一个 uuid命名的目录, 并且在该目录下 生产一对秘钥 :return: 返回目录名(uuid) """ key_basename = "key-" + uuid4().hex if not key_path_dir: key_path_dir = os.path.join(KEY_DIR, 'role_key', key_basename) private_key = os.path.join(key_path_dir, 'id_rsa') public_key = os.path.join(key_path_dir, 'id_rsa.pub') mkdir(key_path_dir, mode=755) if not key: key = RSAKey.generate(2048) key.write_private_key_file(private_key) else: key_file = os.path.join(key_path_dir, 'id_rsa') with open(key_file, 'w') as f: f.write(key) f.close() with open(key_file) as f: try: key = RSAKey.from_private_key(f) except SSHException, e: shutil.rmtree(key_path_dir, ignore_errors=True) raise SSHException(e)
def test_bad_account_password_ssh_key(alice, tmpdir): """ Can't login with unknown username, any password, or wrong SSH pub key. """ # Any password, wrong username: for u, p in [("alice-key", "wrong"), ("someuser", "password")]: with pytest.raises(AuthenticationException): connect_sftp(connect_args={ "username": u, "password": p, }) another_key = os.path.join(str(tmpdir), "ssh_key") generate_ssh_key(another_key) good_key = RSAKey( filename=os.path.join(alice.node_dir, "private", "ssh_client_rsa_key")) bad_key = RSAKey(filename=another_key) # Wrong key: with pytest.raises(AuthenticationException): connect_sftp(connect_args={ "username": "******", "pkey": bad_key, }) # Wrong username: with pytest.raises(AuthenticationException): connect_sftp(connect_args={ "username": "******", "pkey": good_key, })
def public_key_fingerprint(key): paramiko_key = ParamikoRSAKey(vals=(key.e, key.n)) fp = hexlify(paramiko_key.get_fingerprint()) openssh_fp = ":".join([a+b for a, b in zip(fp[::2], fp[1::2])]) return openssh_fp
def public_key_fingerprint(key): # paramiko can compute the OpenSSH-style fingerprint # Only fingerprints the public key paramiko_key = ParamikoRSAKey(vals=(key.e, key.n)) fp = hexlify(paramiko_key.get_fingerprint()) # OpenSSH puts a ":" character between every pair of hex-digits. # For whatever reason. Readability, I guess. openssh_fp = ":".join([a + b for a, b in zip(fp[::2], fp[1::2])]) return openssh_fp
def __init__(self, private_key=None, private_key_path=None, pub_data=None, _key=None, password=None): if private_key: self._key = RSAKey(file_obj=io.StringIO(private_key)) elif private_key_path: self._key = RSAKey(filename=private_key_path, password=password) elif pub_data: if pub_data.startswith(self.SSH_PUB_KEY_PREFIX): pub_data = pub_data[len(self.SSH_PUB_KEY_PREFIX):] self._key = RSAKey(data=b64decode(pub_data.encode('utf-8'))) elif _key: self._key = _key else: self._key = RSAKey.generate(self.KEY_SIZE)
def __init__(self, cb, config=None, address='', port=58337, backlog=100): self.cb = cb # Parse config <3 if config is not None: with open(config, 'r') as f: cfg = yaml.load(f) else: cfg = {} logfile = cfg.get('logfile', None) if logfile is not None: paramiko.util.log_to_file(logile) host_key_path = cfg.get('host_key', 'server.key') host_key_password = cfg.get('host_key_password', None) try: self.host_key = RSAKey.from_private_key_file( host_key_path, host_key_password) except paramiko.ssh_exception.PasswordRequiredException: print 'Invalid host_key_password' sys.exit(1) except IOError: print '*****************************************' print '** host_key does not exists! **' print '** In the name of security by default, **' print '** Sheet will generate one for you. **' print '*****************************************' RSAKey.generate(2048).write_private_key_file( host_key_path, host_key_password) self.handler = Broker.get(cfg.get('auth_handler', 'BaseAuth')) self.handler_conf = cfg.get('auth_handler_config', {}) try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind((address, port)) except Exception as e: print 'Bind failed: ', str(e) traceback.print_exc() sys.exit(1) try: self.socket.listen(backlog) except Exception as e: print 'Listen/accept failed:', str(e) traceback.print_exc() sys.exit(1)
def connect(self): """ Открываем низкоуровневое соединение """ self.logger.debug( u'Open SSH connection {server} (reuse={reuse})'.format( server=self.server_name, reuse=self.reuse_connection)) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) if self.pkey: rsakey = RSAKey.from_private_key(StringIO(self.pkey)) ssh.connect(hostname=self.hostname, port=self.port, username=self.username, pkey=rsakey, timeout=self.timeout) else: ssh.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.password, timeout=self.timeout) ssh.get_transport().window_size = 1024**2 # Возвращаем соединение self.ssh = ssh
def _authenticate_public_key(self) -> None: """ Attempt to authenticate with public key authentication Args: N/A Returns: N/A # noqa: DAR202 Raises: N/A """ try: paramiko_key = RSAKey(filename=self.auth_private_key) self.session.auth_publickey(self.auth_username, paramiko_key) except AuthenticationException as exc: LOG.critical( f"Public key authentication with host {self.host} failed. Exception: {exc}." ) except Exception as exc: # pylint: disable=W0703 LOG.critical( "Unknown error occurred during public key authentication with host " f"{self.host}; Exception: {exc}" )
def renew_master_key(servers: collections.abc.Set, key_store: MasterKeyStore) -> PKey: """Renew the master key. It creates a new master key, makes ``servers`` to authorize the new key, replaces the existing master key with the new key in the ``key_store``, and then makes ``servers`` to deauthorize the old key. All these operations are done in a two-phase renewal transaction. :param servers: servers to renew the master key. every element has to be an instance of :class:`~.remote.Remote` :type servers: :class:`collections.abc.Set` :param key_store: the master key store to update :type key_store: :class:`MasterKeyStore` :returns: the created new master key :rtype: :class:`paramiko.pkey.PKey` """ logger = logging.getLogger(__name__ + '.renew_master_key') logger.info('renew the master key...') old_key = key_store.load() logger.info('the existing master key: %s', get_key_fingerprint(old_key)) new_key = RSAKey.generate(1024) logger.info('created new master key: %s', get_key_fingerprint(new_key)) logger.info('authorize the new master key...') with TwoPhaseRenewal(servers, old_key, new_key): logger.info('the new master key is authorized; ' 'update the key store...') key_store.save(new_key) logger.info('master key store is successfully updated; ' 'deauthorize the existing master key...') logger.info('master key renewal has finished') return new_key
def get_file(url): """ sftp://Some_Compute_UUID/relative/path/from/base_path/file.fastq.gz :param url: :type url: :return: :rtype: """ url = urlparse(url) scheme = url.scheme compute_id = url.host compute = ComputeResource.objects.get(id=compute_id) host = compute.hostname port = compute.port if port is None: port = 22 private_key = compute.private_key username = compute.extra.get('username') base_dir = compute.extra.get('base_dir') params = dict(port=port, username=username, pkey=RSAKey.from_private_key(StringIO(private_key))) storage = SFTPStorage(host=host, params=params) return storage.open(path.join(base_dir, url.path))
def _authenticate_public_key(self) -> None: """ Attempt to authenticate with public key authentication Args: N/A Returns: N/A # noqa: DAR202 Raises: exc: (really the paramiko auth exception) if auth exception occurs exc: (really the paramiko base exception) if unknown exception occurs """ try: # paramiko wants to see its key in a PKey object when crafting the paramiko connection # from Transport and Channel objects from paramiko.rsakey import RSAKey # pylint: disable=C0415 paramiko_key = RSAKey(filename=self.auth_private_key) self.session.auth_publickey(self.auth_username, paramiko_key) except self.lib_auth_exception as exc: LOG.critical( f"Public key authentication with host {self.host} failed. Exception: {exc}." ) except Exception as exc: # pylint: disable=W0703 LOG.critical( "Unknown error occurred during public key authentication with host " f"{self.host}; Exception: {exc}" )
def _authenticate_public_key(self) -> None: """ Attempt to authenticate with public key authentication Args: N/A Returns: None Raises: ScrapliConnectionNotOpened: if session is unopened/None """ if not self.session: raise ScrapliConnectionNotOpened if self._base_transport_args.transport_options.get( "enable_rsa2", False) is False: self.session.disabled_algorithms = { "keys": ["rsa-sha2-256", "rsa-sha2-512"] } try: paramiko_key = RSAKey( filename=self.plugin_transport_args.auth_private_key) self.session.auth_publickey( username=self.plugin_transport_args.auth_username, key=paramiko_key) except AuthenticationException: pass except Exception: # pylint: disable=W0703 pass
def create_worker(host): config = SSHConfig() proxy = None if os.path.exists(os.path.expanduser('~/.ssh/config')): config.parse(open(os.path.expanduser('~/.ssh/config'))) if host.hostname is not None and \ 'proxycommand' in config.lookup(host.hostname): proxy = ProxyCommand(config.lookup(host.hostname)['proxycommand']) # proxy = paramiko.ProxyCommand("ssh -o StrictHostKeyChecking=no [email protected] nc 118.138.239.241 22") worker = SSHClient() worker.load_system_host_keys() worker.set_missing_host_key_policy(AutoAddPolicy()) worker.hostname = host.hostname # store all this for later reference (e.g., logging, reconnection) worker.username = host.username worker.password = host.password worker.proxy = proxy if not host.key_filename is None: worker.pkey = RSAKey.from_private_key_file(host.key_filename, host.key_password) else: worker.pkey = None # time.sleep(4) # worker.connect(hostname=host.hostname, username=host.username, password=host.password, key_filename=host.key_filename, sock=proxy, timeout=3600) worker.connect(hostname=host.hostname, username=host.username, password=host.password, pkey=worker.pkey, sock=proxy) return worker
def __init__(self, hostname, username=None, password=None, port=22, private_key=None, connect_timeout=None, missing_host_key=None, sock=None): super(SshShell, self).__init__(hostname=hostname, username=username, password=password, port=port, connect_timeout=connect_timeout, missing_host_key=missing_host_key) try: self._pkey = RSAKey.from_private_key(StringIO(private_key)) except SSHException: try: self._pkey = DSSKey.from_private_key(StringIO(private_key)) except SSHException: raise ValidatorException("Unknown private key format") self._sock = sock
def generatekey(self): public_key = StringIO() private_key = StringIO() public_key_value = None private_key_value = None try: if self.keytype == 'rsa': key = RSAKey.generate(self.rsabits) elif self.keytype == 'ecdsa': key = ECDSAKey.generate(bits=self.ecdsabits) elif self.keytype == 'dss': key = DSSKey.generate(bits=self.dssbits) else: return None, "sshkey暂时不支持其它类型 %s" % self.keytype key.write_private_key(private_key) public_key.write("%s %s %s" % (key.get_name(), key.get_base64(), self.basename)) public_key_value = public_key.getvalue() private_key_value = private_key.getvalue() cache.set("user_%s_private_key" % self.username, private_key_value) cache.set("user_%s_public_key" % self.username, public_key_value) except Exception as e: logger.error(e.args) return None, e.args finally: public_key.close() private_key.close() return { "publickey": public_key_value, "privatekey": private_key_value }, None
def renew_master_key(servers: collections.abc.Set, key_store: MasterKeyStore) -> PKey: """Renew the master key. It creates a new master key, makes ``servers`` to authorize the new key, replaces the existing master key with the new key in the ``key_store``, and then makes ``servers`` to deauthorize the old key. All these operations are done in a two-phase renewal transaction. :param servers: servers to renew the master key. every element has to be an instance of :class:`~.remote.Remote` :type servers: :class:`collections.abc.Set` :param key_store: the master key store to update :type key_store: :class:`MasterKeyStore` :returns: the created new master key :rtype: :class:`paramiko.pkey.PKey` """ logger = logging.getLogger(__name__ + ".renew_master_key") logger.info("renew the master key...") old_key = key_store.load() logger.info("the existing master key: %s", get_key_fingerprint(old_key)) new_key = RSAKey.generate(1024) logger.info("created new master key: %s", get_key_fingerprint(new_key)) logger.info("authorize the new master key...") with TwoPhaseRenewal(servers, old_key, new_key): logger.info("the new master key is authorized; " "update the key store...") key_store.save(new_key) logger.info("master key store is successfully updated; " "deauthorize the existing master key...") logger.info("master key renewal has finished") return new_key
def load_ssh_key_from_file(filename): """ Load an ssh key from a file into a paramiko RSAKey object """ with open(filename, 'r') as fd: key = RSAKey(file_obj=fd) return key
def create_test_ssh_key(self): self.test_key = RSAKey.generate(1024) self.test_pubkey = "\nssh-rsa %s %s\n" % \ (self.test_key.get_base64(), Tests.TEST_KEY_COMMENT) f = open(os.path.expanduser("~/.ssh/authorized_keys"), "a") f.write(self.test_pubkey) f.close()
def sign_token(key_path, fingerprint, data): # from agent pkey = get_key_from_agent(fingerprint) if not pkey: # or from file (without passphrase) # assuming '.pub' file extension if not os.path.exists(key_path[:-4]): raise SignatureException('WrongKeyPath') try: pkey = RSAKey.from_private_key_file(key_path[:-4]) except PasswordRequiredException: raise SignatureException('EncryptedKey') if not pkey: raise SignatureException('KeyNotFound') try: # paramiko is inconsistent here in that the agent's key # returns Message objects for 'sign_ssh_data' whereas RSAKey # objects returns byte strings. # Workaround: cast both return values to string and build a # new Message object s = str(pkey.sign_ssh_data(data)) m = Message(s) m.rewind() if not m.get_string() == 'ssh-rsa': raise SignatureException('RSAKeyRequired') return base64.b64encode(m.get_string()) except Exception: raise SignatureException('SignatureCreateFailure')
def save(self, **kwargs): super().save(**kwargs) rsakey = RSAKey.from_private_key_file(settings.MEDIA_ROOT + "/" + self.file.name) rsakey.write_private_key_file( settings.MEDIA_ROOT + "/" + self.file.name, settings.SECRET_KEY) os.chmod(settings.MEDIA_ROOT + "/" + self.file.name, 0o640)
def _op_user(self, op, server, cmd_subs, quiet=False): """common code for adding/removing users.""" pkey_f = StringIO(self.private_key) pkey = RSAKey.from_private_key(pkey_f) pkey_f.close() cmd = getattr(self, "%s_user_command" % op) % cmd_subs cmd = cmd + "; echo $?" out, err = server.exec_command( cmd, username=str(self.admin_username), pkey=pkey, ) lines = out.strip().split("\n") ret = int(lines[-1]) if ret != 0: error = "".join(lines[:-1]) if not quiet: # msg example msg = "Failed to %s user on %s. Output was:\n%s" \ % (op, server, error), post_message_to_current_user( msg, msg_type=DatedMessage.TYPE_ERROR, ) # end msg example raise Exception(msg)
def __init__(self, hostname, port=22, username='******', pkey=None, password=None, default_env=None, connect_timeout=10): self.stdout = None self.client = None self.channel = None self.sftp = None self.eof = 'Spug EOF 2108111926' self.already_init = False self.default_env = self._make_env_command(default_env) self.regex = re.compile(r'Spug EOF 2108111926 (-?\d+)[\r\n]?') self.arguments = { 'hostname': hostname, 'port': port, 'username': username, 'password': password, 'pkey': RSAKey.from_private_key(StringIO(pkey)) if isinstance(pkey, str) else pkey, 'timeout': connect_timeout, 'banner_timeout': 30 }
def test_public_key(fx_app, fx_key_store, fx_authorized_identity, fx_token_id): key = RSAKey.generate(1024) fx_key_store.register(fx_authorized_identity, key) with fx_app.test_client() as client: response = client.get( get_url( 'public_key', token_id=fx_token_id, fingerprint=key.get_fingerprint() ) ) assert response.status_code == 200 assert response.mimetype == 'text/plain' assert parse_openssh_pubkey(response.data.decode()) == key with fx_app.test_client() as client: response = client.get( get_url( 'public_key', token_id=fx_token_id, fingerprint=os.urandom(16) ) ) assert response.status_code == 404 assert response.mimetype == 'application/json' error = json.loads(response.data.decode('utf-8')) assert error['error'] == 'not-found'
def main(): # pragma: no cover """The main function for :program:`geofront-server` CLI program.""" parser = main_parser() args = parser.parse_args() try: app.config.from_pyfile(os.path.abspath(args.config), silent=False) except FileNotFoundError: parser.error('unable to load configuration file: ' + args.config) logger = logging.getLogger('geofront') handler = logging.StreamHandler() level = logging.DEBUG if args.debug else logging.INFO handler.setLevel(level) logger.addHandler(handler) logger.setLevel(level) master_key_store = get_master_key_store() servers = frozenset(get_remote_set().values()) try: key = master_key_store.load() except EmptyStoreError: if args.create_master_key or args.renew_master_key: logger.warn('no master key; create one...') key = RSAKey.generate(1024) master_key_store.save(key) logger.info('created new master key: %s', get_key_fingerprint(key)) else: parser.error('no master key; try --create-master-key option ' 'if you want to create one') else: if args.renew_master_key and not os.environ.get('WERKZEUG_RUN_MAIN'): renew_master_key(servers, master_key_store) master_key_renewal_interval = app.config['MASTER_KEY_RENEWAL'] if not (master_key_renewal_interval is None or isinstance(master_key_renewal_interval, datetime.timedelta)): raise RuntimeError( 'MASTER_KEY_RENEWAL configuration must be an instance of ' 'datetime.timedelta, not {!r}'.format(master_key_renewal_interval)) if master_key_renewal_interval is not None: master_key_renewal = PeriodicalRenewal(servers, master_key_store, master_key_renewal_interval) waitress_options = {} if args.trusted_proxy: if hasattr(Adjustments, 'trusted_proxy'): # > 0.8.8 # https://github.com/Pylons/waitress/pull/42 waitress_options['trusted_proxy'] = True else: # <= 0.8.8 app.wsgi_app = ProxyFix(app.wsgi_app) try: if args.debug: app.run(args.host, args.port, debug=True) else: serve(app, host=args.host, port=args.port, asyncore_use_poll=True, **waitress_options) finally: if master_key_renewal_interval is not None: master_key_renewal.terminate()
def test_get_public_key(fx_app, fx_key_store, fx_authorized_identity, fx_token_id): key = RSAKey.generate(1024) fx_key_store.register(fx_authorized_identity, key) with fx_app.test_request_context(): found = get_public_key(fx_token_id, key.get_fingerprint()) assert found == key
def test_authorize_remote(fx_app, fx_authorized_servers, fx_master_key, fx_authorized_remote_set, fx_authorized_identity, fx_token_id, fx_key_store): public_key = RSAKey.generate(1024) fx_key_store.register(fx_authorized_identity, public_key) alias, remote = dict(fx_authorized_remote_set).popitem() with fx_app.test_client() as client: response = client.post( get_url('authorize_remote', token_id=fx_token_id, alias=alias) ) assert response.status_code == 200 assert response.mimetype == 'application/json' result = json.loads(response.data) assert result['success'] == 'authorized' assert result['remote'] == remote_dict(remote) expires_at = parse_date(result['expires_at']) thread, path, ev = fx_authorized_servers[remote.port] authorized_keys_path = path.join('.ssh', 'authorized_keys') with authorized_keys_path.open() as f: saved_keys = map(parse_openssh_pubkey, f) assert frozenset(saved_keys) == {fx_master_key, public_key} while datetime.datetime.now(datetime.timezone.utc) <= expires_at: time.sleep(1) time.sleep(1) with authorized_keys_path.open() as f: saved_keys = map(parse_openssh_pubkey, f) assert frozenset(saved_keys) == {fx_master_key}
def start_server(path: str, host: str, port: int, terminated: threading.Event): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.settimeout(1) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) server_socket.bind((host, port)) server_socket.listen(1) stub_cls = type('StubSFTPServer', (StubSFTPServer,), {'ROOT': path}) host_key = RSAKey.generate(1024) def accept(server_socket, mask): conn, addr = server_socket.accept() transport = Transport(conn) transport.add_server_key(host_key) transport.set_subsystem_handler('sftp', SFTPServer, stub_cls) server = StubServer(path) transport.start_server(server=server) while not terminated.is_set(): channel = transport.accept(1) if channel is not None and not terminated.is_set(): while transport.is_active() and not terminated.is_set(): terminated.wait(1) break sel = selectors.DefaultSelector() sel.register(server_socket, selectors.EVENT_READ, accept) last_used = time.time() while not terminated.is_set() and last_used + 10 > time.time(): events = sel.select(1) for key, mask in events: key.data(key.fileobj, mask) last_used = time.time()
def start_server(path: str, host: str, port: int, terminated: threading.Event): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.settimeout(1) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) server_socket.bind((host, port)) server_socket.listen(1) stub_cls = type('StubSFTPServer', (StubSFTPServer, ), {'ROOT': path}) host_key = RSAKey.generate(1024) def accept(server_socket, mask): conn, addr = server_socket.accept() transport = Transport(conn) transport.add_server_key(host_key) transport.set_subsystem_handler('sftp', SFTPServer, stub_cls) server = StubServer(path) transport.start_server(server=server) while not terminated.is_set(): channel = transport.accept(1) if channel is not None and not terminated.is_set(): while transport.is_active() and not terminated.is_set(): terminated.wait(1) break sel = selectors.DefaultSelector() sel.register(server_socket, selectors.EVENT_READ, accept) last_used = time.time() while not terminated.is_set() and last_used + 10 > time.time(): events = sel.select(1) for key, mask in events: key.data(key.fileobj, mask) last_used = time.time()
def test_delete_public_key(fx_app, fx_key_store, fx_authorized_identity, fx_token_id): key = RSAKey.generate(1024) fx_key_store.register(fx_authorized_identity, key) with fx_app.test_client() as client: response = client.delete( get_url( 'delete_public_key', token_id=fx_token_id, fingerprint=key.get_fingerprint() ) ) assert response.status_code == 200 assert key not in fx_key_store.list_keys(fx_authorized_identity) with fx_app.test_client() as client: response = client.delete( get_url( 'delete_public_key', token_id=fx_token_id, fingerprint=key.get_fingerprint() ) ) assert response.status_code == 404 assert response.mimetype == 'application/json' error = json.loads(response.data.decode('utf-8')) assert error['error'] == 'not-found'
def _authenticate_public_key(self) -> None: """ Attempt to authenticate with public key authentication Args: N/A Returns: None Raises: ScrapliConnectionNotOpened: if session is unopened/None """ if not self.session: raise ScrapliConnectionNotOpened try: paramiko_key = RSAKey( filename=self.plugin_transport_args.auth_private_key) self.session.auth_publickey( username=self.plugin_transport_args.auth_username, key=paramiko_key) except AuthenticationException: pass except Exception: # pylint: disable=W0703 pass
def _pushOtherKey(self, client, keyfile): sftp = client.openSftp() if not os.path.exists(keyfile): print("Can't copy {0}: no such file or directory.".format(keyfile)) return 1 source_key = '' with open(keyfile, 'r') as fp: source_key = fp.readline() # Paramiko RSA private key -- get the public part by converting if source_key.startswith('-----BEGIN RSA PRIVATE KEY-----'): pkey = RSAKey.from_private_key_file(keyfile) source_key = keys.GenerateAuthorizedKeysLine(pkey) try: sftp.chdir('/home/mendel/.ssh') except FileNotFoundError as e: sftp.mkdir('/home/mendel/.ssh', mode=0o700) with sftp.open('/home/mendel/.ssh/authorized_keys', 'a+b') as fp: fp.write(source_key) print("Key {0} pushed.".format(keyfile)) return 0
def test_authorize_remote(fx_app, fx_authorized_servers, fx_master_key, fx_authorized_remote_set, fx_authorized_identity, fx_token_id, fx_key_store): public_key = RSAKey.generate(1024) fx_key_store.register(fx_authorized_identity, public_key) alias, remote = dict(fx_authorized_remote_set).popitem() with fx_app.test_client() as client: response = client.post( get_url('authorize_remote', token_id=fx_token_id, alias=alias)) assert response.status_code == 200 assert response.mimetype == 'application/json' result = json.loads(response.get_data()) assert result['success'] == 'authorized' assert result['remote'] == remote_dict(remote) expires_at = parse_date(result['expires_at']) thread, path, ev = fx_authorized_servers[remote.port] authorized_keys_path = path.join('.ssh', 'authorized_keys') with authorized_keys_path.open() as f: saved_keys = map(parse_openssh_pubkey, f) assert frozenset(saved_keys) == {fx_master_key, public_key} while datetime.datetime.now(datetime.timezone.utc) <= expires_at: time.sleep(1) time.sleep(1) with authorized_keys_path.open() as f: saved_keys = map(parse_openssh_pubkey, f) assert frozenset(saved_keys) == {fx_master_key}
def from_line(cls, line): """ Parses the given line of text to find the names for the host, the type of key, and the key data. The line is expected to be in the format used by the openssh known_hosts file. Lines are expected to not have leading or trailing whitespace. We don't bother to check for comments or empty lines. All of that should be taken care of before sending the line to us. @param line: a line from an OpenSSH known_hosts file @type line: str """ fields = line.split(' ') if len(fields) < 3: # Bad number of fields return None fields = fields[:3] names, keytype, key = fields names = names.split(',') # Decide what kind of key we're looking at and create an object # to hold it accordingly. if keytype == 'ssh-rsa': key = RSAKey(data=base64.decodestring(key)) elif keytype == 'ssh-dss': key = DSSKey(data=base64.decodestring(key)) else: return None return cls(names, key)
def __init__(self, hostname, port=SSH_PORT, username='******', pkey=None, password=None, connect_timeout=10): if pkey is None and password is None: raise Exception( 'public key and password must have one is not None') self.client = None self.arguments = { 'hostname': hostname, 'port': port, 'username': username, 'password': password, 'pkey': RSAKey.from_private_key(StringIO(pkey)) if isinstance(pkey, str) else pkey, 'timeout': connect_timeout, }
def save_key_to_file(private_key, public_key, password=None, key_dir='/tmp'): """ read the key string and save it to an file. :param private_key: <str> private key :param public_key: <str> public key :param password: the private key password :param key_dir: the directory to save keys :return: (<str>, <str>), (private key file path, public key file path) """ private = StringIO() private.write(private_key) private.seek(0) if not os.path.exists(key_dir): os.mkdir(key_dir) private_file = os.path.join(key_dir, 'id_rsa') public_file = os.path.join(key_dir, 'id_rsa.pub') key = RSAKey.from_private_key(private, password) key.write_private_key_file(private_file, password) with open(public_file, 'w') as f: f.write(public_key) f.flush() return private_file, public_file
def generate_ssh_key(path): """Create a new SSH private/public key pair.""" key = RSAKey.generate(2048) key.write_private_key_file(path) with open(path + ".pub", "wb") as f: s = "%s %s" % (key.get_name(), key.get_base64()) f.write(s.encode("ascii"))
def __init__(self, cb, config=None, address='', port=58337, backlog=100): self.cb = cb # Parse config <3 if config is not None: with open(config, 'r') as f: cfg = yaml.load(f) else: cfg = {} logfile = cfg.get('logfile', None) if logfile is not None: paramiko.util.log_to_file(logile) host_key_path = cfg.get('host_key', 'server.key') host_key_password = cfg.get('host_key_password', None) try: self.host_key = RSAKey.from_private_key_file(host_key_path, host_key_password) except paramiko.ssh_exception.PasswordRequiredException: print 'Invalid host_key_password' sys.exit(1) except IOError: print '*****************************************' print '** host_key does not exists! **' print '** In the name of security by default, **' print '** Sheet will generate one for you. **' print '*****************************************' RSAKey.generate(2048).write_private_key_file(host_key_path, host_key_password) self.handler = Broker.get(cfg.get('auth_handler', 'BaseAuth')) self.handler_conf = cfg.get('auth_handler_config', {}) try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind((address, port)) except Exception as e: print 'Bind failed: ', str(e) traceback.print_exc() sys.exit(1) try: self.socket.listen(backlog) except Exception as e: print 'Listen/accept failed:', str(e) traceback.print_exc() sys.exit(1)
def test_add_public_key_415(fx_app, fx_key_store, fx_authorized_identity, fx_token_id): pkey = RSAKey.generate(1024) with fx_app.test_client() as c: response = c.post(get_url("add_public_key", token_id=fx_token_id), data={"key": format_openssh_pubkey(pkey)}) assert response.status_code == 415 error = json.loads(response.data) assert error["error"] == "unsupported-content-type" assert pkey not in fx_key_store.list_keys(fx_authorized_identity)
def parse_private_key(private_key): try: return RSAKey.from_private_key(StringIO(private_key)) except SSHException: try: return DSSKey.from_private_key(StringIO(private_key)) except SSHException: return None
def init_ssh_key(path: PosixPath): if path.exists(): key = RSAKey.from_private_key_file(str(path)) log.info('[⚙] Using existing SSH key in {}'.format(path)) else: key = generate_cert(path) log.info('[⚙] Generated SSH key in {}'.format(path)) return key
def test_cloud_master_public_key_store(): driver = KeyPairSupportedDummyNodeDriver("") actual_store = MemoryMasterKeyStore() store = CloudMasterPublicKeyStore(driver, "geofront-masterkey", actual_store) for _ in range(2): master_key = RSAKey.generate(1024) store.save(master_key) assert actual_store.load() == store.load() == master_key assert parse_openssh_pubkey(driver.get_key_pair("geofront-masterkey").public_key) == master_key
def test_fs_master_key_store_save(tmpdir): path = tmpdir.join('id_rsa') s = FileSystemMasterKeyStore(str(path)) with raises(EmptyStoreError): s.load() key = RSAKey.generate(1024) s.save(key) stored_key = s.load() assert isinstance(stored_key, RSAKey) assert stored_key.get_base64() == stored_key.get_base64()
def test_sftp_key_connect(self): server_interface = MyTServerInterface() pub_key_str = ( "AAAAB3NzaC1yc2EAAAADAQABAAAAgQCzvWE391K1pyBvePGpwDWMboSLIp" "5L5sMq+bXPPeJPSLOm9dnm8XexZOpeg14UpsYcmrkzVPeooaqz5PqtaHO46CdK11dS" "cs2a8PLnavGkJRf25/PDXxlHkiZXXbAfW+6t5aVJxSJ4Jt4FV0aDqMaaYxy4ikw6da" "BCkvug2OZQqQ==" ) priv_key_str = u"""-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQCzvWE391K1pyBvePGpwDWMboSLIp5L5sMq+bXPPeJPSLOm9dnm 8XexZOpeg14UpsYcmrkzVPeooaqz5PqtaHO46CdK11dScs2a8PLnavGkJRf25/PD XxlHkiZXXbAfW+6t5aVJxSJ4Jt4FV0aDqMaaYxy4ikw6daBCkvug2OZQqQIDAQAB AoGASpK9XlIQD+wqafWdFpf3368O8QdI9CbnPNJkG3sKhWidmR0R7l6rEX/UOah5 hUn4km+jfWe4ZU/GGmNbmkznDdOWspDKs7eeYl7saeRzuX2CdTVvrdU7qmD5+JLk mXlWWd6rgRIfrFYXYeDVd8p6/kPR4SJe7dTTHuEKKIt9njECQQDhMqjyoNxftpl4 +mwQu0ZDLCZ4afDCGcsf73W3oSmqLyf401vQ6KAp/PmfxqGXY0ewGMzUJn9LFOyP WOGcDFglAkEAzFL/DI3SYmsvLMt6/vK4qwEwSiJU8byUBj3CL3eL0xjn895GXPzb 9CUMu0fz60Tn7UhbohynPLmQ2w6npbZ9NQJBAN+uujGFpl9LuFV6KCzWV4wRJoUk dYfWpvQpnfuvkPsBq+pzxhdTeQM7y5bwbUE509MOTyXKt1WUiwQ3fKDLgiECQQCb Z4zhSYT4ojlRQrqb6pSWS+Mkn5QoAJw9Wv+1BqHsvwa8rxSpaREKUpuqXgGhsdkM 2noHhO+V+jW4xx6vpWr5AkEAgHoSbQUR5uY8ib3N3mNowVi9NhvBN1FkwGStM9W8 QKHf8Ha+rOx3B7Dbljc+Xdpcn9VyRmDlSqzX9aCkr18mNg== -----END RSA PRIVATE KEY-----""" private_key = RSAKey.from_private_key(file_obj=StringIO(priv_key_str)) # Fail if public key not registered self.assertEqual( server_interface.check_auth_publickey(self.username, private_key), AUTH_FAILED ) pub_key_rec = SFTPPublicKey.objects.create( user = self.user, name = "TestKey", key_type = "ssh-rsa", public_key = pub_key_str ) # Succeed if public key is registered self.assertEqual( server_interface.check_auth_publickey(self.username, private_key), AUTH_SUCCESSFUL ) # Should fail if user is inactive self.user.is_active = False self.user.save() self.assertEqual( server_interface.check_auth_publickey(self.username, private_key), AUTH_FAILED ) self.user.is_active = True self.user.save()
def get_sshkey(self, email): output = io.StringIO() sbuffer = io.StringIO() key = RSAKey.generate(2048) key.write_private_key(output) private_key = output.getvalue() sbuffer.write("{} {} {}".format(key.get_name(), key.get_base64(), email)) public_key = sbuffer.getvalue() return private_key, public_key
def createClient(host, username=None, pkeyPath=None): """ Creates an SSH client object that can be used to perform SSH-related operations """ client = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) pkey = RSAKey.from_private_key_file(os.path.expanduser(pkeyPath)) if pkeyPath else None client.connect(host, username=username, pkey=pkey) return client
def _exec_ssh_cmd(self, cmdline): pkey_buf = StringIO(self.state.pkey) client = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) client.connect(self.droplet_ip, username='******', pkey=RSAKey.from_private_key(pkey_buf)) stdin, stdout, stderr = client.exec_command(cmdline) for line in stdout: logging.info(line) for line in stderr: logging.info(line)
def test_authorized_keys_list_extend(fx_authorized_sftp): sftp_client, path, keys = fx_authorized_sftp key_list = AuthorizedKeyList(sftp_client) new_keys = [RSAKey.generate(1024) for _ in range(3)] key_list.extend(new_keys) with path.join('.ssh', 'authorized_keys').open() as f: for i in range(6): assert parse_openssh_pubkey(f.readline().strip()) == keys[i] for i in range(3): assert parse_openssh_pubkey(f.readline().strip()) == new_keys[i] assert not f.readline().strip()
def test_add_public_key_unsupported_type(fx_app, fx_key_store, fx_authorized_identity, fx_token_id): pkey = RSAKey.generate(1024) with fx_app.test_client() as c: response = c.post( get_url("add_public_key", token_id=fx_token_id), content_type="text/plain", data=("invalid-type " + format_openssh_pubkey(pkey)[7:]).encode(), ) assert response.status_code == 400 error = json.loads(response.data) assert error["error"] == "unsupported-key-type" assert pkey not in fx_key_store.list_keys(fx_authorized_identity)
def key_pair(self): """(:class:`boto.ec2.keypair.KeyPair`) The EC2 key pair matched to :attr:`private_key`. """ try: return self._key_pair except AttributeError: self._key_pair = self.ec2_connection.create_key_pair(self.key_name) private_key = str(self._key_pair.material) self._private_key = RSAKey.from_private_key(io.BytesIO(private_key)) self._create_github_deploy_key()
def test_authorized_keys_list_insert(fx_authorized_sftp): sftp_client, path, keys = fx_authorized_sftp key_list = AuthorizedKeyList(sftp_client) new_key = RSAKey.generate(1024) key_list.insert(2, new_key) with path.join('.ssh', 'authorized_keys').open() as f: assert parse_openssh_pubkey(f.readline().strip()) == keys[0] assert parse_openssh_pubkey(f.readline().strip()) == keys[1] assert parse_openssh_pubkey(f.readline().strip()) == new_key for i in range(2, 6): assert parse_openssh_pubkey(f.readline().strip()) == keys[i] assert not f.readline().strip()
def test_add_public_key_duplicate_key(fx_app, fx_key_store, fx_authorized_identity, fx_token_id): pkey = RSAKey.generate(1024) fx_key_store.register(fx_authorized_identity, pkey) with fx_app.test_client() as c: response = c.post( get_url("add_public_key", token_id=fx_token_id), content_type="text/plain", data=format_openssh_pubkey(pkey).encode(), ) assert response.status_code == 400 error = json.loads(response.data) assert error["error"] == "duplicate-key"
def assignKey(self, key): self.origKey = key # dump key to file self.dumpKey(self.keyPath, self.origKey) try: self._pkey = RSAKey.from_private_key(StringIO(self.origKey)) except paramiko.SSHException: try: self._pkey = DSSKey.from_private_key(StringIO(self.origKey)) except paramiko.SSHException: raise "Unknown private key format"
def _get_key_name_pattern(self, identity: Identity): """Make the regex pattern from the format string. Put two different random keys, compare two outputs, and then replace the difference with wildcard. """ cls = type(self) try: sample_keys = cls.sample_keys except AttributeError: sample_keys = RSAKey.generate(1024), RSAKey.generate(1024) cls.sample_keys = sample_keys sample_name_a = self._get_key_name(identity, sample_keys[0]) sample_name_b = self._get_key_name(identity, sample_keys[1]) if sample_name_a == sample_name_b: return re.compile('^' + re.escape(sample_name_a) + '$') prefix = os.path.commonprefix([sample_name_a, sample_name_b]) postfix = os.path.commonprefix([sample_name_a[::-1], sample_name_b[::-1]])[::-1] return re.compile( '^{}.+?{}$'.format(re.escape(prefix), re.escape(postfix)) )