使用github的七牛SDK,配置名称Kodo->Qiniu

This commit is contained in:
deepzz0
2017-11-05 12:27:22 +08:00
parent c9fc0cc75a
commit 360204995d
429 changed files with 26939 additions and 14206 deletions
-3
View File
@@ -1,3 +0,0 @@
This repository holds supplementary Go cryptography libraries.
To submit changes to this repository, see https://golang.org/doc/contribute.html.
+21
View File
@@ -0,0 +1,21 @@
# Go Cryptography
This repository holds supplementary Go cryptography libraries.
## Download/Install
The easiest way to install is to run `go get -u golang.org/x/crypto/...`. You
can also manually git clone the repository to `$GOPATH/src/golang.org/x/crypto`.
## Report Issues / Send Patches
This repository uses Gerrit for code changes. To learn how to submit changes to
this repository, see https://golang.org/doc/contribute.html.
The main issue tracker for the crypto repository is located at
https://github.com/golang/go/issues. Prefix your issue with "x/crypto:" in the
subject line, so it is easy to find.
Note that contributions to the cryptography package receive additional scrutiny
due to their sensitive nature. Patches may take longer than normal to receive
feedback.
+6 -34
View File
@@ -51,38 +51,6 @@ const (
maxNonces = 100
)
// CertOption is an optional argument type for Client methods which manipulate
// certificate data.
type CertOption interface {
privateCertOpt()
}
// WithKey creates an option holding a private/public key pair.
// The private part signs a certificate, and the public part represents the signee.
func WithKey(key crypto.Signer) CertOption {
return &certOptKey{key}
}
type certOptKey struct {
key crypto.Signer
}
func (*certOptKey) privateCertOpt() {}
// WithTemplate creates an option for specifying a certificate template.
// See x509.CreateCertificate for template usage details.
//
// In TLSSNIxChallengeCert methods, the template is also used as parent,
// resulting in a self-signed certificate.
// The DNSNames field of t is always overwritten for tls-sni challenge certs.
func WithTemplate(t *x509.Certificate) CertOption {
return (*certOptTemplate)(t)
}
type certOptTemplate x509.Certificate
func (*certOptTemplate) privateCertOpt() {}
// Client is an ACME client.
// The only required field is Key. An example of creating a client with a new key
// is as follows:
@@ -174,7 +142,7 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
//
// In the case where CA server does not provide the issued certificate in the response,
// CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips.
// In such scenario the caller can cancel the polling with ctx.
// In such a scenario, the caller can cancel the polling with ctx.
//
// CreateCert returns an error if the CA's response or chain was unreasonably large.
// Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
@@ -289,7 +257,7 @@ func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte,
func AcceptTOS(tosURL string) bool { return true }
// Register creates a new account registration by following the "new-reg" flow.
// It returns registered account. The a argument is not modified.
// It returns the registered account. The account is not modified.
//
// The registration may require the caller to agree to the CA's Terms of Service (TOS).
// If so, and the account has not indicated the acceptance of the terms (see Account for details),
@@ -1027,6 +995,7 @@ func keyAuth(pub crypto.PublicKey, token string) (string, error) {
// tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
// with the given SANs and auto-generated public/private key pair.
// The Subject Common Name is set to the first SAN to aid debugging.
// To create a cert with a custom key pair, specify WithKey option.
func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
var (
@@ -1065,6 +1034,9 @@ func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
}
}
tmpl.DNSNames = san
if len(san) > 0 {
tmpl.Subject.CommonName = san[0]
}
der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key)
if err != nil {
+6
View File
@@ -1186,6 +1186,9 @@ func TestTLSSNI01ChallengeCert(t *testing.T) {
if cert.DNSNames[0] != name {
t.Errorf("cert.DNSNames[0] != name: %q vs %q", cert.DNSNames[0], name)
}
if cn := cert.Subject.CommonName; cn != san {
t.Errorf("cert.Subject.CommonName = %q; want %q", cn, san)
}
}
func TestTLSSNI02ChallengeCert(t *testing.T) {
@@ -1219,6 +1222,9 @@ func TestTLSSNI02ChallengeCert(t *testing.T) {
if i >= len(cert.DNSNames) || cert.DNSNames[i] != name {
t.Errorf("%v doesn't have %q", cert.DNSNames, name)
}
if cn := cert.Subject.CommonName; cn != sanA {
t.Errorf("CommonName = %q; want %q", cn, sanA)
}
}
func TestTLSChallengeCertOpt(t *testing.T) {
+6 -4
View File
@@ -83,8 +83,10 @@ func defaultHostPolicy(context.Context, string) error {
// It obtains and refreshes certificates automatically,
// as well as providing them to a TLS server via tls.Config.
//
// To preserve issued certificates and improve overall performance,
// use a cache implementation of Cache. For instance, DirCache.
// You must specify a cache implementation, such as DirCache,
// to reuse obtained certificates across program restarts.
// Otherwise your server is very likely to exceed the certificate
// issuer's request rate limits.
type Manager struct {
// Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
// The registration may require the caller to agree to the CA's TOS.
@@ -369,7 +371,7 @@ func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certifica
// We are the first; state is locked.
// Unblock the readers when domain ownership is verified
// and the we got the cert or the process failed.
// and we got the cert or the process failed.
defer state.Unlock()
state.locked = false
@@ -437,7 +439,7 @@ func (m *Manager) certState(domain string) (*certState, error) {
return state, nil
}
// authorizedCert starts domain ownership verification process and requests a new cert upon success.
// authorizedCert starts the domain ownership verification process and requests a new cert upon success.
// The key argument is the certificate private key.
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
if err := m.verify(ctx, domain); err != nil {
+1
View File
@@ -23,6 +23,7 @@ func ExampleNewListener() {
func ExampleManager() {
m := autocert.Manager{
Cache: autocert.DirCache("secret-dir"),
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.org"),
}
+34
View File
@@ -5,6 +5,8 @@
package acme
import (
"crypto"
"crypto/x509"
"errors"
"fmt"
"net/http"
@@ -293,3 +295,35 @@ func (e *wireError) error(h http.Header) *Error {
Header: h,
}
}
// CertOption is an optional argument type for the TLSSNIxChallengeCert methods for
// customizing a temporary certificate for TLS-SNI challenges.
type CertOption interface {
privateCertOpt()
}
// WithKey creates an option holding a private/public key pair.
// The private part signs a certificate, and the public part represents the signee.
func WithKey(key crypto.Signer) CertOption {
return &certOptKey{key}
}
type certOptKey struct {
key crypto.Signer
}
func (*certOptKey) privateCertOpt() {}
// WithTemplate creates an option for specifying a certificate template.
// See x509.CreateCertificate for template usage details.
//
// In TLSSNIxChallengeCert methods, the template is also used as parent,
// resulting in a self-signed certificate.
// The DNSNames field of t is always overwritten for tls-sni challenge certs.
func WithTemplate(t *x509.Certificate) CertOption {
return (*certOptTemplate)(t)
}
type certOptTemplate x509.Certificate
func (*certOptTemplate) privateCertOpt() {}
+1 -1
View File
@@ -126,7 +126,7 @@ func testHashes2X(t *testing.T) {
t.Fatalf("#%d (single write): error from Read: %v", i, err)
}
if n, err := h.Read(sum); n != 0 || err != io.EOF {
t.Fatalf("#%d (single write): Read did not return (0, os.EOF) after exhaustion, got (%v, %v)", i, n, err)
t.Fatalf("#%d (single write): Read did not return (0, io.EOF) after exhaustion, got (%v, %v)", i, n, err)
}
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
@@ -167,9 +167,8 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte) {
}
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out may be the same slice but otherwise should not overlap. Counter
// contains the raw ChaCha20 counter bytes (i.e. block counter followed by
// nonce).
// In and out must overlap entirely or not at all. Counter contains the raw
// ChaCha20 counter bytes (i.e. block counter followed by nonce).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
var block [64]byte
var counterCopy [16]byte
+184 -56
View File
@@ -5,40 +5,30 @@
package cryptobyte
import (
"encoding/asn1"
encoding_asn1 "encoding/asn1"
"fmt"
"math/big"
"reflect"
"time"
"golang.org/x/crypto/cryptobyte/asn1"
)
// This file contains ASN.1-related methods for String and Builder.
// Tag represents an ASN.1 tag number and class (together also referred to as
// identifier octets). Methods in this package only support the low-tag-number
// form, i.e. a single identifier octet with bits 7-8 encoding the class and
// bits 1-6 encoding the tag number.
type Tag uint8
// Contructed returns t with the context-specific class bit set.
func (t Tag) ContextSpecific() Tag { return t | 0x80 }
// Contructed returns t with the constructed class bit set.
func (t Tag) Constructed() Tag { return t | 0x20 }
// Builder
// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER.
func (b *Builder) AddASN1Int64(v int64) {
b.addASN1Signed(asn1.TagInteger, v)
b.addASN1Signed(asn1.INTEGER, v)
}
// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
func (b *Builder) AddASN1Enum(v int64) {
b.addASN1Signed(asn1.TagEnum, v)
b.addASN1Signed(asn1.ENUM, v)
}
func (b *Builder) addASN1Signed(tag Tag, v int64) {
func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) {
b.AddASN1(tag, func(c *Builder) {
length := 1
for i := v; i >= 0x80 || i < -0x80; i >>= 8 {
@@ -54,7 +44,7 @@ func (b *Builder) addASN1Signed(tag Tag, v int64) {
// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER.
func (b *Builder) AddASN1Uint64(v uint64) {
b.AddASN1(asn1.TagInteger, func(c *Builder) {
b.AddASN1(asn1.INTEGER, func(c *Builder) {
length := 1
for i := v; i >= 0x80; i >>= 8 {
length++
@@ -73,7 +63,7 @@ func (b *Builder) AddASN1BigInt(n *big.Int) {
return
}
b.AddASN1(asn1.TagInteger, func(c *Builder) {
b.AddASN1(asn1.INTEGER, func(c *Builder) {
if n.Sign() < 0 {
// A negative number has to be converted to two's-complement form. So we
// invert and subtract 1. If the most-significant-bit isn't set then
@@ -103,7 +93,7 @@ func (b *Builder) AddASN1BigInt(n *big.Int) {
// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING.
func (b *Builder) AddASN1OctetString(bytes []byte) {
b.AddASN1(asn1.TagOctetString, func(c *Builder) {
b.AddASN1(asn1.OCTET_STRING, func(c *Builder) {
c.AddBytes(bytes)
})
}
@@ -116,27 +106,97 @@ func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t)
return
}
b.AddASN1(asn1.TagGeneralizedTime, func(c *Builder) {
b.AddASN1(asn1.GeneralizedTime, func(c *Builder) {
c.AddBytes([]byte(t.Format(generalizedTimeFormatStr)))
})
}
// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING.
func (b *Builder) AddASN1BitString(s asn1.BitString) {
// TODO(martinkr): Implement.
b.MarshalASN1(s)
// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not
// support BIT STRINGs that are not a whole number of bytes.
func (b *Builder) AddASN1BitString(data []byte) {
b.AddASN1(asn1.BIT_STRING, func(b *Builder) {
b.AddUint8(0)
b.AddBytes(data)
})
}
// MarshalASN1 calls asn1.Marshal on its input and appends the result if
func (b *Builder) addBase128Int(n int64) {
var length int
if n == 0 {
length = 1
} else {
for i := n; i > 0; i >>= 7 {
length++
}
}
for i := length - 1; i >= 0; i-- {
o := byte(n >> uint(i*7))
o &= 0x7f
if i != 0 {
o |= 0x80
}
b.add(o)
}
}
func isValidOID(oid encoding_asn1.ObjectIdentifier) bool {
if len(oid) < 2 {
return false
}
if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) {
return false
}
for _, v := range oid {
if v < 0 {
return false
}
}
return true
}
func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) {
b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) {
if !isValidOID(oid) {
b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid)
return
}
b.addBase128Int(int64(oid[0])*40 + int64(oid[1]))
for _, v := range oid[2:] {
b.addBase128Int(int64(v))
}
})
}
func (b *Builder) AddASN1Boolean(v bool) {
b.AddASN1(asn1.BOOLEAN, func(b *Builder) {
if v {
b.AddUint8(0xff)
} else {
b.AddUint8(0)
}
})
}
func (b *Builder) AddASN1NULL() {
b.add(uint8(asn1.NULL), 0)
}
// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if
// successful or records an error if one occurred.
func (b *Builder) MarshalASN1(v interface{}) {
// NOTE(martinkr): This is somewhat of a hack to allow propagation of
// asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a
// encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a
// value embedded into a struct, its tag information is lost.
if b.err != nil {
return
}
bytes, err := asn1.Marshal(v)
bytes, err := encoding_asn1.Marshal(v)
if err != nil {
b.err = err
return
@@ -148,7 +208,7 @@ func (b *Builder) MarshalASN1(v interface{}) {
// Tags greater than 30 are not supported and result in an error (i.e.
// low-tag-number form only). The child builder passed to the
// BuilderContinuation can be used to build the content of the ASN.1 object.
func (b *Builder) AddASN1(tag Tag, f BuilderContinuation) {
func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
if b.err != nil {
return
}
@@ -164,6 +224,24 @@ func (b *Builder) AddASN1(tag Tag, f BuilderContinuation) {
// String
func (s *String) ReadASN1Boolean(out *bool) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.INTEGER) || len(bytes) != 1 {
return false
}
switch bytes[0] {
case 0:
*out = false
case 0xff:
*out = true
default:
return false
}
return true
}
var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
@@ -215,7 +293,7 @@ var bigOne = big.NewInt(1)
func (s *String) readASN1BigInt(out *big.Int) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) {
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
return false
}
if bytes[0]&0x80 == 0x80 {
@@ -235,7 +313,7 @@ func (s *String) readASN1BigInt(out *big.Int) bool {
func (s *String) readASN1Int64(out *int64) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
return false
}
return true
@@ -258,7 +336,7 @@ func asn1Signed(out *int64, n []byte) bool {
func (s *String) readASN1Uint64(out *uint64) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.TagInteger) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
return false
}
return true
@@ -286,7 +364,7 @@ func asn1Unsigned(out *uint64, n []byte) bool {
func (s *String) ReadASN1Enum(out *int) bool {
var bytes String
var i int64
if !s.ReadASN1(&bytes, asn1.TagEnum) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
return false
}
if int64(int(i)) != i {
@@ -315,9 +393,9 @@ func (s *String) readBase128Int(out *int) bool {
// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
// advances. It returns true on success and false on error.
func (s *String) ReadASN1ObjectIdentifier(out *asn1.ObjectIdentifier) bool {
func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.TagOID) || len(bytes) == 0 {
if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 {
return false
}
@@ -356,7 +434,7 @@ func (s *String) ReadASN1ObjectIdentifier(out *asn1.ObjectIdentifier) bool {
// advances. It returns true on success and false on error.
func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.TagGeneralizedTime) {
if !s.ReadASN1(&bytes, asn1.GeneralizedTime) {
return false
}
t := string(bytes)
@@ -373,9 +451,9 @@ func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It
// returns true on success and false on error.
func (s *String) ReadASN1BitString(out *asn1.BitString) bool {
func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.TagBitString) || len(bytes) == 0 {
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
return false
}
@@ -392,10 +470,27 @@ func (s *String) ReadASN1BitString(out *asn1.BitString) bool {
return true
}
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It is
// an error if the BIT STRING is not a whole number of bytes. This function
// returns true on success and false on error.
func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
return false
}
paddingBits := uint8(bytes[0])
if paddingBits != 0 {
return false
}
*out = bytes[1:]
return true
}
// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
// tag and length bytes) into out, and advances. The element must match the
// given tag. It returns true on success and false on error.
func (s *String) ReadASN1Bytes(out *[]byte, tag Tag) bool {
func (s *String) ReadASN1Bytes(out *[]byte, tag asn1.Tag) bool {
return s.ReadASN1((*String)(out), tag)
}
@@ -404,8 +499,8 @@ func (s *String) ReadASN1Bytes(out *[]byte, tag Tag) bool {
// given tag. It returns true on success and false on error.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadASN1(out *String, tag Tag) bool {
var t Tag
func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
var t asn1.Tag
if !s.ReadAnyASN1(out, &t) || t != tag {
return false
}
@@ -417,8 +512,8 @@ func (s *String) ReadASN1(out *String, tag Tag) bool {
// given tag. It returns true on success and false on error.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadASN1Element(out *String, tag Tag) bool {
var t Tag
func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
var t asn1.Tag
if !s.ReadAnyASN1Element(out, &t) || t != tag {
return false
}
@@ -430,7 +525,7 @@ func (s *String) ReadASN1Element(out *String, tag Tag) bool {
// returns true on success and false on error.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadAnyASN1(out *String, outTag *Tag) bool {
func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
return s.readASN1(out, outTag, true /* skip header */)
}
@@ -439,24 +534,30 @@ func (s *String) ReadAnyASN1(out *String, outTag *Tag) bool {
// advances. It returns true on success and false on error.
//
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
func (s *String) ReadAnyASN1Element(out *String, outTag *Tag) bool {
func (s *String) ReadAnyASN1Element(out *String, outTag *asn1.Tag) bool {
return s.readASN1(out, outTag, false /* include header */)
}
// PeekASN1Tag returns true if the next ASN.1 value on the string starts with
// the given tag.
func (s String) PeekASN1Tag(tag Tag) bool {
func (s String) PeekASN1Tag(tag asn1.Tag) bool {
if len(s) == 0 {
return false
}
return Tag(s[0]) == tag
return asn1.Tag(s[0]) == tag
}
// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.Element
// (not including tag and length bytes) tagged with the given tag into out. It
// stores whether an element with the tag was found in outPresent, unless
// outPresent is nil. It returns true on success and false on error.
func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag Tag) bool {
// SkipASN1 reads and discards an ASN.1 element with the given tag.
func (s *String) SkipASN1(tag asn1.Tag) bool {
var unused String
return s.ReadASN1(&unused, tag)
}
// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.1
// element (not including tag and length bytes) tagged with the given tag into
// out. It stores whether an element with the tag was found in outPresent,
// unless outPresent is nil. It returns true on success and false on error.
func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) bool {
present := s.PeekASN1Tag(tag)
if outPresent != nil {
*outPresent = present
@@ -467,12 +568,22 @@ func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag Tag) bool {
return true
}
// SkipOptionalASN1 advances s over an ASN.1 element with the given tag, or
// else leaves s unchanged.
func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
if !s.PeekASN1Tag(tag) {
return true
}
var unused String
return s.ReadASN1(&unused, tag)
}
// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
// explicitly tagged with tag into out and advances. If no element with a
// matching tag is present, it writes defaultValue into out instead. If out
// does not point to an integer or to a big.Int, it panics. It returns true on
// success and false on error.
func (s *String) ReadOptionalASN1Integer(out interface{}, tag Tag, defaultValue interface{}) bool {
func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
if reflect.TypeOf(out).Kind() != reflect.Ptr {
panic("out is not a pointer")
}
@@ -510,7 +621,7 @@ func (s *String) ReadOptionalASN1Integer(out interface{}, tag Tag, defaultValue
// explicitly tagged with tag into out and advances. If no element with a
// matching tag is present, it writes defaultValue into out instead. It returns
// true on success and false on error.
func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag Tag) bool {
func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag asn1.Tag) bool {
var present bool
var child String
if !s.ReadOptionalASN1(&child, &present, tag) {
@@ -521,7 +632,7 @@ func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag
}
if present {
var oct String
if !child.ReadASN1(&oct, asn1.TagOctetString) || !child.Empty() {
if !child.ReadASN1(&oct, asn1.OCTET_STRING) || !child.Empty() {
return false
}
*out = oct
@@ -531,7 +642,24 @@ func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag
return true
}
func (s *String) readASN1(out *String, outTag *Tag, skipHeader bool) bool {
// ReadOptionalASN1Boolean sets *out to the value of the next ASN.1 BOOLEAN or,
// if the next bytes are not an ASN.1 BOOLEAN, to the value of defaultValue.
func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
var present bool
var child String
if !s.ReadOptionalASN1(&child, &present, asn1.BOOLEAN) {
return false
}
if !present {
*out = defaultValue
return true
}
return s.ReadASN1Boolean(out)
}
func (s *String) readASN1(out *String, outTag *asn1.Tag, skipHeader bool) bool {
if len(*s) < 2 {
return false
}
@@ -547,7 +675,7 @@ func (s *String) readASN1(out *String, outTag *Tag, skipHeader bool) bool {
}
if outTag != nil {
*outTag = Tag(tag)
*outTag = asn1.Tag(tag)
}
// ITU-T X.690 section 8.1.3
+46
View File
@@ -0,0 +1,46 @@
// Copyright 2017 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 asn1 contains supporting types for parsing and building ASN.1
// messages with the cryptobyte package.
package asn1 // import "golang.org/x/crypto/cryptobyte/asn1"
// Tag represents an ASN.1 identifier octet, consisting of a tag number
// (indicating a type) and class (such as context-specific or constructed).
//
// Methods in the cryptobyte package only support the low-tag-number form, i.e.
// a single identifier octet with bits 7-8 encoding the class and bits 1-6
// encoding the tag number.
type Tag uint8
const (
classConstructed = 0x20
classContextSpecific = 0x80
)
// Constructed returns t with the constructed class bit set.
func (t Tag) Constructed() Tag { return t | classConstructed }
// ContextSpecific returns t with the context-specific class bit set.
func (t Tag) ContextSpecific() Tag { return t | classContextSpecific }
// The following is a list of standard tag and class combinations.
const (
BOOLEAN = Tag(1)
INTEGER = Tag(2)
BIT_STRING = Tag(3)
OCTET_STRING = Tag(4)
NULL = Tag(5)
OBJECT_IDENTIFIER = Tag(6)
ENUM = Tag(10)
UTF8String = Tag(12)
SEQUENCE = Tag(16 | classConstructed)
SET = Tag(17 | classConstructed)
PrintableString = Tag(19)
T61String = Tag(20)
IA5String = Tag(22)
UTCTime = Tag(23)
GeneralizedTime = Tag(24)
GeneralString = Tag(27)
)
+30 -15
View File
@@ -6,17 +6,19 @@ package cryptobyte
import (
"bytes"
"encoding/asn1"
encoding_asn1 "encoding/asn1"
"math/big"
"reflect"
"testing"
"time"
"golang.org/x/crypto/cryptobyte/asn1"
)
type readASN1Test struct {
name string
in []byte
tag Tag
tag asn1.Tag
ok bool
out interface{}
}
@@ -194,7 +196,7 @@ func TestReadASN1IntegerInvalid(t *testing.T) {
}
}
func TestReadASN1ObjectIdentifier(t *testing.T) {
func TestASN1ObjectIdentifier(t *testing.T) {
testData := []struct {
in []byte
ok bool
@@ -212,10 +214,23 @@ func TestReadASN1ObjectIdentifier(t *testing.T) {
for i, test := range testData {
in := String(test.in)
var out asn1.ObjectIdentifier
var out encoding_asn1.ObjectIdentifier
ok := in.ReadASN1ObjectIdentifier(&out)
if ok != test.ok || ok && !out.Equal(test.out) {
t.Errorf("#%d: in.ReadASN1ObjectIdentifier() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
continue
}
var b Builder
b.AddASN1ObjectIdentifier(out)
result, err := b.Bytes()
if builderOk := err == nil; test.ok != builderOk {
t.Errorf("#%d: error from Builder.Bytes: %s", i, err)
continue
}
if test.ok && !bytes.Equal(result, test.in) {
t.Errorf("#%d: reserialisation didn't match, got %x, want %x", i, result, test.in)
continue
}
}
}
@@ -250,7 +265,7 @@ func TestReadASN1GeneralizedTime(t *testing.T) {
{"201001020304-10Z", false, time.Time{}},
}
for i, test := range testData {
in := String(append([]byte{asn1.TagGeneralizedTime, byte(len(test.in))}, test.in...))
in := String(append([]byte{byte(asn1.GeneralizedTime), byte(len(test.in))}, test.in...))
var out time.Time
ok := in.ReadASN1GeneralizedTime(&out)
if ok != test.ok || ok && !reflect.DeepEqual(out, test.out) {
@@ -263,20 +278,20 @@ func TestReadASN1BitString(t *testing.T) {
testData := []struct {
in []byte
ok bool
out asn1.BitString
out encoding_asn1.BitString
}{
{[]byte{}, false, asn1.BitString{}},
{[]byte{0x00}, true, asn1.BitString{}},
{[]byte{0x07, 0x00}, true, asn1.BitString{Bytes: []byte{0}, BitLength: 1}},
{[]byte{0x07, 0x01}, false, asn1.BitString{}},
{[]byte{0x07, 0x40}, false, asn1.BitString{}},
{[]byte{0x08, 0x00}, false, asn1.BitString{}},
{[]byte{0xff}, false, asn1.BitString{}},
{[]byte{0xfe, 0x00}, false, asn1.BitString{}},
{[]byte{}, false, encoding_asn1.BitString{}},
{[]byte{0x00}, true, encoding_asn1.BitString{}},
{[]byte{0x07, 0x00}, true, encoding_asn1.BitString{Bytes: []byte{0}, BitLength: 1}},
{[]byte{0x07, 0x01}, false, encoding_asn1.BitString{}},
{[]byte{0x07, 0x40}, false, encoding_asn1.BitString{}},
{[]byte{0x08, 0x00}, false, encoding_asn1.BitString{}},
{[]byte{0xff}, false, encoding_asn1.BitString{}},
{[]byte{0xfe, 0x00}, false, encoding_asn1.BitString{}},
}
for i, test := range testData {
in := String(append([]byte{3, byte(len(test.in))}, test.in...))
var out asn1.BitString
var out encoding_asn1.BitString
ok := in.ReadASN1BitString(&out)
if ok != test.ok || ok && (!bytes.Equal(out.Bytes, test.out.Bytes) || out.BitLength != test.out.BitLength) {
t.Errorf("#%d: in.ReadASN1BitString() = %v, want %v; out = %v, want %v", i, ok, test.ok, out, test.out)
+70 -16
View File
@@ -10,15 +10,25 @@ import (
)
// A Builder builds byte strings from fixed-length and length-prefixed values.
// Builders either allocate space as needed, or are fixed, which means that
// they write into a given buffer and produce an error if it's exhausted.
//
// The zero value is a usable Builder that allocates space as needed.
//
// Simple values are marshaled and appended to a Builder using methods on the
// Builder. Length-prefixed values are marshaled by providing a
// BuilderContinuation, which is a function that writes the inner contents of
// the value to a given Builder. See the documentation for BuilderContinuation
// for details.
type Builder struct {
err error
result []byte
fixedSize bool
child *Builder
offset int
pendingLenLen int
pendingIsASN1 bool
err error
result []byte
fixedSize bool
child *Builder
offset int
pendingLenLen int
pendingIsASN1 bool
inContinuation *bool
}
// NewBuilder creates a Builder that appends its output to the given buffer.
@@ -86,9 +96,9 @@ func (b *Builder) AddBytes(v []byte) {
// BuilderContinuation is continuation-passing interface for building
// length-prefixed byte sequences. Builder methods for length-prefixed
// sequences (AddUint8LengthPrefixed etc.) will invoke the BuilderContinuation
// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation
// supplied to them. The child builder passed to the continuation can be used
// to build the content of the length-prefixed sequence. Example:
// to build the content of the length-prefixed sequence. For example:
//
// parent := cryptobyte.NewBuilder()
// parent.AddUint8LengthPrefixed(func (child *Builder) {
@@ -102,8 +112,19 @@ func (b *Builder) AddBytes(v []byte) {
// length prefix. After the continuation returns, the child must be considered
// invalid, i.e. users must not store any copies or references of the child
// that outlive the continuation.
//
// If the continuation panics with a value of type BuildError then the inner
// error will be returned as the error from Bytes. If the child panics
// otherwise then Bytes will repanic with the same value.
type BuilderContinuation func(child *Builder)
// BuildError wraps an error. If a BuilderContinuation panics with this value,
// the panic will be recovered and the inner error will be returned from
// Builder.Bytes.
type BuildError struct {
Err error
}
// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence.
func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) {
b.addLengthPrefixed(1, false, f)
@@ -119,6 +140,34 @@ func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) {
b.addLengthPrefixed(3, false, f)
}
// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence.
func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) {
b.addLengthPrefixed(4, false, f)
}
func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) {
if !*b.inContinuation {
*b.inContinuation = true
defer func() {
*b.inContinuation = false
r := recover()
if r == nil {
return
}
if buildError, ok := r.(BuildError); ok {
b.err = buildError.Err
} else {
panic(r)
}
}()
}
f(arg)
}
func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) {
// Subsequent writes can be ignored if the builder has encountered an error.
if b.err != nil {
@@ -128,15 +177,20 @@ func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuati
offset := len(b.result)
b.add(make([]byte, lenLen)...)
b.child = &Builder{
result: b.result,
fixedSize: b.fixedSize,
offset: offset,
pendingLenLen: lenLen,
pendingIsASN1: isASN1,
if b.inContinuation == nil {
b.inContinuation = new(bool)
}
f(b.child)
b.child = &Builder{
result: b.result,
fixedSize: b.fixedSize,
offset: offset,
pendingLenLen: lenLen,
pendingIsASN1: isASN1,
inContinuation: b.inContinuation,
}
b.callContinuation(f, b.child)
b.flushChild()
if b.child != nil {
panic("cryptobyte: internal error")
+49
View File
@@ -6,6 +6,7 @@ package cryptobyte
import (
"bytes"
"errors"
"fmt"
"testing"
)
@@ -18,6 +19,54 @@ func builderBytesEq(b *Builder, want ...byte) error {
return nil
}
func TestContinuationError(t *testing.T) {
const errorStr = "TestContinuationError"
var b Builder
b.AddUint8LengthPrefixed(func(b *Builder) {
b.AddUint8(1)
panic(BuildError{Err: errors.New(errorStr)})
})
ret, err := b.Bytes()
if ret != nil {
t.Error("expected nil result")
}
if err == nil {
t.Fatal("unexpected nil error")
}
if s := err.Error(); s != errorStr {
t.Errorf("expected error %q, got %v", errorStr, s)
}
}
func TestContinuationNonError(t *testing.T) {
defer func() {
recover()
}()
var b Builder
b.AddUint8LengthPrefixed(func(b *Builder) {
b.AddUint8(1)
panic(1)
})
t.Error("Builder did not panic")
}
func TestGeneratedPanic(t *testing.T) {
defer func() {
recover()
}()
var b Builder
b.AddUint8LengthPrefixed(func(b *Builder) {
var p *byte
*p = 0
})
t.Error("Builder did not panic")
}
func TestBytes(t *testing.T) {
var b Builder
v := []byte("foobarbaz")
+42 -8
View File
@@ -5,9 +5,11 @@
package cryptobyte_test
import (
"encoding/asn1"
"errors"
"fmt"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
)
func ExampleString_lengthPrefixed() {
@@ -37,7 +39,7 @@ func ExampleString_lengthPrefixed() {
fmt.Printf("%#v\n", result)
}
func ExampleString_asn1() {
func ExampleString_aSN1() {
// This is an example of parsing ASN.1 data that looks like:
// Foo ::= SEQUENCE {
// version [6] INTEGER DEFAULT 0
@@ -51,12 +53,12 @@ func ExampleString_asn1() {
data, inner, versionBytes cryptobyte.String
haveVersion bool
)
if !input.ReadASN1(&inner, cryptobyte.Tag(asn1.TagSequence).Constructed()) ||
if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
!input.Empty() ||
!inner.ReadOptionalASN1(&versionBytes, &haveVersion, cryptobyte.Tag(6).Constructed().ContextSpecific()) ||
!inner.ReadOptionalASN1(&versionBytes, &haveVersion, asn1.Tag(6).Constructed().ContextSpecific()) ||
(haveVersion && !versionBytes.ReadASN1Integer(&version)) ||
(haveVersion && !versionBytes.Empty()) ||
!inner.ReadASN1(&data, asn1.TagOctetString) ||
!inner.ReadASN1(&data, asn1.OCTET_STRING) ||
!inner.Empty() {
panic("bad format")
}
@@ -65,7 +67,7 @@ func ExampleString_asn1() {
fmt.Printf("haveVersion: %t, version: %d, data: %s\n", haveVersion, version, string(data))
}
func ExampleBuilder_asn1() {
func ExampleBuilder_aSN1() {
// This is an example of building ASN.1 data that looks like:
// Foo ::= SEQUENCE {
// version [6] INTEGER DEFAULT 0
@@ -77,9 +79,9 @@ func ExampleBuilder_asn1() {
const defaultVersion = 0
var b cryptobyte.Builder
b.AddASN1(cryptobyte.Tag(asn1.TagSequence).Constructed(), func(b *cryptobyte.Builder) {
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
if version != defaultVersion {
b.AddASN1(cryptobyte.Tag(6).Constructed().ContextSpecific(), func(b *cryptobyte.Builder) {
b.AddASN1(asn1.Tag(6).Constructed().ContextSpecific(), func(b *cryptobyte.Builder) {
b.AddASN1Int64(version)
})
}
@@ -118,3 +120,35 @@ func ExampleBuilder_lengthPrefixed() {
// Output: 000c0568656c6c6f05776f726c64
fmt.Printf("%x\n", result)
}
func ExampleBuilder_lengthPrefixOverflow() {
// Writing more data that can be expressed by the length prefix results
// in an error from Bytes().
tooLarge := make([]byte, 256)
var b cryptobyte.Builder
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(tooLarge)
})
result, err := b.Bytes()
fmt.Printf("len=%d err=%s\n", len(result), err)
// Output: len=0 err=cryptobyte: pending child length 256 exceeds 1-byte length prefix
}
func ExampleBuilderContinuation_errorHandling() {
var b cryptobyte.Builder
// Continuations that panic with a BuildError will cause Bytes to
// return the inner error.
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint32(0)
panic(cryptobyte.BuildError{Err: errors.New("example error")})
})
result, err := b.Bytes()
fmt.Printf("len=%d err=%s\n", len(result), err)
// Output: len=0 err=example error
}
+13 -3
View File
@@ -2,9 +2,19 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package cryptobyte implements building and parsing of byte strings for
// DER-encoded ASN.1 and TLS messages. See the examples for the Builder and
// String types to get started.
// Package cryptobyte contains types that help with parsing and constructing
// length-prefixed, binary messages, including ASN.1 DER. (The asn1 subpackage
// contains useful ASN.1 constants.)
//
// The String type is for parsing. It wraps a []byte slice and provides helper
// functions for consuming structures, value by value.
//
// The Builder type is for constructing messages. It providers helper functions
// for appending values and also for appending length-prefixed submessages
// without having to worry about calculating the length prefix ahead of time.
//
// See the documentation and examples for the Builder and String types to get
// started.
package cryptobyte // import "golang.org/x/crypto/cryptobyte"
// String represents a string of bytes. It provides methods for parsing
+1 -1
View File
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// We have a implementation in amd64 assembly so this code is only run on
// We have an implementation in amd64 assembly so this code is only run on
// non-amd64 platforms. The amd64 assembly does not support gccgo.
// +build !amd64 gccgo appengine
+3 -3
View File
@@ -6,17 +6,17 @@
// https://ed25519.cr.yp.to/.
//
// These functions are also compatible with the “Ed25519” function defined in
// https://tools.ietf.org/html/draft-irtf-cfrg-eddsa-05.
// RFC 8032.
package ed25519
// This code is a port of the public domain, “ref10” implementation of ed25519
// from SUPERCOP.
import (
"bytes"
"crypto"
cryptorand "crypto/rand"
"crypto/sha512"
"crypto/subtle"
"errors"
"io"
"strconv"
@@ -177,5 +177,5 @@ func Verify(publicKey PublicKey, message, sig []byte) bool {
var checkR [32]byte
R.ToBytes(&checkR)
return subtle.ConstantTimeCompare(sig[:32], checkR[:]) == 1
return bytes.Equal(sig[:32], checkR[:])
}
+20
View File
@@ -0,0 +1,20 @@
// Copyright 2017 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 md4_test
import (
"fmt"
"io"
"golang.org/x/crypto/md4"
)
func ExampleNew() {
h := md4.New()
data := "These pretzels are making me thirsty."
io.WriteString(h, data)
fmt.Printf("%x", h.Sum(nil))
// Output: 48c4e365090b30a32f084c4888deceaa
}
+58
View File
@@ -0,0 +1,58 @@
// Copyright 2017 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 auth authenticates a message using a secret key.
The Sum function, viewed as a function of the message for a uniform random
key, is designed to meet the standard notion of unforgeability. This means
that an attacker cannot find authenticators for any messages not authenticated
by the sender, even if the attacker has adaptively influenced the messages
authenticated by the sender. For a formal definition see, e.g., Section 2.4
of Bellare, Kilian, and Rogaway, "The security of the cipher block chaining
message authentication code," Journal of Computer and System Sciences 61 (2000),
362399; http://www-cse.ucsd.edu/~mihir/papers/cbc.html.
auth does not make any promises regarding "strong" unforgeability; perhaps
one valid authenticator can be converted into another valid authenticator for
the same message. NaCl also does not make any promises regarding "truncated
unforgeability."
This package is interoperable with NaCl: https://nacl.cr.yp.to/auth.html.
*/
package auth
import (
"crypto/hmac"
"crypto/sha512"
)
const (
// Size is the size, in bytes, of an authenticated digest.
Size = 32
// KeySize is the size, in bytes, of an authentication key.
KeySize = 32
)
// Sum generates an authenticator for m using a secret key and returns the
// 32-byte digest.
func Sum(m []byte, key *[KeySize]byte) *[Size]byte {
mac := hmac.New(sha512.New, key[:])
mac.Write(m)
out := new([KeySize]byte)
copy(out[:], mac.Sum(nil)[:Size])
return out
}
// Verify checks that digest is a valid authenticator of message m under the
// given secret key. Verify does not leak timing information.
func Verify(digest []byte, m []byte, key *[32]byte) bool {
if len(digest) != Size {
return false
}
mac := hmac.New(sha512.New, key[:])
mac.Write(m)
expectedMAC := mac.Sum(nil) // first 256 bits of 512-bit sum
return hmac.Equal(digest, expectedMAC[:Size])
}
+172
View File
@@ -0,0 +1,172 @@
// Copyright 2017 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 auth
import (
"bytes"
rand "crypto/rand"
mrand "math/rand"
"testing"
)
// Test cases are from RFC 4231, and match those present in the tests directory
// of the download here: https://nacl.cr.yp.to/install.html
var testCases = []struct {
key [32]byte
msg []byte
out [32]byte
}{
{
key: [32]byte{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b,
},
msg: []byte("Hi There"),
out: [32]byte{
0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
},
},
{
key: [32]byte{'J', 'e', 'f', 'e'},
msg: []byte("what do ya want for nothing?"),
out: [32]byte{
0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
},
},
{
key: [32]byte{
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa,
},
msg: []byte{ // 50 bytes of 0xdd
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd,
},
out: [32]byte{
0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
},
},
{
key: [32]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19,
},
msg: []byte{
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd,
},
out: [32]byte{
0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
},
},
}
func TestSum(t *testing.T) {
for i, test := range testCases {
tag := Sum(test.msg, &test.key)
if !bytes.Equal(tag[:], test.out[:]) {
t.Errorf("#%d: Sum: got\n%x\nwant\n%x", i, tag, test.out)
}
}
}
func TestVerify(t *testing.T) {
wrongMsg := []byte("unknown msg")
for i, test := range testCases {
if !Verify(test.out[:], test.msg, &test.key) {
t.Errorf("#%d: Verify(%x, %q, %x) failed", i, test.out, test.msg, test.key)
}
if Verify(test.out[:], wrongMsg, &test.key) {
t.Errorf("#%d: Verify(%x, %q, %x) unexpectedly passed", i, test.out, wrongMsg, test.key)
}
}
}
func TestStress(t *testing.T) {
if testing.Short() {
t.Skip("exhaustiveness test")
}
var key [32]byte
msg := make([]byte, 10000)
prng := mrand.New(mrand.NewSource(0))
// copied from tests/auth5.c in nacl
for i := 0; i < 10000; i++ {
if _, err := rand.Read(key[:]); err != nil {
t.Fatal(err)
}
if _, err := rand.Read(msg[:i]); err != nil {
t.Fatal(err)
}
tag := Sum(msg[:i], &key)
if !Verify(tag[:], msg[:i], &key) {
t.Errorf("#%d: unexpected failure from Verify", i)
}
if i > 0 {
msgIndex := prng.Intn(i)
oldMsgByte := msg[msgIndex]
msg[msgIndex] += byte(1 + prng.Intn(255))
if Verify(tag[:], msg[:i], &key) {
t.Errorf("#%d: unexpected success from Verify after corrupting message", i)
}
msg[msgIndex] = oldMsgByte
tag[prng.Intn(len(tag))] += byte(1 + prng.Intn(255))
if Verify(tag[:], msg[:i], &key) {
t.Errorf("#%d: unexpected success from Verify after corrupting authenticator", i)
}
}
}
}
func BenchmarkAuth(b *testing.B) {
var key [32]byte
if _, err := rand.Read(key[:]); err != nil {
b.Fatal(err)
}
buf := make([]byte, 1024)
if _, err := rand.Read(buf[:]); err != nil {
b.Fatal(err)
}
b.SetBytes(int64(len(buf)))
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
tag := Sum(buf, &key)
if Verify(tag[:], buf, &key) == false {
b.Fatal("unexpected failure from Verify")
}
}
}
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2017 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 auth_test
import (
"encoding/hex"
"fmt"
"golang.org/x/crypto/nacl/auth"
)
func Example() {
// Load your secret key from a safe place and reuse it across multiple
// Sum calls. (Obviously don't use this example key for anything
// real.) If you want to convert a passphrase to a key, use a suitable
// package like bcrypt or scrypt.
secretKeyBytes, err := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574")
if err != nil {
panic(err)
}
var secretKey [32]byte
copy(secretKey[:], secretKeyBytes)
mac := auth.Sum([]byte("hello world"), &secretKey)
fmt.Printf("%x\n", *mac)
result := auth.Verify(mac[:], []byte("hello world"), &secretKey)
fmt.Println(result)
badResult := auth.Verify(mac[:], []byte("different message"), &secretKey)
fmt.Println(badResult)
// Output: eca5a521f3d77b63f567fb0cb6f5f2d200641bc8dada42f60c5f881260c30317
// true
// false
}
+19 -2
View File
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
/*
Package box authenticates and encrypts messages using public-key cryptography.
Package box authenticates and encrypts small messages using public-key cryptography.
Box uses Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate
messages. The length of messages is not hidden.
@@ -13,6 +13,23 @@ example, by using nonce 1 for the first message, nonce 2 for the second
message, etc. Nonces are long enough that randomly generated nonces have
negligible risk of collision.
Messages should be small because:
1. The whole message needs to be held in memory to be processed.
2. Using large messages pressures implementations on small machines to decrypt
and process plaintext before authenticating it. This is very dangerous, and
this API does not allow it, but a protocol that uses excessive message sizes
might present some implementations with no other choice.
3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.
4. Performance may be improved by working with messages that fit into data caches.
Thus large amounts of data should be chunked so that each message is small.
(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable
chunk size.
This package is interoperable with NaCl: https://nacl.cr.yp.to/box.html.
*/
package box // import "golang.org/x/crypto/nacl/box"
@@ -56,7 +73,7 @@ func Precompute(sharedKey, peersPublicKey, privateKey *[32]byte) {
}
// Seal appends an encrypted and authenticated copy of message to out, which
// will be Overhead bytes longer than the original and must not overlap. The
// will be Overhead bytes longer than the original and must not overlap it. The
// nonce must be unique for each distinct message for a given pair of keys.
func Seal(out, message []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) []byte {
var sharedKey [32]byte
+17
View File
@@ -13,6 +13,23 @@ example, by using nonce 1 for the first message, nonce 2 for the second
message, etc. Nonces are long enough that randomly generated nonces have
negligible risk of collision.
Messages should be small because:
1. The whole message needs to be held in memory to be processed.
2. Using large messages pressures implementations on small machines to decrypt
and process plaintext before authenticating it. This is very dangerous, and
this API does not allow it, but a protocol that uses excessive message sizes
might present some implementations with no other choice.
3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.
4. Performance may be improved by working with messages that fit into data caches.
Thus large amounts of data should be chunked so that each message is small.
(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable
chunk size.
This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
*/
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
+12 -12
View File
@@ -295,17 +295,17 @@ const (
// The enumerated reasons for revoking a certificate. See RFC 5280.
const (
Unspecified = iota
KeyCompromise = iota
CACompromise = iota
AffiliationChanged = iota
Superseded = iota
CessationOfOperation = iota
CertificateHold = iota
_ = iota
RemoveFromCRL = iota
PrivilegeWithdrawn = iota
AACompromise = iota
Unspecified = 0
KeyCompromise = 1
CACompromise = 2
AffiliationChanged = 3
Superseded = 4
CessationOfOperation = 5
CertificateHold = 6
RemoveFromCRL = 8
PrivilegeWithdrawn = 9
AACompromise = 10
)
// Request represents an OCSP request. See RFC 6960.
@@ -659,7 +659,7 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
//
// The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields.
//
// The template is used to populate the SerialNumber, RevocationStatus, RevokedAt,
// The template is used to populate the SerialNumber, Status, RevokedAt,
// RevocationReason, ThisUpdate, and NextUpdate fields.
//
// If template.IssuerHash is not set, SHA1 will be used.
+20 -5
View File
@@ -12,7 +12,10 @@ import (
)
func TestKeyExpiry(t *testing.T) {
kring, _ := ReadKeyRing(readerFromHex(expiringKeyHex))
kring, err := ReadKeyRing(readerFromHex(expiringKeyHex))
if err != nil {
t.Fatal(err)
}
entity := kring[0]
const timeFormat = "2006-01-02"
@@ -104,7 +107,10 @@ func TestGoodCrossSignature(t *testing.T) {
// TestExternallyRevokableKey attempts to load and parse a key with a third party revocation permission.
func TestExternallyRevocableKey(t *testing.T) {
kring, _ := ReadKeyRing(readerFromHex(subkeyUsageHex))
kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
if err != nil {
t.Fatal(err)
}
// The 0xA42704B92866382A key can be revoked by 0xBE3893CB843D0FE70C
// according to this signature that appears within the key:
@@ -125,7 +131,10 @@ func TestExternallyRevocableKey(t *testing.T) {
}
func TestKeyRevocation(t *testing.T) {
kring, _ := ReadKeyRing(readerFromHex(revokedKeyHex))
kring, err := ReadKeyRing(readerFromHex(revokedKeyHex))
if err != nil {
t.Fatal(err)
}
// revokedKeyHex contains these keys:
// pub 1024R/9A34F7C0 2014-03-25 [revoked: 2014-03-25]
@@ -145,7 +154,10 @@ func TestKeyRevocation(t *testing.T) {
}
func TestSubkeyRevocation(t *testing.T) {
kring, _ := ReadKeyRing(readerFromHex(revokedSubkeyHex))
kring, err := ReadKeyRing(readerFromHex(revokedSubkeyHex))
if err != nil {
t.Fatal(err)
}
// revokedSubkeyHex contains these keys:
// pub 1024R/4EF7E4BECCDE97F0 2014-03-25
@@ -178,7 +190,10 @@ func TestSubkeyRevocation(t *testing.T) {
}
func TestKeyUsage(t *testing.T) {
kring, _ := ReadKeyRing(readerFromHex(subkeyUsageHex))
kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
if err != nil {
t.Fatal(err)
}
// subkeyUsageHex contains these keys:
// pub 1024R/2866382A created: 2014-04-01 expires: never usage: SC
+1 -1
View File
@@ -228,7 +228,7 @@ func TestECDSASignerPrivateKey(t *testing.T) {
priv := NewSignerPrivateKey(time.Now(), &ecdsaSigner{ecdsaPriv})
if priv.PubKeyAlgo != PubKeyAlgoECDSA {
t.Fatal("NewSignerPrivateKey should have made a ECSDA private key")
t.Fatal("NewSignerPrivateKey should have made an ECSDA private key")
}
sig := &Signature{
+3 -3
View File
@@ -88,10 +88,10 @@ func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunc
return nil, ske.CipherFunc, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
}
plaintextKey = plaintextKey[1:]
if l := len(plaintextKey); l == 0 || l%cipherFunc.blockSize() != 0 {
return nil, cipherFunc, errors.StructuralError("length of decrypted key not a multiple of block size")
if l, cipherKeySize := len(plaintextKey), cipherFunc.KeySize(); l != cipherFunc.KeySize() {
return nil, cipherFunc, errors.StructuralError("length of decrypted key (" + strconv.Itoa(l) + ") " +
"not equal to cipher keysize (" + strconv.Itoa(cipherKeySize) + ")")
}
return plaintextKey, cipherFunc, nil
}
+48 -34
View File
@@ -61,43 +61,57 @@ func TestSymmetricKeyEncrypted(t *testing.T) {
const symmetricallyEncryptedHex = "8c0d04030302371a0b38d884f02060c91cf97c9973b8e58e028e9501708ccfe618fb92afef7fa2d80ddadd93cf"
const symmetricallyEncryptedContentsHex = "cb1062004d14c4df636f6e74656e74732e0a"
func TestSerializeSymmetricKeyEncrypted(t *testing.T) {
buf := bytes.NewBuffer(nil)
passphrase := []byte("testing")
const cipherFunc = CipherAES128
config := &Config{
DefaultCipher: cipherFunc,
func TestSerializeSymmetricKeyEncryptedCiphers(t *testing.T) {
tests := [...]struct {
cipherFunc CipherFunction
name string
}{
{Cipher3DES, "Cipher3DES"},
{CipherCAST5, "CipherCAST5"},
{CipherAES128, "CipherAES128"},
{CipherAES192, "CipherAES192"},
{CipherAES256, "CipherAES256"},
}
key, err := SerializeSymmetricKeyEncrypted(buf, passphrase, config)
if err != nil {
t.Errorf("failed to serialize: %s", err)
return
}
for _, test := range tests {
var buf bytes.Buffer
passphrase := []byte("testing")
config := &Config{
DefaultCipher: test.cipherFunc,
}
p, err := Read(buf)
if err != nil {
t.Errorf("failed to reparse: %s", err)
return
}
ske, ok := p.(*SymmetricKeyEncrypted)
if !ok {
t.Errorf("parsed a different packet type: %#v", p)
return
}
key, err := SerializeSymmetricKeyEncrypted(&buf, passphrase, config)
if err != nil {
t.Errorf("cipher(%s) failed to serialize: %s", test.name, err)
continue
}
if ske.CipherFunc != config.DefaultCipher {
t.Errorf("SKE cipher function is %d (expected %d)", ske.CipherFunc, config.DefaultCipher)
}
parsedKey, parsedCipherFunc, err := ske.Decrypt(passphrase)
if err != nil {
t.Errorf("failed to decrypt reparsed SKE: %s", err)
return
}
if !bytes.Equal(key, parsedKey) {
t.Errorf("keys don't match after Decrypt: %x (original) vs %x (parsed)", key, parsedKey)
}
if parsedCipherFunc != cipherFunc {
t.Errorf("cipher function doesn't match after Decrypt: %d (original) vs %d (parsed)", cipherFunc, parsedCipherFunc)
p, err := Read(&buf)
if err != nil {
t.Errorf("cipher(%s) failed to reparse: %s", test.name, err)
continue
}
ske, ok := p.(*SymmetricKeyEncrypted)
if !ok {
t.Errorf("cipher(%s) parsed a different packet type: %#v", test.name, p)
continue
}
if ske.CipherFunc != config.DefaultCipher {
t.Errorf("cipher(%s) SKE cipher function is %d (expected %d)", test.name, ske.CipherFunc, config.DefaultCipher)
}
parsedKey, parsedCipherFunc, err := ske.Decrypt(passphrase)
if err != nil {
t.Errorf("cipher(%s) failed to decrypt reparsed SKE: %s", test.name, err)
continue
}
if !bytes.Equal(key, parsedKey) {
t.Errorf("cipher(%s) keys don't match after Decrypt: %x (original) vs %x (parsed)", test.name, key, parsedKey)
}
if parsedCipherFunc != test.cipherFunc {
t.Errorf("cipher(%s) cipher function doesn't match after Decrypt: %d (original) vs %d (parsed)",
test.name, test.cipherFunc, parsedCipherFunc)
}
}
}
+1 -1
View File
@@ -124,7 +124,7 @@ func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error)
return
}
// decryptable abstracts a object that contains ciphertext.
// decryptable abstracts an object that contains ciphertext.
type decryptable interface {
Algorithm() pkix.AlgorithmIdentifier
Data() []byte
+2 -1
View File
@@ -13,11 +13,12 @@ package salsa
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out may be the same slice but otherwise should not overlap. Counter
// In and out must overlap entirely or not at all. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
if len(in) == 0 {
return
}
_ = out[len(in)-1]
salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0])
}
+1 -1
View File
@@ -203,7 +203,7 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
}
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out may be the same slice but otherwise should not overlap. Counter
// In and out must overlap entirely or not at all. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
var block [64]byte
+19
View File
@@ -33,3 +33,22 @@ func TestCore208(t *testing.T) {
t.Errorf("expected %x, got %x", out, in)
}
}
func TestOutOfBoundsWrite(t *testing.T) {
// encrypted "0123456789"
cipherText := []byte{170, 166, 196, 104, 175, 121, 68, 44, 174, 51}
var counter [16]byte
var key [32]byte
want := "abcdefghij"
plainText := []byte(want)
defer func() {
err := recover()
if err == nil {
t.Error("XORKeyStream expected to panic on len(dst) < len(src), but didn't")
}
if plainText[3] == '3' {
t.Errorf("XORKeyStream did out of bounds write, want %v, got %v", want, string(plainText))
}
}()
XORKeyStream(plainText[:3], cipherText, &counter, &key)
}
+2 -2
View File
@@ -27,8 +27,8 @@ import (
"golang.org/x/crypto/salsa20/salsa"
)
// XORKeyStream crypts bytes from in to out using the given key and nonce. In
// and out may be the same slice but otherwise should not overlap. Nonce must
// XORKeyStream crypts bytes from in to out using the given key and nonce.
// In and out must overlap entirely or not at all. Nonce must
// be either 8 or 24 bytes long.
func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) {
if len(out) < len(in) {
+26
View File
@@ -0,0 +1,26 @@
// Copyright 2017 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 scrypt_test
import (
"encoding/base64"
"fmt"
"log"
"golang.org/x/crypto/scrypt"
)
func Example() {
// DO NOT use this salt value; generate your own random salt. 8 bytes is
// a good length.
salt := []byte{0xc8, 0x28, 0xf2, 0x58, 0xa7, 0x6a, 0xad, 0x7b}
dk, err := scrypt.Key([]byte("some password"), salt, 1<<15, 8, 1, 32)
if err != nil {
log.Fatal(err)
}
fmt.Println(base64.StdEncoding.EncodeToString(dk))
// Output: lGnMz8io0AUkfzn6Pls1qX20Vs7PGN6sbYQ2TQgY12M=
}
+4 -3
View File
@@ -220,9 +220,10 @@ func smix(b []byte, r, N int, v, xy []uint32) {
//
// dk, err := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
//
// The recommended parameters for interactive logins as of 2009 are N=16384,
// r=8, p=1. They should be increased as memory latency and CPU parallelism
// increases. Remember to get a good random salt.
// The recommended parameters for interactive logins as of 2017 are N=32768, r=8
// and p=1. The parameters N, r, and p should be increased as memory latency and
// CPU parallelism increases; consider setting N to the highest power of 2 you
// can derive within 100 milliseconds. Remember to get a good random salt.
func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
if N <= 1 || N&(N-1) != 0 {
return nil, errors.New("scrypt: N must be > 1 and a power of 2")
+3 -1
View File
@@ -153,8 +153,10 @@ func TestKey(t *testing.T) {
}
}
var sink []byte
func BenchmarkKey(b *testing.B) {
for i := 0; i < b.N; i++ {
Key([]byte("password"), []byte("salt"), 16384, 8, 1, 64)
sink, _ = Key([]byte("password"), []byte("salt"), 1<<15, 8, 1, 64)
}
}
+2 -3
View File
@@ -42,9 +42,8 @@ type state struct {
storage [maxRate]byte
// Specific to SHA-3 and SHAKE.
fixedOutput bool // whether this is a fixed-output-length instance
outputLen int // the default output size in bytes
state spongeDirection // whether the sponge is absorbing or squeezing
outputLen int // the default output size in bytes
state spongeDirection // whether the sponge is absorbing or squeezing
}
// BlockSize returns the rate of sponge underlying this hash function.
+5
View File
@@ -15,6 +15,7 @@ import (
"compress/flate"
"encoding/hex"
"encoding/json"
"fmt"
"hash"
"os"
"strings"
@@ -289,6 +290,8 @@ func Example_sum() {
h := make([]byte, 64)
// Compute a 64-byte hash of buf and put it in h.
ShakeSum256(h, buf)
fmt.Printf("%x\n", h)
// Output: 0f65fe41fc353e52c55667bb9e2b27bfcc8476f2c413e9437d272ee3194a4e3146d05ec04a25d16b8f577c19b82d16b1424c3e022e783d2b4da98de3658d363d
}
func Example_mac() {
@@ -303,4 +306,6 @@ func Example_mac() {
d.Write(buf)
// Read 32 bytes of output from the hash into h.
d.Read(h)
fmt.Printf("%x\n", h)
// Output: 78de2974bd2711d5549ffd32b753ef0f5fa80a0db2556db60f0987eb8a9218ff
}
+31 -7
View File
@@ -57,6 +57,17 @@ type Agent interface {
Signers() ([]ssh.Signer, error)
}
// ConstraintExtension describes an optional constraint defined by users.
type ConstraintExtension struct {
// ExtensionName consist of a UTF-8 string suffixed by the
// implementation domain following the naming scheme defined
// in Section 4.2 of [RFC4251], e.g. "foo@example.com".
ExtensionName string
// ExtensionDetails contains the actual content of the extended
// constraint.
ExtensionDetails []byte
}
// AddedKey describes an SSH key to be added to an Agent.
type AddedKey struct {
// PrivateKey must be a *rsa.PrivateKey, *dsa.PrivateKey or
@@ -73,6 +84,9 @@ type AddedKey struct {
// ConfirmBeforeUse, if true, requests that the agent confirm with the
// user before each use of this key.
ConfirmBeforeUse bool
// ConstraintExtensions are the experimental or private-use constraints
// defined by users.
ConstraintExtensions []ConstraintExtension
}
// See [PROTOCOL.agent], section 3.
@@ -94,8 +108,9 @@ const (
agentAddSmartcardKeyConstrained = 26
// 3.7 Key constraint identifiers
agentConstrainLifetime = 1
agentConstrainConfirm = 2
agentConstrainLifetime = 1
agentConstrainConfirm = 2
agentConstrainExtension = 3
)
// maxAgentResponseBytes is the maximum agent reply size that is accepted. This
@@ -151,6 +166,19 @@ type publicKey struct {
Rest []byte `ssh:"rest"`
}
// 3.7 Key constraint identifiers
type constrainLifetimeAgentMsg struct {
LifetimeSecs uint32 `sshtype:"1"`
}
type constrainExtensionAgentMsg struct {
ExtensionName string `sshtype:"3"`
ExtensionDetails []byte
// Rest is a field used for parsing, not part of message
Rest []byte `ssh:"rest"`
}
// Key represents a protocol 2 public key as defined in
// [PROTOCOL.agent], section 2.5.2.
type Key struct {
@@ -542,11 +570,7 @@ func (c *client) Add(key AddedKey) error {
var constraints []byte
if secs := key.LifetimeSecs; secs != 0 {
constraints = append(constraints, agentConstrainLifetime)
var secsBytes [4]byte
binary.BigEndian.PutUint32(secsBytes[:], secs)
constraints = append(constraints, secsBytes[:]...)
constraints = append(constraints, ssh.Marshal(constrainLifetimeAgentMsg{secs})...)
}
if key.ConfirmBeforeUse {
+47 -16
View File
@@ -19,8 +19,8 @@ import (
"golang.org/x/crypto/ssh"
)
// startAgent executes ssh-agent, and returns a Agent interface to it.
func startAgent(t *testing.T) (client Agent, socket string, cleanup func()) {
// startOpenSSHAgent executes ssh-agent, and returns an Agent interface to it.
func startOpenSSHAgent(t *testing.T) (client Agent, socket string, cleanup func()) {
if testing.Short() {
// ssh-agent is not always available, and the key
// types supported vary by platform.
@@ -79,16 +79,32 @@ func startAgent(t *testing.T) (client Agent, socket string, cleanup func()) {
}
}
func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
agent, _, cleanup := startAgent(t)
// startKeyringAgent uses Keyring to simulate a ssh-agent Server and returns a client.
func startKeyringAgent(t *testing.T) (client Agent, cleanup func()) {
c1, c2, err := netPipe()
if err != nil {
t.Fatalf("netPipe: %v", err)
}
go ServeAgent(NewKeyring(), c2)
return NewClient(c1), func() {
c1.Close()
c2.Close()
}
}
func testOpenSSHAgent(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
agent, _, cleanup := startOpenSSHAgent(t)
defer cleanup()
testAgentInterface(t, agent, key, cert, lifetimeSecs)
}
func testKeyring(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
a := NewKeyring()
testAgentInterface(t, a, key, cert, lifetimeSecs)
func testKeyringAgent(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
agent, cleanup := startKeyringAgent(t)
defer cleanup()
testAgentInterface(t, agent, key, cert, lifetimeSecs)
}
func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
@@ -159,8 +175,8 @@ func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Ce
func TestAgent(t *testing.T) {
for _, keyType := range []string{"rsa", "dsa", "ecdsa", "ed25519"} {
testAgent(t, testPrivateKeys[keyType], nil, 0)
testKeyring(t, testPrivateKeys[keyType], nil, 1)
testOpenSSHAgent(t, testPrivateKeys[keyType], nil, 0)
testKeyringAgent(t, testPrivateKeys[keyType], nil, 0)
}
}
@@ -172,8 +188,8 @@ func TestCert(t *testing.T) {
}
cert.SignCert(rand.Reader, testSigners["ecdsa"])
testAgent(t, testPrivateKeys["rsa"], cert, 0)
testKeyring(t, testPrivateKeys["rsa"], cert, 1)
testOpenSSHAgent(t, testPrivateKeys["rsa"], cert, 0)
testKeyringAgent(t, testPrivateKeys["rsa"], cert, 0)
}
// netPipe is analogous to net.Pipe, but it uses a real net.Conn, and
@@ -203,7 +219,7 @@ func netPipe() (net.Conn, net.Conn, error) {
}
func TestAuth(t *testing.T) {
agent, _, cleanup := startAgent(t)
agent, _, cleanup := startOpenSSHAgent(t)
defer cleanup()
a, b, err := netPipe()
@@ -247,8 +263,14 @@ func TestAuth(t *testing.T) {
conn.Close()
}
func TestLockClient(t *testing.T) {
agent, _, cleanup := startAgent(t)
func TestLockOpenSSHAgent(t *testing.T) {
agent, _, cleanup := startOpenSSHAgent(t)
defer cleanup()
testLockAgent(agent, t)
}
func TestLockKeyringAgent(t *testing.T) {
agent, cleanup := startKeyringAgent(t)
defer cleanup()
testLockAgent(agent, t)
}
@@ -308,10 +330,19 @@ func testLockAgent(agent Agent, t *testing.T) {
}
}
func TestAgentLifetime(t *testing.T) {
agent, _, cleanup := startAgent(t)
func testOpenSSHAgentLifetime(t *testing.T) {
agent, _, cleanup := startOpenSSHAgent(t)
defer cleanup()
testAgentLifetime(t, agent)
}
func testKeyringAgentLifetime(t *testing.T) {
agent, cleanup := startKeyringAgent(t)
defer cleanup()
testAgentLifetime(t, agent)
}
func testAgentLifetime(t *testing.T, agent Agent) {
for _, keyType := range []string{"rsa", "dsa", "ecdsa"} {
// Add private keys to the agent.
err := agent.Add(AddedKey{
+81 -9
View File
@@ -106,7 +106,7 @@ func (s *server) processRequest(data []byte) (interface{}, error) {
return nil, s.agent.Lock(req.Passphrase)
case agentUnlock:
var req agentLockMsg
var req agentUnlockMsg
if err := ssh.Unmarshal(data, &req); err != nil {
return nil, err
}
@@ -155,6 +155,44 @@ func (s *server) processRequest(data []byte) (interface{}, error) {
return nil, fmt.Errorf("unknown opcode %d", data[0])
}
func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse bool, extensions []ConstraintExtension, err error) {
for len(constraints) != 0 {
switch constraints[0] {
case agentConstrainLifetime:
lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5])
constraints = constraints[5:]
case agentConstrainConfirm:
confirmBeforeUse = true
constraints = constraints[1:]
case agentConstrainExtension:
var msg constrainExtensionAgentMsg
if err = ssh.Unmarshal(constraints, &msg); err != nil {
return 0, false, nil, err
}
extensions = append(extensions, ConstraintExtension{
ExtensionName: msg.ExtensionName,
ExtensionDetails: msg.ExtensionDetails,
})
constraints = msg.Rest
default:
return 0, false, nil, fmt.Errorf("unknown constraint type: %d", constraints[0])
}
}
return
}
func setConstraints(key *AddedKey, constraintBytes []byte) error {
lifetimeSecs, confirmBeforeUse, constraintExtensions, err := parseConstraints(constraintBytes)
if err != nil {
return err
}
key.LifetimeSecs = lifetimeSecs
key.ConfirmBeforeUse = confirmBeforeUse
key.ConstraintExtensions = constraintExtensions
return nil
}
func parseRSAKey(req []byte) (*AddedKey, error) {
var k rsaKeyMsg
if err := ssh.Unmarshal(req, &k); err != nil {
@@ -173,7 +211,11 @@ func parseRSAKey(req []byte) (*AddedKey, error) {
}
priv.Precompute()
return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func parseEd25519Key(req []byte) (*AddedKey, error) {
@@ -182,7 +224,12 @@ func parseEd25519Key(req []byte) (*AddedKey, error) {
return nil, err
}
priv := ed25519.PrivateKey(k.Priv)
return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: &priv, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func parseDSAKey(req []byte) (*AddedKey, error) {
@@ -202,7 +249,11 @@ func parseDSAKey(req []byte) (*AddedKey, error) {
X: k.X,
}
return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (priv *ecdsa.PrivateKey, err error) {
@@ -243,7 +294,12 @@ func parseEd25519Cert(req []byte) (*AddedKey, error) {
if !ok {
return nil, errors.New("agent: bad ED25519 certificate")
}
return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func parseECDSAKey(req []byte) (*AddedKey, error) {
@@ -257,7 +313,11 @@ func parseECDSAKey(req []byte) (*AddedKey, error) {
return nil, err
}
return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func parseRSACert(req []byte) (*AddedKey, error) {
@@ -300,7 +360,11 @@ func parseRSACert(req []byte) (*AddedKey, error) {
}
priv.Precompute()
return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func parseDSACert(req []byte) (*AddedKey, error) {
@@ -338,7 +402,11 @@ func parseDSACert(req []byte) (*AddedKey, error) {
X: k.X,
}
return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func parseECDSACert(req []byte) (*AddedKey, error) {
@@ -371,7 +439,11 @@ func parseECDSACert(req []byte) (*AddedKey, error) {
return nil, err
}
return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
if err := setConstraints(addedKey, k.Constraints); err != nil {
return nil, err
}
return addedKey, nil
}
func (s *server) insertIdentity(req []byte) error {
+51 -1
View File
@@ -8,6 +8,9 @@ import (
"crypto"
"crypto/rand"
"fmt"
pseudorand "math/rand"
"reflect"
"strings"
"testing"
"golang.org/x/crypto/ssh"
@@ -40,7 +43,7 @@ func TestSetupForwardAgent(t *testing.T) {
defer a.Close()
defer b.Close()
_, socket, cleanup := startAgent(t)
_, socket, cleanup := startOpenSSHAgent(t)
defer cleanup()
serverConf := ssh.ServerConfig{
@@ -207,3 +210,50 @@ func TestCertTypes(t *testing.T) {
}
}
}
func TestParseConstraints(t *testing.T) {
// Test LifetimeSecs
var msg = constrainLifetimeAgentMsg{pseudorand.Uint32()}
lifetimeSecs, _, _, err := parseConstraints(ssh.Marshal(msg))
if err != nil {
t.Fatalf("parseConstraints: %v", err)
}
if lifetimeSecs != msg.LifetimeSecs {
t.Errorf("got lifetime %v, want %v", lifetimeSecs, msg.LifetimeSecs)
}
// Test ConfirmBeforeUse
_, confirmBeforeUse, _, err := parseConstraints([]byte{agentConstrainConfirm})
if err != nil {
t.Fatalf("%v", err)
}
if !confirmBeforeUse {
t.Error("got comfirmBeforeUse == false")
}
// Test ConstraintExtensions
var data []byte
var expect []ConstraintExtension
for i := 0; i < 10; i++ {
var ext = ConstraintExtension{
ExtensionName: fmt.Sprintf("name%d", i),
ExtensionDetails: []byte(fmt.Sprintf("details: %d", i)),
}
expect = append(expect, ext)
data = append(data, agentConstrainExtension)
data = append(data, ssh.Marshal(ext)...)
}
_, _, extensions, err := parseConstraints(data)
if err != nil {
t.Fatalf("%v", err)
}
if !reflect.DeepEqual(expect, extensions) {
t.Errorf("got extension %v, want %v", extensions, expect)
}
// Test Unknown Constraint
_, _, _, err = parseConstraints([]byte{128})
if err == nil || !strings.Contains(err.Error(), "unknown constraint") {
t.Errorf("unexpected error: %v", err)
}
}
+2 -3
View File
@@ -51,13 +51,12 @@ func (b *buffer) write(buf []byte) {
}
// eof closes the buffer. Reads from the buffer once all
// the data has been consumed will receive os.EOF.
func (b *buffer) eof() error {
// the data has been consumed will receive io.EOF.
func (b *buffer) eof() {
b.Cond.L.Lock()
b.closed = true
b.Cond.Signal()
b.Cond.L.Unlock()
return nil
}
// Read reads data from the internal buffer in buf. Reads will block
+1 -1
View File
@@ -349,7 +349,7 @@ func handleAuthResponse(c packetConn) (bool, []string, error) {
// both CLI and GUI environments.
type KeyboardInteractiveChallenge func(user, instruction string, questions []string, echos []bool) (answers []string, err error)
// KeyboardInteractive returns a AuthMethod using a prompt/response
// KeyboardInteractive returns an AuthMethod using a prompt/response
// sequence controlled by the server.
func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod {
return challenge
+34 -9
View File
@@ -367,6 +367,17 @@ func (r *dsaPublicKey) Type() string {
return "ssh-dss"
}
func checkDSAParams(param *dsa.Parameters) error {
// SSH specifies FIPS 186-2, which only provided a single size
// (1024 bits) DSA key. FIPS 186-3 allows for larger key
// sizes, which would confuse SSH.
if l := param.P.BitLen(); l != 1024 {
return fmt.Errorf("ssh: unsupported DSA key size %d", l)
}
return nil
}
// parseDSA parses an DSA key according to RFC 4253, section 6.6.
func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
var w struct {
@@ -377,13 +388,18 @@ func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
return nil, nil, err
}
param := dsa.Parameters{
P: w.P,
Q: w.Q,
G: w.G,
}
if err := checkDSAParams(&param); err != nil {
return nil, nil, err
}
key := &dsaPublicKey{
Parameters: dsa.Parameters{
P: w.P,
Q: w.Q,
G: w.G,
},
Y: w.Y,
Parameters: param,
Y: w.Y,
}
return key, w.Rest, nil
}
@@ -630,19 +646,28 @@ func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
}
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
// *ecdsa.PrivateKey or any other crypto.Signer and returns a corresponding
// Signer instance. ECDSA keys must use P-256, P-384 or P-521.
// *ecdsa.PrivateKey or any other crypto.Signer and returns a
// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
// P-521. DSA keys must use parameter size L1024N160.
func NewSignerFromKey(key interface{}) (Signer, error) {
switch key := key.(type) {
case crypto.Signer:
return NewSignerFromSigner(key)
case *dsa.PrivateKey:
return &dsaPrivateKey{key}, nil
return newDSAPrivateKey(key)
default:
return nil, fmt.Errorf("ssh: unsupported key type %T", key)
}
}
func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
if err := checkDSAParams(&key.PublicKey.Parameters); err != nil {
return nil, err
}
return &dsaPrivateKey{key}, nil
}
type wrappedSigner struct {
signer crypto.Signer
pubKey PublicKey
+1 -1
View File
@@ -67,7 +67,7 @@ type ServerConfig struct {
PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)
// PublicKeyCallback, if non-nil, is called when a client
// offers a public key for authentication. It must return true
// offers a public key for authentication. It must return a nil error
// if the given public key can be used to authenticate the
// given user. For example, see CertChecker.Authenticate. A
// call to this function does not guarantee that the key
+20
View File
@@ -231,6 +231,26 @@ func (s *Session) RequestSubsystem(subsystem string) error {
return err
}
// RFC 4254 Section 6.7.
type ptyWindowChangeMsg struct {
Columns uint32
Rows uint32
Width uint32
Height uint32
}
// WindowChange informs the remote host about a terminal window dimension change to h rows and w columns.
func (s *Session) WindowChange(h, w int) error {
req := ptyWindowChangeMsg{
Columns: uint32(w),
Rows: uint32(h),
Width: uint32(w * 8),
Height: uint32(h * 8),
}
_, err := s.ch.SendRequest("window-change", false, Marshal(&req))
return err
}
// RFC 4254 Section 6.9.
type signalMsg struct {
Signal string
+4
View File
@@ -19,6 +19,8 @@ package terminal // import "golang.org/x/crypto/ssh/terminal"
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
// State contains the state of a terminal.
@@ -50,6 +52,8 @@ func MakeRaw(fd int) (*State, error) {
newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
newState.Cflag &^= syscall.CSIZE | syscall.PARENB
newState.Cflag |= syscall.CS8
newState.Cc[unix.VMIN] = 1
newState.Cc[unix.VTIME] = 0
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
return nil, err
}
+3 -3
View File
@@ -6,7 +6,7 @@
package terminal
import "syscall"
import "golang.org/x/sys/unix"
const ioctlReadTermios = syscall.TIOCGETA
const ioctlWriteTermios = syscall.TIOCSETA
const ioctlReadTermios = unix.TIOCGETA
const ioctlWriteTermios = unix.TIOCSETA
+4 -5
View File
@@ -4,8 +4,7 @@
package terminal
// These constants are declared here, rather than importing
// them from the syscall package as some syscall packages, even
// on linux, for example gccgo, do not declare them.
const ioctlReadTermios = 0x5401 // syscall.TCGETS
const ioctlWriteTermios = 0x5402 // syscall.TCSETS
import "golang.org/x/sys/unix"
const ioctlReadTermios = unix.TCGETS
const ioctlWriteTermios = unix.TCSETS
+23 -76
View File
@@ -17,53 +17,7 @@
package terminal
import (
"syscall"
"unsafe"
)
const (
enableLineInput = 2
enableEchoInput = 4
enableProcessedInput = 1
enableWindowInput = 8
enableMouseInput = 16
enableInsertMode = 32
enableQuickEditMode = 64
enableExtendedFlags = 128
enableAutoPosition = 256
enableProcessedOutput = 1
enableWrapAtEolOutput = 2
)
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var (
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
)
type (
short int16
word uint16
coord struct {
x short
y short
}
smallRect struct {
left short
top short
right short
bottom short
}
consoleScreenBufferInfo struct {
size coord
cursorPosition coord
attributes word
window smallRect
maximumWindowSize coord
}
"golang.org/x/sys/windows"
)
type State struct {
@@ -73,8 +27,8 @@ type State struct {
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
var st uint32
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
return r != 0 && e == 0
err := windows.GetConsoleMode(windows.Handle(fd), &st)
return err == nil
}
// MakeRaw put the terminal connected to the given file descriptor into raw
@@ -82,14 +36,12 @@ func IsTerminal(fd int) bool {
// restored.
func MakeRaw(fd int) (*State, error) {
var st uint32
_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
if e != 0 {
return nil, error(e)
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
}
raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0)
if e != 0 {
return nil, error(e)
raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
return nil, err
}
return &State{st}, nil
}
@@ -98,9 +50,8 @@ func MakeRaw(fd int) (*State, error) {
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
var st uint32
_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
if e != 0 {
return nil, error(e)
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
}
return &State{st}, nil
}
@@ -108,25 +59,23 @@ func GetState(fd int) (*State, error) {
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
_, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0)
return err
return windows.SetConsoleMode(windows.Handle(fd), state.mode)
}
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
var info consoleScreenBufferInfo
_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0)
if e != 0 {
return 0, 0, error(e)
var info windows.ConsoleScreenBufferInfo
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
return 0, 0, err
}
return int(info.size.x), int(info.size.y), nil
return int(info.Size.X), int(info.Size.Y), nil
}
// passwordReader is an io.Reader that reads from a specific Windows HANDLE.
type passwordReader int
func (r passwordReader) Read(buf []byte) (int, error) {
return syscall.Read(syscall.Handle(r), buf)
return windows.Read(windows.Handle(r), buf)
}
// ReadPassword reads a line of input from a terminal without local echo. This
@@ -134,21 +83,19 @@ func (r passwordReader) Read(buf []byte) (int, error) {
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
var st uint32
_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
if e != 0 {
return nil, error(e)
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
}
old := st
st &^= (enableEchoInput)
st |= (enableProcessedInput | enableLineInput | enableProcessedOutput)
_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0)
if e != 0 {
return nil, error(e)
st &^= (windows.ENABLE_ECHO_INPUT)
st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
return nil, err
}
defer func() {
syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0)
windows.SetConsoleMode(windows.Handle(fd), old)
}()
return readPasswordLine(passwordReader(fd))
+48
View File
@@ -276,6 +276,54 @@ func TestValidTerminalMode(t *testing.T) {
}
}
func TestWindowChange(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial(clientConfig())
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Fatalf("session failed: %v", err)
}
defer session.Close()
stdout, err := session.StdoutPipe()
if err != nil {
t.Fatalf("unable to acquire stdout pipe: %s", err)
}
stdin, err := session.StdinPipe()
if err != nil {
t.Fatalf("unable to acquire stdin pipe: %s", err)
}
tm := ssh.TerminalModes{ssh.ECHO: 0}
if err = session.RequestPty("xterm", 80, 40, tm); err != nil {
t.Fatalf("req-pty failed: %s", err)
}
if err := session.WindowChange(100, 100); err != nil {
t.Fatalf("window-change failed: %s", err)
}
err = session.Shell()
if err != nil {
t.Fatalf("session failed: %s", err)
}
stdin.Write([]byte("stty size && exit\n"))
var buf bytes.Buffer
if _, err := io.Copy(&buf, stdout); err != nil {
t.Fatalf("reading failed: %s", err)
}
if sttyOutput := buf.String(); !strings.Contains(sttyOutput, "100 100") {
t.Fatalf("terminal WindowChange failure: expected \"100 100\" stty output, got %s", sttyOutput)
}
}
func TestCiphers(t *testing.T) {
var config ssh.Config
config.SetDefaults()
+2 -2
View File
@@ -55,7 +55,7 @@ func NewCipher(cipherFunc func([]byte) (cipher.Block, error), key []byte) (c *Ci
}
// Encrypt encrypts a sector of plaintext and puts the result into ciphertext.
// Plaintext and ciphertext may be the same slice but should not overlap.
// Plaintext and ciphertext must overlap entirely or not at all.
// Sectors must be a multiple of 16 bytes and less than 2²⁴ bytes.
func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
if len(ciphertext) < len(plaintext) {
@@ -86,7 +86,7 @@ func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
}
// Decrypt decrypts a sector of ciphertext and puts the result into plaintext.
// Plaintext and ciphertext may be the same slice but should not overlap.
// Plaintext and ciphertext must overlap entirely or not at all.
// Sectors must be a multiple of 16 bytes and less than 2²⁴ bytes.
func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
if len(plaintext) < len(ciphertext) {
-3
View File
@@ -1,3 +0,0 @@
This repository holds supplemental Go packages for low-level interactions with the operating system.
To submit changes to this repository, see http://golang.org/doc/contribute.html.
+18
View File
@@ -0,0 +1,18 @@
# sys
This repository holds supplemental Go packages for low-level interactions with
the operating system.
## Download/Install
The easiest way to install is to run `go get -u golang.org/x/sys`. You can
also manually git clone the repository to `$GOPATH/src/golang.org/x/sys`.
## Report Issues / Send Patches
This repository uses Gerrit for code changes. To learn how to submit changes to
this repository, see https://golang.org/doc/contribute.html.
The main issue tracker for the sys repository is located at
https://github.com/golang/go/issues. Prefix your issue with "x/sys:" in the
subject line, so it is easy to find.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Copyright 2014 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.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Copyright 2011 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.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Copyright 2014 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.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Copyright 2011 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.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// 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.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// 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.
+3 -3
View File
@@ -5,10 +5,10 @@
// +build plan9
// Package plan9 contains an interface to the low-level operating system
// primitives. OS details vary depending on the underlying system, and
// primitives. OS details vary depending on the underlying system, and
// by default, godoc will display the OS-specific documentation for the current
// system. If you want godoc to display documentation for another
// system, set $GOOS and $GOARCH to the desired system. For example, if
// system. If you want godoc to display documentation for another
// system, set $GOOS and $GOARCH to the desired system. For example, if
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
// to freebsd and $GOARCH to arm.
// The primary use of this package is inside other packages that provide a more
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2017 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 !gccgo
#include "textflag.h"
//
// System call support for ARM, OpenBSD
//
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-28
B syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-40
B syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-52
B syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
B syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
B syscall·RawSyscall6(SB)
+195
View File
@@ -0,0 +1,195 @@
// Copyright 2017 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 freebsd
package unix
import (
errorspkg "errors"
"fmt"
)
// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
const (
// This is the version of CapRights this package understands. See C implementation for parallels.
capRightsGoVersion = CAP_RIGHTS_VERSION_00
capArSizeMin = CAP_RIGHTS_VERSION_00 + 2
capArSizeMax = capRightsGoVersion + 2
)
var (
bit2idx = []int{
-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
}
)
func capidxbit(right uint64) int {
return int((right >> 57) & 0x1f)
}
func rightToIndex(right uint64) (int, error) {
idx := capidxbit(right)
if idx < 0 || idx >= len(bit2idx) {
return -2, fmt.Errorf("index for right 0x%x out of range", right)
}
return bit2idx[idx], nil
}
func caprver(right uint64) int {
return int(right >> 62)
}
func capver(rights *CapRights) int {
return caprver(rights.Rights[0])
}
func caparsize(rights *CapRights) int {
return capver(rights) + 2
}
// CapRightsSet sets the permissions in setrights in rights.
func CapRightsSet(rights *CapRights, setrights []uint64) error {
// This is essentially a copy of cap_rights_vset()
if capver(rights) != CAP_RIGHTS_VERSION_00 {
return fmt.Errorf("bad rights version %d", capver(rights))
}
n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size")
}
for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version")
}
i, err := rightToIndex(right)
if err != nil {
return err
}
if i >= n {
return errorspkg.New("index overflow")
}
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch")
}
rights.Rights[i] |= right
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)")
}
}
return nil
}
// CapRightsClear clears the permissions in clearrights from rights.
func CapRightsClear(rights *CapRights, clearrights []uint64) error {
// This is essentially a copy of cap_rights_vclear()
if capver(rights) != CAP_RIGHTS_VERSION_00 {
return fmt.Errorf("bad rights version %d", capver(rights))
}
n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size")
}
for _, right := range clearrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version")
}
i, err := rightToIndex(right)
if err != nil {
return err
}
if i >= n {
return errorspkg.New("index overflow")
}
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch")
}
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)")
}
}
return nil
}
// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
// This is essentially a copy of cap_rights_is_vset()
if capver(rights) != CAP_RIGHTS_VERSION_00 {
return false, fmt.Errorf("bad rights version %d", capver(rights))
}
n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax {
return false, errorspkg.New("bad rights size")
}
for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 {
return false, errorspkg.New("bad right version")
}
i, err := rightToIndex(right)
if err != nil {
return false, err
}
if i >= n {
return false, errorspkg.New("index overflow")
}
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return false, errorspkg.New("index mismatch")
}
if (rights.Rights[i] & right) != right {
return false, nil
}
}
return true, nil
}
func capright(idx uint64, bit uint64) uint64 {
return ((1 << (57 + idx)) | bit)
}
// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
// See man cap_rights_init(3) and rights(4).
func CapRightsInit(rights []uint64) (*CapRights, error) {
var r CapRights
r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
r.Rights[1] = capright(1, 0)
err := CapRightsSet(&r, rights)
if err != nil {
return nil, err
}
return &r, nil
}
// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
// The capability rights on fd can never be increased by CapRightsLimit.
// See man cap_rights_limit(2) and rights(4).
func CapRightsLimit(fd uintptr, rights *CapRights) error {
return capRightsLimit(int(fd), rights)
}
// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
// See man cap_rights_get(3) and rights(4).
func CapRightsGet(fd uintptr) (*CapRights, error) {
r, err := CapRightsInit(nil)
if err != nil {
return nil, err
}
err = capRightsGet(capRightsGoVersion, int(fd), r)
if err != nil {
return nil, err
}
return r, nil
}
+101 -86
View File
@@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// 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.
@@ -21,101 +21,116 @@ import (
// sockets. The SO_PASSCRED socket option is enabled on the sending
// socket for this to work.
func TestSCMCredentials(t *testing.T) {
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
if err != nil {
t.Fatalf("Socketpair: %v", err)
}
defer unix.Close(fds[0])
defer unix.Close(fds[1])
err = unix.SetsockoptInt(fds[0], unix.SOL_SOCKET, unix.SO_PASSCRED, 1)
if err != nil {
t.Fatalf("SetsockoptInt: %v", err)
socketTypeTests := []struct {
socketType int
dataLen int
}{
{
unix.SOCK_STREAM,
1,
}, {
unix.SOCK_DGRAM,
0,
},
}
srvFile := os.NewFile(uintptr(fds[0]), "server")
defer srvFile.Close()
srv, err := net.FileConn(srvFile)
if err != nil {
t.Errorf("FileConn: %v", err)
return
}
defer srv.Close()
for _, tt := range socketTypeTests {
fds, err := unix.Socketpair(unix.AF_LOCAL, tt.socketType, 0)
if err != nil {
t.Fatalf("Socketpair: %v", err)
}
defer unix.Close(fds[0])
defer unix.Close(fds[1])
cliFile := os.NewFile(uintptr(fds[1]), "client")
defer cliFile.Close()
cli, err := net.FileConn(cliFile)
if err != nil {
t.Errorf("FileConn: %v", err)
return
}
defer cli.Close()
err = unix.SetsockoptInt(fds[0], unix.SOL_SOCKET, unix.SO_PASSCRED, 1)
if err != nil {
t.Fatalf("SetsockoptInt: %v", err)
}
srvFile := os.NewFile(uintptr(fds[0]), "server")
defer srvFile.Close()
srv, err := net.FileConn(srvFile)
if err != nil {
t.Errorf("FileConn: %v", err)
return
}
defer srv.Close()
cliFile := os.NewFile(uintptr(fds[1]), "client")
defer cliFile.Close()
cli, err := net.FileConn(cliFile)
if err != nil {
t.Errorf("FileConn: %v", err)
return
}
defer cli.Close()
var ucred unix.Ucred
if os.Getuid() != 0 {
ucred.Pid = int32(os.Getpid())
ucred.Uid = 0
ucred.Gid = 0
oob := unix.UnixCredentials(&ucred)
_, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
if op, ok := err.(*net.OpError); ok {
err = op.Err
}
if sys, ok := err.(*os.SyscallError); ok {
err = sys.Err
}
if err != syscall.EPERM {
t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
}
}
var ucred unix.Ucred
if os.Getuid() != 0 {
ucred.Pid = int32(os.Getpid())
ucred.Uid = 0
ucred.Gid = 0
ucred.Uid = uint32(os.Getuid())
ucred.Gid = uint32(os.Getgid())
oob := unix.UnixCredentials(&ucred)
_, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
if op, ok := err.(*net.OpError); ok {
err = op.Err
// On SOCK_STREAM, this is internally going to send a dummy byte
n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
if err != nil {
t.Fatalf("WriteMsgUnix: %v", err)
}
if sys, ok := err.(*os.SyscallError); ok {
err = sys.Err
if n != 0 {
t.Fatalf("WriteMsgUnix n = %d, want 0", n)
}
if err != syscall.EPERM {
t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
if oobn != len(oob) {
t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
}
}
ucred.Pid = int32(os.Getpid())
ucred.Uid = uint32(os.Getuid())
ucred.Gid = uint32(os.Getgid())
oob := unix.UnixCredentials(&ucred)
oob2 := make([]byte, 10*len(oob))
n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
if err != nil {
t.Fatalf("ReadMsgUnix: %v", err)
}
if flags != 0 {
t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
}
if n != tt.dataLen {
t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
}
if oobn2 != oobn {
// without SO_PASSCRED set on the socket, ReadMsgUnix will
// return zero oob bytes
t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
}
oob2 = oob2[:oobn2]
if !bytes.Equal(oob, oob2) {
t.Fatal("ReadMsgUnix oob bytes don't match")
}
// this is going to send a dummy byte
n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
if err != nil {
t.Fatalf("WriteMsgUnix: %v", err)
}
if n != 0 {
t.Fatalf("WriteMsgUnix n = %d, want 0", n)
}
if oobn != len(oob) {
t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
}
oob2 := make([]byte, 10*len(oob))
n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
if err != nil {
t.Fatalf("ReadMsgUnix: %v", err)
}
if flags != 0 {
t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
}
if n != 1 {
t.Fatalf("ReadMsgUnix n = %d, want 1 (dummy byte)", n)
}
if oobn2 != oobn {
// without SO_PASSCRED set on the socket, ReadMsgUnix will
// return zero oob bytes
t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
}
oob2 = oob2[:oobn2]
if !bytes.Equal(oob, oob2) {
t.Fatal("ReadMsgUnix oob bytes don't match")
}
scm, err := unix.ParseSocketControlMessage(oob2)
if err != nil {
t.Fatalf("ParseSocketControlMessage: %v", err)
}
newUcred, err := unix.ParseUnixCredentials(&scm[0])
if err != nil {
t.Fatalf("ParseUnixCredentials: %v", err)
}
if *newUcred != ucred {
t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
scm, err := unix.ParseSocketControlMessage(oob2)
if err != nil {
t.Fatalf("ParseSocketControlMessage: %v", err)
}
newUcred, err := unix.ParseUnixCredentials(&scm[0])
if err != nil {
t.Fatalf("ParseUnixCredentials: %v", err)
}
if *newUcred != ucred {
t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
}
}
}
+24
View File
@@ -0,0 +1,24 @@
// Copyright 2017 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in Darwin's sys/types.h header.
package unix
// Major returns the major component of a Darwin device number.
func Major(dev uint64) uint32 {
return uint32((dev >> 24) & 0xff)
}
// Minor returns the minor component of a Darwin device number.
func Minor(dev uint64) uint32 {
return uint32(dev & 0xffffff)
}
// Mkdev returns a Darwin device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
return (uint64(major) << 24) | uint64(minor)
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2017 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 unix_test
import (
"fmt"
"testing"
"golang.org/x/sys/unix"
)
func TestDevices(t *testing.T) {
testCases := []struct {
path string
major uint32
minor uint32
}{
// Most of the device major/minor numbers on Darwin are
// dynamically generated by devfs. These are some well-known
// static numbers.
{"/dev/ttyp0", 4, 0},
{"/dev/ttys0", 4, 48},
{"/dev/ptyp0", 5, 0},
{"/dev/ptyr0", 5, 32},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
var stat unix.Stat_t
err := unix.Stat(tc.path, &stat)
if err != nil {
t.Errorf("failed to stat device: %v", err)
return
}
dev := uint64(stat.Rdev)
if unix.Major(dev) != tc.major {
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
}
if unix.Minor(dev) != tc.minor {
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
}
if unix.Mkdev(tc.major, tc.minor) != dev {
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
}
})
}
}
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2017 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in Dragonfly's sys/types.h header.
//
// The information below is extracted and adapted from sys/types.h:
//
// Minor gives a cookie instead of an index since in order to avoid changing the
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
// devices that don't use them.
package unix
// Major returns the major component of a DragonFlyBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev >> 8) & 0xff)
}
// Minor returns the minor component of a DragonFlyBSD device number.
func Minor(dev uint64) uint32 {
return uint32(dev & 0xffff00ff)
}
// Mkdev returns a DragonFlyBSD device number generated from the given major and
// minor components.
func Mkdev(major, minor uint32) uint64 {
return (uint64(major) << 8) | uint64(minor)
}
+48
View File
@@ -0,0 +1,48 @@
// Copyright 2017 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 unix_test
import (
"fmt"
"testing"
"golang.org/x/sys/unix"
)
func TestDevices(t *testing.T) {
testCases := []struct {
path string
major uint32
minor uint32
}{
// Minor is a cookie instead of an index on DragonFlyBSD
{"/dev/null", 10, 0x00000002},
{"/dev/random", 10, 0x00000003},
{"/dev/urandom", 10, 0x00000004},
{"/dev/zero", 10, 0x0000000c},
{"/dev/bpf", 15, 0xffff00ff},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
var stat unix.Stat_t
err := unix.Stat(tc.path, &stat)
if err != nil {
t.Errorf("failed to stat device: %v", err)
return
}
dev := uint64(stat.Rdev)
if unix.Major(dev) != tc.major {
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
}
if unix.Minor(dev) != tc.minor {
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
}
if unix.Mkdev(tc.major, tc.minor) != dev {
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
}
})
}
}
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2017 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in FreeBSD's sys/types.h header.
//
// The information below is extracted and adapted from sys/types.h:
//
// Minor gives a cookie instead of an index since in order to avoid changing the
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
// devices that don't use them.
package unix
// Major returns the major component of a FreeBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev >> 8) & 0xff)
}
// Minor returns the minor component of a FreeBSD device number.
func Minor(dev uint64) uint32 {
return uint32(dev & 0xffff00ff)
}
// Mkdev returns a FreeBSD device number generated from the given major and
// minor components.
func Mkdev(major, minor uint32) uint64 {
return (uint64(major) << 8) | uint64(minor)
}
+42
View File
@@ -0,0 +1,42 @@
// Copyright 2017 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.
// Functions to access/create device major and minor numbers matching the
// encoding used by the Linux kernel and glibc.
//
// The information below is extracted and adapted from bits/sysmacros.h in the
// glibc sources:
//
// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's
// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major
// number and m is a hex digit of the minor number. This is backward compatible
// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also
// backward compatible with the Linux kernel, which for some architectures uses
// 32-bit dev_t, encoded as mmmM MMmm.
package unix
// Major returns the major component of a Linux device number.
func Major(dev uint64) uint32 {
major := uint32((dev & 0x00000000000fff00) >> 8)
major |= uint32((dev & 0xfffff00000000000) >> 32)
return major
}
// Minor returns the minor component of a Linux device number.
func Minor(dev uint64) uint32 {
minor := uint32((dev & 0x00000000000000ff) >> 0)
minor |= uint32((dev & 0x00000ffffff00000) >> 12)
return minor
}
// Mkdev returns a Linux device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
dev := (uint64(major) & 0x00000fff) << 8
dev |= (uint64(major) & 0xfffff000) << 32
dev |= (uint64(minor) & 0x000000ff) << 0
dev |= (uint64(minor) & 0xffffff00) << 12
return dev
}
+51
View File
@@ -0,0 +1,51 @@
// Copyright 2017 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 unix_test
import (
"fmt"
"testing"
"golang.org/x/sys/unix"
)
func TestDevices(t *testing.T) {
testCases := []struct {
path string
major uint32
minor uint32
}{
// well known major/minor numbers according to
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/devices.txt
{"/dev/null", 1, 3},
{"/dev/zero", 1, 5},
{"/dev/random", 1, 8},
{"/dev/full", 1, 7},
{"/dev/urandom", 1, 9},
{"/dev/tty", 5, 0},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
var stat unix.Stat_t
err := unix.Stat(tc.path, &stat)
if err != nil {
t.Errorf("failed to stat device: %v", err)
return
}
dev := uint64(stat.Rdev)
if unix.Major(dev) != tc.major {
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
}
if unix.Minor(dev) != tc.minor {
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
}
if unix.Mkdev(tc.major, tc.minor) != dev {
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
}
})
}
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2017 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in NetBSD's sys/types.h header.
package unix
// Major returns the major component of a NetBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev & 0x000fff00) >> 8)
}
// Minor returns the minor component of a NetBSD device number.
func Minor(dev uint64) uint32 {
minor := uint32((dev & 0x000000ff) >> 0)
minor |= uint32((dev & 0xfff00000) >> 12)
return minor
}
// Mkdev returns a NetBSD device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
dev := (uint64(major) << 8) & 0x000fff00
dev |= (uint64(minor) << 12) & 0xfff00000
dev |= (uint64(minor) << 0) & 0x000000ff
return dev
}
+50
View File
@@ -0,0 +1,50 @@
// Copyright 2017 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 unix_test
import (
"fmt"
"testing"
"golang.org/x/sys/unix"
)
func TestDevices(t *testing.T) {
testCases := []struct {
path string
major uint32
minor uint32
}{
// well known major/minor numbers according to /dev/MAKEDEV on
// NetBSD 7.0
{"/dev/null", 2, 2},
{"/dev/zero", 2, 12},
{"/dev/ttyp0", 5, 0},
{"/dev/ttyp1", 5, 1},
{"/dev/random", 46, 0},
{"/dev/urandom", 46, 1},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
var stat unix.Stat_t
err := unix.Stat(tc.path, &stat)
if err != nil {
t.Errorf("failed to stat device: %v", err)
return
}
dev := uint64(stat.Rdev)
if unix.Major(dev) != tc.major {
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
}
if unix.Minor(dev) != tc.minor {
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
}
if unix.Mkdev(tc.major, tc.minor) != dev {
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
}
})
}
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2017 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in OpenBSD's sys/types.h header.
package unix
// Major returns the major component of an OpenBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev & 0x0000ff00) >> 8)
}
// Minor returns the minor component of an OpenBSD device number.
func Minor(dev uint64) uint32 {
minor := uint32((dev & 0x000000ff) >> 0)
minor |= uint32((dev & 0xffff0000) >> 8)
return minor
}
// Mkdev returns an OpenBSD device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
dev := (uint64(major) << 8) & 0x0000ff00
dev |= (uint64(minor) << 8) & 0xffff0000
dev |= (uint64(minor) << 0) & 0x000000ff
return dev
}
+52
View File
@@ -0,0 +1,52 @@
// Copyright 2017 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 unix_test
import (
"fmt"
"testing"
"golang.org/x/sys/unix"
)
func TestDevices(t *testing.T) {
testCases := []struct {
path string
major uint32
minor uint32
}{
// well known major/minor numbers according to /dev/MAKEDEV on
// OpenBSD 6.0
{"/dev/null", 2, 2},
{"/dev/zero", 2, 12},
{"/dev/ttyp0", 5, 0},
{"/dev/ttyp1", 5, 1},
{"/dev/random", 45, 0},
{"/dev/srandom", 45, 1},
{"/dev/urandom", 45, 2},
{"/dev/arandom", 45, 3},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
var stat unix.Stat_t
err := unix.Stat(tc.path, &stat)
if err != nil {
t.Errorf("failed to stat device: %v", err)
return
}
dev := uint64(stat.Rdev)
if unix.Major(dev) != tc.major {
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
}
if unix.Minor(dev) != tc.minor {
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
}
if unix.Mkdev(tc.major, tc.minor) != dev {
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
}
})
}
}
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2017 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 unix_test
import (
"fmt"
"testing"
"golang.org/x/sys/unix"
)
func TestDevices(t *testing.T) {
testCases := []struct {
path string
major uint32
minor uint32
}{
// Well-known major/minor numbers on OpenSolaris according to
// /etc/name_to_major
{"/dev/zero", 134, 12},
{"/dev/null", 134, 2},
{"/dev/ptyp0", 172, 0},
{"/dev/ttyp0", 175, 0},
{"/dev/ttyp1", 175, 1},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
var stat unix.Stat_t
err := unix.Stat(tc.path, &stat)
if err != nil {
t.Errorf("failed to stat device: %v", err)
return
}
dev := uint64(stat.Rdev)
if unix.Major(dev) != tc.major {
t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
}
if unix.Minor(dev) != tc.minor {
t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
}
if unix.Mkdev(tc.major, tc.minor) != dev {
t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
}
})
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Copyright 2010 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.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Copyright 2014 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.
+227
View File
@@ -0,0 +1,227 @@
// Copyright 2017 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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)
+227
View File
@@ -0,0 +1,227 @@
// Copyright 2017 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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8040720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8040720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)
+226
View File
@@ -0,0 +1,226 @@
// Copyright 2017 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 unix
const (
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
IFF_SMART = 0x20
IFT_FAITH = 0xf2
IFT_IPXIP = 0xf9
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Copyright 2015 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.
+27
View File
@@ -0,0 +1,27 @@
// Copyright 2017 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 unix
import (
"os"
"syscall"
)
// FIXME: unexported function from os
// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
func syscallMode(i os.FileMode) (o uint32) {
o |= uint32(i.Perm())
if i&os.ModeSetuid != 0 {
o |= syscall.S_ISUID
}
if i&os.ModeSetgid != 0 {
o |= syscall.S_ISGID
}
if i&os.ModeSticky != 0 {
o |= syscall.S_ISVTX
}
// No mapping for Go's ModeTemporary (plan9 only).
return
}
-2
View File
@@ -1,5 +1,3 @@
// +build linux darwin freebsd openbsd netbsd dragonfly
// Copyright 2014 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.
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Copyright 2015 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.
@@ -8,7 +8,7 @@ package unix
import "syscall"
// We can't use the gc-syntax .s files for gccgo. On the plus side
// We can't use the gc-syntax .s files for gccgo. On the plus side
// much of the functionality can be written directly in Go.
//extern gccgoRealSyscall
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Copyright 2015 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.
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Copyright 2015 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.
-20
View File
@@ -1,20 +0,0 @@
// Copyright 2016 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 gccgo,linux,sparc64
package unix
import "syscall"
//extern sysconf
func realSysconf(name int) int64
func sysconf(name int) (n int64, err syscall.Errno) {
r := realSysconf(name)
if r < 0 {
return 0, syscall.GetErrno()
}
return r, 0
}
+11 -8
View File
@@ -1,5 +1,8 @@
FROM ubuntu:16.04
# Use the most recent ubuntu sources
RUN echo 'deb http://en.archive.ubuntu.com/ubuntu/ artful main universe' >> /etc/apt/sources.list
# Dependencies to get the git sources and go binaries
RUN apt-get update && apt-get install -y \
curl \
@@ -9,15 +12,15 @@ RUN apt-get update && apt-get install -y \
# Get the git sources. If not cached, this takes O(5 minutes).
WORKDIR /git
RUN git config --global advice.detachedHead false
# Linux Kernel: Released 19 Feb 2017
RUN git clone --branch v4.10 --depth 1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
# GNU C library: Released 05 Feb 2017 (we should try to get a secure way to clone this)
RUN git clone --branch glibc-2.25 --depth 1 git://sourceware.org/git/glibc.git
# Linux Kernel: Released 03 Sep 2017
RUN git clone --branch v4.13 --depth 1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
# GNU C library: Released 02 Aug 2017 (we should try to get a secure way to clone this)
RUN git clone --branch glibc-2.26 --depth 1 git://sourceware.org/git/glibc.git
# Get Go 1.8 (https://github.com/docker-library/golang/blob/master/1.8/Dockerfile)
ENV GOLANG_VERSION 1.8
# Get Go 1.9.2
ENV GOLANG_VERSION 1.9.2
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
ENV GOLANG_DOWNLOAD_SHA256 53ab94104ee3923e228a2cb2116e5e462ad3ebaeea06ff04463479d7f12d27ca
ENV GOLANG_DOWNLOAD_SHA256 de874549d9a8d8d8062be05808509c09a88a248e77ec14eb77453530829ac02b
RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \
&& echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \
@@ -30,7 +33,7 @@ ENV PATH /usr/local/go/bin:$PATH
RUN apt-get update && apt-get install -y \
gawk make python \
gcc gcc-multilib \
gettext texinfo \
gettext texinfo \
&& rm -rf /var/lib/apt/lists/*
# Emulator and cross compilers
RUN apt-get update && apt-get install -y \
+103
View File
@@ -15,12 +15,17 @@
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"unicode"
)
// These will be paths to the appropriate source directories.
@@ -128,6 +133,15 @@ var targets = []target{
// },
}
// ptracePairs is a list of pairs of targets that can, in some cases,
// run each other's binaries.
var ptracePairs = []struct{ a1, a2 string }{
{"386", "amd64"},
{"arm", "arm64"},
{"mips", "mips64"},
{"mipsle", "mips64le"},
}
func main() {
if runtime.GOOS != GOOS || runtime.GOARCH != BuildArch {
fmt.Printf("Build system has GOOS_GOARCH = %s_%s, need %s_%s\n",
@@ -158,6 +172,18 @@ func main() {
fmt.Printf("----- SUCCESS: %s -----\n\n", t.GoArch)
}
}
fmt.Printf("----- GENERATING ptrace pairs -----\n")
ok := true
for _, p := range ptracePairs {
if err := generatePtracePair(p.a1, p.a2); err != nil {
fmt.Printf("%v\n***** FAILURE: %s/%s *****\n\n", err, p.a1, p.a2)
ok = false
}
}
if ok {
fmt.Printf("----- SUCCESS ptrace pairs -----\n\n")
}
}
// Makes an exec.Cmd with Stderr attached to os.Stderr
@@ -377,3 +403,80 @@ func (t *target) mksyscallFlags() (flags []string) {
}
return
}
// generatePtracePair takes a pair of GOARCH values that can run each
// other's binaries, such as 386 and amd64. It extracts the PtraceRegs
// type for each one. It writes a new file defining the types
// PtraceRegsArch1 and PtraceRegsArch2 and the corresponding functions
// Ptrace{Get,Set}Regs{arch1,arch2}. This permits debugging the other
// binary on a native system.
func generatePtracePair(arch1, arch2 string) error {
def1, err := ptraceDef(arch1)
if err != nil {
return err
}
def2, err := ptraceDef(arch2)
if err != nil {
return err
}
f, err := os.Create(fmt.Sprintf("zptrace%s_linux.go", arch1))
if err != nil {
return err
}
buf := bufio.NewWriter(f)
fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%s, %s). DO NOT EDIT.\n", arch1, arch2)
fmt.Fprintf(buf, "\n")
fmt.Fprintf(buf, "// +build linux\n")
fmt.Fprintf(buf, "// +build %s %s\n", arch1, arch2)
fmt.Fprintf(buf, "\n")
fmt.Fprintf(buf, "package unix\n")
fmt.Fprintf(buf, "\n")
fmt.Fprintf(buf, "%s\n", `import "unsafe"`)
fmt.Fprintf(buf, "\n")
writeOnePtrace(buf, arch1, def1)
fmt.Fprintf(buf, "\n")
writeOnePtrace(buf, arch2, def2)
if err := buf.Flush(); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
return nil
}
// ptraceDef returns the definition of PtraceRegs for arch.
func ptraceDef(arch string) (string, error) {
filename := fmt.Sprintf("ztypes_linux_%s.go", arch)
data, err := ioutil.ReadFile(filename)
if err != nil {
return "", fmt.Errorf("reading %s: %v", filename, err)
}
start := bytes.Index(data, []byte("type PtraceRegs struct"))
if start < 0 {
return "", fmt.Errorf("%s: no definition of PtraceRegs", filename)
}
data = data[start:]
end := bytes.Index(data, []byte("\n}\n"))
if end < 0 {
return "", fmt.Errorf("%s: can't find end of PtraceRegs definition", filename)
}
return string(data[:end+2]), nil
}
// writeOnePtrace writes out the ptrace definitions for arch.
func writeOnePtrace(w io.Writer, arch, def string) {
uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:]
fmt.Fprintf(w, "// PtraceRegs%s is the registers used by %s binaries.\n", uarch, arch)
fmt.Fprintf(w, "%s\n", strings.Replace(def, "PtraceRegs", "PtraceRegs"+uarch, 1))
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "// PtraceGetRegs%s fetches the registers used by %s binaries.\n", uarch, arch)
fmt.Fprintf(w, "func PtraceGetRegs%s(pid int, regsout *PtraceRegs%s) error {\n", uarch, uarch)
fmt.Fprintf(w, "\treturn ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))\n")
fmt.Fprintf(w, "}\n")
fmt.Fprintf(w, "\n")
fmt.Fprintf(w, "// PtraceSetRegs%s sets the registers used by %s binaries.\n", uarch, arch)
fmt.Fprintf(w, "func PtraceSetRegs%s(pid int, regs *PtraceRegs%s) error {\n", uarch, uarch)
fmt.Fprintf(w, "\treturn ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))\n")
fmt.Fprintf(w, "}\n")
}
+62 -12
View File
@@ -28,6 +28,7 @@ package unix
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/param.h>
@@ -61,6 +62,8 @@ package unix
#include <linux/fs.h>
#include <linux/vm_sockets.h>
#include <linux/random.h>
#include <linux/taskstats.h>
#include <linux/genetlink.h>
// On mips64, the glibc stat and kernel stat do not agree
#if (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64)
@@ -111,14 +114,6 @@ struct stat {
#endif
// Certain constants and structs are missing from the fs/crypto UAPI
#define FS_MAX_KEY_SIZE 64
struct fscrypt_key {
__u32 mode;
__u8 raw[FS_MAX_KEY_SIZE];
__u32 size;
};
#ifdef TCSETS2
// On systems that have "struct termios2" use this as type Termios.
typedef struct termios2 termios_t;
@@ -315,6 +310,8 @@ type IPMreqn C.struct_ip_mreqn
type IPv6Mreq C.struct_ipv6_mreq
type PacketMreq C.struct_packet_mreq
type Msghdr C.struct_msghdr
type Cmsghdr C.struct_cmsghdr
@@ -343,9 +340,11 @@ const (
SizeofSockaddrALG = C.sizeof_struct_sockaddr_alg
SizeofSockaddrVM = C.sizeof_struct_sockaddr_vm
SizeofLinger = C.sizeof_struct_linger
SizeofIovec = C.sizeof_struct_iovec
SizeofIPMreq = C.sizeof_struct_ip_mreq
SizeofIPMreqn = C.sizeof_struct_ip_mreqn
SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
SizeofPacketMreq = C.sizeof_struct_packet_mreq
SizeofMsghdr = C.sizeof_struct_msghdr
SizeofCmsghdr = C.sizeof_struct_cmsghdr
SizeofInet4Pktinfo = C.sizeof_struct_in_pktinfo
@@ -536,10 +535,61 @@ const RNDGETENTCNT = C.RNDGETENTCNT
const PERF_IOC_FLAG_GROUP = C.PERF_IOC_FLAG_GROUP
// sysconf information
const _SC_PAGESIZE = C._SC_PAGESIZE
// Terminal handling
type Termios C.termios_t
type Winsize C.struct_winsize
// Taskstats
type Taskstats C.struct_taskstats
const (
TASKSTATS_CMD_UNSPEC = C.TASKSTATS_CMD_UNSPEC
TASKSTATS_CMD_GET = C.TASKSTATS_CMD_GET
TASKSTATS_CMD_NEW = C.TASKSTATS_CMD_NEW
TASKSTATS_TYPE_UNSPEC = C.TASKSTATS_TYPE_UNSPEC
TASKSTATS_TYPE_PID = C.TASKSTATS_TYPE_PID
TASKSTATS_TYPE_TGID = C.TASKSTATS_TYPE_TGID
TASKSTATS_TYPE_STATS = C.TASKSTATS_TYPE_STATS
TASKSTATS_TYPE_AGGR_PID = C.TASKSTATS_TYPE_AGGR_PID
TASKSTATS_TYPE_AGGR_TGID = C.TASKSTATS_TYPE_AGGR_TGID
TASKSTATS_TYPE_NULL = C.TASKSTATS_TYPE_NULL
TASKSTATS_CMD_ATTR_UNSPEC = C.TASKSTATS_CMD_ATTR_UNSPEC
TASKSTATS_CMD_ATTR_PID = C.TASKSTATS_CMD_ATTR_PID
TASKSTATS_CMD_ATTR_TGID = C.TASKSTATS_CMD_ATTR_TGID
TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = C.TASKSTATS_CMD_ATTR_REGISTER_CPUMASK
TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = C.TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK
)
// Generic netlink
type Genlmsghdr C.struct_genlmsghdr
const (
CTRL_CMD_UNSPEC = C.CTRL_CMD_UNSPEC
CTRL_CMD_NEWFAMILY = C.CTRL_CMD_NEWFAMILY
CTRL_CMD_DELFAMILY = C.CTRL_CMD_DELFAMILY
CTRL_CMD_GETFAMILY = C.CTRL_CMD_GETFAMILY
CTRL_CMD_NEWOPS = C.CTRL_CMD_NEWOPS
CTRL_CMD_DELOPS = C.CTRL_CMD_DELOPS
CTRL_CMD_GETOPS = C.CTRL_CMD_GETOPS
CTRL_CMD_NEWMCAST_GRP = C.CTRL_CMD_NEWMCAST_GRP
CTRL_CMD_DELMCAST_GRP = C.CTRL_CMD_DELMCAST_GRP
CTRL_CMD_GETMCAST_GRP = C.CTRL_CMD_GETMCAST_GRP
CTRL_ATTR_UNSPEC = C.CTRL_ATTR_UNSPEC
CTRL_ATTR_FAMILY_ID = C.CTRL_ATTR_FAMILY_ID
CTRL_ATTR_FAMILY_NAME = C.CTRL_ATTR_FAMILY_NAME
CTRL_ATTR_VERSION = C.CTRL_ATTR_VERSION
CTRL_ATTR_HDRSIZE = C.CTRL_ATTR_HDRSIZE
CTRL_ATTR_MAXATTR = C.CTRL_ATTR_MAXATTR
CTRL_ATTR_OPS = C.CTRL_ATTR_OPS
CTRL_ATTR_MCAST_GROUPS = C.CTRL_ATTR_MCAST_GROUPS
CTRL_ATTR_OP_UNSPEC = C.CTRL_ATTR_OP_UNSPEC
CTRL_ATTR_OP_ID = C.CTRL_ATTR_OP_ID
CTRL_ATTR_OP_FLAGS = C.CTRL_ATTR_OP_FLAGS
CTRL_ATTR_MCAST_GRP_UNSPEC = C.CTRL_ATTR_MCAST_GRP_UNSPEC
CTRL_ATTR_MCAST_GRP_NAME = C.CTRL_ATTR_MCAST_GRP_NAME
CTRL_ATTR_MCAST_GRP_ID = C.CTRL_ATTR_MCAST_GRP_ID
)
+19 -4
View File
@@ -72,7 +72,7 @@ darwin_amd64)
;;
darwin_arm)
mkerrors="$mkerrors"
mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
darwin_arm64)
@@ -108,7 +108,7 @@ freebsd_arm)
mksyscall="./mksyscall.pl -l32 -arm"
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
# Let the type of C char be signed for making the bare syscall
# API consistent across over platforms.
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
linux_sparc64)
@@ -130,11 +130,18 @@ netbsd_amd64)
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
netbsd_arm)
mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -netbsd -arm"
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
openbsd_386)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -openbsd"
mksysctl="./mksysctl_openbsd.pl"
zsysctl="zsysctl_openbsd.go"
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
@@ -142,10 +149,18 @@ openbsd_amd64)
mkerrors="$mkerrors -m64"
mksyscall="./mksyscall.pl -openbsd"
mksysctl="./mksysctl_openbsd.pl"
zsysctl="zsysctl_openbsd.go"
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
openbsd_arm)
mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -openbsd -arm"
mksysctl="./mksysctl_openbsd.pl"
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
solaris_amd64)
mksyscall="./mksyscall_solaris.pl"
mkerrors="$mkerrors -m64"
+20 -3
View File
@@ -17,8 +17,8 @@ if test -z "$GOARCH" -o -z "$GOOS"; then
fi
# Check that we are using the new build system if we should
if [[ "$GOOS" -eq "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
if [[ "$GOLANG_SYS_BUILD" -ne "docker" ]]; then
if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
if [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then
echo 1>&2 "In the new build system, mkerrors should not be called directly."
echo 1>&2 "See README.md"
exit 1
@@ -27,7 +27,7 @@ fi
CC=${CC:-cc}
if [[ "$GOOS" -eq "solaris" ]]; then
if [[ "$GOOS" = "solaris" ]]; then
# Assumes GNU versions of utilities in PATH.
export PATH=/usr/gnu/bin:$PATH
fi
@@ -38,6 +38,8 @@ includes_Darwin='
#define _DARWIN_C_SOURCE
#define KERNEL
#define _DARWIN_USE_64_BIT_INODE
#include <stdint.h>
#include <sys/attr.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/ptrace.h>
@@ -45,6 +47,7 @@ includes_Darwin='
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
@@ -75,6 +78,7 @@ includes_DragonFly='
'
includes_FreeBSD='
#include <sys/capability.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/event.h>
@@ -82,6 +86,7 @@ includes_FreeBSD='
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
@@ -179,6 +184,9 @@ struct ltchars {
#include <linux/serial.h>
#include <linux/can.h>
#include <linux/vm_sockets.h>
#include <linux/taskstats.h>
#include <linux/genetlink.h>
#include <linux/watchdog.h>
#include <net/route.h>
#include <asm/termbits.h>
@@ -279,6 +287,7 @@ includes_SunOS='
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/mkdev.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -343,6 +352,7 @@ ccflags="$@"
$2 !~ /^EXPR_/ &&
$2 ~ /^E[A-Z0-9_]+$/ ||
$2 ~ /^B[0-9_]+$/ ||
$2 ~ /^(OLD|NEW)DEV$/ ||
$2 == "BOTHER" ||
$2 ~ /^CI?BAUD(EX)?$/ ||
$2 == "IBSHIFT" ||
@@ -401,6 +411,7 @@ ccflags="$@"
$2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^CLOCK_/ ||
$2 ~ /^CAN_/ ||
$2 ~ /^CAP_/ ||
$2 ~ /^ALG_/ ||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
$2 ~ /^GRND_/ ||
@@ -410,7 +421,13 @@ ccflags="$@"
$2 ~ /^SECCOMP_MODE_/ ||
$2 ~ /^SPLICE_/ ||
$2 ~ /^(VM|VMADDR)_/ ||
$2 ~ /^(TASKSTATS|TS)_/ ||
$2 ~ /^GENL_/ ||
$2 ~ /^UTIME_/ ||
$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
$2 ~ /^FSOPT_/ ||
$2 ~ /^WDIOC_/ ||
$2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
+5
View File
@@ -56,6 +56,11 @@ func main() {
removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Convert [65]int8 to [65]byte in Utsname members to simplify
// conversion to string; see golang.org/issue/20753
convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
// We refuse to export private fields on s390x
if goarch == "s390x" && goos == "linux" {
// Remove cgo padding fields
-13
View File
@@ -40,21 +40,8 @@ while(<>){
if($name eq 'SYS_SYS_EXIT'){
$name = 'SYS_EXIT';
}
if($name =~ /^SYS_CAP_+/ || $name =~ /^SYS___CAP_+/){
next
}
print " $name = $num; // $proto\n";
# We keep Capsicum syscall numbers for FreeBSD
# 9-STABLE here because we are not sure whether they
# are mature and stable.
if($num == 513){
print " SYS_CAP_NEW = 514 // { int cap_new(int fd, uint64_t rights); }\n";
print " SYS_CAP_GETRIGHTS = 515 // { int cap_getrights(int fd, \\\n";
print " SYS_CAP_ENTER = 516 // { int cap_enter(void); }\n";
print " SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); }\n";
}
}
}
+1 -1
View File
@@ -47,7 +47,7 @@ while(<>){
$name = "$7_$11" if $11 ne '';
$name =~ y/a-z/A-Z/;
if($compat eq '' || $compat eq '30' || $compat eq '50') {
if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') {
print " $name = $num; // $proto\n";
}
}
+12
View File
@@ -17,6 +17,18 @@ func TestMmap(t *testing.T) {
if err != nil {
t.Fatalf("Mmap: %v", err)
}
if err := unix.Mprotect(b, unix.PROT_READ|unix.PROT_WRITE); err != nil {
t.Fatalf("Mprotect: %v", err)
}
b[0] = 42
if err := unix.Msync(b, unix.MS_SYNC); err != nil {
t.Fatalf("Msync: %v", err)
}
if err := unix.Madvise(b, unix.MADV_DONTNEED); err != nil {
t.Fatalf("Madvise: %v", err)
}
if err := unix.Munmap(b); err != nil {
t.Fatalf("Munmap: %v", err)
}
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2017 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 dragonfly freebsd linux netbsd openbsd solaris
// For Unix, get the pagesize from the runtime.
package unix
import "syscall"
func Getpagesize() int {
return syscall.Getpagesize()
}

Some files were not shown because too many files have changed in this diff Show More