Documentation ¶
Overview ¶
Package `ucred` provides `SO_PEERCRED` auth for gRPC over a Unix domain socket.
Package `github.com/nogproject/nog/backend/pkg/grpc/ucred` has been duplicated from `github.com/nogproject/bcpfs/pkg/grpc/ucred` and modified:
- It uses the `nog/backend` logger convention `Logger.Warnw()`.
- It supports `ClientHandshake()`.
Both packages should perhaps be refactored to a common library package.
Index ¶
- Variables
- type AnyAuthorizer
- type AuthInfo
- type ConnAuthorizer
- type Logger
- type NoneAuthorizer
- type SoPeerCred
- func (creds *SoPeerCred) ClientHandshake(ctx context.Context, authority string, conn net.Conn) (net.Conn, credentials.AuthInfo, error)
- func (creds *SoPeerCred) Clone() credentials.TransportCredentials
- func (creds *SoPeerCred) Info() credentials.ProtocolInfo
- func (creds *SoPeerCred) OverrideServerName(string) error
- func (creds *SoPeerCred) ServerHandshake(conn net.Conn) (net.Conn, credentials.AuthInfo, error)
- type UidAuthorizer
Constants ¶
This section is empty.
Variables ¶
var ErrDisabled = status.Error(codes.PermissionDenied, "service disabled")
`ErrDisabled` is used by `NoneAuthorizer` to indicate that a service cannot be used.
var ErrMissingUcred = status.Error(codes.Unauthenticated, "missing ucred")
`ErrUcredMissing` indicates that a context has no ucred.
var ErrNoAuthorizer = errors.New("missing authorizer")
var ErrUnimplemented = errors.New("unimplemented")
Functions ¶
This section is empty.
Types ¶
type AnyAuthorizer ¶
type AnyAuthorizer struct{}
`AnyAuthorizer.Authorize()` authorizes every context, even if the context has no ucred.
func (*AnyAuthorizer) Authorize ¶
func (a *AnyAuthorizer) Authorize(ctx context.Context) error
`AnyAuthorizer.Authorize()` always returns `nil`.
func (*AnyAuthorizer) AuthorizeInfo ¶
func (a *AnyAuthorizer) AuthorizeInfo(*AuthInfo) error
`AnyAuthorizer.AuthorizeInfo()` always returns `nil`.
type AuthInfo ¶
`AuthInfo.Ucred` is a field, so that further information, like TLS, could be added to `AuthInfo`.
func FromContext ¶
`FromContext()` returns the `ucred.AuthInfo` if it exists in `ctx`. It uses `grpc/peer.FromContext()`.
type ConnAuthorizer ¶
A `ConnAuthorizer` is set on `SoPeerCred` to accept connection during `ServerHandshake()`.
type NoneAuthorizer ¶
type NoneAuthorizer struct{}
`NoneAuthorizer.Authorize()` rejects every context.
func (*NoneAuthorizer) Authorize ¶
func (a *NoneAuthorizer) Authorize(ctx context.Context) error
`NoneAuthorizer.Authorize()` always returns `ErrDisabled`.
func (*NoneAuthorizer) AuthorizeInfo ¶
func (a *NoneAuthorizer) AuthorizeInfo(*AuthInfo) error
`NoneAuthorizer.AuthorizeInfo()` always returns `ErrDisabled`.
type SoPeerCred ¶
type SoPeerCred struct { Authorizer ConnAuthorizer Logger Logger }
`SoPeerCred` implements `grpc/credentials.TransportCredentials` for use as a `grpc.Creds()` server option or a `grpc.WithTransportCredentials()` client dial option.
func (*SoPeerCred) ClientHandshake ¶
func (creds *SoPeerCred) ClientHandshake( ctx context.Context, authority string, conn net.Conn, ) (net.Conn, credentials.AuthInfo, error)
`ClientHandshake()` does the same as `ServerHandshake()`.
func (*SoPeerCred) Clone ¶
func (creds *SoPeerCred) Clone() credentials.TransportCredentials
Dummy implementation that returns self, which should be ok, because `SoPeerCred` is immutable.
func (*SoPeerCred) Info ¶
func (creds *SoPeerCred) Info() credentials.ProtocolInfo
`Info()` returns something moderately useful. It was not obvious that it needs to do more.
func (*SoPeerCred) OverrideServerName ¶
func (creds *SoPeerCred) OverrideServerName(string) error
Dummy implementation.
func (*SoPeerCred) ServerHandshake ¶
func (creds *SoPeerCred) ServerHandshake( conn net.Conn, ) (net.Conn, credentials.AuthInfo, error)
`ServerHandshake()` uses `SO_PEERCRED`, see man page `socket(7), to get the client ucred. It then checks that the ucred is authorized and stores it as `AuthInfo` on the context, from where it can later be retrieved with `FromContext(ctx)` to authorize individual gRPC operations.
If ucred is not authorized, `ServerHandshake()` returns an error to gRPC, which will close the connection. The server logs a warning. The client receives `code = Unavailable desc = transport`.
type UidAuthorizer ¶
type UidAuthorizer struct {
// contains filtered or unexported fields
}
`UidAuthorizer.Authorize(ctx)` authorizes a context if it has a ucred UID that is in the list of allowed uids.
func NewUidAuthorizer ¶
func NewUidAuthorizer(uids ...uint32) *UidAuthorizer
`NewUidAuthorizer(uids)` creates an `UidAuthorizer` that authorizes if ucred matches `uids`, and rejects all other ucreds.
func (*UidAuthorizer) Authorize ¶
func (a *UidAuthorizer) Authorize(ctx context.Context) error
`UidAuthorizer.Authorize(ctx)` returns an error unless a valid ucred that matches the list of uids is in the `ctx`.
func (*UidAuthorizer) AuthorizeInfo ¶
func (a *UidAuthorizer) AuthorizeInfo(info *AuthInfo) error
`UidAuthorizer.AuthorizeInfo(info)` returns an error unless `info` matches the `UidAuthorizer` list of uids.