github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/sluinit/uinit.go (about) 1 // Copyright 2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "errors" 9 "flag" 10 "fmt" 11 "log" 12 "os" 13 "time" 14 15 "github.com/u-root/iscsinl" 16 "github.com/u-root/u-root/pkg/cmdline" 17 "github.com/u-root/u-root/pkg/dhclient" 18 slaunch "github.com/u-root/u-root/pkg/securelaunch" 19 "github.com/u-root/u-root/pkg/securelaunch/policy" 20 "github.com/u-root/u-root/pkg/securelaunch/tpm" 21 ) 22 23 var ( 24 slDebug = flag.Bool("d", false, "enable debug logs") 25 ) 26 27 func checkDebugFlag() { 28 /* 29 * check if uroot.uinitargs=-d is set in kernel cmdline. 30 * if set, slaunch.Debug is set to log.Printf. 31 */ 32 flag.Parse() 33 34 if flag.NArg() > 1 { 35 log.Fatal("Incorrect number of arguments") 36 } 37 38 if *slDebug { 39 slaunch.Debug = log.Printf 40 slaunch.Debug("debug flag is set. Logging Enabled.") 41 } 42 } 43 44 /* 45 * main parses platform policy file, and based on the inputs, 46 * performs measurements and then launches a target kernel. 47 * 48 * steps followed by sluinit: 49 * 1. if debug flag is set, enable logging. 50 * 2. gets the TPM handle 51 * 3. Gets secure launch policy file entered by user. 52 * 4. calls collectors to collect measurements(hashes) a.k.a evidence. 53 */ 54 func main() { 55 checkDebugFlag() 56 57 err := scanIscsiDrives() 58 if err != nil { 59 log.Printf("NO ISCSI DRIVES found, err=[%v]", err) 60 } 61 62 defer unmountAndExit() // called only on error, on success we kexec 63 slaunch.Debug("********Step 1: init completed. starting main ********") 64 if err := tpm.New(); err != nil { 65 log.Printf("tpm.New() failed. err=%v", err) 66 return 67 } 68 defer tpm.Close() 69 70 slaunch.Debug("********Step 2: locate and parse SL Policy ********") 71 p, err := policy.Get() 72 if err != nil { 73 log.Printf("failed to get policy err=%v", err) 74 return 75 } 76 slaunch.Debug("policy file successfully parsed") 77 78 slaunch.Debug("********Step 3: Collecting Evidence ********") 79 for _, c := range p.Collectors { 80 slaunch.Debug("Input Collector: %v", c) 81 if e := c.Collect(); e != nil { 82 log.Printf("Collector %v failed, err = %v", c, e) 83 } 84 } 85 slaunch.Debug("Collectors completed") 86 87 slaunch.Debug("********Step 4: Measuring target kernel, initrd ********") 88 if err := p.Launcher.MeasureKernel(); err != nil { 89 log.Printf("Launcher.MeasureKernel failed err=%v", err) 90 return 91 } 92 93 slaunch.Debug("********Step 5: Parse eventlogs *********") 94 if err := p.EventLog.Parse(); err != nil { 95 log.Printf("EventLog.Parse() failed err=%v", err) 96 return 97 } 98 99 slaunch.Debug("*****Step 6: Dump logs to disk *******") 100 if err := slaunch.ClearPersistQueue(); err != nil { 101 log.Printf("ClearPersistQueue failed err=%v", err) 102 return 103 } 104 105 slaunch.Debug("********Step *: Unmount all ********") 106 slaunch.UnmountAll() 107 108 slaunch.Debug("********Step 7: Launcher called to Boot ********") 109 if err := p.Launcher.Boot(); err != nil { 110 log.Printf("Boot failed. err=%s", err) 111 return 112 } 113 } 114 115 // unmountAndExit is called on error and unmounts all devices. 116 // sluinit ends here. 117 func unmountAndExit() { 118 slaunch.UnmountAll() 119 time.Sleep(5 * time.Second) // let queued up debug statements get printed 120 os.Exit(1) 121 } 122 123 // scanIscsiDrives calls dhcleint to parse cmdline and 124 // iscsinl to mount iscsi drives. 125 func scanIscsiDrives() error { 126 val, ok := cmdline.Flag("netroot") 127 if !ok { 128 return errors.New("netroot flag is not set") 129 } 130 slaunch.Debug("netroot flag is set with val=%s", val) 131 132 target, volume, err := dhclient.ParseISCSIURI(val) 133 if err != nil { 134 return fmt.Errorf("dhclient ISCSI parser failed err=%v", err) 135 } 136 137 slaunch.Debug("resolved ip:port=%s", target) 138 slaunch.Debug("resolved vol=%v", volume) 139 140 slaunch.Debug("Scanning kernel cmd line for *rd.iscsi.initiator* flag") 141 initiatorName, ok := cmdline.Flag("rd.iscsi.initiator") 142 if !ok { 143 return errors.New("rd.iscsi.initiator flag is not set") 144 } 145 146 devices, err := iscsinl.MountIscsi( 147 iscsinl.WithInitiator(initiatorName), 148 iscsinl.WithTarget(target.String(), volume), 149 iscsinl.WithCmdsMax(128), 150 iscsinl.WithQueueDepth(16), 151 iscsinl.WithScheduler("noop"), 152 ) 153 if err != nil { 154 return err 155 } 156 157 for i := range devices { 158 slaunch.Debug("Mounted at dev %v", devices[i]) 159 } 160 return nil 161 }