github.com/blixtra/rkt@v0.8.1-0.20160204105720-ab0d1add1a43/rkt/image/filefetcher.go (about) 1 // Copyright 2015 The rkt Authors 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 image 16 17 import ( 18 "errors" 19 "fmt" 20 "os" 21 "path/filepath" 22 23 "github.com/coreos/rkt/pkg/keystore" 24 rktflag "github.com/coreos/rkt/rkt/flag" 25 "github.com/coreos/rkt/store" 26 "github.com/hashicorp/errwrap" 27 ) 28 29 // fileFetcher is used to fetch files from a local filesystem 30 type fileFetcher struct { 31 InsecureFlags *rktflag.SecFlags 32 S *store.Store 33 Ks *keystore.Keystore 34 Debug bool 35 } 36 37 // GetHash opens a file, optionally verifies it against passed asc, 38 // stores it in the store and returns the hash. 39 func (f *fileFetcher) GetHash(aciPath string, a *asc) (string, error) { 40 ensureLogger(f.Debug) 41 absPath, err := filepath.Abs(aciPath) 42 if err != nil { 43 return "", errwrap.Wrap(fmt.Errorf("failed to get an absolute path for %q", aciPath), err) 44 } 45 aciPath = absPath 46 47 aciFile, err := f.getFile(aciPath, a) 48 if err != nil { 49 return "", err 50 } 51 defer aciFile.Close() 52 53 key, err := f.S.WriteACI(aciFile, false) 54 if err != nil { 55 return "", err 56 } 57 58 return key, nil 59 } 60 61 func (f *fileFetcher) getFile(aciPath string, a *asc) (*os.File, error) { 62 if f.InsecureFlags.SkipImageCheck() && f.Ks != nil { 63 log.Printf("warning: image signature verification has been disabled") 64 } 65 if f.InsecureFlags.SkipImageCheck() || f.Ks == nil { 66 aciFile, err := os.Open(aciPath) 67 if err != nil { 68 return nil, errwrap.Wrap(errors.New("error opening ACI file"), err) 69 } 70 return aciFile, nil 71 } 72 aciFile, err := f.getVerifiedFile(aciPath, a) 73 if err != nil { 74 return nil, err 75 } 76 return aciFile, nil 77 } 78 79 // fetch opens and verifies the ACI. 80 func (f *fileFetcher) getVerifiedFile(aciPath string, a *asc) (*os.File, error) { 81 f.maybeOverrideAsc(aciPath, a) 82 ascFile, err := a.Get() 83 if err != nil { 84 return nil, errwrap.Wrap(errors.New("error opening signature file"), err) 85 } 86 defer func() { maybeClose(ascFile) }() 87 88 aciFile, err := os.Open(aciPath) 89 if err != nil { 90 return nil, errwrap.Wrap(errors.New("error opening ACI file"), err) 91 } 92 defer func() { maybeClose(aciFile) }() 93 94 validator, err := newValidator(aciFile) 95 if err != nil { 96 return nil, err 97 } 98 99 entity, err := validator.ValidateWithSignature(f.Ks, ascFile) 100 if err != nil { 101 return nil, errwrap.Wrap(fmt.Errorf("image %q verification failed", validator.GetImageName()), err) 102 } 103 printIdentities(entity) 104 105 retAciFile := aciFile 106 aciFile = nil 107 return retAciFile, nil 108 } 109 110 func (f *fileFetcher) maybeOverrideAsc(aciPath string, a *asc) { 111 if a.Fetcher != nil { 112 return 113 } 114 a.Location = ascPathFromImgPath(aciPath) 115 a.Fetcher = &localAscFetcher{} 116 }