Updated ...md (markdown)

manojampalam 2016-02-24 18:50:21 -08:00
parent 5a315a01a6
commit 9ea9a5eb66

@ -21,7 +21,7 @@ Here, we'll discuss the design choices aimed at keeping majority of code base co
### POSIX IO
POSIX IO calls are a significant part of OpenSSH code. A POSIX IO wrapper will be implemented on top of Win32 async File IO. This wrapper strictly implements the POSIX IO needs of OpenSSH keeping the code differences, especially in the transport layer, to a minimum. Note that the wrapper implements only the calls needed by OpenSSH (and not all defined in POSIX standard). Specifically, the wrapper implements
+ IO calls creating file descriptors - open, creat, socket, accept, socketpair, pipe
+ operations on a single file descriptor - fd_set, FD_* macros, read, write, recv, send, fstat, fdopen, close, dup and dup2
+ operations on a single file descriptor - fd_set, FD_* macros, fcntl, read, write, recv, send, fstat, fdopen, close, dup and dup2
+ operations on multiple file descriptors - select
+ signal semantics on these operations - ex. select (or any blocking IO call) returning EINTR
+ SIGABRT, SIGTERM, SIGCHLD, SIGINT, SIGPIPE and SIGALRM
@ -36,6 +36,7 @@ Design summary of POSIX wrapper
- Signals
- Timers
+ All underlying Win32 IO API calls are made asynchronous (non-blocking). Blocking semantics are implemented within the wrapper by an explicit "wait_for_any" for IO to complete.
+ FD_CLOEXEC is supported, setting this flag denies inheritance of underlying Windows handle.
+ Uses [APCs](https://msdn.microsoft.com/en-us/library/windows/desktop/ms681951(v=vs.85).aspx) wherever available and minimzing use of [events](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx). This simplifies code and has performance benefits.
+ Maintains internal buffers to accommodate a fundamental underlying difference between POSIX and Win32 IO async models - IOReady Vs IOComplete (Ex for a Read operation, POSIX APIs signal when IO is ready - date will be subsequently explicitly read, Win32 APIs signal when IO has completed - data is already copied to a user provided buffer. Though this may be perceived as a performance hit, a validation exercise did not show any major impact. It in fact proved beneficial in reducing kernel calls during "read"s (ex. reading a header, would fetch the entire packet in a single call).
+ Additional details on underlying Win32 calls used
@ -61,18 +62,32 @@ A fully functional prototype (for socket, file and pipe IO) of this wrapper is a
#### fork()
There is no easy fork() equivalent in Windows. fork() is used in OpenSSH in multiple places, of those - 2 are worth mentioning
+ Session isolation: Each accepted connection in sshd is handed off and processed in a forked child. This will be implemented in Windows using CreateProcess based custom logic - will need #def differentiated code between Unix and Windows
+ Privilege separation: Implemented by processing and parsing network data in forked and underprivileged child processes that communicate to privileged Monitor process through IPC. Monitor does the core crypto validation and authentication. Security model in Windows is going to be different, running the SSHD service itself in a low privileged mode. So, the whole Privilege separation relevant code will be #def'ed out into a separate feature that will be disabled in Windows.
+ Privilege separation: Implemented in OpenSSH by processing and parsing network data in forked and underprivileged child processes that communicate to privileged Monitor process through IPC. Monitor does the core crypto validation and authentication. Privilege downgrading is done by setuid(restricted_user). Security model in Windows will be different, running the SSHD service itself in a low privileged mode. So, the whole Privilege separation relevant code will be #def'ed out in a separate feature macro that will be disabled in Windows.
+ The rest of the places fork() is used is listed below. None of these are critical to the functionality in Windows and will be appropriately disabled for Windows.
- TBD
#### AF_UNIX domain sockets
Unix domain sockets are used for IPC communication between processes on the same host. Apart from providing stream/datagram modes, they also support a secure way to transmit ancillary data (like file descriptors). The only place ancillary data is used in OpenSSH is in "ProxyUseFDPass" feature where a proxy command is issued by ssh client to create a connected socket, and its FD is transmitted back over IPC. This feature will be disabled on Windows. The rest of the places AF_UNIX sockets are used:
+ ControlMaster - used to multiplex multiple sessions over a single SSH connection.
+ SSHAgent - used to managed store keys and crypto validation based on those. Current plan is to replace its client side usage with Windows Credential manager. Server side plan is TBD.
+ SSHAgent - used to managed store keys and crypto validation based on those. Current plan is to replace its client side usage with Windows Credential manager. We will discuss its relevance on server side later in this page.
+ Local Socket Forwarding - This is forwarding traffic to AF_UNIX sockets and this feature is not applicable in Windows
+ SSHD rexec - Not applicable for Windows. SSHD will be implemented as Windows service, that can be configured for auto restart.
+ SSHD from inetd - Not applicable for Windows.
AF_UNIX channel will be implemented using secure bidirectional named pipes in Windows. This does not support ancillary data but is sufficient for above listed features relevant in Windows.
#### Privilege Separation
#### Privilege Separation and Security model in Windows (tentative design)
SSHD will be implemented as a Windows service, running in its [virtual account](https://technet.microsoft.com/en-us/library/dd548356.aspx) context - NT Service\SSHD - this is a restricted account that will only be granted the following needed privileges - to be added.
SSHD host public keys and configuration files will be [ACL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374872(v=vs.85).aspx)ed to allow READ by NT Service\SSHD. SSHD host private keys are ACLed to admin-only access - mandating that relying signature generation happens in a privileged process. We will be leveraging ssh-agent for this purpose, adding additional logic to launch it automatically on demand (most likely using COM). ssh-agent will serve all signature requests irrespective of whether the private key is password protected/not.
As detailed earlier, session isolation in Windows will be done using CreateProcess based custom logic (in place of fork based logic in Unix). Spawned child process will run in NT Service\SSHD too.
Authentication logic will be different between Windows and Unix. Password authentication is done using [LogonUser](https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx) while
Key-based authentication will be implemented in a custom [SSP](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380497(v=vs.85).aspx) that is executed in [lsass](https://msdn.microsoft.com/en-us/library/aa939478(v=winembedded.5).aspx). End result of authentication in Windows is a Windows user token (if authentication success). SSH sessions that need client user capabilities are hosted in processes running under the context of client user (launched using CreateProcess(user_token)). Ex. cmd.exe for terminal session, sftp_server.exe for sftp session and scp.exe for scp session.