 888b3839e7
			
		
	
	888b3839e7
	
	
	
		
			
			Summary:
Fixes T2229. This sets the stage for a patch similar to D7417, but for SSH. In particular, SSH 6.2 introduced an `AuthorizedKeysCommand` directive, which lets us do this in a mostly-reasonable way without needing users to patch sshd (if they have a recent enough version, at least).
The way the `AuthorizedKeysCommand` works is that it gets run and produces an `authorized_keys`-style file fragment. This isn't ideal, because we have to dump every key into the result, but should be fine for most installs. The earlier patch against `sshd` passes the public key itself, which allows the script to just look up the key. We might use this eventually, since it can scale much better, so I haven't removed it.
Generally, auth is split into two scripts now which mostly do the same thing:
  - `ssh-auth` is the AuthorizedKeysCommand auth, which takes nothing and dumps the whole keyfile.
  - `ssh-auth-key` is the slightly cleaner and more scalable (but patch-dependent) version, which takes the public key and dumps only matching options.
I also reworked the argument parsing to be a bit more sane.
Test Plan:
This is somewhat-intentionally a bit obtuse since I don't really want anyone using it yet, but basically:
  - Copy `phabricator-ssh-hook.sh` to somewhere like `/usr/libexec/openssh/`, chown it `root` and chmod it `500`.
    - This script should probably also do a username check in the future.
  - Create a copy of `sshd_config` and fix the paths/etc. Point the KeyScript at your copy of the hook.
  - Start a copy of sshd (6.2 or newer) with `-f <your config file>` and maybe `-d -d -d` to foreground and debug.
  - Run `ssh -p 2222 localhost` or similar.
Specifically, I did this setup and then ran a bunch of commands like:
  - `ssh host` (denied, no command)
  - `ssh host ls` (denied, not supported)
  - `echo '{}' | ssh host conduit conduit.ping` (works)
Reviewers: btrahan
Reviewed By: btrahan
CC: hach-que, aran
Maniphest Tasks: T2229, T2230
Differential Revision: https://secure.phabricator.com/D7419
		
	
		
			
				
	
	
		
			49 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			49 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env php
 | |
| <?php
 | |
| 
 | |
| $root = dirname(dirname(dirname(__FILE__)));
 | |
| require_once $root.'/scripts/__init_script__.php';
 | |
| 
 | |
| $user_dao = new PhabricatorUser();
 | |
| $ssh_dao = new PhabricatorUserSSHKey();
 | |
| $conn_r = $user_dao->establishConnection('r');
 | |
| 
 | |
| $rows = queryfx_all(
 | |
|   $conn_r,
 | |
|   'SELECT userName, keyBody, keyType FROM %T u JOIN %T ssh
 | |
|     ON u.phid = ssh.userPHID',
 | |
|   $user_dao->getTableName(),
 | |
|   $ssh_dao->getTableName());
 | |
| 
 | |
| $bin = $root.'/bin/ssh-exec';
 | |
| foreach ($rows as $row) {
 | |
|   $user = $row['userName'];
 | |
| 
 | |
|   $cmd = csprintf('%s --phabricator-ssh-user %s', $bin, $user);
 | |
|   // This is additional escaping for the SSH 'command="..."' string.
 | |
|   $cmd = addcslashes($cmd, '"\\');
 | |
| 
 | |
|   // Strip out newlines and other nonsense from the key type and key body.
 | |
| 
 | |
|   $type = $row['keyType'];
 | |
|   $type = preg_replace('@[\x00-\x20]+@', '', $type);
 | |
| 
 | |
|   $key = $row['keyBody'];
 | |
|   $key = preg_replace('@[\x00-\x20]+@', '', $key);
 | |
| 
 | |
| 
 | |
|   $options = array(
 | |
|     'command="'.$cmd.'"',
 | |
|     'no-port-forwarding',
 | |
|     'no-X11-forwarding',
 | |
|     'no-agent-forwarding',
 | |
|     'no-pty',
 | |
|   );
 | |
|   $options = implode(',', $options);
 | |
| 
 | |
|   $lines[] = $options.' '.$type.' '.$key."\n";
 | |
| }
 | |
| 
 | |
| echo implode('', $lines);
 | |
| exit(0);
 |