github.com/coreos/rocket@v1.30.1-0.20200224141603-171c416fac02/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/hashicorp/errwrap" 24 "github.com/rkt/rkt/pkg/keystore" 25 rktflag "github.com/rkt/rkt/rkt/flag" 26 "github.com/rkt/rkt/store/imagestore" 27 ) 28 29 // fileFetcher is used to fetch files from a local filesystem 30 type fileFetcher struct { 31 InsecureFlags *rktflag.SecFlags 32 S *imagestore.Store 33 Ks *keystore.Keystore 34 Debug bool 35 } 36 37 // Hash opens a file, optionally verifies it against passed asc, 38 // stores it in the store and returns the hash. 39 func (f *fileFetcher) Hash(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, imagestore.ACIFetchInfo{ 54 Latest: false, 55 }) 56 if err != nil { 57 return "", err 58 } 59 60 return key, nil 61 } 62 63 func (f *fileFetcher) getFile(aciPath string, a *asc) (*os.File, error) { 64 if f.InsecureFlags.SkipImageCheck() && f.Ks != nil { 65 log.Printf("warning: image signature verification has been disabled") 66 } 67 if f.InsecureFlags.SkipImageCheck() || f.Ks == nil { 68 aciFile, err := os.Open(aciPath) 69 if err != nil { 70 return nil, errwrap.Wrap(errors.New("error opening ACI file"), err) 71 } 72 return aciFile, nil 73 } 74 aciFile, err := f.getVerifiedFile(aciPath, a) 75 if err != nil { 76 return nil, err 77 } 78 return aciFile, nil 79 } 80 81 // fetch opens and verifies the ACI. 82 func (f *fileFetcher) getVerifiedFile(aciPath string, a *asc) (*os.File, error) { 83 var aciFile *os.File // closed on error 84 var errClose error // error signaling to close aciFile 85 86 f.maybeOverrideAsc(aciPath, a) 87 ascFile, err := a.Get() 88 if err != nil { 89 return nil, errwrap.Wrap(errors.New("error opening signature file"), err) 90 } 91 defer ascFile.Close() 92 93 aciFile, err = os.Open(aciPath) 94 if err != nil { 95 return nil, errwrap.Wrap(errors.New("error opening ACI file"), err) 96 } 97 98 defer func() { 99 if errClose != nil { 100 aciFile.Close() 101 } 102 }() 103 104 validator, errClose := newValidator(aciFile) 105 if errClose != nil { 106 return nil, errClose 107 } 108 109 entity, errClose := validator.ValidateWithSignature(f.Ks, ascFile) 110 if errClose != nil { 111 return nil, errwrap.Wrap(fmt.Errorf("image %q verification failed", validator.ImageName()), errClose) 112 } 113 printIdentities(entity) 114 115 return aciFile, nil 116 } 117 118 func (f *fileFetcher) maybeOverrideAsc(aciPath string, a *asc) { 119 if a.Fetcher != nil { 120 return 121 } 122 a.Location = ascPathFromImgPath(aciPath) 123 a.Fetcher = &localAscFetcher{} 124 }