Jonathan Turner 9 vuotta sitten
vanhempi
commit
dfdcadd9a3

+ 29 - 15
GSSAPI/NegotiationToken.go

@@ -43,16 +43,26 @@ NegTokenResp ::= SEQUENCE {
 // Tag attribute of NegotiationToken will indicate type:
 // 0xa0 (160) - negTokenInit
 // 0xa1 (161) - negTokenResp
-type NegotiationToken asn1.RawValue
+type NegotiationToken struct {
+	Choice asn1.RawValue
+}
 
 type NegTokenInit struct {
+	Body    asn1.RawValue `asn1:"explicit,tag:0"`
+}
+
+type NegTokenResp struct {
+	Body    NegTokenRespBody `asn1:"explicit,tag:1"`
+}
+
+type NegTokenInitBody struct {
 	MechTypes    MechTypeList `asn1:"explicit,tag:0"`
 	ReqFlags     ContextFlags `asn1:"explicit,optional,tag:1"`
 	MechToken    []byte       `asn1:"explicit,optional,tag:2"`
 	MechTokenMIC []byte       `asn1:"explicit,optional,tag:3"`
 }
 
-type NegTokenResp struct {
+type NegTokenRespBody struct {
 	NegState      asn1.Enumerated `asn1:"explicit,optional,tag:0"`
 	SupportedMech MechType        `asn1:"explicit,optional,tag:1"`
 	ResponseToken []byte          `asn1:"explicit,optional,tag:2"`
@@ -70,18 +80,18 @@ func (n *NegotiationToken) Unmarshal(b []byte) (bool, interface{}, error) {
 	}
 	var negToken interface{}
 	var isInit bool
-	switch n.Tag {
+	switch n.Choice.Tag {
 	case 0:
-		negToken = &NegTokenInit{}
+		negToken = NegTokenInit{}
 		isInit = true
 	case 1:
-		negToken = &NegTokenResp{}
+		negToken = NegTokenResp{}
 	default:
 		return false, nil, errors.New("Unknown choice type for NegotiationToken")
 	}
-	_, err = asn1.Unmarshal(n.Bytes, negToken)
+	_, err = asn1.Unmarshal(b, &negToken)
 	if err != nil {
-		return nil, fmt.Errorf("Error unmarshalling NegotiationToken type %d: %v", n.Tag, err)
+		return false, nil, fmt.Errorf("Error unmarshalling NegotiationToken type %d: %v", n.Choice.Tag, err)
 	}
 	return isInit, negToken, nil
 }
@@ -93,10 +103,12 @@ func (n *NegTokenInit) Marshal() ([]byte, error) {
 		return nil, err
 	}
 	nt := NegotiationToken{
-		Tag:        0,
-		Class:      2,
-		IsCompound: true,
-		Bytes:      b,
+		Choice: asn1.RawValue{
+			Tag:        0,
+			Class:      2,
+			IsCompound: true,
+			Bytes:      b,
+		},
 	}
 	nb, err := asn1.Marshal(nt)
 	if err != nil {
@@ -112,10 +124,12 @@ func (n *NegTokenResp) Marshal() ([]byte, error) {
 		return nil, err
 	}
 	nt := NegotiationToken{
-		Tag:        1,
-		Class:      2,
-		IsCompound: true,
-		Bytes:      b,
+		Choice: asn1.RawValue{
+			Tag:        1,
+			Class:      2,
+			IsCompound: true,
+			Bytes:      b,
+		},
 	}
 	nb, err := asn1.Marshal(nt)
 	if err != nil {

+ 27 - 0
GSSAPI/NegotiationToken_test.go

@@ -0,0 +1,27 @@
+package GSSAPI
+
+import (
+	"testing"
+	"encoding/hex"
+	"github.com/stretchr/testify/assert"
+)
+
+const (
+	test_negTokenInit = "308202a6a027302506092a864886f71201020206052b0501050206092a864882f71201020206062b0601050205a2820279048202756082027106092a864886f71201020201006e8202603082025ca003020105a10302010ea20703050000000000a38201706182016c30820168a003020105a10d1b0b544553542e474f4b524235a2233021a003020103a11a30181b04485454501b10686f73742e746573742e676f6b726235a382012b30820127a003020112a103020102a282011904820115d4bd890abc456f44e2e7a2e8111bd6767abf03266dfcda97c629af2ece450a5ae1f145e4a4d1bc2c848e66a6c6b31d9740b26b03cdbd2570bfcf126e90adf5f5ebce9e283ff5086da47b129b14fc0aabd4d1df9c1f3c72b80cc614dfc28783450b2c7b7749651f432b47aaa2ff158c0066b757f3fb00dd7b4f63d68276c76373ecdd3f19c66ebc43a81e577f3c263b878356f57e8d6c4eccd587b81538e70392cf7e73fc12a6f7c537a894a7bb5566c83ac4d69757aa320a51d8d690017aebf952add1889adfc3307b0e6cd8c9b57cf8589fbe52800acb6461c25473d49faa1bdceb8bce3f61db23f9cd6a09d5adceb411e1c4546b30b33331e570fd6bc50aa403557e75f488e759750ea038aab6454667d9b64f41a481d23081cfa003020112a281c70481c4eb593beb5afcb1a2a669d54cb85a3772231559f2d40c9f8f053f218ba6eb084ed7efc467d94b88bcd189dda920d6e675ec001a6a2bca11f0a1de37f2f7ae9929f94a86d625b2ec1b213a88cbae6099dda7b172cd3bd1802cb177ae4554d59277004bfd3435248f55044fe7af7b2c9c5a3c43763278c585395aebe2856cdff9f2569d8b823564ce6be2d19748b910ec06bd3c0a9bc5de51ddcf7d875f1108ca6ad935f52d90cb62a18197d9b8e796bef0fbe1463f61df61cfbce6008ae9e1a2d2314a986d"
+)
+
+func TestUnmarshal_negTokenInit(t *testing.T) {
+	b, err := hex.DecodeString(test_negTokenInit)
+	if err != nil{
+		t.Fatalf("Error converting hex string test data to bytes: %v", err)
+	}
+	var n NegotiationToken
+
+	isInit, nt, err := n.Unmarshal(b)
+	if err != nil {
+		t.Fatalf("Error unmarshalling negotiation token: %v", err)
+	}
+	nInit := nt.(NegTokenInit)
+	assert.True(t, isInit, "Boolean indicating type is negTokenInit is not true")
+	assert.Equal(t, 4, len(nInit.Body.MechTypes))
+}

+ 1 - 1
asn1tools/tools.go

@@ -48,7 +48,7 @@ func AddASNAppTag(b []byte, tag int) []byte {
 	// 1st byte -> Identifier Octet - Application Tag
 	// 2nd byte -> The length (this will be the size indicated in the input bytes + 2 for the additional bytes we add here.
 	// Application Tag:
-	//| Byte:       | 8                            | 7                          | 6                                         | 5 | 4 | 3 | 2 | 1             |
+	//| Bit:        | 8                            | 7                          | 6                                         | 5 | 4 | 3 | 2 | 1             |
 	//| Value:      | 0                            | 1                          | 1                                         | From the RFC spec 4120        |
 	//| Explanation | Defined by the ASN1 encoding rules for an application tag | A value of 1 indicates a constructed type | The ASN Application tag value |
 	// Therefore the value of the byte is an integer = ( Application tag value + 96 )

+ 12 - 0
testenv/krbhttp-vagrant/Vagrantfile

@@ -0,0 +1,12 @@
+Vagrant.configure("2") do |config|
+  config.vm.provider "virtualbox" do |v|
+    v.memory = 1024
+    v.cpus = 1
+  end
+  config.vm.define "krbhttp", primary: true do |krbhttp|
+    krbhttp.vm.hostname = "http.test.gokrb5"
+    krbhttp.vm.box = "centos/7"
+    krbhttp.vm.network "private_network", ip: "10.80.88.90", netmask: "255.255.0.0"
+    krbhttp.vm.provision :shell, path: "bootstrap.sh"
+  end
+end

+ 36 - 0
testenv/krbhttp-vagrant/bootstrap.sh

@@ -0,0 +1,36 @@
+#!/bin/bash
+
+rm /etc/localtime
+ln -s /usr/share/zoneinfo/Europe/London /etc/localtime
+setenforce 0
+sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux
+
+yum update -y
+yum install -y \
+   httpd \
+   mod_auth_kerb \
+   mod_ssl
+
+systemctl stop firewalld
+systemctl disable firewalld
+systemctl enable ntpd
+
+cat <<EOF >> /etc/sysctl.conf
+net.ipv6.conf.all.disable_ipv6 = 1
+net.ipv6.conf.default.disable_ipv6 = 1
+net.ipv6.conf.lo.disable_ipv6 = 1
+EOF
+
+echo "10.80.88.89 client.test.gokrb5" >> /etc/hosts
+echo "10.80.88.90 http.test.gokrb5" >> /etc/hosts
+
+sh /vagrant/krb-setup.sh
+mv /vagrant/httpd-krb5.conf /etc/httpd/conf.d/
+chcon system_u:object_r:httpd_config_t:s0 /etc/httpd/conf.d/*
+chcon system_u:object_r:httpd_config_t:s0 /vagrant/http.keytab
+chmod 644 /vagrant/http.keytab
+
+systemctl restart httpd
+systemctl enable httpd
+
+reboot

+ 14 - 0
testenv/krbhttp-vagrant/httpd-krb5.conf

@@ -0,0 +1,14 @@
+LimitRequestFieldSize 65536
+ProxyIOBufferSize 65536
+<LocationMatch />
+        AuthType Kerberos
+        AuthName "TEST"
+        KrbServiceName HTTP
+        KrbMethodNegotiate On
+        KrbMethodK5Passwd On
+        KrbLocalUserMapping On
+        KrbAuthRealms TEST.GOKRB5
+        Krb5KeyTab /etc/httpd/http.keytab
+        #KrbSaveCredentials On
+        require valid-user
+</LocationMatch>

+ 12 - 0
testenv/krbhttp-vagrant/krb-setup.sh

@@ -0,0 +1,12 @@
+#!/bin/bash
+
+
+REALM=TEST.GOKRB5
+DOMAIN=test.gokrb5
+SERVER_HOST=kdc.test.gokrb5
+
+cp /vagrant/krb5.conf /etc/krb5.conf
+
+sed -i "s/__REALM__/${REALM}/g" /etc/krb5.conf
+sed -i "s/__DOMAIN__/${DOMAIN}/g" /etc/krb5.conf
+sed -i "s/__SERVER_HOST__/${SERVER_HOST}/g" /etc/krb5.conf

+ 32 - 0
testenv/krbhttp-vagrant/krb5.conf

@@ -0,0 +1,32 @@
+[logging]
+ default = FILE:/var/log/krb5libs.log
+ kdc = FILE:/var/log/krb5kdc.log
+ admin_server = FILE:/var/log/kadmind.log
+
+
+[libdefaults]
+  default_realm = __REALM__
+  dns_lookup_realm = false
+  dns_lookup_kdc = false
+  ticket_lifetime = 24h
+  forwardable = yes
+
+[realms]
+ __REALM__ = {
+  kdc = __SERVER_HOST__:88
+  admin_server = __SERVER_HOST__:749
+  default_domain = __DOMAIN__
+ }
+
+[domain_realm]
+ .__DOMAIN__ = __REALM__
+ __DOMAIN__ = __REALM__
+
+[appdefaults]
+ pam = {
+   debug = false
+   ticket_lifetime = 36000
+   renew_lifetime = 36000
+   forwardable = true
+   krb4_convert = false
+ }