gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ssh_gss.go (5570B)


      1 // Copyright 2011 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package ssh
      6 
      7 import (
      8 	"encoding/asn1"
      9 	"errors"
     10 )
     11 
     12 var krb5OID []byte
     13 
     14 func init() {
     15 	krb5OID, _ = asn1.Marshal(krb5Mesh)
     16 }
     17 
     18 // GSSAPIClient provides the API to plug-in GSSAPI authentication for client logins.
     19 type GSSAPIClient interface {
     20 	// InitSecContext initiates the establishment of a security context for GSS-API between the
     21 	// ssh client and ssh server. Initially the token parameter should be specified as nil.
     22 	// The routine may return a outputToken which should be transferred to
     23 	// the ssh server, where the ssh server will present it to
     24 	// AcceptSecContext. If no token need be sent, InitSecContext will indicate this by setting
     25 	// needContinue to false. To complete the context
     26 	// establishment, one or more reply tokens may be required from the ssh
     27 	// server;if so, InitSecContext will return a needContinue which is true.
     28 	// In this case, InitSecContext should be called again when the
     29 	// reply token is received from the ssh server, passing the reply
     30 	// token to InitSecContext via the token parameters.
     31 	// See RFC 2743 section 2.2.1 and RFC 4462 section 3.4.
     32 	InitSecContext(target string, token []byte, isGSSDelegCreds bool) (outputToken []byte, needContinue bool, err error)
     33 	// GetMIC generates a cryptographic MIC for the SSH2 message, and places
     34 	// the MIC in a token for transfer to the ssh server.
     35 	// The contents of the MIC field are obtained by calling GSS_GetMIC()
     36 	// over the following, using the GSS-API context that was just
     37 	// established:
     38 	//  string    session identifier
     39 	//  byte      SSH_MSG_USERAUTH_REQUEST
     40 	//  string    user name
     41 	//  string    service
     42 	//  string    "gssapi-with-mic"
     43 	// See RFC 2743 section 2.3.1 and RFC 4462 3.5.
     44 	GetMIC(micFiled []byte) ([]byte, error)
     45 	// Whenever possible, it should be possible for
     46 	// DeleteSecContext() calls to be successfully processed even
     47 	// if other calls cannot succeed, thereby enabling context-related
     48 	// resources to be released.
     49 	// In addition to deleting established security contexts,
     50 	// gss_delete_sec_context must also be able to delete "half-built"
     51 	// security contexts resulting from an incomplete sequence of
     52 	// InitSecContext()/AcceptSecContext() calls.
     53 	// See RFC 2743 section 2.2.3.
     54 	DeleteSecContext() error
     55 }
     56 
     57 // GSSAPIServer provides the API to plug in GSSAPI authentication for server logins.
     58 type GSSAPIServer interface {
     59 	// AcceptSecContext allows a remotely initiated security context between the application
     60 	// and a remote peer to be established by the ssh client. The routine may return a
     61 	// outputToken which should be transferred to the ssh client,
     62 	// where the ssh client will present it to InitSecContext.
     63 	// If no token need be sent, AcceptSecContext will indicate this
     64 	// by setting the needContinue to false. To
     65 	// complete the context establishment, one or more reply tokens may be
     66 	// required from the ssh client. if so, AcceptSecContext
     67 	// will return a needContinue which is true, in which case it
     68 	// should be called again when the reply token is received from the ssh
     69 	// client, passing the token to AcceptSecContext via the
     70 	// token parameters.
     71 	// The srcName return value is the authenticated username.
     72 	// See RFC 2743 section 2.2.2 and RFC 4462 section 3.4.
     73 	AcceptSecContext(token []byte) (outputToken []byte, srcName string, needContinue bool, err error)
     74 	// VerifyMIC verifies that a cryptographic MIC, contained in the token parameter,
     75 	// fits the supplied message is received from the ssh client.
     76 	// See RFC 2743 section 2.3.2.
     77 	VerifyMIC(micField []byte, micToken []byte) error
     78 	// Whenever possible, it should be possible for
     79 	// DeleteSecContext() calls to be successfully processed even
     80 	// if other calls cannot succeed, thereby enabling context-related
     81 	// resources to be released.
     82 	// In addition to deleting established security contexts,
     83 	// gss_delete_sec_context must also be able to delete "half-built"
     84 	// security contexts resulting from an incomplete sequence of
     85 	// InitSecContext()/AcceptSecContext() calls.
     86 	// See RFC 2743 section 2.2.3.
     87 	DeleteSecContext() error
     88 }
     89 
     90 var (
     91 	// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,
     92 	// so we also support the krb5 mechanism only.
     93 	// See RFC 1964 section 1.
     94 	krb5Mesh = asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
     95 )
     96 
     97 // The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST
     98 // See RFC 4462 section 3.2.
     99 type userAuthRequestGSSAPI struct {
    100 	N    uint32
    101 	OIDS []asn1.ObjectIdentifier
    102 }
    103 
    104 func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) {
    105 	n, rest, ok := parseUint32(payload)
    106 	if !ok {
    107 		return nil, errors.New("parse uint32 failed")
    108 	}
    109 	s := &userAuthRequestGSSAPI{
    110 		N:    n,
    111 		OIDS: make([]asn1.ObjectIdentifier, n),
    112 	}
    113 	for i := 0; i < int(n); i++ {
    114 		var (
    115 			desiredMech []byte
    116 			err         error
    117 		)
    118 		desiredMech, rest, ok = parseString(rest)
    119 		if !ok {
    120 			return nil, errors.New("parse string failed")
    121 		}
    122 		if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil {
    123 			return nil, err
    124 		}
    125 
    126 	}
    127 	return s, nil
    128 }
    129 
    130 // See RFC 4462 section 3.6.
    131 func buildMIC(sessionID string, username string, service string, authMethod string) []byte {
    132 	out := make([]byte, 0, 0)
    133 	out = appendString(out, sessionID)
    134 	out = append(out, msgUserAuthRequest)
    135 	out = appendString(out, username)
    136 	out = appendString(out, service)
    137 	out = appendString(out, authMethod)
    138 	return out
    139 }