github.com/vmware/govmomi@v0.37.2/sts/signer_test.go (about)

     1  /*
     2  Copyright (c) 2018 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package sts
    18  
    19  import (
    20  	"crypto/tls"
    21  	"net/http"
    22  	"strings"
    23  	"testing"
    24  
    25  	"github.com/vmware/govmomi/session"
    26  	"github.com/vmware/govmomi/vim25/methods"
    27  	"github.com/vmware/govmomi/vim25/soap"
    28  	"github.com/vmware/govmomi/vim25/types"
    29  	"github.com/vmware/govmomi/vim25/xml"
    30  )
    31  
    32  var _ soap.Signer = new(Signer)
    33  
    34  // LocalhostCert copied from simulator/internal/testcert.go
    35  var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
    36  MIIDOjCCAiKgAwIBAgIRAK6d/JpGL75P2wOSYc6WalEwDQYJKoZIhvcNAQELBQAw
    37  EjEQMA4GA1UEChMHQWNtZSBDbzAgFw03MDAxMDEwMDAwMDBaGA8yMDg0MDEyOTE2
    38  MDAwMFowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEP
    39  ADCCAQoCggEBAK9lInM4OAKI4z+wDNkvcZC6S6exFSOysp7NPJyaEAhW93kPY7gO
    40  f6H5aP3V3YU0vYpCSnz/UhyDD+/knBof1J3Do7FVwYtC293vrtXffNtAvygfJodW
    41  1dPllp17ZJbq76ei9oWq1Y5Hox/sVYmNVNztvBfK1mtpS8z8Qrk1LWCyLiDHkvDA
    42  hCy2OjuaopxC6qQejdWT1PxwbqptuLVakQmecpiFrupy8DTG0x0rxxdMdAATywhY
    43  Gm49A/FroagZ6HMz3bm39we/w6VIx3pX1lbUUyrfjvBgfUlRwxyZABBj2STGsOQJ
    44  a451eEcESXcSEWzjGjUQ1Wf+zzxr2GAHmI8CAwEAAaOBiDCBhTAOBgNVHQ8BAf8E
    45  BAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
    46  HQ4EFgQUjtR2VSuxchTxe0UNDVqWDNMR37AwLgYDVR0RBCcwJYILZXhhbXBsZS5j
    47  b22HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggEBACK7
    48  1L15IeYPiQHFDml3EgDoRnd/tAaZP9nUZIIPLRgUnQITNAtjFgBvqneQZwlQtco2
    49  s8YXSivBQiATlBEtGBzVxv36R4tTXldIgJxaCUxxZtqALLwyGqSaI/cwE0pWa6Z0
    50  Op2wkzUmoQ5rRrJfRM+C6HR/+lWkNtHRzaUFOSlxNJbPo53K53OoDriwEc1PvEYP
    51  wFeUXwTzCZ68pAlWUmDKCyp+lPhjIt2Gznig+BSPCNJqmwKM76oFyywi3HIP56rD
    52  /cwUtoplF68uVuD8HXb1ggGsqtGiAT4GLT8tU5w+BtK8ZIs/LK7mdi7W8aIOhUUH
    53  l1lgeV3oEQue3A7SogA=
    54  -----END CERTIFICATE-----`)
    55  
    56  // LocalhostKey copied from simulator/internal/testcert.go
    57  var LocalhostKey = []byte(`-----BEGIN PRIVATE KEY-----
    58  MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvZSJzODgCiOM/
    59  sAzZL3GQukunsRUjsrKezTycmhAIVvd5D2O4Dn+h+Wj91d2FNL2KQkp8/1Icgw/v
    60  5JwaH9Sdw6OxVcGLQtvd767V33zbQL8oHyaHVtXT5Zade2SW6u+novaFqtWOR6Mf
    61  7FWJjVTc7bwXytZraUvM/EK5NS1gsi4gx5LwwIQstjo7mqKcQuqkHo3Vk9T8cG6q
    62  bbi1WpEJnnKYha7qcvA0xtMdK8cXTHQAE8sIWBpuPQPxa6GoGehzM925t/cHv8Ol
    63  SMd6V9ZW1FMq347wYH1JUcMcmQAQY9kkxrDkCWuOdXhHBEl3EhFs4xo1ENVn/s88
    64  a9hgB5iPAgMBAAECggEAEpeS3knQThx6kk60HfWUgTXuPRldV0pi+shgq2z9VBT7
    65  6J5EAMewqdfJVFbuQ2eCy/wY70UVTCZscw51qaNEI3EQkgS4Hm345n64tr0Y/BjR
    66  6ovaxq/ivLJyk8D3ubOvscJphWPFfW6EkSa5LnqHy197972tmvcvbMw0unMzmzM7
    67  DenXdoIJQu1SqLiLUiDXEfkvCReekqhe1jATCwTzIBTCnTWxgI4Ox2qsBaxuwrnl
    68  D1GpWy4sh8NpDB0EBwdrjAOmLDOyvsy2X65DIlHS/k7901tvzyNjRrsr2Ig0sAz4
    69  w0ke6CUKQ2B+Pqn3p6bvxRYMP08+ZjlQpPuU4RrxGQKBgQDd3HCrZCgUJAGcfzYX
    70  ZzSmSoxB9+sEuVUZGU+ICMPlG0Dd8aEkXIyDjGMWsLFMIvzNBf4wB1FwdLaCJu6y
    71  0PbX3KVfg/Yc4lvYUuQ+1nD/3gm2hE46lZuSfbmExH5SQVLSbSQf9S/5BTHAWQO9
    72  PNie71AZ8fO5YDBM18tq2V7dBQKBgQDKYk1+Zup5p0BeRyCNnVYnpngO+pAZZmld
    73  gYiRn8095QJ/Y+yV0kYc2+0+5f6St462E+PVH3tX1l9OG3ujVQnWfu2iSsRJRMUf
    74  0blxqTWvqdcGi8SLpVjkrHn30scFNWmojhJv3k42H3nUMC1+WU3rp2f7+W58afyd
    75  NY9x4sqzgwKBgQCoeMq9+3JLyQPIOPl0UBS06gsT1RUMI0gxpPy1yiInich6QRAi
    76  snypMCPWiRo5PKBHd/OLuSLoiFhHARVliDTJum2B2I09Zc5kuJ1F8kUgpxUtGc7l
    77  wdG/LeWAok1iXORtkh9KfT+Ok5kx/OZP/zJnjkZ/TTHMZPSIhZ2cZ7AXmQKBgHMP
    78  HjWNtyKApsSytVwtpgyWxMznQMNgCOkjOoxoCJx2tUvNeHTY/glsM14+DdRFzTnQ
    79  5weEhXAzrS1PzKPYNeafdOR+k0eAdH2Zk09+PspmyZusHIqz72zabeEqEQHyEubE
    80  FtFI1rhIfs/WsBaUGQuvuhtz/I95BiguiiXaJRmXAoGADwcO6YXoWXga07gGRwZP
    81  LYKwt5wBh13LAGbSsUyCSK5FG6ZrTmzaFdAGV1U4wc/wgiIgv33m8BG4Ikxvpa0r
    82  Wg3dbhBx9Oya8QWIMBPk72KKEzsSDfi+Cn52ZmxTkWbBDCnkRhG77Ooi8vJ3dhq4
    83  fHeAu1F9OwF83SBi1oNySd8=
    84  -----END PRIVATE KEY-----`)
    85  
    86  func TestSigner(t *testing.T) {
    87  	cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey)
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	s := &Signer{}
    93  
    94  	env := soap.Envelope{
    95  		Header: new(soap.Header),
    96  		Body: &methods.LoginByTokenBody{
    97  			Req: &types.LoginByToken{
    98  				This: types.ManagedObjectReference{
    99  					Type:  "SessionManager",
   100  					Value: "SessionManager",
   101  				},
   102  				Locale: session.Locale,
   103  			},
   104  		},
   105  	}
   106  
   107  	_, err = s.Sign(env)
   108  	if err != nil {
   109  		t.Error(err)
   110  	}
   111  
   112  	s.Certificate = &cert
   113  
   114  	_, err = s.Sign(env)
   115  	if err == nil {
   116  		t.Error("expected error")
   117  	}
   118  
   119  	// Sign() just needs to parse the Assertion.ID
   120  	s.Token = `<saml2:Assertion ID="tokenID"></saml2:Assertion>`
   121  
   122  	b, err := s.Sign(env)
   123  	if err != nil {
   124  		t.Error(err)
   125  	}
   126  
   127  	// TODO: new(internal.Security) would require more use of xml.Name instead of field tags
   128  	security := struct {
   129  		InnerXML string `xml:",innerxml"`
   130  	}{}
   131  
   132  	senv := soap.Envelope{
   133  		Header: &soap.Header{
   134  			Security: &security,
   135  		},
   136  	}
   137  	err = xml.Unmarshal(b, &senv)
   138  	if err != nil {
   139  		t.Fatal(err)
   140  	}
   141  
   142  	if !strings.HasPrefix(security.InnerXML, "<wsu:Timestamp ") {
   143  		t.Error("missing timestamp")
   144  	}
   145  
   146  	if !strings.HasSuffix(security.InnerXML, "</ds:Signature>") {
   147  		t.Error("missing signature")
   148  	}
   149  
   150  	req, _ := http.NewRequest(http.MethodPost, "https://127.0.0.1", nil)
   151  	err = s.SignRequest(req)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	req, _ = http.NewRequest(http.MethodPost, "https://[0:0:0:0:0:0:0:1]", nil)
   157  	err = s.SignRequest(req)
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  }
   162  
   163  func TestIsIPv6(t *testing.T) {
   164  	tests := []struct {
   165  		ip string
   166  		v6 bool
   167  	}{
   168  		{"0:0:0:0:0:0:0:1", true},
   169  		{"10.0.0.42", false},
   170  	}
   171  
   172  	for _, test := range tests {
   173  		v6 := isIPv6(test.ip)
   174  		if v6 != test.v6 {
   175  			t.Errorf("%s: expected %t, got %t", test.ip, test.v6, v6)
   176  		}
   177  	}
   178  }