Source File
client_auth.go
Belonging Package
golang.org/x/crypto/ssh
package ssh
import (
)
type authResult int
const (
authFailure authResult = iota
authPartialSuccess
authSuccess
)
if := .transport.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})); != nil {
return
}
, := .transport.readPacket()
if != nil {
return
}
var serviceAcceptMsg
if := Unmarshal(, &); != nil {
return
}
return nil
} else if == authFailure {
if := .method(); !contains(, ) {
= append(, )
}
}
if == nil {
=
}
=
= nil
:
for , := range .Auth {
:= .method()
if contains(, ) {
continue
}
for , := range {
if == {
=
break
}
}
}
}
return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", )
}
func ( []string, string) bool {
for , := range {
if == {
return true
}
}
return false
}
auth(session []byte, user string, p packetConn, rand io.Reader) (authResult, []string, error)
method() string
}
type noneAuth int
func ( *noneAuth) ( []byte, string, packetConn, io.Reader) (authResult, []string, error) {
if := .writePacket(Marshal(&userAuthRequestMsg{
User: ,
Service: serviceSSH,
Method: "none",
})); != nil {
return authFailure, nil,
}
return handleAuthResponse()
}
func ( *noneAuth) () string {
return "none"
}
type passwordCallback func() (password string, err error)
func ( passwordCallback) ( []byte, string, packetConn, io.Reader) (authResult, []string, error) {
type struct {
string `sshtype:"50"`
string
string
bool
string
}
if != nil {
return authFailure, nil,
}
if := .writePacket(Marshal(&{
: ,
: serviceSSH,
: .method(),
: false,
: ,
})); != nil {
return authFailure, nil,
}
return handleAuthResponse()
}
func ( passwordCallback) () string {
return "password"
}
func ( string) AuthMethod {
return passwordCallback(func() (string, error) { return , nil })
}
func ( func() ( string, error)) AuthMethod {
return passwordCallback()
}
type publickeyAuthMsg struct {
User string `sshtype:"50"`
Service string
type publicKeyCallback func() ([]Signer, error)
func ( publicKeyCallback) () string {
return "publickey"
}
, := ()
if != nil {
return authFailure, nil,
}
var []string
for , := range {
, := validateKey(.PublicKey(), , )
if != nil {
return authFailure, nil,
}
if ! {
continue
}
:= .PublicKey()
:= .Marshal()
, := .Sign(, buildDataSignedForAuth(, userAuthRequestMsg{
User: ,
Service: serviceSSH,
Method: .method(),
}, []byte(.Type()), ))
if != nil {
return authFailure, nil,
}
:= Marshal()
:= make([]byte, stringLength(len()))
marshalString(, )
:= publickeyAuthMsg{
User: ,
Service: serviceSSH,
Method: .method(),
HasSig: true,
Algoname: .Type(),
PubKey: ,
Sig: ,
}
:= Marshal(&)
if := .writePacket(); != nil {
return authFailure, nil,
}
var authResult
, , = handleAuthResponse()
if != nil {
return authFailure, nil,
}
if == authSuccess || !containsMethod(, .method()) {
return , ,
}
}
return authFailure, , nil
}
func ( []string, string) bool {
for , := range {
if == {
return true
}
}
return false
}
func ( PublicKey, string, packetConn) (bool, error) {
:= .Marshal()
:= publickeyAuthMsg{
User: ,
Service: serviceSSH,
Method: "publickey",
HasSig: false,
Algoname: .Type(),
PubKey: ,
}
if := .writePacket(Marshal(&)); != nil {
return false,
}
return confirmKeyAck(, )
}
func ( PublicKey, packetConn) (bool, error) {
:= .Marshal()
:= .Type()
for {
, := .readPacket()
if != nil {
return false,
}
switch [0] {
case msgUserAuthBanner:
if := handleBannerResponse(, ); != nil {
return false,
}
case msgUserAuthPubKeyOk:
var userAuthPubKeyOkMsg
if := Unmarshal(, &); != nil {
return false,
}
if .Algo != || !bytes.Equal(.PubKey, ) {
return false, nil
}
return true, nil
case msgUserAuthFailure:
return false, nil
default:
return false, unexpectedMessageError(msgUserAuthSuccess, [0])
}
}
}
func ( ...Signer) AuthMethod {
return publicKeyCallback(func() ([]Signer, error) { return , nil })
}
func ( func() ( []Signer, error)) AuthMethod {
return publicKeyCallback()
}
func ( packetConn) (authResult, []string, error) {
for {
, := .readPacket()
if != nil {
return authFailure, nil,
}
switch [0] {
case msgUserAuthBanner:
if := handleBannerResponse(, ); != nil {
return authFailure, nil,
}
case msgUserAuthFailure:
var userAuthFailureMsg
if := Unmarshal(, &); != nil {
return authFailure, nil,
}
if .PartialSuccess {
return authPartialSuccess, .Methods, nil
}
return authFailure, .Methods, nil
case msgUserAuthSuccess:
return authSuccess, nil, nil
default:
return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, [0])
}
}
}
func ( packetConn, []byte) error {
var userAuthBannerMsg
if := Unmarshal(, &); != nil {
return
}
, := .(*handshakeTransport)
if ! {
return nil
}
if .bannerCallback != nil {
return .bannerCallback(.Message)
}
return nil
}
func ( KeyboardInteractiveChallenge) AuthMethod {
return
}
func ( KeyboardInteractiveChallenge) () string {
return "keyboard-interactive"
}
func ( KeyboardInteractiveChallenge) ( []byte, string, packetConn, io.Reader) (authResult, []string, error) {
type struct {
string `sshtype:"50"`
string
string
string
string
}
if := .writePacket(Marshal(&{
: ,
: serviceSSH,
: "keyboard-interactive",
})); != nil {
return authFailure, nil,
}
for {
, := .readPacket()
if != nil {
return authFailure, nil,
}
switch [0] {
case msgUserAuthBanner:
if := handleBannerResponse(, ); != nil {
return authFailure, nil,
}
continue
case msgUserAuthFailure:
var userAuthFailureMsg
if := Unmarshal(, &); != nil {
return authFailure, nil,
}
if .PartialSuccess {
return authPartialSuccess, .Methods, nil
}
return authFailure, .Methods, nil
case msgUserAuthSuccess:
return authSuccess, nil, nil
default:
return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, [0])
}
var userAuthInfoRequestMsg
if := Unmarshal(, &); != nil {
return authFailure, nil,
}
:= .Prompts
var []string
var []bool
for := 0; < int(.NumPrompts); ++ {
, , := parseString()
if ! || len() == 0 {
return authFailure, nil, errors.New("ssh: prompt format error")
}
= append(, string())
= append(, [0] != 0)
= [1:]
}
if len() != 0 {
return authFailure, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
}
, := (.User, .Instruction, , )
if != nil {
return authFailure, nil,
}
if len() != len() {
return authFailure, nil, fmt.Errorf("ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)", len(), len())
}
:= 1 + 4
for , := range {
+= stringLength(len())
}
:= make([]byte, )
:=
[0] = msgUserAuthInfoResponse
= [1:]
= marshalUint32(, uint32(len()))
for , := range {
= marshalString(, []byte())
}
if := .writePacket(); != nil {
return authFailure, nil,
}
}
}
type retryableAuthMethod struct {
authMethod AuthMethod
maxTries int
}
func ( *retryableAuthMethod) ( []byte, string, packetConn, io.Reader) ( authResult, []string, error) {
for := 0; .maxTries <= 0 || < .maxTries; ++ {
, , = .authMethod.auth(, , , )
if != authFailure || != nil { // either success, partial success or error terminate
return , ,
}
}
return , ,
}
func ( *retryableAuthMethod) () string {
return .authMethod.method()
}
func ( AuthMethod, int) AuthMethod {
return &retryableAuthMethod{authMethod: , maxTries: }
}
func ( GSSAPIClient, string) AuthMethod {
if == nil {
panic("gss-api client must be not nil with enable gssapi-with-mic")
}
return &gssAPIWithMICCallback{gssAPIClient: , target: }
}
type gssAPIWithMICCallback struct {
gssAPIClient GSSAPIClient
target string
}
func ( *gssAPIWithMICCallback) ( []byte, string, packetConn, io.Reader) (authResult, []string, error) {
:= &userAuthRequestMsg{
User: ,
Service: serviceSSH,
Method: .method(),
.Payload = appendU32(.Payload, 1)
.Payload = appendString(.Payload, string(krb5OID))
if := .writePacket(Marshal()); != nil {
return authFailure, nil,
, := .readPacket()
if != nil {
return authFailure, nil,
}
:= &userAuthGSSAPIResponse{}
if := Unmarshal(, ); != nil {
return authFailure, nil,
var []byte
defer .gssAPIClient.DeleteSecContext()
, , := .gssAPIClient.InitSecContext("host@"+.target, , false)
if != nil {
return authFailure, nil,
}
if len() > 0 {
if := .writePacket(Marshal(&userAuthGSSAPIToken{
Token: ,
})); != nil {
return authFailure, nil,
}
}
if ! {
break
}
, = .readPacket()
if != nil {
return authFailure, nil,
}
switch [0] {
case msgUserAuthFailure:
var userAuthFailureMsg
if := Unmarshal(, &); != nil {
return authFailure, nil,
}
if .PartialSuccess {
return authPartialSuccess, .Methods, nil
}
return authFailure, .Methods, nil
case msgUserAuthGSSAPIError:
:= &userAuthGSSAPIError{}
if := Unmarshal(, ); != nil {
return authFailure, nil,
}
return authFailure, nil, fmt.Errorf("GSS-API Error:\n"+
"Major Status: %d\n"+
"Minor Status: %d\n"+
"Error Message: %s\n", .MajorStatus, .MinorStatus,
.Message)
case msgUserAuthGSSAPIToken:
:= &userAuthGSSAPIToken{}
if := Unmarshal(, ); != nil {
return authFailure, nil,
}
= .Token
}
:= buildMIC(string(), , "ssh-connection", "gssapi-with-mic")
, := .gssAPIClient.GetMIC()
if != nil {
return authFailure, nil,
}
if := .writePacket(Marshal(&userAuthGSSAPIMIC{
MIC: ,
})); != nil {
return authFailure, nil,
}
return handleAuthResponse()
}
func ( *gssAPIWithMICCallback) () string {
return "gssapi-with-mic"
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |