commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

hurd-l4/doc hurd-on-l4.tex


From: Marcus Brinkmann
Subject: hurd-l4/doc hurd-on-l4.tex
Date: Sat, 30 Aug 2003 20:02:17 -0400

CVSROOT:        /cvsroot/hurd
Module name:    hurd-l4
Branch:         
Changes by:     Marcus Brinkmann <address@hidden>       03/08/30 20:02:17

Modified files:
        doc            : hurd-on-l4.tex 

Log message:
        Add authentication, signal handling.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd-l4/doc/hurd-on-l4.tex.diff?tr1=1.4&tr2=1.5&r1=text&r2=text

Patches:
Index: hurd-l4/doc/hurd-on-l4.tex
diff -u hurd-l4/doc/hurd-on-l4.tex:1.4 hurd-l4/doc/hurd-on-l4.tex:1.5
--- hurd-l4/doc/hurd-on-l4.tex:1.4      Sat Aug 30 16:11:12 2003
+++ hurd-l4/doc/hurd-on-l4.tex  Sat Aug 30 20:02:17 2003
@@ -499,6 +499,7 @@
 
 
 \subsubsection{Bootstrapping a client-server connection}
+\label{ipcbootstrap}
 
 If the client and the server do not know about each other yet, then
 they can bootstrap a connection without support from any other task
@@ -1385,8 +1386,6 @@
   do not need anymore.
 \end{comment}
 
-
-
 \paragraph{Task manager capability}
 A task is a relatively simple object, compared to a full blown POSIX
 process, for example.  As the \texttt{task} server is enforced system
@@ -1440,13 +1439,20 @@
 \end{comment}
 
 Task IDs will be reused only if there are no task control or info
-capabilities for that task ID held by any task in the system.
+capabilities for that task ID held by any task in the system.  To
+support bootstrapping an IPC connection (see section
+\ref{ipcbootstrap} on page \pageref{ipcbootstrap}), the \texttt{task}
+server will delay reusing a task ID as long as possible.
 
 \begin{comment}
-  If the \texttt{task} server never ignores this rule, even if a task
-  does not release task control or info capabilities voluntarily, then
-  there is no need for the \texttt{task} server to not keep task IDs
-  small and reuse them as early as possible.
+  This is similar to how PIDs are generated in Unix.  Although it is
+  attempted to keep PIDs small for ease of use, PIDs are not reused
+  immediately.  Instead, the PID is incremented up to a certain
+  maximum number, and only then smaller PID values are reused again.
+  
+  As task IDs are not a user interface, there is no need to keep them
+  small.  The whole available range can be used to delay reusing a
+  task ID as long as possible.
 \end{comment}
 
 When creating a new task, the \texttt{task} server also has to create
@@ -1568,34 +1574,221 @@
 \section{Authentication}
 \label{auth}
 
-The auth server gives out auth objects that contain zero or more of
-effective user IDs, available user IDs, effective group IDs and
-available group IDs.  New objects can be created from existing
-objects, but only as subsets from the union of the IDs a user
-possesses.  If an auth object has an effective or available user ID 0,
-then arbitrary new auth objects can be created from that.
-
-A passport can be created from an auth object that can be used by
-everyone who possesses a handle to the passport object to verify the
-IDs of the auth object that the passport was created from, and if the
-auth object is owned by any particular task (normally the user
-requesting the.
+Capabilities are a good way to give access to protected objects and
+services.  They are flexible, lightweight and generic.  However, Unix
+traditionally uses access control lists (ACL) to restrict access to
+objects like files.  Any task running with a certain user ID can
+access all files that are readable for the user with that user ID.
+Although all objects are implemented as capabilities in the Hurd, the
+Hurd also supports the use of user IDs for access control.
+
+The system authentication server \texttt{auth} implements the Unix
+authentication scheme using capabilities.  It provides auth
+capabilities, which are associated with a list of effective and
+available user and group IDs.  The holder of such a capability can use
+it to authenticate itself to other servers, using the protocol below.
+
+Of course, these other servers must use (and trust) the same
+\texttt{auth} server as the user.  Otherwise, the authentication will
+fail.  Once a capability is authenticated in the server, the server
+will know the user IDs of the client, and can use them to validate
+further operations.
+
+The \texttt{auth} server provides two types of capabilities:
+
+\paragraph{Auth capabilities}
+An auth capability is associated with four vectors of IDs: The
+effective user and group IDs, which should be used by other servers to
+authenticate operations that require certain user or group IDs, and
+the available user and group IDs.  Available IDs should not be used
+for authentication purposes, but can be turned into effective IDs by
+the holder of an auth capability at any time.
+
+New auth capabilities can be created from existing auth capabilities,
+but only if the requested IDs are a subsets from the union of the
+(effective and available) IDs in the provided auth capabilities.  If
+an auth capability has an effective or available user ID 0, then
+arbitrary new auth objects can be created from that.
+
+\paragraph{Passport capabilities}
+A passport capability can be created from an auth capability and is
+only valid for the task that created it.  It can be provided to a
+server in an authentication process (see below).  For the client, the
+passport capability does not directly implement any useful operation.
+For the server, it can be used to verify the identity of a user and
+read out the effective user and group IDs.
 
 The auth server should always create new passport objects for
 different tasks, even if the underlying auth object is the same, so
 that a task having the passport capability can not spy on other tasks
-unless they were given the passport object by that task.
+unless they were given the passport capability by that task.
+
+\subsection{Authenticating a client to a server}
+
+A client can authenticate itself to a server with the following
+protocol:
+
+\paragraph{Preconditions}
+The client $C$ has an auth capability implemented by the \texttt{auth}
+server $A$.  It also has a capability implemented by the server $S$.
+It wants to reauthenticate this capability with the auth capability,
+so the server associates the new user and group IDs with it.
+
+The server also has an auth capability implemented by its trusted
+\texttt{auth} server.  For the reauthentication to succeed, the
+\texttt{auth} server of the client and the server must be identical.
+If this is the case, the participating tasks hold task info caps for
+all other participating tasks (because of the capabilities they hold).
+
+\begin{enumerate}
+\item The client $C$ requests the passport capability for itself from
+  the auth capability from $A$.
+
+  \begin{comment}
+    Normally, the client will request the passport capability only
+    once and store it together with the auth capability.
+  \end{comment}
+  
+\item The \texttt{auth} server receives the request and creates a new
+  passport capability for this auth capability and this client.  The
+  passport capability is returned to the user.
+  
+\item The user receives the reply from the \texttt{auth} server.
+  
+  It then sends the reauthentication request to the server $S$, which
+  is invoked on the capability the client wants to reauthenticate.  It
+  provides the passport capability as an argument.
+  
+\item The server $S$ can accept the passport capability, if it
+  verifies that it is really implemented by the \texttt{auth} server
+  it trusts.  If the client does not provide a passport capability to
+  the trusted \texttt{auth} server, the authentication process is
+  aborted with an error.
+  
+  Now the server can send a request to the \texttt{auth} server to
+  validate the passport capability.  The RPC is invoked on the
+  passport capability.
+  
+\item The \texttt{auth} server receives the validation request on the
+  passport capability and returns the task ID of the client $C$ that
+  this passport belongs to, and the effective user and group IDs for
+  the auth cap to which this passport cap belongs.
+
+  \begin{comment}
+    The Hurd on Mach returned the available IDs as well.  This feature
+    is not used anywhere in the Hurd, and as the available IDs should
+    not be used for authentication anyway, this does not seem to be
+    useful.  If it is needed, it can be added in an extended version
+    of the validation RPC.
+  \end{comment}
+  
+\item The server receives the task ID and the effective user and group
+  IDs.  The server now verifies that the task ID is the same as the
+  task ID of the sender of the reauthentication request.  Only then
+  was the reauthentication request made by the owner of the auth cap.
+  It can then return a new capability authenticated with the new user
+  and group IDs.
+
+  \begin{comment}
+    The verification of the client's task ID is necessary.  As the
+    passport cap is copied to other tasks, it can not serve as a proof
+    of identity alone.  It is of course absolutely crucial that the
+    server holds the task info cap for the client task $C$ for the
+    whole time of the protocol.  But the same is actually true for any
+    RPC, as the server needs to be sure that the reply message is sent
+    to the sender thread (and not any imposter).
+  \end{comment}
+  
+\item The client receives the reply with the new, reauthenticated
+  capability.  Usually this capability is associated in the server
+  with the same abstract object, but different user credentials.
+
+  \begin{comment}
+    Of course a new capability must be created.  Otherwise, all other
+    users holding the same capability would be affected as well.
+  \end{comment}
+
+  The client can now deallocate the passport cap.
+
+  \begin{comment}
+    As said before, normally the passport cap is cached by the client
+    for other reauthentications.
+  \end{comment}
+\end{enumerate}
+
+\paragraph{Result}
+The client $C$ has a new capability that is authenticated with the new
+effective user and group IDs.  The server has obtained the effective
+user and group IDs from the \texttt{auth} server it trusts.
+
+\begin{comment}
+  The Hurd on Mach uses a different protocol, which is more complex
+  and is vulnerable to DoS attacks.  The above protocol can not
+  readily be used on Mach, because the sender task of a message can
+  not be easily identified.
+\end{comment}
 
 
 \section{Process Management}
 \label{proc}
 
-The \texttt{proc} server.
+The \texttt{proc} server implements Unix process semantics in the Hurd
+system.
+
 
+\subsection{Signals}
 
-\section{Miscs}
+Each process can register the thread ID of a signal thread with the
+\texttt{proc} server.  The proc server will give the signal thread ID
+to any other task which asks for it.
 
-\subsection{Exec}
+\begin{comment}
+  The thread ID can be guessed, so there is no point in protecting it.
+\end{comment}
+
+The signal thread ID can then be used by a task to contact the task to
+which it wants to send a signal.  The task must bootstrap its
+connection with the intended receiver of the signal, according to the
+protocol described in section \ref{ipcbootstrap} on page
+\pageref{ipcbootstrap}.  As a result, it will receive the signal
+capability of the receiving task.
+
+The sender of a signal must then provide some capability that proves
+that the sender is allowed to send the signal when a signal is posted
+to the signal capability.  For example, the owner of the task control
+cap is usually allowed to send any signal to it.  Other capabilities
+might only give permission to send some types of signals.
+
+\begin{comment}
+  The receiver of the signal decides itself which signals to accept
+  from which other tasks.  The default implementation in the C library
+  provides POSIX semantics, plus some extensions.
+\end{comment}
+
+Signal handling is thus completely implemented locally in each task.
+The \texttt{proc} server only serves as a name-server for the thread
+IDs of the signal threads.
+
+\begin{comment}
+  The \texttt{proc} server can not hold the signal capability itself,
+  as it used to do in the implementation on Mach, as it does not trust
+  the tasks implementing the capability.  But this is not a problem,
+  as the sender and receiver of a signal can negotiate and bootstrap
+  the connection without any further support by the \texttt{proc}
+  server.
+  
+  Also, the \texttt{proc} server can not even hold task info caps to
+  support the sender of a signal in bootstrapping the connection.
+  This means that there is a race between looking up the signal thread
+  ID from the PID in the \texttt{proc} server and acquiring a task
+  info cap for the task ID of the signal receiver in the sender.
+  However, in Unix, there is always a race when sending a signal using
+  \verb/kill/.  The task server helps the users a bit here by not
+  reusing task IDs as long as possible.
+\end{comment}
+
+  
+\section{Exec}
 
 The exec() operation will be done locally in a task.  Traditionally,
 exec() overlays the same task with a new process image, because
@@ -1679,7 +1872,7 @@
 idea.  The details will depend a lot on the actual implementation.
 
 
-\section{Unix Domain Sockets and Pipes}
+\section{Unix Domain Sockets}
 
 In the Hurd on Mach, there was a global pflocal server that provided
 unix domain sockets and pipes to all users.  This will not work very
@@ -1713,6 +1906,18 @@
 All this are optimizations: It should work to have one pflocal process
 for each socketpair.  However, performance should be better with a
 shared pflocal server, one per user.
+
+
+\section{Pipes}
+
+Pipes can be either implemented using Unix Domain Sockets, or maybe
+even using shared memory for extra performance.
+
+\begin{comment}
+  Either a shared lock has to be used (implemented inside the physical
+  memory server), or the shared memory protocol must be able to deal
+  with multiple concurrent readers and writers.
+\end{comment}
 
 
 \section{Filesystem Translators}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]