499 |
|
|
500 |
|
|
501 |
\subsubsection{Bootstrapping a client-server connection} |
\subsubsection{Bootstrapping a client-server connection} |
502 |
|
\label{ipcbootstrap} |
503 |
|
|
504 |
If the client and the server do not know about each other yet, then |
If the client and the server do not know about each other yet, then |
505 |
they can bootstrap a connection without support from any other task |
they can bootstrap a connection without support from any other task |
1386 |
do not need anymore. |
do not need anymore. |
1387 |
\end{comment} |
\end{comment} |
1388 |
|
|
|
|
|
|
|
|
1389 |
\paragraph{Task manager capability} |
\paragraph{Task manager capability} |
1390 |
A task is a relatively simple object, compared to a full blown POSIX |
A task is a relatively simple object, compared to a full blown POSIX |
1391 |
process, for example. As the \texttt{task} server is enforced system |
process, for example. As the \texttt{task} server is enforced system |
1439 |
\end{comment} |
\end{comment} |
1440 |
|
|
1441 |
Task IDs will be reused only if there are no task control or info |
Task IDs will be reused only if there are no task control or info |
1442 |
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 |
1443 |
|
support bootstrapping an IPC connection (see section |
1444 |
|
\ref{ipcbootstrap} on page \pageref{ipcbootstrap}), the \texttt{task} |
1445 |
|
server will delay reusing a task ID as long as possible. |
1446 |
|
|
1447 |
\begin{comment} |
\begin{comment} |
1448 |
If the \texttt{task} server never ignores this rule, even if a task |
This is similar to how PIDs are generated in Unix. Although it is |
1449 |
does not release task control or info capabilities voluntarily, then |
attempted to keep PIDs small for ease of use, PIDs are not reused |
1450 |
there is no need for the \texttt{task} server to not keep task IDs |
immediately. Instead, the PID is incremented up to a certain |
1451 |
small and reuse them as early as possible. |
maximum number, and only then smaller PID values are reused again. |
1452 |
|
|
1453 |
|
As task IDs are not a user interface, there is no need to keep them |
1454 |
|
small. The whole available range can be used to delay reusing a |
1455 |
|
task ID as long as possible. |
1456 |
\end{comment} |
\end{comment} |
1457 |
|
|
1458 |
When creating a new task, the \texttt{task} server also has to create |
When creating a new task, the \texttt{task} server also has to create |
1574 |
\section{Authentication} |
\section{Authentication} |
1575 |
\label{auth} |
\label{auth} |
1576 |
|
|
1577 |
The auth server gives out auth objects that contain zero or more of |
Capabilities are a good way to give access to protected objects and |
1578 |
effective user IDs, available user IDs, effective group IDs and |
services. They are flexible, lightweight and generic. However, Unix |
1579 |
available group IDs. New objects can be created from existing |
traditionally uses access control lists (ACL) to restrict access to |
1580 |
objects, but only as subsets from the union of the IDs a user |
objects like files. Any task running with a certain user ID can |
1581 |
possesses. If an auth object has an effective or available user ID 0, |
access all files that are readable for the user with that user ID. |
1582 |
then arbitrary new auth objects can be created from that. |
Although all objects are implemented as capabilities in the Hurd, the |
1583 |
|
Hurd also supports the use of user IDs for access control. |
1584 |
A passport can be created from an auth object that can be used by |
|
1585 |
everyone who possesses a handle to the passport object to verify the |
The system authentication server \texttt{auth} implements the Unix |
1586 |
IDs of the auth object that the passport was created from, and if the |
authentication scheme using capabilities. It provides auth |
1587 |
auth object is owned by any particular task (normally the user |
capabilities, which are associated with a list of effective and |
1588 |
requesting the. |
available user and group IDs. The holder of such a capability can use |
1589 |
|
it to authenticate itself to other servers, using the protocol below. |
1590 |
|
|
1591 |
|
Of course, these other servers must use (and trust) the same |
1592 |
|
\texttt{auth} server as the user. Otherwise, the authentication will |
1593 |
|
fail. Once a capability is authenticated in the server, the server |
1594 |
|
will know the user IDs of the client, and can use them to validate |
1595 |
|
further operations. |
1596 |
|
|
1597 |
|
The \texttt{auth} server provides two types of capabilities: |
1598 |
|
|
1599 |
|
\paragraph{Auth capabilities} |
1600 |
|
An auth capability is associated with four vectors of IDs: The |
1601 |
|
effective user and group IDs, which should be used by other servers to |
1602 |
|
authenticate operations that require certain user or group IDs, and |
1603 |
|
the available user and group IDs. Available IDs should not be used |
1604 |
|
for authentication purposes, but can be turned into effective IDs by |
1605 |
|
the holder of an auth capability at any time. |
1606 |
|
|
1607 |
|
New auth capabilities can be created from existing auth capabilities, |
1608 |
|
but only if the requested IDs are a subsets from the union of the |
1609 |
|
(effective and available) IDs in the provided auth capabilities. If |
1610 |
|
an auth capability has an effective or available user ID 0, then |
1611 |
|
arbitrary new auth objects can be created from that. |
1612 |
|
|
1613 |
|
\paragraph{Passport capabilities} |
1614 |
|
A passport capability can be created from an auth capability and is |
1615 |
|
only valid for the task that created it. It can be provided to a |
1616 |
|
server in an authentication process (see below). For the client, the |
1617 |
|
passport capability does not directly implement any useful operation. |
1618 |
|
For the server, it can be used to verify the identity of a user and |
1619 |
|
read out the effective user and group IDs. |
1620 |
|
|
1621 |
The auth server should always create new passport objects for |
The auth server should always create new passport objects for |
1622 |
different tasks, even if the underlying auth object is the same, so |
different tasks, even if the underlying auth object is the same, so |
1623 |
that a task having the passport capability can not spy on other tasks |
that a task having the passport capability can not spy on other tasks |
1624 |
unless they were given the passport object by that task. |
unless they were given the passport capability by that task. |
1625 |
|
|
1626 |
|
\subsection{Authenticating a client to a server} |
1627 |
|
|
1628 |
|
A client can authenticate itself to a server with the following |
1629 |
|
protocol: |
1630 |
|
|
1631 |
|
\paragraph{Preconditions} |
1632 |
|
The client $C$ has an auth capability implemented by the \texttt{auth} |
1633 |
|
server $A$. It also has a capability implemented by the server $S$. |
1634 |
|
It wants to reauthenticate this capability with the auth capability, |
1635 |
|
so the server associates the new user and group IDs with it. |
1636 |
|
|
1637 |
|
The server also has an auth capability implemented by its trusted |
1638 |
|
\texttt{auth} server. For the reauthentication to succeed, the |
1639 |
|
\texttt{auth} server of the client and the server must be identical. |
1640 |
|
If this is the case, the participating tasks hold task info caps for |
1641 |
|
all other participating tasks (because of the capabilities they hold). |
1642 |
|
|
1643 |
|
\begin{enumerate} |
1644 |
|
\item The client $C$ requests the passport capability for itself from |
1645 |
|
the auth capability from $A$. |
1646 |
|
|
1647 |
|
\begin{comment} |
1648 |
|
Normally, the client will request the passport capability only |
1649 |
|
once and store it together with the auth capability. |
1650 |
|
\end{comment} |
1651 |
|
|
1652 |
|
\item The \texttt{auth} server receives the request and creates a new |
1653 |
|
passport capability for this auth capability and this client. The |
1654 |
|
passport capability is returned to the user. |
1655 |
|
|
1656 |
|
\item The user receives the reply from the \texttt{auth} server. |
1657 |
|
|
1658 |
|
It then sends the reauthentication request to the server $S$, which |
1659 |
|
is invoked on the capability the client wants to reauthenticate. It |
1660 |
|
provides the passport capability as an argument. |
1661 |
|
|
1662 |
|
\item The server $S$ can accept the passport capability, if it |
1663 |
|
verifies that it is really implemented by the \texttt{auth} server |
1664 |
|
it trusts. If the client does not provide a passport capability to |
1665 |
|
the trusted \texttt{auth} server, the authentication process is |
1666 |
|
aborted with an error. |
1667 |
|
|
1668 |
|
Now the server can send a request to the \texttt{auth} server to |
1669 |
|
validate the passport capability. The RPC is invoked on the |
1670 |
|
passport capability. |
1671 |
|
|
1672 |
|
\item The \texttt{auth} server receives the validation request on the |
1673 |
|
passport capability and returns the task ID of the client $C$ that |
1674 |
|
this passport belongs to, and the effective user and group IDs for |
1675 |
|
the auth cap to which this passport cap belongs. |
1676 |
|
|
1677 |
|
\begin{comment} |
1678 |
|
The Hurd on Mach returned the available IDs as well. This feature |
1679 |
|
is not used anywhere in the Hurd, and as the available IDs should |
1680 |
|
not be used for authentication anyway, this does not seem to be |
1681 |
|
useful. If it is needed, it can be added in an extended version |
1682 |
|
of the validation RPC. |
1683 |
|
\end{comment} |
1684 |
|
|
1685 |
|
\item The server receives the task ID and the effective user and group |
1686 |
|
IDs. The server now verifies that the task ID is the same as the |
1687 |
|
task ID of the sender of the reauthentication request. Only then |
1688 |
|
was the reauthentication request made by the owner of the auth cap. |
1689 |
|
It can then return a new capability authenticated with the new user |
1690 |
|
and group IDs. |
1691 |
|
|
1692 |
|
\begin{comment} |
1693 |
|
The verification of the client's task ID is necessary. As the |
1694 |
|
passport cap is copied to other tasks, it can not serve as a proof |
1695 |
|
of identity alone. It is of course absolutely crucial that the |
1696 |
|
server holds the task info cap for the client task $C$ for the |
1697 |
|
whole time of the protocol. But the same is actually true for any |
1698 |
|
RPC, as the server needs to be sure that the reply message is sent |
1699 |
|
to the sender thread (and not any imposter). |
1700 |
|
\end{comment} |
1701 |
|
|
1702 |
|
\item The client receives the reply with the new, reauthenticated |
1703 |
|
capability. Usually this capability is associated in the server |
1704 |
|
with the same abstract object, but different user credentials. |
1705 |
|
|
1706 |
|
\begin{comment} |
1707 |
|
Of course a new capability must be created. Otherwise, all other |
1708 |
|
users holding the same capability would be affected as well. |
1709 |
|
\end{comment} |
1710 |
|
|
1711 |
|
The client can now deallocate the passport cap. |
1712 |
|
|
1713 |
|
\begin{comment} |
1714 |
|
As said before, normally the passport cap is cached by the client |
1715 |
|
for other reauthentications. |
1716 |
|
\end{comment} |
1717 |
|
\end{enumerate} |
1718 |
|
|
1719 |
|
\paragraph{Result} |
1720 |
|
The client $C$ has a new capability that is authenticated with the new |
1721 |
|
effective user and group IDs. The server has obtained the effective |
1722 |
|
user and group IDs from the \texttt{auth} server it trusts. |
1723 |
|
|
1724 |
|
\begin{comment} |
1725 |
|
The Hurd on Mach uses a different protocol, which is more complex |
1726 |
|
and is vulnerable to DoS attacks. The above protocol can not |
1727 |
|
readily be used on Mach, because the sender task of a message can |
1728 |
|
not be easily identified. |
1729 |
|
\end{comment} |
1730 |
|
|
1731 |
|
|
1732 |
\section{Process Management} |
\section{Process Management} |
1733 |
\label{proc} |
\label{proc} |
1734 |
|
|
1735 |
The \texttt{proc} server. |
The \texttt{proc} server implements Unix process semantics in the Hurd |
1736 |
|
system. |
1737 |
|
|
1738 |
|
|
1739 |
|
\subsection{Signals} |
1740 |
|
|
1741 |
\section{Miscs} |
Each process can register the thread ID of a signal thread with the |
1742 |
|
\texttt{proc} server. The proc server will give the signal thread ID |
1743 |
|
to any other task which asks for it. |
1744 |
|
|
1745 |
\subsection{Exec} |
\begin{comment} |
1746 |
|
The thread ID can be guessed, so there is no point in protecting it. |
1747 |
|
\end{comment} |
1748 |
|
|
1749 |
|
The signal thread ID can then be used by a task to contact the task to |
1750 |
|
which it wants to send a signal. The task must bootstrap its |
1751 |
|
connection with the intended receiver of the signal, according to the |
1752 |
|
protocol described in section \ref{ipcbootstrap} on page |
1753 |
|
\pageref{ipcbootstrap}. As a result, it will receive the signal |
1754 |
|
capability of the receiving task. |
1755 |
|
|
1756 |
|
The sender of a signal must then provide some capability that proves |
1757 |
|
that the sender is allowed to send the signal when a signal is posted |
1758 |
|
to the signal capability. For example, the owner of the task control |
1759 |
|
cap is usually allowed to send any signal to it. Other capabilities |
1760 |
|
might only give permission to send some types of signals. |
1761 |
|
|
1762 |
|
\begin{comment} |
1763 |
|
The receiver of the signal decides itself which signals to accept |
1764 |
|
from which other tasks. The default implementation in the C library |
1765 |
|
provides POSIX semantics, plus some extensions. |
1766 |
|
\end{comment} |
1767 |
|
|
1768 |
|
Signal handling is thus completely implemented locally in each task. |
1769 |
|
The \texttt{proc} server only serves as a name-server for the thread |
1770 |
|
IDs of the signal threads. |
1771 |
|
|
1772 |
|
\begin{comment} |
1773 |
|
The \texttt{proc} server can not hold the signal capability itself, |
1774 |
|
as it used to do in the implementation on Mach, as it does not trust |
1775 |
|
the tasks implementing the capability. But this is not a problem, |
1776 |
|
as the sender and receiver of a signal can negotiate and bootstrap |
1777 |
|
the connection without any further support by the \texttt{proc} |
1778 |
|
server. |
1779 |
|
|
1780 |
|
Also, the \texttt{proc} server can not even hold task info caps to |
1781 |
|
support the sender of a signal in bootstrapping the connection. |
1782 |
|
This means that there is a race between looking up the signal thread |
1783 |
|
ID from the PID in the \texttt{proc} server and acquiring a task |
1784 |
|
info cap for the task ID of the signal receiver in the sender. |
1785 |
|
However, in Unix, there is always a race when sending a signal using |
1786 |
|
\verb/kill/. The task server helps the users a bit here by not |
1787 |
|
reusing task IDs as long as possible. |
1788 |
|
\end{comment} |
1789 |
|
|
1790 |
|
|
1791 |
|
\section{Exec} |
1792 |
|
|
1793 |
The exec() operation will be done locally in a task. Traditionally, |
The exec() operation will be done locally in a task. Traditionally, |
1794 |
exec() overlays the same task with a new process image, because |
exec() overlays the same task with a new process image, because |
1872 |
idea. The details will depend a lot on the actual implementation. |
idea. The details will depend a lot on the actual implementation. |
1873 |
|
|
1874 |
|
|
1875 |
\section{Unix Domain Sockets and Pipes} |
\section{Unix Domain Sockets} |
1876 |
|
|
1877 |
In the Hurd on Mach, there was a global pflocal server that provided |
In the Hurd on Mach, there was a global pflocal server that provided |
1878 |
unix domain sockets and pipes to all users. This will not work very |
unix domain sockets and pipes to all users. This will not work very |
1908 |
shared pflocal server, one per user. |
shared pflocal server, one per user. |
1909 |
|
|
1910 |
|
|
1911 |
|
\section{Pipes} |
1912 |
|
|
1913 |
|
Pipes can be either implemented using Unix Domain Sockets, or maybe |
1914 |
|
even using shared memory for extra performance. |
1915 |
|
|
1916 |
|
\begin{comment} |
1917 |
|
Either a shared lock has to be used (implemented inside the physical |
1918 |
|
memory server), or the shared memory protocol must be able to deal |
1919 |
|
with multiple concurrent readers and writers. |
1920 |
|
\end{comment} |
1921 |
|
|
1922 |
|
|
1923 |
\section{Filesystem Translators} |
\section{Filesystem Translators} |
1924 |
|
|
1925 |
\label{xfslookup} |
\label{xfslookup} |