mirror of
https://github.com/minio/minio.git
synced 2025-11-10 05:59:43 -05:00
Support in-place upgrades of new minio binary and releases. (#4961)
This PR allows 'minio update' to not only shows update banner but also allows for in-place upgrades. Updates are done safely by validating the downloaded sha256 of the binary. Fixes #4781
This commit is contained in:
committed by
Dee Koder
parent
8c08571cd9
commit
eb7c690ea9
15
vendor/github.com/howeyc/gopass/LICENSE.txt
generated
vendored
Normal file
15
vendor/github.com/howeyc/gopass/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2012 Chris Howey
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
384
vendor/github.com/howeyc/gopass/OPENSOLARIS.LICENSE
generated
vendored
Normal file
384
vendor/github.com/howeyc/gopass/OPENSOLARIS.LICENSE
generated
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
Unless otherwise noted, all files in this distribution are released
|
||||
under the Common Development and Distribution License (CDDL).
|
||||
Exceptions are noted within the associated source files.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
|
||||
COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0
|
||||
|
||||
1. Definitions.
|
||||
|
||||
1.1. "Contributor" means each individual or entity that creates
|
||||
or contributes to the creation of Modifications.
|
||||
|
||||
1.2. "Contributor Version" means the combination of the Original
|
||||
Software, prior Modifications used by a Contributor (if any),
|
||||
and the Modifications made by that particular Contributor.
|
||||
|
||||
1.3. "Covered Software" means (a) the Original Software, or (b)
|
||||
Modifications, or (c) the combination of files containing
|
||||
Original Software with files containing Modifications, in
|
||||
each case including portions thereof.
|
||||
|
||||
1.4. "Executable" means the Covered Software in any form other
|
||||
than Source Code.
|
||||
|
||||
1.5. "Initial Developer" means the individual or entity that first
|
||||
makes Original Software available under this License.
|
||||
|
||||
1.6. "Larger Work" means a work which combines Covered Software or
|
||||
portions thereof with code not governed by the terms of this
|
||||
License.
|
||||
|
||||
1.7. "License" means this document.
|
||||
|
||||
1.8. "Licensable" means having the right to grant, to the maximum
|
||||
extent possible, whether at the time of the initial grant or
|
||||
subsequently acquired, any and all of the rights conveyed
|
||||
herein.
|
||||
|
||||
1.9. "Modifications" means the Source Code and Executable form of
|
||||
any of the following:
|
||||
|
||||
A. Any file that results from an addition to, deletion from or
|
||||
modification of the contents of a file containing Original
|
||||
Software or previous Modifications;
|
||||
|
||||
B. Any new file that contains any part of the Original
|
||||
Software or previous Modifications; or
|
||||
|
||||
C. Any new file that is contributed or otherwise made
|
||||
available under the terms of this License.
|
||||
|
||||
1.10. "Original Software" means the Source Code and Executable
|
||||
form of computer software code that is originally released
|
||||
under this License.
|
||||
|
||||
1.11. "Patent Claims" means any patent claim(s), now owned or
|
||||
hereafter acquired, including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by
|
||||
grantor.
|
||||
|
||||
1.12. "Source Code" means (a) the common form of computer software
|
||||
code in which modifications are made and (b) associated
|
||||
documentation included in or with such code.
|
||||
|
||||
1.13. "You" (or "Your") means an individual or a legal entity
|
||||
exercising rights under, and complying with all of the terms
|
||||
of, this License. For legal entities, "You" includes any
|
||||
entity which controls, is controlled by, or is under common
|
||||
control with You. For purposes of this definition,
|
||||
"control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by
|
||||
contract or otherwise, or (b) ownership of more than fifty
|
||||
percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants.
|
||||
|
||||
2.1. The Initial Developer Grant.
|
||||
|
||||
Conditioned upon Your compliance with Section 3.1 below and
|
||||
subject to third party intellectual property claims, the Initial
|
||||
Developer hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or
|
||||
trademark) Licensable by Initial Developer, to use,
|
||||
reproduce, modify, display, perform, sublicense and
|
||||
distribute the Original Software (or portions thereof),
|
||||
with or without Modifications, and/or as part of a Larger
|
||||
Work; and
|
||||
|
||||
(b) under Patent Claims infringed by the making, using or
|
||||
selling of Original Software, to make, have made, use,
|
||||
practice, sell, and offer for sale, and/or otherwise
|
||||
dispose of the Original Software (or portions thereof).
|
||||
|
||||
(c) The licenses granted in Sections 2.1(a) and (b) are
|
||||
effective on the date Initial Developer first distributes
|
||||
or otherwise makes the Original Software available to a
|
||||
third party under the terms of this License.
|
||||
|
||||
(d) Notwithstanding Section 2.1(b) above, no patent license is
|
||||
granted: (1) for code that You delete from the Original
|
||||
Software, or (2) for infringements caused by: (i) the
|
||||
modification of the Original Software, or (ii) the
|
||||
combination of the Original Software with other software
|
||||
or devices.
|
||||
|
||||
2.2. Contributor Grant.
|
||||
|
||||
Conditioned upon Your compliance with Section 3.1 below and
|
||||
subject to third party intellectual property claims, each
|
||||
Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or
|
||||
trademark) Licensable by Contributor to use, reproduce,
|
||||
modify, display, perform, sublicense and distribute the
|
||||
Modifications created by such Contributor (or portions
|
||||
thereof), either on an unmodified basis, with other
|
||||
Modifications, as Covered Software and/or as part of a
|
||||
Larger Work; and
|
||||
|
||||
(b) under Patent Claims infringed by the making, using, or
|
||||
selling of Modifications made by that Contributor either
|
||||
alone and/or in combination with its Contributor Version
|
||||
(or portions of such combination), to make, use, sell,
|
||||
offer for sale, have made, and/or otherwise dispose of:
|
||||
(1) Modifications made by that Contributor (or portions
|
||||
thereof); and (2) the combination of Modifications made by
|
||||
that Contributor with its Contributor Version (or portions
|
||||
of such combination).
|
||||
|
||||
(c) The licenses granted in Sections 2.2(a) and 2.2(b) are
|
||||
effective on the date Contributor first distributes or
|
||||
otherwise makes the Modifications available to a third
|
||||
party.
|
||||
|
||||
(d) Notwithstanding Section 2.2(b) above, no patent license is
|
||||
granted: (1) for any code that Contributor has deleted
|
||||
from the Contributor Version; (2) for infringements caused
|
||||
by: (i) third party modifications of Contributor Version,
|
||||
or (ii) the combination of Modifications made by that
|
||||
Contributor with other software (except as part of the
|
||||
Contributor Version) or other devices; or (3) under Patent
|
||||
Claims infringed by Covered Software in the absence of
|
||||
Modifications made by that Contributor.
|
||||
|
||||
3. Distribution Obligations.
|
||||
|
||||
3.1. Availability of Source Code.
|
||||
|
||||
Any Covered Software that You distribute or otherwise make
|
||||
available in Executable form must also be made available in Source
|
||||
Code form and that Source Code form must be distributed only under
|
||||
the terms of this License. You must include a copy of this
|
||||
License with every copy of the Source Code form of the Covered
|
||||
Software You distribute or otherwise make available. You must
|
||||
inform recipients of any such Covered Software in Executable form
|
||||
as to how they can obtain such Covered Software in Source Code
|
||||
form in a reasonable manner on or through a medium customarily
|
||||
used for software exchange.
|
||||
|
||||
3.2. Modifications.
|
||||
|
||||
The Modifications that You create or to which You contribute are
|
||||
governed by the terms of this License. You represent that You
|
||||
believe Your Modifications are Your original creation(s) and/or
|
||||
You have sufficient rights to grant the rights conveyed by this
|
||||
License.
|
||||
|
||||
3.3. Required Notices.
|
||||
|
||||
You must include a notice in each of Your Modifications that
|
||||
identifies You as the Contributor of the Modification. You may
|
||||
not remove or alter any copyright, patent or trademark notices
|
||||
contained within the Covered Software, or any notices of licensing
|
||||
or any descriptive text giving attribution to any Contributor or
|
||||
the Initial Developer.
|
||||
|
||||
3.4. Application of Additional Terms.
|
||||
|
||||
You may not offer or impose any terms on any Covered Software in
|
||||
Source Code form that alters or restricts the applicable version
|
||||
of this License or the recipients' rights hereunder. You may
|
||||
choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of
|
||||
Covered Software. However, you may do so only on Your own behalf,
|
||||
and not on behalf of the Initial Developer or any Contributor.
|
||||
You must make it absolutely clear that any such warranty, support,
|
||||
indemnity or liability obligation is offered by You alone, and You
|
||||
hereby agree to indemnify the Initial Developer and every
|
||||
Contributor for any liability incurred by the Initial Developer or
|
||||
such Contributor as a result of warranty, support, indemnity or
|
||||
liability terms You offer.
|
||||
|
||||
3.5. Distribution of Executable Versions.
|
||||
|
||||
You may distribute the Executable form of the Covered Software
|
||||
under the terms of this License or under the terms of a license of
|
||||
Your choice, which may contain terms different from this License,
|
||||
provided that You are in compliance with the terms of this License
|
||||
and that the license for the Executable form does not attempt to
|
||||
limit or alter the recipient's rights in the Source Code form from
|
||||
the rights set forth in this License. If You distribute the
|
||||
Covered Software in Executable form under a different license, You
|
||||
must make it absolutely clear that any terms which differ from
|
||||
this License are offered by You alone, not by the Initial
|
||||
Developer or Contributor. You hereby agree to indemnify the
|
||||
Initial Developer and every Contributor for any liability incurred
|
||||
by the Initial Developer or such Contributor as a result of any
|
||||
such terms You offer.
|
||||
|
||||
3.6. Larger Works.
|
||||
|
||||
You may create a Larger Work by combining Covered Software with
|
||||
other code not governed by the terms of this License and
|
||||
distribute the Larger Work as a single product. In such a case,
|
||||
You must make sure the requirements of this License are fulfilled
|
||||
for the Covered Software.
|
||||
|
||||
4. Versions of the License.
|
||||
|
||||
4.1. New Versions.
|
||||
|
||||
Sun Microsystems, Inc. is the initial license steward and may
|
||||
publish revised and/or new versions of this License from time to
|
||||
time. Each version will be given a distinguishing version number.
|
||||
Except as provided in Section 4.3, no one other than the license
|
||||
steward has the right to modify this License.
|
||||
|
||||
4.2. Effect of New Versions.
|
||||
|
||||
You may always continue to use, distribute or otherwise make the
|
||||
Covered Software available under the terms of the version of the
|
||||
License under which You originally received the Covered Software.
|
||||
If the Initial Developer includes a notice in the Original
|
||||
Software prohibiting it from being distributed or otherwise made
|
||||
available under any subsequent version of the License, You must
|
||||
distribute and make the Covered Software available under the terms
|
||||
of the version of the License under which You originally received
|
||||
the Covered Software. Otherwise, You may also choose to use,
|
||||
distribute or otherwise make the Covered Software available under
|
||||
the terms of any subsequent version of the License published by
|
||||
the license steward.
|
||||
|
||||
4.3. Modified Versions.
|
||||
|
||||
When You are an Initial Developer and You want to create a new
|
||||
license for Your Original Software, You may create and use a
|
||||
modified version of this License if You: (a) rename the license
|
||||
and remove any references to the name of the license steward
|
||||
(except to note that the license differs from this License); and
|
||||
(b) otherwise make it clear that the license contains terms which
|
||||
differ from this License.
|
||||
|
||||
5. DISCLAIMER OF WARRANTY.
|
||||
|
||||
COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
|
||||
BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||
INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
|
||||
SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
|
||||
PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
|
||||
COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
|
||||
INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
|
||||
WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
|
||||
ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
|
||||
DISCLAIMER.
|
||||
|
||||
6. TERMINATION.
|
||||
|
||||
6.1. This License and the rights granted hereunder will terminate
|
||||
automatically if You fail to comply with terms herein and fail to
|
||||
cure such breach within 30 days of becoming aware of the breach.
|
||||
Provisions which, by their nature, must remain in effect beyond
|
||||
the termination of this License shall survive.
|
||||
|
||||
6.2. If You assert a patent infringement claim (excluding
|
||||
declaratory judgment actions) against Initial Developer or a
|
||||
Contributor (the Initial Developer or Contributor against whom You
|
||||
assert such claim is referred to as "Participant") alleging that
|
||||
the Participant Software (meaning the Contributor Version where
|
||||
the Participant is a Contributor or the Original Software where
|
||||
the Participant is the Initial Developer) directly or indirectly
|
||||
infringes any patent, then any and all rights granted directly or
|
||||
indirectly to You by such Participant, the Initial Developer (if
|
||||
the Initial Developer is not the Participant) and all Contributors
|
||||
under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
|
||||
notice from Participant terminate prospectively and automatically
|
||||
at the expiration of such 60 day notice period, unless if within
|
||||
such 60 day period You withdraw Your claim with respect to the
|
||||
Participant Software against such Participant either unilaterally
|
||||
or pursuant to a written agreement with Participant.
|
||||
|
||||
6.3. In the event of termination under Sections 6.1 or 6.2 above,
|
||||
all end user licenses that have been validly granted by You or any
|
||||
distributor hereunder prior to termination (excluding licenses
|
||||
granted to You by any distributor) shall survive termination.
|
||||
|
||||
7. LIMITATION OF LIABILITY.
|
||||
|
||||
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
|
||||
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
|
||||
INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
|
||||
COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
|
||||
LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
|
||||
CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
|
||||
LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
|
||||
STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
|
||||
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
|
||||
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
|
||||
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
|
||||
INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
|
||||
APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
|
||||
NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
|
||||
APPLY TO YOU.
|
||||
|
||||
8. U.S. GOVERNMENT END USERS.
|
||||
|
||||
The Covered Software is a "commercial item," as that term is
|
||||
defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
|
||||
computer software" (as that term is defined at 48
|
||||
C.F.R. 252.227-7014(a)(1)) and "commercial computer software
|
||||
documentation" as such terms are used in 48 C.F.R. 12.212
|
||||
(Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
|
||||
C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
|
||||
U.S. Government End Users acquire Covered Software with only those
|
||||
rights set forth herein. This U.S. Government Rights clause is in
|
||||
lieu of, and supersedes, any other FAR, DFAR, or other clause or
|
||||
provision that addresses Government rights in computer software
|
||||
under this License.
|
||||
|
||||
9. MISCELLANEOUS.
|
||||
|
||||
This License represents the complete agreement concerning subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. This License shall be governed
|
||||
by the law of the jurisdiction specified in a notice contained
|
||||
within the Original Software (except to the extent applicable law,
|
||||
if any, provides otherwise), excluding such jurisdiction's
|
||||
conflict-of-law provisions. Any litigation relating to this
|
||||
License shall be subject to the jurisdiction of the courts located
|
||||
in the jurisdiction and venue specified in a notice contained
|
||||
within the Original Software, with the losing party responsible
|
||||
for costs, including, without limitation, court costs and
|
||||
reasonable attorneys' fees and expenses. The application of the
|
||||
United Nations Convention on Contracts for the International Sale
|
||||
of Goods is expressly excluded. Any law or regulation which
|
||||
provides that the language of a contract shall be construed
|
||||
against the drafter shall not apply to this License. You agree
|
||||
that You alone are responsible for compliance with the United
|
||||
States export administration regulations (and the export control
|
||||
laws and regulation of any other countries) when You use,
|
||||
distribute or otherwise make available any Covered Software.
|
||||
|
||||
10. RESPONSIBILITY FOR CLAIMS.
|
||||
|
||||
As between Initial Developer and the Contributors, each party is
|
||||
responsible for claims and damages arising, directly or
|
||||
indirectly, out of its utilization of rights under this License
|
||||
and You agree to work with Initial Developer and Contributors to
|
||||
distribute such responsibility on an equitable basis. Nothing
|
||||
herein is intended or shall be deemed to constitute any admission
|
||||
of liability.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND
|
||||
DISTRIBUTION LICENSE (CDDL)
|
||||
|
||||
For Covered Software in this distribution, this License shall
|
||||
be governed by the laws of the State of California (excluding
|
||||
conflict-of-law provisions).
|
||||
|
||||
Any litigation relating to this License shall be subject to the
|
||||
jurisdiction of the Federal Courts of the Northern District of
|
||||
California and the state courts of the State of California, with
|
||||
venue lying in Santa Clara County, California.
|
||||
27
vendor/github.com/howeyc/gopass/README.md
generated
vendored
Normal file
27
vendor/github.com/howeyc/gopass/README.md
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# getpasswd in Go [](https://godoc.org/github.com/howeyc/gopass) [](http://travis-ci.org/howeyc/gopass)
|
||||
|
||||
Retrieve password from user terminal or piped input without echo.
|
||||
|
||||
Verified on BSD, Linux, and Windows.
|
||||
|
||||
Example:
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import "github.com/howeyc/gopass"
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Password: ")
|
||||
|
||||
// Silent. For printing *'s use gopass.GetPasswdMasked()
|
||||
pass, err := gopass.GetPasswd()
|
||||
if err != nil {
|
||||
// Handle gopass.ErrInterrupted or getch() read error
|
||||
}
|
||||
|
||||
// Do something with pass
|
||||
}
|
||||
```
|
||||
|
||||
Caution: Multi-byte characters not supported!
|
||||
110
vendor/github.com/howeyc/gopass/pass.go
generated
vendored
Normal file
110
vendor/github.com/howeyc/gopass/pass.go
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
package gopass
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type FdReader interface {
|
||||
io.Reader
|
||||
Fd() uintptr
|
||||
}
|
||||
|
||||
var defaultGetCh = func(r io.Reader) (byte, error) {
|
||||
buf := make([]byte, 1)
|
||||
if n, err := r.Read(buf); n == 0 || err != nil {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return 0, io.EOF
|
||||
}
|
||||
return buf[0], nil
|
||||
}
|
||||
|
||||
var (
|
||||
maxLength = 512
|
||||
ErrInterrupted = errors.New("interrupted")
|
||||
ErrMaxLengthExceeded = fmt.Errorf("maximum byte limit (%v) exceeded", maxLength)
|
||||
|
||||
// Provide variable so that tests can provide a mock implementation.
|
||||
getch = defaultGetCh
|
||||
)
|
||||
|
||||
// getPasswd returns the input read from terminal.
|
||||
// If prompt is not empty, it will be output as a prompt to the user
|
||||
// If masked is true, typing will be matched by asterisks on the screen.
|
||||
// Otherwise, typing will echo nothing.
|
||||
func getPasswd(prompt string, masked bool, r FdReader, w io.Writer) ([]byte, error) {
|
||||
var err error
|
||||
var pass, bs, mask []byte
|
||||
if masked {
|
||||
bs = []byte("\b \b")
|
||||
mask = []byte("*")
|
||||
}
|
||||
|
||||
if isTerminal(r.Fd()) {
|
||||
if oldState, err := makeRaw(r.Fd()); err != nil {
|
||||
return pass, err
|
||||
} else {
|
||||
defer func() {
|
||||
restore(r.Fd(), oldState)
|
||||
fmt.Fprintln(w)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
if prompt != "" {
|
||||
fmt.Fprint(w, prompt)
|
||||
}
|
||||
|
||||
// Track total bytes read, not just bytes in the password. This ensures any
|
||||
// errors that might flood the console with nil or -1 bytes infinitely are
|
||||
// capped.
|
||||
var counter int
|
||||
for counter = 0; counter <= maxLength; counter++ {
|
||||
if v, e := getch(r); e != nil {
|
||||
err = e
|
||||
break
|
||||
} else if v == 127 || v == 8 {
|
||||
if l := len(pass); l > 0 {
|
||||
pass = pass[:l-1]
|
||||
fmt.Fprint(w, string(bs))
|
||||
}
|
||||
} else if v == 13 || v == 10 {
|
||||
break
|
||||
} else if v == 3 {
|
||||
err = ErrInterrupted
|
||||
break
|
||||
} else if v != 0 {
|
||||
pass = append(pass, v)
|
||||
fmt.Fprint(w, string(mask))
|
||||
}
|
||||
}
|
||||
|
||||
if counter > maxLength {
|
||||
err = ErrMaxLengthExceeded
|
||||
}
|
||||
|
||||
return pass, err
|
||||
}
|
||||
|
||||
// GetPasswd returns the password read from the terminal without echoing input.
|
||||
// The returned byte array does not include end-of-line characters.
|
||||
func GetPasswd() ([]byte, error) {
|
||||
return getPasswd("", false, os.Stdin, os.Stdout)
|
||||
}
|
||||
|
||||
// GetPasswdMasked returns the password read from the terminal, echoing asterisks.
|
||||
// The returned byte array does not include end-of-line characters.
|
||||
func GetPasswdMasked() ([]byte, error) {
|
||||
return getPasswd("", true, os.Stdin, os.Stdout)
|
||||
}
|
||||
|
||||
// GetPasswdPrompt prompts the user and returns the password read from the terminal.
|
||||
// If mask is true, then asterisks are echoed.
|
||||
// The returned byte array does not include end-of-line characters.
|
||||
func GetPasswdPrompt(prompt string, mask bool, r FdReader, w io.Writer) ([]byte, error) {
|
||||
return getPasswd(prompt, mask, r, w)
|
||||
}
|
||||
25
vendor/github.com/howeyc/gopass/terminal.go
generated
vendored
Normal file
25
vendor/github.com/howeyc/gopass/terminal.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// +build !solaris
|
||||
|
||||
package gopass
|
||||
|
||||
import "golang.org/x/crypto/ssh/terminal"
|
||||
|
||||
type terminalState struct {
|
||||
state *terminal.State
|
||||
}
|
||||
|
||||
func isTerminal(fd uintptr) bool {
|
||||
return terminal.IsTerminal(int(fd))
|
||||
}
|
||||
|
||||
func makeRaw(fd uintptr) (*terminalState, error) {
|
||||
state, err := terminal.MakeRaw(int(fd))
|
||||
|
||||
return &terminalState{
|
||||
state: state,
|
||||
}, err
|
||||
}
|
||||
|
||||
func restore(fd uintptr, oldState *terminalState) error {
|
||||
return terminal.Restore(int(fd), oldState.state)
|
||||
}
|
||||
69
vendor/github.com/howeyc/gopass/terminal_solaris.go
generated
vendored
Normal file
69
vendor/github.com/howeyc/gopass/terminal_solaris.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
// Below is derived from Solaris source, so CDDL license is included.
|
||||
|
||||
package gopass
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type terminalState struct {
|
||||
state *unix.Termios
|
||||
}
|
||||
|
||||
// isTerminal returns true if there is a terminal attached to the given
|
||||
// file descriptor.
|
||||
// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
|
||||
func isTerminal(fd uintptr) bool {
|
||||
var termio unix.Termio
|
||||
err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// makeRaw puts the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
|
||||
func makeRaw(fd uintptr) (*terminalState, error) {
|
||||
oldTermiosPtr, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldTermios := *oldTermiosPtr
|
||||
|
||||
newTermios := oldTermios
|
||||
newTermios.Lflag &^= syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL
|
||||
if err := unix.IoctlSetTermios(int(fd), unix.TCSETS, &newTermios); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &terminalState{
|
||||
state: oldTermiosPtr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func restore(fd uintptr, oldState *terminalState) error {
|
||||
return unix.IoctlSetTermios(int(fd), unix.TCSETS, oldState.state)
|
||||
}
|
||||
13
vendor/github.com/inconshreveable/go-update/LICENSE
generated
vendored
Normal file
13
vendor/github.com/inconshreveable/go-update/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2015 Alan Shreve
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
65
vendor/github.com/inconshreveable/go-update/README.md
generated
vendored
Normal file
65
vendor/github.com/inconshreveable/go-update/README.md
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# go-update: Build self-updating Go programs [](https://godoc.org/github.com/inconshreveable/go-update)
|
||||
|
||||
Package update provides functionality to implement secure, self-updating Go programs (or other single-file targets)
|
||||
A program can update itself by replacing its executable file with a new version.
|
||||
|
||||
It provides the flexibility to implement different updating user experiences
|
||||
like auto-updating, or manual user-initiated updates. It also boasts
|
||||
advanced features like binary patching and code signing verification.
|
||||
|
||||
Example of updating from a URL:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/inconshreveable/go-update"
|
||||
)
|
||||
|
||||
func doUpdate(url string) error {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
err := update.Apply(resp.Body, update.Options{})
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Cross platform support (Windows too!)
|
||||
- Binary patch application
|
||||
- Checksum verification
|
||||
- Code signing verification
|
||||
- Support for updating arbitrary files
|
||||
|
||||
## [equinox.io](https://equinox.io)
|
||||
[equinox.io](https://equinox.io) is a complete ready-to-go updating solution built on top of go-update that provides:
|
||||
|
||||
- Hosted updates
|
||||
- Update channels (stable, beta, nightly, ...)
|
||||
- Dynamically computed binary diffs
|
||||
- Automatic key generation and code
|
||||
- Release tooling with proper code signing
|
||||
- Update/download metrics
|
||||
|
||||
## API Compatibility Promises
|
||||
The master branch of `go-update` is *not* guaranteed to have a stable API over time. For any production application, you should vendor
|
||||
your dependency on `go-update` with a tool like git submodules, [gb](http://getgb.io/) or [govendor](https://github.com/kardianos/govendor).
|
||||
|
||||
The `go-update` package makes the following promises about API compatibility:
|
||||
1. A list of all API-breaking changes will be documented in this README.
|
||||
1. `go-update` will strive for as few API-breaking changes as possible.
|
||||
|
||||
## API Breaking Changes
|
||||
- **Sept 3, 2015**: The `Options` struct passed to `Apply` was changed to be passed by value instead of passed by pointer. Old API at `28de026`.
|
||||
- **Aug 9, 2015**: 2.0 API. Old API at `221d034` or `gopkg.in/inconshreveable/go-update.v0`.
|
||||
|
||||
## License
|
||||
Apache
|
||||
322
vendor/github.com/inconshreveable/go-update/apply.go
generated
vendored
Normal file
322
vendor/github.com/inconshreveable/go-update/apply.go
generated
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/inconshreveable/go-update/internal/osext"
|
||||
)
|
||||
|
||||
var (
|
||||
openFile = os.OpenFile
|
||||
)
|
||||
|
||||
// Apply performs an update of the current executable (or opts.TargetFile, if set) with the contents of the given io.Reader.
|
||||
//
|
||||
// Apply performs the following actions to ensure a safe cross-platform update:
|
||||
//
|
||||
// 1. If configured, applies the contents of the update io.Reader as a binary patch.
|
||||
//
|
||||
// 2. If configured, computes the checksum of the new executable and verifies it matches.
|
||||
//
|
||||
// 3. If configured, verifies the signature with a public key.
|
||||
//
|
||||
// 4. Creates a new file, /path/to/.target.new with the TargetMode with the contents of the updated file
|
||||
//
|
||||
// 5. Renames /path/to/target to /path/to/.target.old
|
||||
//
|
||||
// 6. Renames /path/to/.target.new to /path/to/target
|
||||
//
|
||||
// 7. If the final rename is successful, deletes /path/to/.target.old, returns no error. On Windows,
|
||||
// the removal of /path/to/target.old always fails, so instead Apply hides the old file instead.
|
||||
//
|
||||
// 8. If the final rename fails, attempts to roll back by renaming /path/to/.target.old
|
||||
// back to /path/to/target.
|
||||
//
|
||||
// If the roll back operation fails, the file system is left in an inconsistent state (betweet steps 5 and 6) where
|
||||
// there is no new executable file and the old executable file could not be be moved to its original location. In this
|
||||
// case you should notify the user of the bad news and ask them to recover manually. Applications can determine whether
|
||||
// the rollback failed by calling RollbackError, see the documentation on that function for additional detail.
|
||||
func Apply(update io.Reader, opts Options) error {
|
||||
// validate
|
||||
verify := false
|
||||
switch {
|
||||
case opts.Signature != nil && opts.PublicKey != nil:
|
||||
// okay
|
||||
verify = true
|
||||
case opts.Signature != nil:
|
||||
return errors.New("no public key to verify signature with")
|
||||
case opts.PublicKey != nil:
|
||||
return errors.New("No signature to verify with")
|
||||
}
|
||||
|
||||
// set defaults
|
||||
if opts.Hash == 0 {
|
||||
opts.Hash = crypto.SHA256
|
||||
}
|
||||
if opts.Verifier == nil {
|
||||
opts.Verifier = NewECDSAVerifier()
|
||||
}
|
||||
if opts.TargetMode == 0 {
|
||||
opts.TargetMode = 0755
|
||||
}
|
||||
|
||||
// get target path
|
||||
var err error
|
||||
opts.TargetPath, err = opts.getPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var newBytes []byte
|
||||
if opts.Patcher != nil {
|
||||
if newBytes, err = opts.applyPatch(update); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// no patch to apply, go on through
|
||||
if newBytes, err = ioutil.ReadAll(update); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// verify checksum if requested
|
||||
if opts.Checksum != nil {
|
||||
if err = opts.verifyChecksum(newBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if verify {
|
||||
if err = opts.verifySignature(newBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// get the directory the executable exists in
|
||||
updateDir := filepath.Dir(opts.TargetPath)
|
||||
filename := filepath.Base(opts.TargetPath)
|
||||
|
||||
// Copy the contents of newbinary to a new executable file
|
||||
newPath := filepath.Join(updateDir, fmt.Sprintf(".%s.new", filename))
|
||||
fp, err := openFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, opts.TargetMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
_, err = io.Copy(fp, bytes.NewReader(newBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if we don't call fp.Close(), windows won't let us move the new executable
|
||||
// because the file will still be "in use"
|
||||
fp.Close()
|
||||
|
||||
// this is where we'll move the executable to so that we can swap in the updated replacement
|
||||
oldPath := opts.OldSavePath
|
||||
removeOld := opts.OldSavePath == ""
|
||||
if removeOld {
|
||||
oldPath = filepath.Join(updateDir, fmt.Sprintf(".%s.old", filename))
|
||||
}
|
||||
|
||||
// delete any existing old exec file - this is necessary on Windows for two reasons:
|
||||
// 1. after a successful update, Windows can't remove the .old file because the process is still running
|
||||
// 2. windows rename operations fail if the destination file already exists
|
||||
_ = os.Remove(oldPath)
|
||||
|
||||
// move the existing executable to a new file in the same directory
|
||||
err = os.Rename(opts.TargetPath, oldPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// move the new exectuable in to become the new program
|
||||
err = os.Rename(newPath, opts.TargetPath)
|
||||
|
||||
if err != nil {
|
||||
// move unsuccessful
|
||||
//
|
||||
// The filesystem is now in a bad state. We have successfully
|
||||
// moved the existing binary to a new location, but we couldn't move the new
|
||||
// binary to take its place. That means there is no file where the current executable binary
|
||||
// used to be!
|
||||
// Try to rollback by restoring the old binary to its original path.
|
||||
rerr := os.Rename(oldPath, opts.TargetPath)
|
||||
if rerr != nil {
|
||||
return &rollbackErr{err, rerr}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// move successful, remove the old binary if needed
|
||||
if removeOld {
|
||||
errRemove := os.Remove(oldPath)
|
||||
|
||||
// windows has trouble with removing old binaries, so hide it instead
|
||||
if errRemove != nil {
|
||||
_ = hideFile(oldPath)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RollbackError takes an error value returned by Apply and returns the error, if any,
|
||||
// that occurred when attempting to roll back from a failed update. Applications should
|
||||
// always call this function on any non-nil errors returned by Apply.
|
||||
//
|
||||
// If no rollback was needed or if the rollback was successful, RollbackError returns nil,
|
||||
// otherwise it returns the error encountered when trying to roll back.
|
||||
func RollbackError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if rerr, ok := err.(*rollbackErr); ok {
|
||||
return rerr.rollbackErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type rollbackErr struct {
|
||||
error // original error
|
||||
rollbackErr error // error encountered while rolling back
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
// TargetPath defines the path to the file to update.
|
||||
// The emptry string means 'the executable file of the running program'.
|
||||
TargetPath string
|
||||
|
||||
// Create TargetPath replacement with this file mode. If zero, defaults to 0755.
|
||||
TargetMode os.FileMode
|
||||
|
||||
// Checksum of the new binary to verify against. If nil, no checksum or signature verification is done.
|
||||
Checksum []byte
|
||||
|
||||
// Public key to use for signature verification. If nil, no signature verification is done.
|
||||
PublicKey crypto.PublicKey
|
||||
|
||||
// Signature to verify the updated file. If nil, no signature verification is done.
|
||||
Signature []byte
|
||||
|
||||
// Pluggable signature verification algorithm. If nil, ECDSA is used.
|
||||
Verifier Verifier
|
||||
|
||||
// Use this hash function to generate the checksum. If not set, SHA256 is used.
|
||||
Hash crypto.Hash
|
||||
|
||||
// If nil, treat the update as a complete replacement for the contents of the file at TargetPath.
|
||||
// If non-nil, treat the update contents as a patch and use this object to apply the patch.
|
||||
Patcher Patcher
|
||||
|
||||
// Store the old executable file at this path after a successful update.
|
||||
// The empty string means the old executable file will be removed after the update.
|
||||
OldSavePath string
|
||||
}
|
||||
|
||||
// CheckPermissions determines whether the process has the correct permissions to
|
||||
// perform the requested update. If the update can proceed, it returns nil, otherwise
|
||||
// it returns the error that would occur if an update were attempted.
|
||||
func (o *Options) CheckPermissions() error {
|
||||
// get the directory the file exists in
|
||||
path, err := o.getPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fileDir := filepath.Dir(path)
|
||||
fileName := filepath.Base(path)
|
||||
|
||||
// attempt to open a file in the file's directory
|
||||
newPath := filepath.Join(fileDir, fmt.Sprintf(".%s.new", fileName))
|
||||
fp, err := openFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, o.TargetMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fp.Close()
|
||||
|
||||
_ = os.Remove(newPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPublicKeyPEM is a convenience method to set the PublicKey property
|
||||
// used for checking a completed update's signature by parsing a
|
||||
// Public Key formatted as PEM data.
|
||||
func (o *Options) SetPublicKeyPEM(pembytes []byte) error {
|
||||
block, _ := pem.Decode(pembytes)
|
||||
if block == nil {
|
||||
return errors.New("couldn't parse PEM data")
|
||||
}
|
||||
|
||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.PublicKey = pub
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Options) getPath() (string, error) {
|
||||
if o.TargetPath == "" {
|
||||
return osext.Executable()
|
||||
} else {
|
||||
return o.TargetPath, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Options) applyPatch(patch io.Reader) ([]byte, error) {
|
||||
// open the file to patch
|
||||
old, err := os.Open(o.TargetPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer old.Close()
|
||||
|
||||
// apply the patch
|
||||
var applied bytes.Buffer
|
||||
if err = o.Patcher.Patch(old, &applied, patch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return applied.Bytes(), nil
|
||||
}
|
||||
|
||||
func (o *Options) verifyChecksum(updated []byte) error {
|
||||
checksum, err := checksumFor(o.Hash, updated)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !bytes.Equal(o.Checksum, checksum) {
|
||||
return fmt.Errorf("Updated file has wrong checksum. Expected: %x, got: %x", o.Checksum, checksum)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Options) verifySignature(updated []byte) error {
|
||||
checksum, err := checksumFor(o.Hash, updated)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return o.Verifier.VerifySignature(checksum, o.Signature, o.Hash, o.PublicKey)
|
||||
}
|
||||
|
||||
func checksumFor(h crypto.Hash, payload []byte) ([]byte, error) {
|
||||
if !h.Available() {
|
||||
return nil, errors.New("requested hash function not available")
|
||||
}
|
||||
hash := h.New()
|
||||
hash.Write(payload) // guaranteed not to error
|
||||
return hash.Sum([]byte{}), nil
|
||||
}
|
||||
172
vendor/github.com/inconshreveable/go-update/doc.go
generated
vendored
Normal file
172
vendor/github.com/inconshreveable/go-update/doc.go
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
Package update provides functionality to implement secure, self-updating Go programs (or other single-file targets).
|
||||
|
||||
For complete updating solutions please see Equinox (https://equinox.io) and go-tuf (https://github.com/flynn/go-tuf).
|
||||
|
||||
Basic Example
|
||||
|
||||
This example shows how to update a program remotely from a URL.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/inconshreveable/go-update"
|
||||
)
|
||||
|
||||
func doUpdate(url string) error {
|
||||
// request the new file
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
err := update.Apply(resp.Body, update.Options{})
|
||||
if err != nil {
|
||||
if rerr := update.RollbackError(err); rerr != nil {
|
||||
fmt.Println("Failed to rollback from bad update: %v", rerr)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Binary Patching
|
||||
|
||||
Go binaries can often be large. It can be advantageous to only ship a binary patch to a client
|
||||
instead of the complete program text of a new version.
|
||||
|
||||
This example shows how to update a program with a bsdiff binary patch. Other patch formats
|
||||
may be applied by implementing the Patcher interface.
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"github.com/inconshreveable/go-update"
|
||||
)
|
||||
|
||||
func updateWithPatch(patch io.Reader) error {
|
||||
err := update.Apply(patch, update.Options{
|
||||
Patcher: update.NewBSDiffPatcher()
|
||||
})
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Checksum Verification
|
||||
|
||||
Updating executable code on a computer can be a dangerous operation unless you
|
||||
take the appropriate steps to guarantee the authenticity of the new code. While
|
||||
checksum verification is important, it should always be combined with signature
|
||||
verification (next section) to guarantee that the code came from a trusted party.
|
||||
|
||||
go-update validates SHA256 checksums by default, but this is pluggable via the Hash
|
||||
property on the Options struct.
|
||||
|
||||
This example shows how to guarantee that the newly-updated binary is verified to
|
||||
have an appropriate checksum (that was otherwise retrived via a secure channel)
|
||||
specified as a hex string.
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
_ "crypto/sha256"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"github.com/inconshreveable/go-update"
|
||||
)
|
||||
|
||||
func updateWithChecksum(binary io.Reader, hexChecksum string) error {
|
||||
checksum, err := hex.DecodeString(hexChecksum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = update.Apply(binary, update.Options{
|
||||
Hash: crypto.SHA256, // this is the default, you don't need to specify it
|
||||
Checksum: checksum,
|
||||
})
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Cryptographic Signature Verification
|
||||
|
||||
Cryptographic verification of new code from an update is an extremely important way to guarantee the
|
||||
security and integrity of your updates.
|
||||
|
||||
Verification is performed by validating the signature of a hash of the new file. This
|
||||
means nothing changes if you apply your update with a patch.
|
||||
|
||||
This example shows how to add signature verification to your updates. To make all of this work
|
||||
an application distributor must first create a public/private key pair and embed the public key
|
||||
into their application. When they issue a new release, the issuer must sign the new executable file
|
||||
with the private key and distribute the signature along with the update.
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
_ "crypto/sha256"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"github.com/inconshreveable/go-update"
|
||||
)
|
||||
|
||||
var publicKey = []byte(`
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtrVmBxQvheRArXjg2vG1xIprWGuCyESx
|
||||
MMY8pjmjepSy2kuz+nl9aFLqmr+rDNdYvEBqQaZrYMc6k29gjvoQnQ==
|
||||
-----END PUBLIC KEY-----
|
||||
`)
|
||||
|
||||
func verifiedUpdate(binary io.Reader, hexChecksum, hexSignature string) {
|
||||
checksum, err := hex.DecodeString(hexChecksum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
signature, err := hex.DecodeString(hexSignature)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := update.Options{
|
||||
Checksum: checksum,
|
||||
Signature: signature,
|
||||
Hash: crypto.SHA256, // this is the default, you don't need to specify it
|
||||
Verifier: update.NewECDSAVerifier(), // this is the default, you don't need to specify it
|
||||
}
|
||||
err = opts.SetPublicKeyPEM(publicKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = update.Apply(binary, opts)
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Building Single-File Go Binaries
|
||||
|
||||
In order to update a Go application with go-update, you must distributed it as a single executable.
|
||||
This is often easy, but some applications require static assets (like HTML and CSS asset files or TLS certificates).
|
||||
In order to update applications like these, you'll want to make sure to embed those asset files into
|
||||
the distributed binary with a tool like go-bindata (my favorite): https://github.com/jteeuwen/go-bindata
|
||||
|
||||
Non-Goals
|
||||
|
||||
Mechanisms and protocols for determining whether an update should be applied and, if so, which one are
|
||||
out of scope for this package. Please consult go-tuf (https://github.com/flynn/go-tuf) or Equinox (https://equinox.io)
|
||||
for more complete solutions.
|
||||
|
||||
go-update only works for self-updating applications that are distributed as a single binary, i.e.
|
||||
applications that do not have additional assets or dependency files.
|
||||
Updating application that are distributed as mutliple on-disk files is out of scope, although this
|
||||
may change in future versions of this library.
|
||||
|
||||
*/
|
||||
package update
|
||||
7
vendor/github.com/inconshreveable/go-update/hide_noop.go
generated
vendored
Normal file
7
vendor/github.com/inconshreveable/go-update/hide_noop.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// +build !windows
|
||||
|
||||
package update
|
||||
|
||||
func hideFile(path string) error {
|
||||
return nil
|
||||
}
|
||||
19
vendor/github.com/inconshreveable/go-update/hide_windows.go
generated
vendored
Normal file
19
vendor/github.com/inconshreveable/go-update/hide_windows.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func hideFile(path string) error {
|
||||
kernel32 := syscall.NewLazyDLL("kernel32.dll")
|
||||
setFileAttributes := kernel32.NewProc("SetFileAttributesW")
|
||||
|
||||
r1, _, err := setFileAttributes.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), 2)
|
||||
|
||||
if r1 == 0 {
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
22
vendor/github.com/inconshreveable/go-update/internal/binarydist/License
generated
vendored
Normal file
22
vendor/github.com/inconshreveable/go-update/internal/binarydist/License
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright 2012 Keith Rarick
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
7
vendor/github.com/inconshreveable/go-update/internal/binarydist/Readme.md
generated
vendored
Normal file
7
vendor/github.com/inconshreveable/go-update/internal/binarydist/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# binarydist
|
||||
|
||||
Package binarydist implements binary diff and patch as described on
|
||||
<http://www.daemonology.net/bsdiff/>. It reads and writes files
|
||||
compatible with the tools there.
|
||||
|
||||
Documentation at <http://go.pkgdoc.org/github.com/kr/binarydist>.
|
||||
40
vendor/github.com/inconshreveable/go-update/internal/binarydist/bzip2.go
generated
vendored
Normal file
40
vendor/github.com/inconshreveable/go-update/internal/binarydist/bzip2.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
type bzip2Writer struct {
|
||||
c *exec.Cmd
|
||||
w io.WriteCloser
|
||||
}
|
||||
|
||||
func (w bzip2Writer) Write(b []byte) (int, error) {
|
||||
return w.w.Write(b)
|
||||
}
|
||||
|
||||
func (w bzip2Writer) Close() error {
|
||||
if err := w.w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return w.c.Wait()
|
||||
}
|
||||
|
||||
// Package compress/bzip2 implements only decompression,
|
||||
// so we'll fake it by running bzip2 in another process.
|
||||
func newBzip2Writer(w io.Writer) (wc io.WriteCloser, err error) {
|
||||
var bw bzip2Writer
|
||||
bw.c = exec.Command("bzip2", "-c")
|
||||
bw.c.Stdout = w
|
||||
|
||||
if bw.w, err = bw.c.StdinPipe(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = bw.c.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bw, nil
|
||||
}
|
||||
408
vendor/github.com/inconshreveable/go-update/internal/binarydist/diff.go
generated
vendored
Normal file
408
vendor/github.com/inconshreveable/go-update/internal/binarydist/diff.go
generated
vendored
Normal file
@@ -0,0 +1,408 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func swap(a []int, i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
func split(I, V []int, start, length, h int) {
|
||||
var i, j, k, x, jj, kk int
|
||||
|
||||
if length < 16 {
|
||||
for k = start; k < start+length; k += j {
|
||||
j = 1
|
||||
x = V[I[k]+h]
|
||||
for i = 1; k+i < start+length; i++ {
|
||||
if V[I[k+i]+h] < x {
|
||||
x = V[I[k+i]+h]
|
||||
j = 0
|
||||
}
|
||||
if V[I[k+i]+h] == x {
|
||||
swap(I, k+i, k+j)
|
||||
j++
|
||||
}
|
||||
}
|
||||
for i = 0; i < j; i++ {
|
||||
V[I[k+i]] = k + j - 1
|
||||
}
|
||||
if j == 1 {
|
||||
I[k] = -1
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
x = V[I[start+length/2]+h]
|
||||
jj = 0
|
||||
kk = 0
|
||||
for i = start; i < start+length; i++ {
|
||||
if V[I[i]+h] < x {
|
||||
jj++
|
||||
}
|
||||
if V[I[i]+h] == x {
|
||||
kk++
|
||||
}
|
||||
}
|
||||
jj += start
|
||||
kk += jj
|
||||
|
||||
i = start
|
||||
j = 0
|
||||
k = 0
|
||||
for i < jj {
|
||||
if V[I[i]+h] < x {
|
||||
i++
|
||||
} else if V[I[i]+h] == x {
|
||||
swap(I, i, jj+j)
|
||||
j++
|
||||
} else {
|
||||
swap(I, i, kk+k)
|
||||
k++
|
||||
}
|
||||
}
|
||||
|
||||
for jj+j < kk {
|
||||
if V[I[jj+j]+h] == x {
|
||||
j++
|
||||
} else {
|
||||
swap(I, jj+j, kk+k)
|
||||
k++
|
||||
}
|
||||
}
|
||||
|
||||
if jj > start {
|
||||
split(I, V, start, jj-start, h)
|
||||
}
|
||||
|
||||
for i = 0; i < kk-jj; i++ {
|
||||
V[I[jj+i]] = kk - 1
|
||||
}
|
||||
if jj == kk-1 {
|
||||
I[jj] = -1
|
||||
}
|
||||
|
||||
if start+length > kk {
|
||||
split(I, V, kk, start+length-kk, h)
|
||||
}
|
||||
}
|
||||
|
||||
func qsufsort(obuf []byte) []int {
|
||||
var buckets [256]int
|
||||
var i, h int
|
||||
I := make([]int, len(obuf)+1)
|
||||
V := make([]int, len(obuf)+1)
|
||||
|
||||
for _, c := range obuf {
|
||||
buckets[c]++
|
||||
}
|
||||
for i = 1; i < 256; i++ {
|
||||
buckets[i] += buckets[i-1]
|
||||
}
|
||||
copy(buckets[1:], buckets[:])
|
||||
buckets[0] = 0
|
||||
|
||||
for i, c := range obuf {
|
||||
buckets[c]++
|
||||
I[buckets[c]] = i
|
||||
}
|
||||
|
||||
I[0] = len(obuf)
|
||||
for i, c := range obuf {
|
||||
V[i] = buckets[c]
|
||||
}
|
||||
|
||||
V[len(obuf)] = 0
|
||||
for i = 1; i < 256; i++ {
|
||||
if buckets[i] == buckets[i-1]+1 {
|
||||
I[buckets[i]] = -1
|
||||
}
|
||||
}
|
||||
I[0] = -1
|
||||
|
||||
for h = 1; I[0] != -(len(obuf) + 1); h += h {
|
||||
var n int
|
||||
for i = 0; i < len(obuf)+1; {
|
||||
if I[i] < 0 {
|
||||
n -= I[i]
|
||||
i -= I[i]
|
||||
} else {
|
||||
if n != 0 {
|
||||
I[i-n] = -n
|
||||
}
|
||||
n = V[I[i]] + 1 - i
|
||||
split(I, V, i, n, h)
|
||||
i += n
|
||||
n = 0
|
||||
}
|
||||
}
|
||||
if n != 0 {
|
||||
I[i-n] = -n
|
||||
}
|
||||
}
|
||||
|
||||
for i = 0; i < len(obuf)+1; i++ {
|
||||
I[V[i]] = i
|
||||
}
|
||||
return I
|
||||
}
|
||||
|
||||
func matchlen(a, b []byte) (i int) {
|
||||
for i < len(a) && i < len(b) && a[i] == b[i] {
|
||||
i++
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func search(I []int, obuf, nbuf []byte, st, en int) (pos, n int) {
|
||||
if en-st < 2 {
|
||||
x := matchlen(obuf[I[st]:], nbuf)
|
||||
y := matchlen(obuf[I[en]:], nbuf)
|
||||
|
||||
if x > y {
|
||||
return I[st], x
|
||||
} else {
|
||||
return I[en], y
|
||||
}
|
||||
}
|
||||
|
||||
x := st + (en-st)/2
|
||||
if bytes.Compare(obuf[I[x]:], nbuf) < 0 {
|
||||
return search(I, obuf, nbuf, x, en)
|
||||
} else {
|
||||
return search(I, obuf, nbuf, st, x)
|
||||
}
|
||||
panic("unreached")
|
||||
}
|
||||
|
||||
// Diff computes the difference between old and new, according to the bsdiff
|
||||
// algorithm, and writes the result to patch.
|
||||
func Diff(old, new io.Reader, patch io.Writer) error {
|
||||
obuf, err := ioutil.ReadAll(old)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nbuf, err := ioutil.ReadAll(new)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pbuf, err := diffBytes(obuf, nbuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = patch.Write(pbuf)
|
||||
return err
|
||||
}
|
||||
|
||||
func diffBytes(obuf, nbuf []byte) ([]byte, error) {
|
||||
var patch seekBuffer
|
||||
err := diff(obuf, nbuf, &patch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return patch.buf, nil
|
||||
}
|
||||
|
||||
func diff(obuf, nbuf []byte, patch io.WriteSeeker) error {
|
||||
var lenf int
|
||||
I := qsufsort(obuf)
|
||||
db := make([]byte, len(nbuf))
|
||||
eb := make([]byte, len(nbuf))
|
||||
var dblen, eblen int
|
||||
|
||||
var hdr header
|
||||
hdr.Magic = magic
|
||||
hdr.NewSize = int64(len(nbuf))
|
||||
err := binary.Write(patch, signMagLittleEndian{}, &hdr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compute the differences, writing ctrl as we go
|
||||
pfbz2, err := newBzip2Writer(patch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var scan, pos, length int
|
||||
var lastscan, lastpos, lastoffset int
|
||||
for scan < len(nbuf) {
|
||||
var oldscore int
|
||||
scan += length
|
||||
for scsc := scan; scan < len(nbuf); scan++ {
|
||||
pos, length = search(I, obuf, nbuf[scan:], 0, len(obuf))
|
||||
|
||||
for ; scsc < scan+length; scsc++ {
|
||||
if scsc+lastoffset < len(obuf) &&
|
||||
obuf[scsc+lastoffset] == nbuf[scsc] {
|
||||
oldscore++
|
||||
}
|
||||
}
|
||||
|
||||
if (length == oldscore && length != 0) || length > oldscore+8 {
|
||||
break
|
||||
}
|
||||
|
||||
if scan+lastoffset < len(obuf) && obuf[scan+lastoffset] == nbuf[scan] {
|
||||
oldscore--
|
||||
}
|
||||
}
|
||||
|
||||
if length != oldscore || scan == len(nbuf) {
|
||||
var s, Sf int
|
||||
lenf = 0
|
||||
for i := 0; lastscan+i < scan && lastpos+i < len(obuf); {
|
||||
if obuf[lastpos+i] == nbuf[lastscan+i] {
|
||||
s++
|
||||
}
|
||||
i++
|
||||
if s*2-i > Sf*2-lenf {
|
||||
Sf = s
|
||||
lenf = i
|
||||
}
|
||||
}
|
||||
|
||||
lenb := 0
|
||||
if scan < len(nbuf) {
|
||||
var s, Sb int
|
||||
for i := 1; (scan >= lastscan+i) && (pos >= i); i++ {
|
||||
if obuf[pos-i] == nbuf[scan-i] {
|
||||
s++
|
||||
}
|
||||
if s*2-i > Sb*2-lenb {
|
||||
Sb = s
|
||||
lenb = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if lastscan+lenf > scan-lenb {
|
||||
overlap := (lastscan + lenf) - (scan - lenb)
|
||||
s := 0
|
||||
Ss := 0
|
||||
lens := 0
|
||||
for i := 0; i < overlap; i++ {
|
||||
if nbuf[lastscan+lenf-overlap+i] == obuf[lastpos+lenf-overlap+i] {
|
||||
s++
|
||||
}
|
||||
if nbuf[scan-lenb+i] == obuf[pos-lenb+i] {
|
||||
s--
|
||||
}
|
||||
if s > Ss {
|
||||
Ss = s
|
||||
lens = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
lenf += lens - overlap
|
||||
lenb -= lens
|
||||
}
|
||||
|
||||
for i := 0; i < lenf; i++ {
|
||||
db[dblen+i] = nbuf[lastscan+i] - obuf[lastpos+i]
|
||||
}
|
||||
for i := 0; i < (scan-lenb)-(lastscan+lenf); i++ {
|
||||
eb[eblen+i] = nbuf[lastscan+lenf+i]
|
||||
}
|
||||
|
||||
dblen += lenf
|
||||
eblen += (scan - lenb) - (lastscan + lenf)
|
||||
|
||||
err = binary.Write(pfbz2, signMagLittleEndian{}, int64(lenf))
|
||||
if err != nil {
|
||||
pfbz2.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
val := (scan - lenb) - (lastscan + lenf)
|
||||
err = binary.Write(pfbz2, signMagLittleEndian{}, int64(val))
|
||||
if err != nil {
|
||||
pfbz2.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
val = (pos - lenb) - (lastpos + lenf)
|
||||
err = binary.Write(pfbz2, signMagLittleEndian{}, int64(val))
|
||||
if err != nil {
|
||||
pfbz2.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
lastscan = scan - lenb
|
||||
lastpos = pos - lenb
|
||||
lastoffset = pos - scan
|
||||
}
|
||||
}
|
||||
err = pfbz2.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compute size of compressed ctrl data
|
||||
l64, err := patch.Seek(0, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.CtrlLen = int64(l64 - 32)
|
||||
|
||||
// Write compressed diff data
|
||||
pfbz2, err = newBzip2Writer(patch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, err := pfbz2.Write(db[:dblen])
|
||||
if err != nil {
|
||||
pfbz2.Close()
|
||||
return err
|
||||
}
|
||||
if n != dblen {
|
||||
pfbz2.Close()
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
err = pfbz2.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compute size of compressed diff data
|
||||
n64, err := patch.Seek(0, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.DiffLen = n64 - l64
|
||||
|
||||
// Write compressed extra data
|
||||
pfbz2, err = newBzip2Writer(patch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, err = pfbz2.Write(eb[:eblen])
|
||||
if err != nil {
|
||||
pfbz2.Close()
|
||||
return err
|
||||
}
|
||||
if n != eblen {
|
||||
pfbz2.Close()
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
err = pfbz2.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Seek to the beginning, write the header, and close the file
|
||||
_, err = patch.Seek(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(patch, signMagLittleEndian{}, &hdr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
24
vendor/github.com/inconshreveable/go-update/internal/binarydist/doc.go
generated
vendored
Normal file
24
vendor/github.com/inconshreveable/go-update/internal/binarydist/doc.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// Package binarydist implements binary diff and patch as described on
|
||||
// http://www.daemonology.net/bsdiff/. It reads and writes files
|
||||
// compatible with the tools there.
|
||||
package binarydist
|
||||
|
||||
var magic = [8]byte{'B', 'S', 'D', 'I', 'F', 'F', '4', '0'}
|
||||
|
||||
// File format:
|
||||
// 0 8 "BSDIFF40"
|
||||
// 8 8 X
|
||||
// 16 8 Y
|
||||
// 24 8 sizeof(newfile)
|
||||
// 32 X bzip2(control block)
|
||||
// 32+X Y bzip2(diff block)
|
||||
// 32+X+Y ??? bzip2(extra block)
|
||||
// with control block a set of triples (x,y,z) meaning "add x bytes
|
||||
// from oldfile to x bytes from the diff block; copy y bytes from the
|
||||
// extra block; seek forwards in oldfile by z bytes".
|
||||
type header struct {
|
||||
Magic [8]byte
|
||||
CtrlLen int64
|
||||
DiffLen int64
|
||||
NewSize int64
|
||||
}
|
||||
53
vendor/github.com/inconshreveable/go-update/internal/binarydist/encoding.go
generated
vendored
Normal file
53
vendor/github.com/inconshreveable/go-update/internal/binarydist/encoding.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
package binarydist
|
||||
|
||||
// SignMagLittleEndian is the numeric encoding used by the bsdiff tools.
|
||||
// It implements binary.ByteOrder using a sign-magnitude format
|
||||
// and little-endian byte order. Only methods Uint64 and String
|
||||
// have been written; the rest panic.
|
||||
type signMagLittleEndian struct{}
|
||||
|
||||
func (signMagLittleEndian) Uint16(b []byte) uint16 { panic("unimplemented") }
|
||||
|
||||
func (signMagLittleEndian) PutUint16(b []byte, v uint16) { panic("unimplemented") }
|
||||
|
||||
func (signMagLittleEndian) Uint32(b []byte) uint32 { panic("unimplemented") }
|
||||
|
||||
func (signMagLittleEndian) PutUint32(b []byte, v uint32) { panic("unimplemented") }
|
||||
|
||||
func (signMagLittleEndian) Uint64(b []byte) uint64 {
|
||||
y := int64(b[0]) |
|
||||
int64(b[1])<<8 |
|
||||
int64(b[2])<<16 |
|
||||
int64(b[3])<<24 |
|
||||
int64(b[4])<<32 |
|
||||
int64(b[5])<<40 |
|
||||
int64(b[6])<<48 |
|
||||
int64(b[7]&0x7f)<<56
|
||||
|
||||
if b[7]&0x80 != 0 {
|
||||
y = -y
|
||||
}
|
||||
return uint64(y)
|
||||
}
|
||||
|
||||
func (signMagLittleEndian) PutUint64(b []byte, v uint64) {
|
||||
x := int64(v)
|
||||
neg := x < 0
|
||||
if neg {
|
||||
x = -x
|
||||
}
|
||||
|
||||
b[0] = byte(x)
|
||||
b[1] = byte(x >> 8)
|
||||
b[2] = byte(x >> 16)
|
||||
b[3] = byte(x >> 24)
|
||||
b[4] = byte(x >> 32)
|
||||
b[5] = byte(x >> 40)
|
||||
b[6] = byte(x >> 48)
|
||||
b[7] = byte(x >> 56)
|
||||
if neg {
|
||||
b[7] |= 0x80
|
||||
}
|
||||
}
|
||||
|
||||
func (signMagLittleEndian) String() string { return "signMagLittleEndian" }
|
||||
109
vendor/github.com/inconshreveable/go-update/internal/binarydist/patch.go
generated
vendored
Normal file
109
vendor/github.com/inconshreveable/go-update/internal/binarydist/patch.go
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/bzip2"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
var ErrCorrupt = errors.New("corrupt patch")
|
||||
|
||||
// Patch applies patch to old, according to the bspatch algorithm,
|
||||
// and writes the result to new.
|
||||
func Patch(old io.Reader, new io.Writer, patch io.Reader) error {
|
||||
var hdr header
|
||||
err := binary.Read(patch, signMagLittleEndian{}, &hdr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hdr.Magic != magic {
|
||||
return ErrCorrupt
|
||||
}
|
||||
if hdr.CtrlLen < 0 || hdr.DiffLen < 0 || hdr.NewSize < 0 {
|
||||
return ErrCorrupt
|
||||
}
|
||||
|
||||
ctrlbuf := make([]byte, hdr.CtrlLen)
|
||||
_, err = io.ReadFull(patch, ctrlbuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cpfbz2 := bzip2.NewReader(bytes.NewReader(ctrlbuf))
|
||||
|
||||
diffbuf := make([]byte, hdr.DiffLen)
|
||||
_, err = io.ReadFull(patch, diffbuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dpfbz2 := bzip2.NewReader(bytes.NewReader(diffbuf))
|
||||
|
||||
// The entire rest of the file is the extra block.
|
||||
epfbz2 := bzip2.NewReader(patch)
|
||||
|
||||
obuf, err := ioutil.ReadAll(old)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nbuf := make([]byte, hdr.NewSize)
|
||||
|
||||
var oldpos, newpos int64
|
||||
for newpos < hdr.NewSize {
|
||||
var ctrl struct{ Add, Copy, Seek int64 }
|
||||
err = binary.Read(cpfbz2, signMagLittleEndian{}, &ctrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Sanity-check
|
||||
if newpos+ctrl.Add > hdr.NewSize {
|
||||
return ErrCorrupt
|
||||
}
|
||||
|
||||
// Read diff string
|
||||
_, err = io.ReadFull(dpfbz2, nbuf[newpos:newpos+ctrl.Add])
|
||||
if err != nil {
|
||||
return ErrCorrupt
|
||||
}
|
||||
|
||||
// Add old data to diff string
|
||||
for i := int64(0); i < ctrl.Add; i++ {
|
||||
if oldpos+i >= 0 && oldpos+i < int64(len(obuf)) {
|
||||
nbuf[newpos+i] += obuf[oldpos+i]
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust pointers
|
||||
newpos += ctrl.Add
|
||||
oldpos += ctrl.Add
|
||||
|
||||
// Sanity-check
|
||||
if newpos+ctrl.Copy > hdr.NewSize {
|
||||
return ErrCorrupt
|
||||
}
|
||||
|
||||
// Read extra string
|
||||
_, err = io.ReadFull(epfbz2, nbuf[newpos:newpos+ctrl.Copy])
|
||||
if err != nil {
|
||||
return ErrCorrupt
|
||||
}
|
||||
|
||||
// Adjust pointers
|
||||
newpos += ctrl.Copy
|
||||
oldpos += ctrl.Seek
|
||||
}
|
||||
|
||||
// Write the new file
|
||||
for len(nbuf) > 0 {
|
||||
n, err := new.Write(nbuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nbuf = nbuf[n:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
43
vendor/github.com/inconshreveable/go-update/internal/binarydist/seek.go
generated
vendored
Normal file
43
vendor/github.com/inconshreveable/go-update/internal/binarydist/seek.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package binarydist
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type seekBuffer struct {
|
||||
buf []byte
|
||||
pos int
|
||||
}
|
||||
|
||||
func (b *seekBuffer) Write(p []byte) (n int, err error) {
|
||||
n = copy(b.buf[b.pos:], p)
|
||||
if n == len(p) {
|
||||
b.pos += n
|
||||
return n, nil
|
||||
}
|
||||
b.buf = append(b.buf, p[n:]...)
|
||||
b.pos += len(p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (b *seekBuffer) Seek(offset int64, whence int) (ret int64, err error) {
|
||||
var abs int64
|
||||
switch whence {
|
||||
case 0:
|
||||
abs = offset
|
||||
case 1:
|
||||
abs = int64(b.pos) + offset
|
||||
case 2:
|
||||
abs = int64(len(b.buf)) + offset
|
||||
default:
|
||||
return 0, errors.New("binarydist: invalid whence")
|
||||
}
|
||||
if abs < 0 {
|
||||
return 0, errors.New("binarydist: negative position")
|
||||
}
|
||||
if abs >= 1<<31 {
|
||||
return 0, errors.New("binarydist: position out of range")
|
||||
}
|
||||
b.pos = int(abs)
|
||||
return abs, nil
|
||||
}
|
||||
27
vendor/github.com/inconshreveable/go-update/internal/osext/LICENSE
generated
vendored
Normal file
27
vendor/github.com/inconshreveable/go-update/internal/osext/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
16
vendor/github.com/inconshreveable/go-update/internal/osext/README.md
generated
vendored
Normal file
16
vendor/github.com/inconshreveable/go-update/internal/osext/README.md
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
### Extensions to the "os" package.
|
||||
|
||||
## Find the current Executable and ExecutableFolder.
|
||||
|
||||
There is sometimes utility in finding the current executable file
|
||||
that is running. This can be used for upgrading the current executable
|
||||
or finding resources located relative to the executable file. Both
|
||||
working directory and the os.Args[0] value are arbitrary and cannot
|
||||
be relied on; os.Args[0] can be "faked".
|
||||
|
||||
Multi-platform and supports:
|
||||
* Linux
|
||||
* OS X
|
||||
* Windows
|
||||
* Plan 9
|
||||
* BSDs.
|
||||
27
vendor/github.com/inconshreveable/go-update/internal/osext/osext.go
generated
vendored
Normal file
27
vendor/github.com/inconshreveable/go-update/internal/osext/osext.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Extensions to the standard "os" package.
|
||||
package osext
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
// Executable returns an absolute path that can be used to
|
||||
// re-invoke the current program.
|
||||
// It may not be valid after the current program exits.
|
||||
func Executable() (string, error) {
|
||||
p, err := executable()
|
||||
return filepath.Clean(p), err
|
||||
}
|
||||
|
||||
// Returns same path as Executable, returns just the folder
|
||||
// path. Excludes the executable name and any trailing slash.
|
||||
func ExecutableFolder() (string, error) {
|
||||
p, err := Executable()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return filepath.Dir(p), nil
|
||||
}
|
||||
20
vendor/github.com/inconshreveable/go-update/internal/osext/osext_plan9.go
generated
vendored
Normal file
20
vendor/github.com/inconshreveable/go-update/internal/osext/osext_plan9.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func executable() (string, error) {
|
||||
f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
return syscall.Fd2path(int(f.Fd()))
|
||||
}
|
||||
36
vendor/github.com/inconshreveable/go-update/internal/osext/osext_procfs.go
generated
vendored
Normal file
36
vendor/github.com/inconshreveable/go-update/internal/osext/osext_procfs.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux netbsd openbsd solaris dragonfly
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func executable() (string, error) {
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
const deletedTag = " (deleted)"
|
||||
execpath, err := os.Readlink("/proc/self/exe")
|
||||
if err != nil {
|
||||
return execpath, err
|
||||
}
|
||||
execpath = strings.TrimSuffix(execpath, deletedTag)
|
||||
execpath = strings.TrimPrefix(execpath, deletedTag)
|
||||
return execpath, nil
|
||||
case "netbsd":
|
||||
return os.Readlink("/proc/curproc/exe")
|
||||
case "openbsd", "dragonfly":
|
||||
return os.Readlink("/proc/curproc/file")
|
||||
case "solaris":
|
||||
return os.Readlink(fmt.Sprintf("/proc/%d/path/a.out", os.Getpid()))
|
||||
}
|
||||
return "", errors.New("ExecPath not implemented for " + runtime.GOOS)
|
||||
}
|
||||
79
vendor/github.com/inconshreveable/go-update/internal/osext/osext_sysctl.go
generated
vendored
Normal file
79
vendor/github.com/inconshreveable/go-update/internal/osext/osext_sysctl.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var initCwd, initCwdErr = os.Getwd()
|
||||
|
||||
func executable() (string, error) {
|
||||
var mib [4]int32
|
||||
switch runtime.GOOS {
|
||||
case "freebsd":
|
||||
mib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1}
|
||||
case "darwin":
|
||||
mib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1}
|
||||
}
|
||||
|
||||
n := uintptr(0)
|
||||
// Get length.
|
||||
_, _, errNum := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if errNum != 0 {
|
||||
return "", errNum
|
||||
}
|
||||
if n == 0 { // This shouldn't happen.
|
||||
return "", nil
|
||||
}
|
||||
buf := make([]byte, n)
|
||||
_, _, errNum = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if errNum != 0 {
|
||||
return "", errNum
|
||||
}
|
||||
if n == 0 { // This shouldn't happen.
|
||||
return "", nil
|
||||
}
|
||||
for i, v := range buf {
|
||||
if v == 0 {
|
||||
buf = buf[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
var err error
|
||||
execPath := string(buf)
|
||||
// execPath will not be empty due to above checks.
|
||||
// Try to get the absolute path if the execPath is not rooted.
|
||||
if execPath[0] != '/' {
|
||||
execPath, err = getAbs(execPath)
|
||||
if err != nil {
|
||||
return execPath, err
|
||||
}
|
||||
}
|
||||
// For darwin KERN_PROCARGS may return the path to a symlink rather than the
|
||||
// actual executable.
|
||||
if runtime.GOOS == "darwin" {
|
||||
if execPath, err = filepath.EvalSymlinks(execPath); err != nil {
|
||||
return execPath, err
|
||||
}
|
||||
}
|
||||
return execPath, nil
|
||||
}
|
||||
|
||||
func getAbs(execPath string) (string, error) {
|
||||
if initCwdErr != nil {
|
||||
return execPath, initCwdErr
|
||||
}
|
||||
// The execPath may begin with a "../" or a "./" so clean it first.
|
||||
// Join the two paths, trailing and starting slashes undetermined, so use
|
||||
// the generic Join function.
|
||||
return filepath.Join(initCwd, filepath.Clean(execPath)), nil
|
||||
}
|
||||
34
vendor/github.com/inconshreveable/go-update/internal/osext/osext_windows.go
generated
vendored
Normal file
34
vendor/github.com/inconshreveable/go-update/internal/osext/osext_windows.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package osext
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
kernel = syscall.MustLoadDLL("kernel32.dll")
|
||||
getModuleFileNameProc = kernel.MustFindProc("GetModuleFileNameW")
|
||||
)
|
||||
|
||||
// GetModuleFileName() with hModule = NULL
|
||||
func executable() (exePath string, err error) {
|
||||
return getModuleFileName()
|
||||
}
|
||||
|
||||
func getModuleFileName() (string, error) {
|
||||
var n uint32
|
||||
b := make([]uint16, syscall.MAX_PATH)
|
||||
size := uint32(len(b))
|
||||
|
||||
r0, _, e1 := getModuleFileNameProc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(size))
|
||||
n = uint32(r0)
|
||||
if n == 0 {
|
||||
return "", e1
|
||||
}
|
||||
return string(utf16.Decode(b[0:n])), nil
|
||||
}
|
||||
24
vendor/github.com/inconshreveable/go-update/patcher.go
generated
vendored
Normal file
24
vendor/github.com/inconshreveable/go-update/patcher.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/inconshreveable/go-update/internal/binarydist"
|
||||
)
|
||||
|
||||
// Patcher defines an interface for applying binary patches to an old item to get an updated item.
|
||||
type Patcher interface {
|
||||
Patch(old io.Reader, new io.Writer, patch io.Reader) error
|
||||
}
|
||||
|
||||
type patchFn func(io.Reader, io.Writer, io.Reader) error
|
||||
|
||||
func (fn patchFn) Patch(old io.Reader, new io.Writer, patch io.Reader) error {
|
||||
return fn(old, new, patch)
|
||||
}
|
||||
|
||||
// NewBSDifferPatcher returns a new Patcher that applies binary patches using
|
||||
// the bsdiff algorithm. See http://www.daemonology.net/bsdiff/
|
||||
func NewBSDiffPatcher() Patcher {
|
||||
return patchFn(binarydist.Patch)
|
||||
}
|
||||
74
vendor/github.com/inconshreveable/go-update/verifier.go
generated
vendored
Normal file
74
vendor/github.com/inconshreveable/go-update/verifier.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// Verifier defines an interface for verfiying an update's signature with a public key.
|
||||
type Verifier interface {
|
||||
VerifySignature(checksum, signature []byte, h crypto.Hash, publicKey crypto.PublicKey) error
|
||||
}
|
||||
|
||||
type verifyFn func([]byte, []byte, crypto.Hash, crypto.PublicKey) error
|
||||
|
||||
func (fn verifyFn) VerifySignature(checksum []byte, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {
|
||||
return fn(checksum, signature, hash, publicKey)
|
||||
}
|
||||
|
||||
// NewRSAVerifier returns a Verifier that uses the RSA algorithm to verify updates.
|
||||
func NewRSAVerifier() Verifier {
|
||||
return verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {
|
||||
key, ok := publicKey.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.New("not a valid RSA public key")
|
||||
}
|
||||
return rsa.VerifyPKCS1v15(key, hash, checksum, signature)
|
||||
})
|
||||
}
|
||||
|
||||
type rsDER struct {
|
||||
R *big.Int
|
||||
S *big.Int
|
||||
}
|
||||
|
||||
// NewECDSAVerifier returns a Verifier that uses the ECDSA algorithm to verify updates.
|
||||
func NewECDSAVerifier() Verifier {
|
||||
return verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {
|
||||
key, ok := publicKey.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.New("not a valid ECDSA public key")
|
||||
}
|
||||
var rs rsDER
|
||||
if _, err := asn1.Unmarshal(signature, &rs); err != nil {
|
||||
return err
|
||||
}
|
||||
if !ecdsa.Verify(key, checksum, rs.R, rs.S) {
|
||||
return errors.New("failed to verify ecsda signature")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// NewDSAVerifier returns a Verifier that uses the DSA algorithm to verify updates.
|
||||
func NewDSAVerifier() Verifier {
|
||||
return verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {
|
||||
key, ok := publicKey.(*dsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.New("not a valid DSA public key")
|
||||
}
|
||||
var rs rsDER
|
||||
if _, err := asn1.Unmarshal(signature, &rs); err != nil {
|
||||
return err
|
||||
}
|
||||
if !dsa.Verify(key, checksum, rs.R, rs.S) {
|
||||
return errors.New("failed to verify ecsda signature")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
13
vendor/github.com/segmentio/go-prompt/History.md
generated
vendored
Normal file
13
vendor/github.com/segmentio/go-prompt/History.md
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
v1.2.0 / 2014-12-10
|
||||
===================
|
||||
|
||||
* remove appending of ? to Confirm()
|
||||
|
||||
v1.1.0 / 2014-10-22
|
||||
==================
|
||||
|
||||
* add passwords example
|
||||
* add password docs
|
||||
* Merge pull request #2 from nrmitchi/add/gopass
|
||||
* Adding convenience wrappers around howeyc/gopass
|
||||
33
vendor/github.com/segmentio/go-prompt/Readme.md
generated
vendored
Normal file
33
vendor/github.com/segmentio/go-prompt/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
# go-prompt
|
||||
|
||||
Terminal prompts for Go.
|
||||
|
||||
View the [docs](http://godoc.org/pkg/github.com/segmentio/go-prompt).
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/segmentio/go-prompt"
|
||||
|
||||
var langs = []string{
|
||||
"c",
|
||||
"c++",
|
||||
"lua",
|
||||
"go",
|
||||
"js",
|
||||
"ruby",
|
||||
"python",
|
||||
}
|
||||
|
||||
func main() {
|
||||
i := prompt.Choose("What's your favorite language?", langs)
|
||||
println("picked: " + langs[i])
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
94
vendor/github.com/segmentio/go-prompt/prompt.go
generated
vendored
Normal file
94
vendor/github.com/segmentio/go-prompt/prompt.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
package prompt
|
||||
|
||||
import "github.com/howeyc/gopass"
|
||||
import "strings"
|
||||
import "strconv"
|
||||
import "fmt"
|
||||
|
||||
// String prompt.
|
||||
func String(prompt string, args ...interface{}) string {
|
||||
var s string
|
||||
fmt.Printf(prompt+": ", args...)
|
||||
fmt.Scanln(&s)
|
||||
return s
|
||||
}
|
||||
|
||||
// String prompt (required).
|
||||
func StringRequired(prompt string, args ...interface{}) (s string) {
|
||||
for strings.Trim(s, " ") == "" {
|
||||
s = String(prompt, args...)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Confirm continues prompting until the input is boolean-ish.
|
||||
func Confirm(prompt string, args ...interface{}) bool {
|
||||
for {
|
||||
switch String(prompt, args...) {
|
||||
case "Yes", "yes", "y", "Y":
|
||||
return true
|
||||
case "No", "no", "n", "N":
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Choose prompts for a single selection from `list`, returning in the index.
|
||||
func Choose(prompt string, list []string) int {
|
||||
fmt.Println()
|
||||
for i, val := range list {
|
||||
fmt.Printf(" %d) %s\n", i+1, val)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
i := -1
|
||||
|
||||
for {
|
||||
s := String(prompt)
|
||||
|
||||
// index
|
||||
n, err := strconv.Atoi(s)
|
||||
if err == nil {
|
||||
if n > 0 && n <= len(list) {
|
||||
i = n - 1
|
||||
break
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// value
|
||||
i = indexOf(s, list)
|
||||
if i != -1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// Password prompt.
|
||||
func Password(prompt string, args ...interface{}) string {
|
||||
fmt.Printf(prompt+": ", args...)
|
||||
password, _ := gopass.GetPasswd()
|
||||
s := string(password[0:])
|
||||
return s
|
||||
}
|
||||
|
||||
// Password prompt with mask.
|
||||
func PasswordMasked(prompt string, args ...interface{}) string {
|
||||
fmt.Printf(prompt+": ", args...)
|
||||
password, _ := gopass.GetPasswdMasked()
|
||||
s := string(password[0:])
|
||||
return s
|
||||
}
|
||||
|
||||
// index of `s` in `list`.
|
||||
func indexOf(s string, list []string) int {
|
||||
for i, val := range list {
|
||||
if val == s {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
Reference in New Issue
Block a user