github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/acl_guard_test.go (about)

     1  // Copyright (c) 2014, Google Inc.  All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tao
    16  
    17  import (
    18  	"fmt"
    19  	"errors"
    20  	"io/ioutil"
    21  	"os"
    22  	"path"
    23  	"strconv"
    24  	"testing"
    25  
    26  	"github.com/golang/protobuf/proto"
    27  	"github.com/jlmucb/cloudproxy/go/tao/auth"
    28  )
    29  
    30  func generateSigner() (*Signer, error) {
    31  
    32  	keyName := "TestSigningKey"
    33  	keyEpoch := int32(1)
    34  	keyPurpose := "signing"
    35  	keyStatus := "active"
    36  	keyType := SignerTypeFromSuiteName(TaoCryptoSuite)
    37  	if keyType == nil {
    38  		return nil, errors.New("unsupported sealer crypter")
    39  	}
    40  	ck := GenerateCryptoKey(*keyType, &keyName, &keyEpoch, &keyPurpose, &keyStatus)
    41  	if ck == nil {
    42  		return nil, errors.New("Can't generate signing key")
    43  	}
    44  	s := SignerFromCryptoKey(*ck)
    45  	if s  == nil {
    46  		return nil, errors.New("Can't get signer from signing key")
    47  	}
    48  	return s, nil
    49  }
    50  
    51  func makeACLGuard() (*ACLGuard, *Keys, string, error) {
    52  	tmpDir, err := ioutil.TempDir("", "acl_guard_test")
    53  	if err != nil {
    54  		return nil, nil, "",
    55  			fmt.Errorf("Couldn't get a temp directory for the ACL guard test")
    56  	}
    57  	keys, err := NewTemporaryKeys(Signing)
    58  	if err != nil {
    59  		return nil, nil, "", err
    60  	}
    61  
    62  	config := ACLGuardDetails{
    63  		SignedAclsPath: proto.String(path.Join(tmpDir, "acls")),
    64  	}
    65  	tg := NewACLGuard(keys.VerifyingKey, config)
    66  
    67  	// Add a bogus rule.
    68  	p := auth.NewKeyPrin([]byte(`Fake key`))
    69  	if err := tg.Authorize(p, "Write", []string{"filename"}); err != nil {
    70  		return nil, nil, "", err
    71  	}
    72  
    73  	return tg.(*ACLGuard), keys, tmpDir, err
    74  }
    75  
    76  func testNewACLGuard(t *testing.T, v *Verifier) (Guard, string) {
    77  	tmpdir, err := ioutil.TempDir("/tmp", "acl_guard_test")
    78  	if err != nil {
    79  		t.Fatal("Couldn't get a temp directory for the new ACL guard:", err)
    80  	}
    81  
    82  	config := ACLGuardDetails{SignedAclsPath: proto.String(path.Join(tmpdir, "acls"))}
    83  	tg := NewACLGuard(v, config)
    84  	return tg, tmpdir
    85  }
    86  
    87  func TestACLGuardSaveACLs(t *testing.T) {
    88  	s, err := generateSigner()
    89  	if err != nil {
    90  		t.Fatal("Couldn't generate a signer")
    91  	}
    92  
    93  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
    94  	defer os.RemoveAll(tmpdir)
    95  
    96  	p := auth.NewKeyPrin([]byte(`Fake key`))
    97  	if err := tg.Authorize(p, "Write", []string{"filename"}); err != nil {
    98  		t.Fatal("Couldn't authorize a simple operation:", err)
    99  	}
   100  
   101  	if err := tg.Save(s); err != nil {
   102  		t.Fatal("Couldn't save the file")
   103  	}
   104  
   105  	config := ACLGuardDetails{SignedAclsPath: proto.String(path.Join(tmpdir, "acls"))}
   106  	v := s.GetVerifierFromSigner()
   107  	aclg, err := LoadACLGuard(v, config)
   108  	if err != nil {
   109  		t.Fatal("Couldn't load the ACLs:", err)
   110  	}
   111  
   112  	if aclg.RuleCount() != tg.RuleCount() {
   113  		t.Fatal("Wrong number of rules in loaded ACLGuard")
   114  	}
   115  
   116  	if aclg.String() != tg.String() {
   117  		t.Fatal("Wrong string representation of loaded ACLGuard")
   118  	}
   119  }
   120  
   121  func TestACLGuardEmptySave(t *testing.T) {
   122  	s, err := generateSigner()
   123  	if err != nil {
   124  		t.Fatal("Couldn't generate a signer")
   125  	}
   126  
   127  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   128  	defer os.RemoveAll(tmpdir)
   129  
   130  	if err := tg.Save(s); err != nil {
   131  		t.Fatal("Couldn't save the file")
   132  	}
   133  
   134  	config := ACLGuardDetails{SignedAclsPath: proto.String(path.Join(tmpdir, "acls"))}
   135  	v := s.GetVerifierFromSigner()
   136  	aclg, err := LoadACLGuard(v, config)
   137  	if err != nil {
   138  		t.Fatal("Couldn't load the ACLs:", err)
   139  	}
   140  
   141  	if aclg.RuleCount() != tg.RuleCount() {
   142  		t.Fatal("Wrong number of rules in loaded ACLGuard")
   143  	}
   144  
   145  	if aclg.String() != tg.String() {
   146  		t.Fatal("Wrong string representation of loaded ACLGuard")
   147  	}
   148  }
   149  
   150  func TestACLGuardAuthorize(t *testing.T) {
   151  	s, err := generateSigner()
   152  	if err != nil {
   153  		t.Fatal("Couldn't generate a signer")
   154  	}
   155  
   156  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   157  	defer os.RemoveAll(tmpdir)
   158  
   159  	p := auth.NewKeyPrin([]byte(`Fake key`))
   160  	if err := tg.Authorize(p, "Write", []string{"filename"}); err != nil {
   161  		t.Fatal("Couldn't authorize a simple operation:", err)
   162  	}
   163  
   164  	if !tg.IsAuthorized(p, "Write", []string{"filename"}) {
   165  		t.Fatal("A rule that was added to the ACL was not present")
   166  	}
   167  
   168  	if tg.IsAuthorized(p, "Write", []string{"file"}) {
   169  		t.Fatal("A rule was authorized even though it has the wrong file name")
   170  	}
   171  
   172  	if tg.IsAuthorized(p, "Read", []string{"filename"}) {
   173  		t.Fatal("A rule was authorized even though it has the wrong op")
   174  	}
   175  
   176  	if tg.IsAuthorized(auth.Prin{}, "Write", []string{"filename"}) {
   177  		t.Fatal("A rule was authorized even though it has the wrong principal")
   178  	}
   179  
   180  	if err := tg.Retract(p, "Write", []string{"filename"}); err != nil {
   181  		t.Fatal("Couldn't retract an existing rule:", err)
   182  	}
   183  
   184  	if tg.IsAuthorized(p, "Write", []string{"filename"}) {
   185  		t.Fatal("A rule was still authorized after it was retracted")
   186  	}
   187  }
   188  
   189  func TestACLGuardDoubleAuthorize(t *testing.T) {
   190  	s, err := generateSigner()
   191  	if err != nil {
   192  		t.Fatal("Couldn't generate a signer")
   193  	}
   194  
   195  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   196  	defer os.RemoveAll(tmpdir)
   197  
   198  	p := auth.NewKeyPrin([]byte(`Fake key`))
   199  	if err := tg.Authorize(p, "Write", []string{"filename"}); err != nil {
   200  		t.Fatal("Couldn't authorize a simple operation:", err)
   201  	}
   202  
   203  	// So nice, we authorize it twice.
   204  	if err := tg.Authorize(p, "Write", []string{"filename"}); err != nil {
   205  		t.Fatal("Couldn't authorize a simple operation:", err)
   206  	}
   207  
   208  	if !tg.IsAuthorized(p, "Write", []string{"filename"}) {
   209  		t.Fatal("A rule that was added to the ACL was not present")
   210  	}
   211  
   212  	if err := tg.Retract(p, "Write", []string{"filename"}); err != nil {
   213  		t.Fatal("Couldn't retract an existing double-added rule:", err)
   214  	}
   215  
   216  	if tg.IsAuthorized(p, "Write", []string{"filename"}) {
   217  		t.Fatal("A rule was still authorized after it was retracted")
   218  	}
   219  }
   220  
   221  func TestACLGuardAddRule(t *testing.T) {
   222  	s, err := generateSigner()
   223  	if err != nil {
   224  		t.Fatal("Couldn't generate a signer")
   225  	}
   226  
   227  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   228  	defer os.RemoveAll(tmpdir)
   229  
   230  	if err := tg.AddRule("Fake rule"); err != nil {
   231  		t.Fatal("Couldn't add a fake rule to the ACL")
   232  	}
   233  
   234  	ret, err := tg.Query("Fake rule")
   235  	if err != nil {
   236  		t.Fatal("Couldn't query a fake rule from the ACLGuard:", err)
   237  	}
   238  
   239  	if !ret {
   240  		t.Fatal("ACLGuard.Query did not return true for a rule that was added by AddRule")
   241  	}
   242  
   243  	if err := tg.Clear(); err != nil {
   244  		t.Fatal("Couldn't clear the ACLGuard:", err)
   245  	}
   246  
   247  	ret, err = tg.Query("Fake rule")
   248  	if err != nil {
   249  		t.Fatal("Couldn't query a fake rule after clearing the ACLGuard:", err)
   250  	}
   251  
   252  	if ret {
   253  		t.Fatal("ACLGuard.Query returned true for a rule after clearing the ACLGuard")
   254  	}
   255  }
   256  
   257  func TestACLGuardRetractRule(t *testing.T) {
   258  	s, err := generateSigner()
   259  	if err != nil {
   260  		t.Fatal("Couldn't generate a signer")
   261  	}
   262  
   263  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   264  	defer os.RemoveAll(tmpdir)
   265  
   266  	if err := tg.AddRule("Fake rule"); err != nil {
   267  		t.Fatal("Couldn't add a fake rule to the ACL")
   268  	}
   269  
   270  	ret, err := tg.Query("Fake rule")
   271  	if err != nil {
   272  		t.Fatal("Couldn't query a fake rule from the ACLGuard:", err)
   273  	}
   274  
   275  	if !ret {
   276  		t.Fatal("ACLGuard.Query did not return true for a rule that was added by AddRule")
   277  	}
   278  
   279  	if err := tg.RetractRule("Fake rule"); err != nil {
   280  		t.Fatal("Couldn't clear the ACLGuard:", err)
   281  	}
   282  
   283  	ret, err = tg.Query("Fake rule")
   284  	if err != nil {
   285  		t.Fatal("Couldn't query a fake rule after clearing the ACLGuard:", err)
   286  	}
   287  
   288  	if ret {
   289  		t.Fatal("ACLGuard.Query returned true for a rule after retracting the rule")
   290  	}
   291  }
   292  
   293  func TestACLGuardRuleCount(t *testing.T) {
   294  	s, err := generateSigner()
   295  	if err != nil {
   296  		t.Fatal("Couldn't generate a signer")
   297  	}
   298  
   299  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   300  	defer os.RemoveAll(tmpdir)
   301  
   302  	count := 20
   303  	for i := 0; i < count; i++ {
   304  		if err := tg.AddRule(strconv.Itoa(i)); err != nil {
   305  			t.Fatal("Couldn't add a rule that was a single integer as a string:", err)
   306  		}
   307  	}
   308  
   309  	if tg.RuleCount() != count {
   310  		t.Fatal("Wrong rule count after adding 20 rules")
   311  	}
   312  
   313  	// add the same rule again and make sure the RuleCount goes up.
   314  	if err := tg.AddRule("0"); err != nil {
   315  		t.Fatal("Couldn't add the same rule twice to the list:", err)
   316  	}
   317  
   318  	if tg.RuleCount() != count+1 {
   319  		t.Fatal("Wrong rule count after adding a rule twice")
   320  	}
   321  
   322  	if err := tg.RetractRule("0"); err != nil {
   323  		t.Fatal("Couldn't retract a rule that had been added twice:", err)
   324  	}
   325  
   326  	if tg.RuleCount() != count-1 {
   327  		t.Fatal("Wrong rule count after removing a rule that had been added twice")
   328  	}
   329  }
   330  
   331  func TestACLGuardGetRule(t *testing.T) {
   332  	s, err := generateSigner()
   333  	if err != nil {
   334  		t.Fatal("Couldn't generate a signer")
   335  	}
   336  
   337  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   338  	defer os.RemoveAll(tmpdir)
   339  
   340  	count := 20
   341  	for i := 0; i < count; i++ {
   342  		if err := tg.AddRule(strconv.Itoa(i)); err != nil {
   343  			t.Fatal("Couldn't add a rule that was a single integer as a string:", err)
   344  		}
   345  	}
   346  
   347  	if tg.GetRule(0) != "0" {
   348  		t.Fatal("Got the wrong rule from GetRule")
   349  	}
   350  
   351  	if tg.GetRule(200) != "" {
   352  		t.Fatal("Got a non-empty rule string for a non-existent rule")
   353  	}
   354  
   355  	if tg.GetRule(-1) != "" {
   356  		t.Fatal("Got a non-empty rule string for a negative rule index")
   357  	}
   358  }
   359  
   360  func TestACLGuardRuleDebugString(t *testing.T) {
   361  	s, err := generateSigner()
   362  	if err != nil {
   363  		t.Fatal("Couldn't generate a signer")
   364  	}
   365  
   366  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   367  	defer os.RemoveAll(tmpdir)
   368  
   369  	count := 20
   370  	for i := 0; i < count; i++ {
   371  		if err := tg.AddRule(strconv.Itoa(i)); err != nil {
   372  			t.Fatal("Couldn't add a rule that was a single integer as a string:", err)
   373  		}
   374  	}
   375  
   376  	if tg.RuleDebugString(0) != "0" {
   377  		t.Fatal("Got the wrong rule from GetRule")
   378  	}
   379  
   380  	if tg.RuleDebugString(200) != "" {
   381  		t.Fatal("Got a non-empty rule string for a non-existent rule")
   382  	}
   383  
   384  	if tg.RuleDebugString(-1) != "" {
   385  		t.Fatal("Got a non-empty rule string for a negative rule index")
   386  	}
   387  }
   388  
   389  func TestACLGuardString(t *testing.T) {
   390  	s, err := generateSigner()
   391  	if err != nil {
   392  		t.Fatal("Couldn't generate a signer")
   393  	}
   394  
   395  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   396  	defer os.RemoveAll(tmpdir)
   397  
   398  	if err := tg.AddRule("0"); err != nil {
   399  		t.Fatal("Couldn't add a rule that was a single integer as a string:", err)
   400  	}
   401  
   402  	ss := "ACLGuard{\n0\n}"
   403  	if tg.String() != ss {
   404  		t.Fatalf("Got the wrong string representation of the ACLGuard: expected '%s', but got '%s'", tg.String(), ss)
   405  	}
   406  }
   407  
   408  func TestACLGuardSignedSubprincipal(t *testing.T) {
   409  	s, err := generateSigner()
   410  	if err != nil {
   411  		t.Fatal("Couldn't generate a signer")
   412  	}
   413  
   414  	tg, tmpdir := testNewACLGuard(t, s.GetVerifierFromSigner())
   415  	defer os.RemoveAll(tmpdir)
   416  
   417  	p := auth.NewKeyPrin([]byte(`Fake key`))
   418  	if err := tg.Authorize(p, "Write", []string{"filename"}); err != nil {
   419  		t.Fatal("Couldn't authorize a simple operation:", err)
   420  	}
   421  	name := tg.Subprincipal().String()
   422  	k := s.ToPrincipal().String()
   423  	if name != ".ACLGuard("+k+")" {
   424  		t.Fatalf("ACL guard has wrong name: %v", name)
   425  	}
   426  }
   427  
   428  func TestACLGuardUnsignedSubprincipal(t *testing.T) {
   429  	g := NewACLGuard(nil, ACLGuardDetails{})
   430  	err := g.Authorize(subj, "read", []string{"somefile"})
   431  	if err != nil {
   432  		t.Fatal(err)
   433  	}
   434  	name := g.Subprincipal().String()
   435  	if name != ".ACLGuard([3ba9dc4681ad463d830d98e4a7c98c4fc909cce061cca19d1c9831ea1d9f5f48])" {
   436  		t.Fatalf("ACL guard has wrong name: %v", name)
   437  	}
   438  }