File: spnego_transport.go

package info (click to toggle)
gitlab-shell 14.35.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 23,652 kB
  • sloc: ruby: 1,129; makefile: 583; sql: 391; sh: 384
file content (77 lines) | stat: -rw-r--r-- 1,955 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2013-2015 Apcera Inc. All rights reserved.

package spnego

import (
	"encoding/base64"
	"fmt"
	"net/http"
	"strings"

	"github.com/apcera/gssapi"
)

const negotiateScheme = "Negotiate"

// AddSPNEGONegotiate adds a Negotiate header with the value of a serialized
// token to an http header.
func AddSPNEGONegotiate(h http.Header, name string, token *gssapi.Buffer) {
	if name == "" {
		return
	}

	v := negotiateScheme
	if token.Length() != 0 {
		data := token.Bytes()
		v = v + " " + base64.StdEncoding.EncodeToString(data)
	}
	h.Set(name, v)
}

// CheckSPNEGONegotiate checks for the presence of a Negotiate header. If
// present, we return a gssapi Token created from the header value sent to us.
func CheckSPNEGONegotiate(lib *gssapi.Lib, h http.Header, name string) (bool, *gssapi.Buffer) {
	var err error
	defer func() {
		if err != nil {
			lib.Debug(fmt.Sprintf("CheckSPNEGONegotiate: %v", err))
		}
	}()

	for _, header := range h[http.CanonicalHeaderKey(name)] {
		if len(header) < len(negotiateScheme) {
			continue
		}
		if !strings.EqualFold(header[:len(negotiateScheme)], negotiateScheme) {
			continue
		}

		// Remove the "Negotiate" prefix
		normalizedToken := header[len(negotiateScheme):]
		// Trim leading and trailing whitespace
		normalizedToken = strings.TrimSpace(normalizedToken)
		// Remove internal whitespace (some servers insert whitespace every 76 chars)
		normalizedToken = strings.Replace(normalizedToken, " ", "", -1)
		// Pad to a multiple of 4 chars for base64 (some servers strip trailing padding)
		if unpaddedChars := len(normalizedToken) % 4; unpaddedChars != 0 {
			normalizedToken += strings.Repeat("=", 4-unpaddedChars)
		}

		tbytes, err := base64.StdEncoding.DecodeString(normalizedToken)
		if err != nil {
			continue
		}

		if len(tbytes) == 0 {
			return true, nil
		}

		token, err := lib.MakeBufferBytes(tbytes)
		if err != nil {
			continue
		}
		return true, token
	}

	return false, nil
}