Adding dep files and dependencies.
This commit is contained in:
parent
45f9efa578
commit
b341c0a0e4
539 changed files with 313111 additions and 0 deletions
361
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/authenticatee.go
generated
vendored
Normal file
361
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/authenticatee.go
generated
vendored
Normal file
|
@ -0,0 +1,361 @@
|
|||
package sasl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
log "github.com/golang/glog"
|
||||
"github.com/mesos/mesos-go/api/v0/auth"
|
||||
"github.com/mesos/mesos-go/api/v0/auth/callback"
|
||||
"github.com/mesos/mesos-go/api/v0/auth/sasl/mech"
|
||||
mesos "github.com/mesos/mesos-go/api/v0/mesosproto"
|
||||
"github.com/mesos/mesos-go/api/v0/mesosutil/process"
|
||||
"github.com/mesos/mesos-go/api/v0/messenger"
|
||||
"github.com/mesos/mesos-go/api/v0/upid"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
UnexpectedAuthenticationMechanisms = errors.New("Unexpected authentication 'mechanisms' received")
|
||||
UnexpectedAuthenticationStep = errors.New("Unexpected authentication 'step' received")
|
||||
UnexpectedAuthenticationCompleted = errors.New("Unexpected authentication 'completed' received")
|
||||
UnexpectedAuthenticatorPid = errors.New("Unexpected authentator pid") // authenticator pid changed mid-process
|
||||
UnsupportedMechanism = errors.New("failed to identify a compatible mechanism")
|
||||
)
|
||||
|
||||
type statusType int32
|
||||
|
||||
const (
|
||||
statusReady statusType = iota
|
||||
statusStarting
|
||||
statusStepping
|
||||
_statusTerminal // meta status, should never be assigned: all status types following are "terminal"
|
||||
statusCompleted
|
||||
statusFailed
|
||||
statusError
|
||||
statusDiscarded
|
||||
|
||||
// this login provider name is automatically registered with the auth package; see init()
|
||||
ProviderName = "SASL"
|
||||
)
|
||||
|
||||
type authenticateeProcess struct {
|
||||
transport messenger.Messenger
|
||||
client upid.UPID
|
||||
status statusType
|
||||
done chan struct{}
|
||||
err error
|
||||
mech mech.Interface
|
||||
stepFn mech.StepFunc
|
||||
from *upid.UPID
|
||||
handler callback.Handler
|
||||
}
|
||||
|
||||
type authenticateeConfig struct {
|
||||
client upid.UPID // pid of the client we're attempting to authenticate
|
||||
handler callback.Handler
|
||||
transport messenger.Messenger // mesos communications transport
|
||||
}
|
||||
|
||||
type transportFactory interface {
|
||||
makeTransport() messenger.Messenger
|
||||
}
|
||||
|
||||
type transportFactoryFunc func() messenger.Messenger
|
||||
|
||||
func (f transportFactoryFunc) makeTransport() messenger.Messenger {
|
||||
return f()
|
||||
}
|
||||
|
||||
func init() {
|
||||
factory := func(ctx context.Context) transportFactoryFunc {
|
||||
return transportFactoryFunc(func() messenger.Messenger {
|
||||
parent := auth.ParentUPID(ctx)
|
||||
if parent == nil {
|
||||
log.Fatal("expected to have a parent UPID in context")
|
||||
}
|
||||
|
||||
process := process.New("sasl_authenticatee")
|
||||
tpid := upid.UPID{
|
||||
ID: process.Label(),
|
||||
Host: parent.Host,
|
||||
Port: BindingPortFrom(ctx),
|
||||
}
|
||||
|
||||
return messenger.NewHttpWithBindingAddress(tpid, BindingAddressFrom(ctx))
|
||||
})
|
||||
}
|
||||
delegate := auth.AuthenticateeFunc(func(ctx context.Context, handler callback.Handler) error {
|
||||
if impl, err := makeAuthenticatee(handler, factory(ctx)); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return impl.Authenticate(ctx, handler)
|
||||
}
|
||||
})
|
||||
if err := auth.RegisterAuthenticateeProvider(ProviderName, delegate); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *statusType) get() statusType {
|
||||
return statusType(atomic.LoadInt32((*int32)(s)))
|
||||
}
|
||||
|
||||
func (s *statusType) swap(old, new statusType) bool {
|
||||
return old != new && atomic.CompareAndSwapInt32((*int32)(s), int32(old), int32(new))
|
||||
}
|
||||
|
||||
// build a new authenticatee implementation using the given callbacks and a new transport instance
|
||||
func makeAuthenticatee(handler callback.Handler, factory transportFactory) (auth.Authenticatee, error) {
|
||||
|
||||
ip := callback.NewInterprocess()
|
||||
if err := handler.Handle(ip); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config := &authenticateeConfig{
|
||||
client: ip.Client(),
|
||||
handler: handler,
|
||||
transport: factory.makeTransport(),
|
||||
}
|
||||
return auth.AuthenticateeFunc(func(ctx context.Context, handler callback.Handler) error {
|
||||
ctx, auth := newAuthenticatee(ctx, config)
|
||||
auth.authenticate(ctx, ip.Server())
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return auth.discard(ctx)
|
||||
case <-auth.done:
|
||||
return auth.err
|
||||
}
|
||||
}), nil
|
||||
}
|
||||
|
||||
// Terminate the authentication process upon context cancellation;
|
||||
// only to be called if/when ctx.Done() has been signalled.
|
||||
func (self *authenticateeProcess) discard(ctx context.Context) error {
|
||||
err := ctx.Err()
|
||||
status := statusFrom(ctx)
|
||||
for ; status < _statusTerminal; status = (&self.status).get() {
|
||||
if self.terminate(status, statusDiscarded, err) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func newAuthenticatee(ctx context.Context, config *authenticateeConfig) (context.Context, *authenticateeProcess) {
|
||||
initialStatus := statusReady
|
||||
proc := &authenticateeProcess{
|
||||
transport: config.transport,
|
||||
client: config.client,
|
||||
handler: config.handler,
|
||||
status: initialStatus,
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
ctx = withStatus(ctx, initialStatus)
|
||||
err := proc.installHandlers(ctx)
|
||||
if err == nil {
|
||||
err = proc.startTransport()
|
||||
}
|
||||
if err != nil {
|
||||
proc.terminate(initialStatus, statusError, err)
|
||||
}
|
||||
return ctx, proc
|
||||
}
|
||||
|
||||
func (self *authenticateeProcess) startTransport() error {
|
||||
if err := self.transport.Start(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
go func() {
|
||||
// stop the authentication transport upon termination of the
|
||||
// authenticator process
|
||||
select {
|
||||
case <-self.done:
|
||||
log.V(2).Infof("stopping authenticator transport: %v", self.transport.UPID())
|
||||
self.transport.Stop()
|
||||
}
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns true when handlers are installed without error, otherwise terminates the
|
||||
// authentication process.
|
||||
func (self *authenticateeProcess) installHandlers(ctx context.Context) error {
|
||||
|
||||
type handlerFn func(ctx context.Context, from *upid.UPID, pbMsg proto.Message)
|
||||
|
||||
withContext := func(f handlerFn) messenger.MessageHandler {
|
||||
return func(from *upid.UPID, m proto.Message) {
|
||||
status := (&self.status).get()
|
||||
if self.from != nil && !self.from.Equal(from) {
|
||||
self.terminate(status, statusError, UnexpectedAuthenticatorPid)
|
||||
} else {
|
||||
f(withStatus(ctx, status), from, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Anticipate mechanisms and steps from the server
|
||||
handlers := []struct {
|
||||
f handlerFn
|
||||
m proto.Message
|
||||
}{
|
||||
{self.mechanisms, &mesos.AuthenticationMechanismsMessage{}},
|
||||
{self.step, &mesos.AuthenticationStepMessage{}},
|
||||
{self.completed, &mesos.AuthenticationCompletedMessage{}},
|
||||
{self.failed, &mesos.AuthenticationFailedMessage{}},
|
||||
{self.errored, &mesos.AuthenticationErrorMessage{}},
|
||||
}
|
||||
for _, h := range handlers {
|
||||
if err := self.transport.Install(withContext(h.f), h.m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// return true if the authentication status was updated (if true, self.done will have been closed)
|
||||
func (self *authenticateeProcess) terminate(old, new statusType, err error) bool {
|
||||
if (&self.status).swap(old, new) {
|
||||
self.err = err
|
||||
if self.mech != nil {
|
||||
self.mech.Discard()
|
||||
}
|
||||
close(self.done)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *authenticateeProcess) authenticate(ctx context.Context, pid upid.UPID) {
|
||||
status := statusFrom(ctx)
|
||||
if status != statusReady {
|
||||
return
|
||||
}
|
||||
message := &mesos.AuthenticateMessage{
|
||||
Pid: proto.String(self.client.String()),
|
||||
}
|
||||
if err := self.transport.Send(ctx, &pid, message); err != nil {
|
||||
self.terminate(status, statusError, err)
|
||||
} else {
|
||||
(&self.status).swap(status, statusStarting)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *authenticateeProcess) mechanisms(ctx context.Context, from *upid.UPID, pbMsg proto.Message) {
|
||||
status := statusFrom(ctx)
|
||||
if status != statusStarting {
|
||||
self.terminate(status, statusError, UnexpectedAuthenticationMechanisms)
|
||||
return
|
||||
}
|
||||
|
||||
msg, ok := pbMsg.(*mesos.AuthenticationMechanismsMessage)
|
||||
if !ok {
|
||||
self.terminate(status, statusError, fmt.Errorf("Expected AuthenticationMechanismsMessage, not %T", pbMsg))
|
||||
return
|
||||
}
|
||||
|
||||
mechanisms := msg.GetMechanisms()
|
||||
log.Infof("Received SASL authentication mechanisms: %v", mechanisms)
|
||||
|
||||
selectedMech, factory := mech.SelectSupported(mechanisms)
|
||||
if selectedMech == "" {
|
||||
self.terminate(status, statusError, UnsupportedMechanism)
|
||||
return
|
||||
}
|
||||
|
||||
if m, f, err := factory(self.handler); err != nil {
|
||||
self.terminate(status, statusError, err)
|
||||
return
|
||||
} else {
|
||||
self.mech = m
|
||||
self.stepFn = f
|
||||
self.from = from
|
||||
}
|
||||
|
||||
// execute initialization step...
|
||||
nextf, data, err := self.stepFn(self.mech, nil)
|
||||
if err != nil {
|
||||
self.terminate(status, statusError, err)
|
||||
return
|
||||
} else {
|
||||
self.stepFn = nextf
|
||||
}
|
||||
|
||||
message := &mesos.AuthenticationStartMessage{
|
||||
Mechanism: proto.String(selectedMech),
|
||||
Data: data, // may be nil, depends on init step
|
||||
}
|
||||
|
||||
if err := self.transport.Send(ctx, from, message); err != nil {
|
||||
self.terminate(status, statusError, err)
|
||||
} else {
|
||||
(&self.status).swap(status, statusStepping)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *authenticateeProcess) step(ctx context.Context, from *upid.UPID, pbMsg proto.Message) {
|
||||
status := statusFrom(ctx)
|
||||
if status != statusStepping {
|
||||
self.terminate(status, statusError, UnexpectedAuthenticationStep)
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("Received SASL authentication step")
|
||||
|
||||
msg, ok := pbMsg.(*mesos.AuthenticationStepMessage)
|
||||
if !ok {
|
||||
self.terminate(status, statusError, fmt.Errorf("Expected AuthenticationStepMessage, not %T", pbMsg))
|
||||
return
|
||||
}
|
||||
|
||||
input := msg.GetData()
|
||||
fn, output, err := self.stepFn(self.mech, input)
|
||||
|
||||
if err != nil {
|
||||
self.terminate(status, statusError, fmt.Errorf("failed to perform authentication step: %v", err))
|
||||
return
|
||||
}
|
||||
self.stepFn = fn
|
||||
|
||||
// We don't start the client with SASL_SUCCESS_DATA so we may
|
||||
// need to send one more "empty" message to the server.
|
||||
message := &mesos.AuthenticationStepMessage{}
|
||||
if len(output) > 0 {
|
||||
message.Data = output
|
||||
}
|
||||
if err := self.transport.Send(ctx, from, message); err != nil {
|
||||
self.terminate(status, statusError, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *authenticateeProcess) completed(ctx context.Context, from *upid.UPID, pbMsg proto.Message) {
|
||||
status := statusFrom(ctx)
|
||||
if status != statusStepping {
|
||||
self.terminate(status, statusError, UnexpectedAuthenticationCompleted)
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("Authentication success")
|
||||
self.terminate(status, statusCompleted, nil)
|
||||
}
|
||||
|
||||
func (self *authenticateeProcess) failed(ctx context.Context, from *upid.UPID, pbMsg proto.Message) {
|
||||
status := statusFrom(ctx)
|
||||
self.terminate(status, statusFailed, auth.AuthenticationFailed)
|
||||
}
|
||||
|
||||
func (self *authenticateeProcess) errored(ctx context.Context, from *upid.UPID, pbMsg proto.Message) {
|
||||
var err error
|
||||
if msg, ok := pbMsg.(*mesos.AuthenticationErrorMessage); !ok {
|
||||
err = fmt.Errorf("Expected AuthenticationErrorMessage, not %T", pbMsg)
|
||||
} else {
|
||||
err = fmt.Errorf("Authentication error: %s", msg.GetError())
|
||||
}
|
||||
status := statusFrom(ctx)
|
||||
self.terminate(status, statusError, err)
|
||||
}
|
56
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/context.go
generated
vendored
Normal file
56
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/context.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
package sasl
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// unexported to prevent collisions with context keys defined in
|
||||
// other packages.
|
||||
type _key int
|
||||
|
||||
// If this package defined other context keys, they would have
|
||||
// different integer values.
|
||||
const (
|
||||
statusKey _key = iota
|
||||
bindingAddressKey // bind address for login-related network ops
|
||||
bindingPortKey // port to bind auth listener if a specific port is needed
|
||||
)
|
||||
|
||||
func withStatus(ctx context.Context, s statusType) context.Context {
|
||||
return context.WithValue(ctx, statusKey, s)
|
||||
}
|
||||
|
||||
func statusFrom(ctx context.Context) statusType {
|
||||
s, ok := ctx.Value(statusKey).(statusType)
|
||||
if !ok {
|
||||
panic("missing status in context")
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func WithBindingAddress(ctx context.Context, address net.IP) context.Context {
|
||||
return context.WithValue(ctx, bindingAddressKey, address)
|
||||
}
|
||||
|
||||
func BindingAddressFrom(ctx context.Context) net.IP {
|
||||
obj := ctx.Value(bindingAddressKey)
|
||||
if addr, ok := obj.(net.IP); ok {
|
||||
return addr
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithBindingPort(ctx context.Context, port uint16) context.Context {
|
||||
return context.WithValue(ctx, bindingPortKey, port)
|
||||
}
|
||||
|
||||
func BindingPortFrom(ctx context.Context) string {
|
||||
if port, ok := ctx.Value(bindingPortKey).(uint16); ok {
|
||||
return strconv.Itoa(int(port))
|
||||
}
|
||||
return "0"
|
||||
}
|
72
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/mech/crammd5/mechanism.go
generated
vendored
Normal file
72
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/mech/crammd5/mechanism.go
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
package crammd5
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
log "github.com/golang/glog"
|
||||
"github.com/mesos/mesos-go/api/v0/auth/callback"
|
||||
"github.com/mesos/mesos-go/api/v0/auth/sasl/mech"
|
||||
)
|
||||
|
||||
var (
|
||||
Name = "CRAM-MD5" // name this mechanism is registered with
|
||||
|
||||
//TODO(jdef) is this a generic SASL error? if so, move it up to mech
|
||||
challengeDataRequired = errors.New("challenge data may not be empty")
|
||||
)
|
||||
|
||||
func init() {
|
||||
mech.Register(Name, newInstance)
|
||||
}
|
||||
|
||||
type mechanism struct {
|
||||
handler callback.Handler
|
||||
}
|
||||
|
||||
func (m *mechanism) Handler() callback.Handler {
|
||||
return m.handler
|
||||
}
|
||||
|
||||
func (m *mechanism) Discard() {
|
||||
// noop
|
||||
}
|
||||
|
||||
func newInstance(h callback.Handler) (mech.Interface, mech.StepFunc, error) {
|
||||
m := &mechanism{
|
||||
handler: h,
|
||||
}
|
||||
fn := func(m mech.Interface, data []byte) (mech.StepFunc, []byte, error) {
|
||||
// noop: no initialization needed
|
||||
return challengeResponse, nil, nil
|
||||
}
|
||||
return m, fn, nil
|
||||
}
|
||||
|
||||
// algorithm lifted from wikipedia: http://en.wikipedia.org/wiki/CRAM-MD5
|
||||
// except that the SASL mechanism used by Mesos doesn't leverage base64 encoding
|
||||
func challengeResponse(m mech.Interface, data []byte) (mech.StepFunc, []byte, error) {
|
||||
if len(data) == 0 {
|
||||
return mech.IllegalState, nil, challengeDataRequired
|
||||
}
|
||||
decoded := string(data)
|
||||
log.V(4).Infof("challenge(decoded): %s", decoded) // for deep debugging only
|
||||
|
||||
username := callback.NewName()
|
||||
secret := callback.NewPassword()
|
||||
|
||||
if err := m.Handler().Handle(username, secret); err != nil {
|
||||
return mech.IllegalState, nil, err
|
||||
}
|
||||
hash := hmac.New(md5.New, secret.Get())
|
||||
if _, err := io.WriteString(hash, decoded); err != nil {
|
||||
return mech.IllegalState, nil, err
|
||||
}
|
||||
|
||||
codes := hex.EncodeToString(hash.Sum(nil))
|
||||
msg := username.Get() + " " + codes
|
||||
return nil, []byte(msg), nil
|
||||
}
|
33
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/mech/interface.go
generated
vendored
Normal file
33
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/mech/interface.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
package mech
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/mesos/mesos-go/api/v0/auth/callback"
|
||||
)
|
||||
|
||||
var (
|
||||
IllegalStateErr = errors.New("illegal mechanism state")
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Handler() callback.Handler
|
||||
Discard() // clean up resources or sensitive information; idempotent
|
||||
}
|
||||
|
||||
// return a mechanism and it's initialization step (may be a noop that returns
|
||||
// a nil data blob and handle to the first "real" challenge step).
|
||||
type Factory func(h callback.Handler) (Interface, StepFunc, error)
|
||||
|
||||
// StepFunc implementations should never return a nil StepFunc result. This
|
||||
// helps keep the logic in the SASL authticatee simpler: step functions are
|
||||
// never nil. Mechanisms that end up an error state (for example, some decoding
|
||||
// logic fails...) should return a StepFunc that represents an error state.
|
||||
// Some mechanisms may be able to recover from such.
|
||||
type StepFunc func(m Interface, data []byte) (StepFunc, []byte, error)
|
||||
|
||||
// reflects an unrecoverable, illegal mechanism state; always returns IllegalState
|
||||
// as the next step along with an IllegalStateErr
|
||||
func IllegalState(m Interface, data []byte) (StepFunc, []byte, error) {
|
||||
return IllegalState, nil, IllegalStateErr
|
||||
}
|
49
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/mech/plugins.go
generated
vendored
Normal file
49
vendor/github.com/mesos/mesos-go/api/v0/auth/sasl/mech/plugins.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
package mech
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
log "github.com/golang/glog"
|
||||
)
|
||||
|
||||
var (
|
||||
mechLock sync.Mutex
|
||||
supportedMechs = make(map[string]Factory)
|
||||
)
|
||||
|
||||
func Register(name string, f Factory) error {
|
||||
mechLock.Lock()
|
||||
defer mechLock.Unlock()
|
||||
|
||||
if _, found := supportedMechs[name]; found {
|
||||
return fmt.Errorf("Mechanism registered twice: %s", name)
|
||||
}
|
||||
supportedMechs[name] = f
|
||||
log.V(1).Infof("Registered mechanism %s", name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListSupported() (list []string) {
|
||||
mechLock.Lock()
|
||||
defer mechLock.Unlock()
|
||||
|
||||
for mechname := range supportedMechs {
|
||||
list = append(list, mechname)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func SelectSupported(mechanisms []string) (selectedMech string, factory Factory) {
|
||||
mechLock.Lock()
|
||||
defer mechLock.Unlock()
|
||||
|
||||
for _, m := range mechanisms {
|
||||
if f, ok := supportedMechs[m]; ok {
|
||||
selectedMech = m
|
||||
factory = f
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
Reference in a new issue