diff --git a/cmd/containerd-shim/main_unix.go b/cmd/containerd-shim/main_unix.go index 209462f75..4bcab7973 100644 --- a/cmd/containerd-shim/main_unix.go +++ b/cmd/containerd-shim/main_unix.go @@ -47,7 +47,7 @@ func main() { }, cli.StringFlag{ Name: "socket,s", - Usage: "abstract socket path to server on", + Usage: "abstract socket path to serve on", }, } app.Before = func(context *cli.Context) error { diff --git a/cmd/containerd-shim/shim_linux.go b/cmd/containerd-shim/shim_linux.go index e8cb32294..10d51b78b 100644 --- a/cmd/containerd-shim/shim_linux.go +++ b/cmd/containerd-shim/shim_linux.go @@ -1,14 +1,21 @@ package main import ( + "net" "os" "os/signal" + "syscall" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + "golang.org/x/net/context" "golang.org/x/sys/unix" "github.com/containerd/containerd/reaper" "github.com/containerd/containerd/sys" runc "github.com/containerd/go-runc" + "github.com/pkg/errors" ) // setupSignals creates a new signal handler for all signals and sets the shim as a @@ -30,3 +37,64 @@ func setupSignals() (chan os.Signal, error) { func setupRoot() error { return unix.Mount("", "/", "", unix.MS_SLAVE|unix.MS_REC, "") } + +func newServer() *grpc.Server { + return grpc.NewServer(grpc.Creds(NewUnixSocketCredentils(0, 0))) +} + +type unixSocketCredentials struct { + uid int + gid int + serverName string +} + +func NewUnixSocketCredentils(uid, gid int) credentials.TransportCredentials { + return &unixSocketCredentials{uid, gid, "locahost"} +} + +func (u *unixSocketCredentials) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + return nil, nil, errors.New("ClientHandshake is not supported by unixSocketCredentials") +} + +func (u *unixSocketCredentials) ServerHandshake(c net.Conn) (net.Conn, credentials.AuthInfo, error) { + uc, ok := c.(*net.UnixConn) + if !ok { + return nil, nil, errors.New("unixSocketCredentials only supports unix socket") + } + + f, err := uc.File() + if err != nil { + return nil, nil, errors.Wrap(err, "unixSocketCredentials: failed to retrieve connection underlying fd") + } + pcred, err := syscall.GetsockoptUcred(int(f.Fd()), syscall.SOL_SOCKET, syscall.SO_PEERCRED) + if err != nil { + return nil, nil, errors.Wrap(err, "unixSocketCredentials: failed to retrieve socket peer credentials") + } + + if (u.uid != -1 && uint32(u.uid) != pcred.Uid) || (u.gid != -1 && uint32(u.gid) != pcred.Gid) { + return nil, nil, errors.New("unixSocketCredentials: invalid credentials") + } + + return c, u, nil +} + +func (u *unixSocketCredentials) Info() credentials.ProtocolInfo { + return credentials.ProtocolInfo{ + SecurityProtocol: "unix-socket-peer-creds", + SecurityVersion: "1.0", + ServerName: u.serverName, + } +} + +func (u *unixSocketCredentials) Clone() credentials.TransportCredentials { + return &unixSocketCredentials{u.uid, u.gid, u.serverName} +} + +func (u *unixSocketCredentials) OverrideServerName(serverName string) error { + u.serverName = serverName + return nil +} + +func (u *unixSocketCredentials) AuthType() string { + return "unix-socket-peer-creds" +} diff --git a/cmd/containerd-shim/shim_unix.go b/cmd/containerd-shim/shim_unix.go index 2315163b7..110123d7f 100644 --- a/cmd/containerd-shim/shim_unix.go +++ b/cmd/containerd-shim/shim_unix.go @@ -6,6 +6,8 @@ import ( "os" "os/signal" + "google.golang.org/grpc" + "github.com/containerd/containerd/reaper" runc "github.com/containerd/go-runc" ) @@ -25,3 +27,7 @@ func setupSignals() (chan os.Signal, error) { func setupRoot() error { return nil } + +func newServer() *grpc.Server { + return grpc.NewServer() +}