// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssh

import (
	"encoding/asn1"
	"errors"
)

var krb5OID []byte

func init() {
	krb5OID, _ = asn1.Marshal(krb5Mesh)
}

// GSSAPIClient provides the API to plug-in GSSAPI authentication for client logins.
type GSSAPIClient interface {
	// InitSecContext initiates the establishment of a security context for GSS-API between the
	// ssh client and ssh server. Initially the token parameter should be specified as nil.
	// The routine may return a outputToken which should be transferred to
	// the ssh server, where the ssh server will present it to
	// AcceptSecContext. If no token need be sent, InitSecContext will indicate this by setting
	// needContinue to false. To complete the context
	// establishment, one or more reply tokens may be required from the ssh
	// server;if so, InitSecContext will return a needContinue which is true.
	// In this case, InitSecContext should be called again when the
	// reply token is received from the ssh server, passing the reply
	// token to InitSecContext via the token parameters.
	// See RFC 2743 section 2.2.1 and RFC 4462 section 3.4.
	InitSecContext(target string, token []byte, isGSSDelegCreds bool) (outputToken []byte, needContinue bool, err error)
	// GetMIC generates a cryptographic MIC for the SSH2 message, and places
	// the MIC in a token for transfer to the ssh server.
	// The contents of the MIC field are obtained by calling GSS_GetMIC()
	// over the following, using the GSS-API context that was just
	// established:
	//  string    session identifier
	//  byte      SSH_MSG_USERAUTH_REQUEST
	//  string    user name
	//  string    service
	//  string    "gssapi-with-mic"
	// See RFC 2743 section 2.3.1 and RFC 4462 3.5.
	GetMIC(micFiled []byte) ([]byte, error)
	// Whenever possible, it should be possible for
	// DeleteSecContext() calls to be successfully processed even
	// if other calls cannot succeed, thereby enabling context-related
	// resources to be released.
	// In addition to deleting established security contexts,
	// gss_delete_sec_context must also be able to delete "half-built"
	// security contexts resulting from an incomplete sequence of
	// InitSecContext()/AcceptSecContext() calls.
	// See RFC 2743 section 2.2.3.
	DeleteSecContext() error
}

// GSSAPIServer provides the API to plug in GSSAPI authentication for server logins.
type GSSAPIServer interface {
	// AcceptSecContext allows a remotely initiated security context between the application
	// and a remote peer to be established by the ssh client. The routine may return a
	// outputToken which should be transferred to the ssh client,
	// where the ssh client will present it to InitSecContext.
	// If no token need be sent, AcceptSecContext will indicate this
	// by setting the needContinue to false. To
	// complete the context establishment, one or more reply tokens may be
	// required from the ssh client. if so, AcceptSecContext
	// will return a needContinue which is true, in which case it
	// should be called again when the reply token is received from the ssh
	// client, passing the token to AcceptSecContext via the
	// token parameters.
	// The srcName return value is the authenticated username.
	// See RFC 2743 section 2.2.2 and RFC 4462 section 3.4.
	AcceptSecContext(token []byte) (outputToken []byte, srcName string, needContinue bool, err error)
	// VerifyMIC verifies that a cryptographic MIC, contained in the token parameter,
	// fits the supplied message is received from the ssh client.
	// See RFC 2743 section 2.3.2.
	VerifyMIC(micField []byte, micToken []byte) error
	// Whenever possible, it should be possible for
	// DeleteSecContext() calls to be successfully processed even
	// if other calls cannot succeed, thereby enabling context-related
	// resources to be released.
	// In addition to deleting established security contexts,
	// gss_delete_sec_context must also be able to delete "half-built"
	// security contexts resulting from an incomplete sequence of
	// InitSecContext()/AcceptSecContext() calls.
	// See RFC 2743 section 2.2.3.
	DeleteSecContext() error
}

var (
	// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,
	// so we also support the krb5 mechanism only.
	// See RFC 1964 section 1.
	krb5Mesh = asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
)

// The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST
// See RFC 4462 section 3.2.
type userAuthRequestGSSAPI struct {
	N    uint32
	OIDS []asn1.ObjectIdentifier
}

func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) {
	n, rest, ok := parseUint32(payload)
	if !ok {
		return nil, errors.New("parse uint32 failed")
	}
	s := &userAuthRequestGSSAPI{
		N:    n,
		OIDS: make([]asn1.ObjectIdentifier, n),
	}
	for i := 0; i < int(n); i++ {
		var (
			desiredMech []byte
			err         error
		)
		desiredMech, rest, ok = parseString(rest)
		if !ok {
			return nil, errors.New("parse string failed")
		}
		if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil {
			return nil, err
		}

	}
	return s, nil
}

// See RFC 4462 section 3.6.
func buildMIC(sessionID string, username string, service string, authMethod string) []byte {
	out := make([]byte, 0, 0)
	out = appendString(out, sessionID)
	out = append(out, msgUserAuthRequest)
	out = appendString(out, username)
	out = appendString(out, service)
	out = appendString(out, authMethod)
	return out
}
