github.com/ruishantech/selfupdate@v1.0.3/doc.go (about)

     1  /*
     2  Package update provides functionality to implement secure, self-updating Go programs (or other single-file targets).
     3  
     4  For complete updating solutions please see Equinox (https://equinox.io) and go-tuf (https://github.com/flynn/go-tuf).
     5  
     6  # Basic Example
     7  
     8  This example shows how to update a program remotely from a URL.
     9  
    10  	import (
    11  		"fmt"
    12  		"net/http"
    13  
    14  		"github.com/ruishantech/selfupdate"
    15  	)
    16  
    17  	func doUpdate(url string) error {
    18  		// request the new file
    19  		resp, err := http.Get(url)
    20  		if err != nil {
    21  			return err
    22  		}
    23  		defer resp.Body.Close()
    24  		err := selfupdate.Apply(resp.Body, selfupdate.Options{})
    25  		if err != nil {
    26  			if rerr := selfupdate.RollbackError(err); rerr != nil {
    27  				fmt.Println("Failed to rollback from bad update: %v", rerr)
    28  			}
    29  		}
    30  		return err
    31  	}
    32  
    33  # Binary Patching
    34  
    35  Go binaries can often be large. It can be advantageous to only ship a binary patch to a client
    36  instead of the complete program text of a new version.
    37  
    38  This example shows how to update a program with a bsdiff binary patch. Other patch formats
    39  may be applied by implementing the Patcher interface.
    40  
    41  	import (
    42  		"encoding/hex"
    43  		"io"
    44  
    45  		"github.com/ruishantech/selfupdate"
    46  	)
    47  
    48  	func updateWithPatch(patch io.Reader) error {
    49  		err := selfupdate.Apply(patch, selfupdate.Options{
    50  			Patcher: selfupdate.NewBSDiffPatcher()
    51  		})
    52  		if err != nil {
    53  			// error handling
    54  		}
    55  		return err
    56  	}
    57  
    58  # Checksum Verification
    59  
    60  Updating executable code on a computer can be a dangerous operation unless you
    61  take the appropriate steps to guarantee the authenticity of the new code. While
    62  checksum verification is important, it should always be combined with signature
    63  verification (next section) to guarantee that the code came from a trusted party.
    64  
    65  selfupdate validates SHA256 checksums by default, but this is pluggable via the Hash
    66  property on the Options struct.
    67  
    68  This example shows how to guarantee that the newly-updated binary is verified to
    69  have an appropriate checksum (that was otherwise retrieved via a secure channel)
    70  specified as a hex string.
    71  
    72  	import (
    73  		"crypto"
    74  		_ "crypto/sha256"
    75  		"encoding/hex"
    76  		"io"
    77  
    78  		"github.com/ruishantech/selfupdate"
    79  	)
    80  
    81  	func updateWithChecksum(binary io.Reader, hexChecksum string) error {
    82  		checksum, err := hex.DecodeString(hexChecksum)
    83  		if err != nil {
    84  			return err
    85  		}
    86  		err = selfupdate.Apply(binary, selfupdate.Options{
    87  			Hash: crypto.SHA256, 	// this is the default, you don't need to specify it
    88  			Checksum: checksum,
    89  		})
    90  		if err != nil {
    91  			// error handling
    92  		}
    93  		return err
    94  	}
    95  
    96  # Cryptographic Signature Verification
    97  
    98  Cryptographic verification of new code from an update is an extremely important way to guarantee the
    99  security and integrity of your updates.
   100  
   101  Verification is performed by validating the signature of a hash of the new file. This
   102  means nothing changes if you apply your update with a patch.
   103  
   104  This example shows how to add signature verification to your updates. To make all of this work
   105  an application distributor must first create a public/private key pair and embed the public key
   106  into their application. When they issue a new release, the issuer must sign the new executable file
   107  with the private key and distribute the signature along with the selfupdate.
   108  
   109  	import (
   110  		"crypto"
   111  		_ "crypto/sha256"
   112  		"encoding/hex"
   113  		"io"
   114  
   115  		"github.com/ruishantech/selfupdate"
   116  	)
   117  
   118  	func verifiedUpdate(binary io.Reader, hexChecksum string) {
   119  		checksum, err := hex.DecodeString(hexChecksum)
   120  		if err != nil {
   121  			return err
   122  		}
   123  		opts := selfupdate.Options{
   124  			Checksum: checksum,
   125  			Hash: crypto.SHA256,                // this is the default, you don't need to specify it
   126  		}
   127  		err = selfupdate.Apply(binary, opts)
   128  		if err != nil {
   129  			// error handling
   130  		}
   131  		return err
   132  	}
   133  
   134  # Building Single-File Go Binaries
   135  
   136  In order to update a Go application with selfupdate, you must distribute it as a single executable.
   137  This is often easy, but some applications require static assets (like HTML and CSS asset files or TLS certificates).
   138  In order to update applications like these, you'll want to make sure to embed those asset files into
   139  the distributed binary with a tool like go-bindata (my favorite): https://github.com/jteeuwen/go-bindata
   140  
   141  # Non-Goals
   142  
   143  Mechanisms and protocols for determining whether an update should be applied and, if so, which one are
   144  out of scope for this package. Please consult go-tuf (https://github.com/flynn/go-tuf) or Equinox (https://equinox.io)
   145  for more complete solutions.
   146  
   147  selfupdate only works for self-updating applications that are distributed as a single binary, i.e.
   148  applications that do not have additional assets or dependency files.
   149  Updating application that are distributed as multiple on-disk files is out of scope, although this
   150  may change in future versions of this library.
   151  */
   152  package selfupdate