mirror of https://github.com/go-gitea/gitea.git
Add support for ssh commit signing (#17743)
* Add support for ssh commit signing * Split out ssh verification to separate file * Show ssh key fingerprint on commit page * Update sshsig lib * Make sure we verify against correct namespace * Add ssh public key verification via ssh signatures When adding a public ssh key also validate that this user actually owns the key by signing a token with the private key. * Remove some gpg references and make verify key optional * Fix spaces indentation * Update options/locale/locale_en-US.ini Co-authored-by: Gusted <williamzijl7@hotmail.com> * Update templates/user/settings/keys_ssh.tmpl Co-authored-by: Gusted <williamzijl7@hotmail.com> * Update options/locale/locale_en-US.ini Co-authored-by: Gusted <williamzijl7@hotmail.com> * Update options/locale/locale_en-US.ini Co-authored-by: Gusted <williamzijl7@hotmail.com> * Update models/ssh_key_commit_verification.go Co-authored-by: Gusted <williamzijl7@hotmail.com> * Reword ssh/gpg_key_success message * Change Badsignature to NoKeyFound * Add sign/verify tests * Fix upstream api changes to user_model User * Match exact on SSH signature * Fix code review remarks Co-authored-by: Gusted <williamzijl7@hotmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
parent
f1e85622da
commit
6fe756dc93
7
go.mod
7
go.mod
|
@ -11,6 +11,7 @@ require (
|
||||||
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
|
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
|
||||||
gitea.com/go-chi/session v0.0.0-20211013065435-7d334f340c09
|
gitea.com/go-chi/session v0.0.0-20211013065435-7d334f340c09
|
||||||
gitea.com/lunny/levelqueue v0.4.1
|
gitea.com/lunny/levelqueue v0.4.1
|
||||||
|
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121
|
||||||
github.com/Microsoft/go-winio v0.5.0 // indirect
|
github.com/Microsoft/go-winio v0.5.0 // indirect
|
||||||
github.com/NYTimes/gziphandler v1.1.1
|
github.com/NYTimes/gziphandler v1.1.1
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20210705153151-cc34b1f6908b // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20210705153151-cc34b1f6908b // indirect
|
||||||
|
@ -121,10 +122,10 @@ require (
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.7.0 // indirect
|
go.uber.org/multierr v1.7.0 // indirect
|
||||||
go.uber.org/zap v1.19.0 // indirect
|
go.uber.org/zap v1.19.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
||||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
|
||||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
||||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf
|
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1
|
||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.7
|
||||||
golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 // indirect
|
golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 // indirect
|
||||||
golang.org/x/tools v0.1.0
|
golang.org/x/tools v0.1.0
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -54,6 +54,8 @@ gitea.com/lunny/levelqueue v0.4.1 h1:RZ+AFx5gBsZuyqCvofhAkPQ9uaVDPJnsULoJZIYaJNw
|
||||||
gitea.com/lunny/levelqueue v0.4.1/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
|
gitea.com/lunny/levelqueue v0.4.1/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
|
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 h1:r3qt8PCHnfjOv9PN3H+XXKmDA1dfFMIN1AislhlA/ps=
|
||||||
|
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121/go.mod h1:Ock8XgA7pvULhIaHGAk/cDnRfNrF9Jey81nPcc403iU=
|
||||||
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
|
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
|
||||||
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
|
||||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||||
|
@ -1261,6 +1263,8 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5
|
||||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
|
||||||
|
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -1355,6 +1359,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
|
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
|
||||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||||
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -1462,6 +1468,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
|
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
|
||||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI=
|
||||||
|
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
|
|
@ -246,3 +246,19 @@ func IsErrDeployKeyNameAlreadyUsed(err error) bool {
|
||||||
func (err ErrDeployKeyNameAlreadyUsed) Error() string {
|
func (err ErrDeployKeyNameAlreadyUsed) Error() string {
|
||||||
return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
|
return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrSSHInvalidTokenSignature represents a "ErrSSHInvalidTokenSignature" kind of error.
|
||||||
|
type ErrSSHInvalidTokenSignature struct {
|
||||||
|
Wrapped error
|
||||||
|
Fingerprint string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrSSHInvalidTokenSignature checks if an error is a ErrSSHInvalidTokenSignature.
|
||||||
|
func IsErrSSHInvalidTokenSignature(err error) bool {
|
||||||
|
_, ok := err.(ErrSSHInvalidTokenSignature)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrSSHInvalidTokenSignature) Error() string {
|
||||||
|
return "the provided signature does not sign the token with the provided key"
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ type CommitVerification struct {
|
||||||
CommittingUser *user_model.User
|
CommittingUser *user_model.User
|
||||||
SigningEmail string
|
SigningEmail string
|
||||||
SigningKey *GPGKey
|
SigningKey *GPGKey
|
||||||
|
SigningSSHKey *PublicKey
|
||||||
TrustStatus string
|
TrustStatus string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +123,11 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this a SSH signature handle it differently
|
||||||
|
if strings.HasPrefix(c.Signature.Signature, "-----BEGIN SSH SIGNATURE-----") {
|
||||||
|
return ParseCommitWithSSHSignature(c, committer)
|
||||||
|
}
|
||||||
|
|
||||||
// Parsing signature
|
// Parsing signature
|
||||||
sig, err := extractSignature(c.Signature.Signature)
|
sig, err := extractSignature(c.Signature.Signature)
|
||||||
if err != nil { // Skipping failed to extract sign
|
if err != nil { // Skipping failed to extract sign
|
||||||
|
@ -487,28 +493,31 @@ func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var isMember bool
|
// Check we actually have a GPG SigningKey
|
||||||
if keyMap != nil {
|
if verification.SigningKey != nil {
|
||||||
var has bool
|
var isMember bool
|
||||||
isMember, has = (*keyMap)[verification.SigningKey.KeyID]
|
if keyMap != nil {
|
||||||
if !has {
|
var has bool
|
||||||
|
isMember, has = (*keyMap)[verification.SigningKey.KeyID]
|
||||||
|
if !has {
|
||||||
|
isMember, err = isCodeReader(verification.SigningUser)
|
||||||
|
(*keyMap)[verification.SigningKey.KeyID] = isMember
|
||||||
|
}
|
||||||
|
} else {
|
||||||
isMember, err = isCodeReader(verification.SigningUser)
|
isMember, err = isCodeReader(verification.SigningUser)
|
||||||
(*keyMap)[verification.SigningKey.KeyID] = isMember
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
isMember, err = isCodeReader(verification.SigningUser)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !isMember {
|
if !isMember {
|
||||||
verification.TrustStatus = "untrusted"
|
verification.TrustStatus = "untrusted"
|
||||||
if verification.CommittingUser.ID != verification.SigningUser.ID {
|
if verification.CommittingUser.ID != verification.SigningUser.ID {
|
||||||
// The committing user and the signing user are not the same
|
// The committing user and the signing user are not the same
|
||||||
// This should be marked as questionable unless the signing user is a collaborator/team member etc.
|
// This should be marked as questionable unless the signing user is a collaborator/team member etc.
|
||||||
|
verification.TrustStatus = "unmatched"
|
||||||
|
}
|
||||||
|
} else if repoTrustModel == repo_model.CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
|
||||||
|
// The committing user and the signing user are not the same and our trustmodel states that they must match
|
||||||
verification.TrustStatus = "unmatched"
|
verification.TrustStatus = "unmatched"
|
||||||
}
|
}
|
||||||
} else if repoTrustModel == repo_model.CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
|
|
||||||
// The committing user and the signing user are not the same and our trustmodel states that they must match
|
|
||||||
verification.TrustStatus = "unmatched"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -50,6 +50,7 @@ type PublicKey struct {
|
||||||
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
|
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
|
||||||
HasRecentActivity bool `xorm:"-"`
|
HasRecentActivity bool `xorm:"-"`
|
||||||
HasUsed bool `xorm:"-"`
|
HasUsed bool `xorm:"-"`
|
||||||
|
Verified bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package asymkey
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
|
"github.com/42wim/sshsig"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseCommitWithSSHSignature check if signature is good against keystore.
|
||||||
|
func ParseCommitWithSSHSignature(c *git.Commit, committer *user_model.User) *CommitVerification {
|
||||||
|
// Now try to associate the signature with the committer, if present
|
||||||
|
if committer.ID != 0 {
|
||||||
|
keys, err := ListPublicKeys(committer.ID, db.ListOptions{})
|
||||||
|
if err != nil { // Skipping failed to get ssh keys of user
|
||||||
|
log.Error("ListPublicKeys: %v", err)
|
||||||
|
return &CommitVerification{
|
||||||
|
CommittingUser: committer,
|
||||||
|
Verified: false,
|
||||||
|
Reason: "gpg.error.failed_retrieval_gpg_keys",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
committerEmailAddresses, err := user_model.GetEmailAddresses(committer.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("GetEmailAddresses: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
activated := false
|
||||||
|
for _, e := range committerEmailAddresses {
|
||||||
|
if e.IsActivated && strings.EqualFold(e.Email, c.Committer.Email) {
|
||||||
|
activated = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range keys {
|
||||||
|
if k.Verified && activated {
|
||||||
|
commitVerification := verifySSHCommitVerification(c.Signature.Signature, c.Signature.Payload, k, committer, committer, c.Committer.Email)
|
||||||
|
if commitVerification != nil {
|
||||||
|
return commitVerification
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CommitVerification{
|
||||||
|
CommittingUser: committer,
|
||||||
|
Verified: false,
|
||||||
|
Reason: NoKeyFound,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifySSHCommitVerification(sig, payload string, k *PublicKey, committer, signer *user_model.User, email string) *CommitVerification {
|
||||||
|
if err := sshsig.Verify(bytes.NewBuffer([]byte(payload)), []byte(sig), []byte(k.Content), "git"); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CommitVerification{ // Everything is ok
|
||||||
|
CommittingUser: committer,
|
||||||
|
Verified: true,
|
||||||
|
Reason: fmt.Sprintf("%s / %s", signer.Name, k.Fingerprint),
|
||||||
|
SigningUser: signer,
|
||||||
|
SigningSSHKey: k,
|
||||||
|
SigningEmail: email,
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,11 +6,16 @@
|
||||||
package asymkey
|
package asymkey
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
|
"github.com/42wim/sshsig"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -185,3 +190,309 @@ func Test_calcFingerprint(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Generated with "ssh-keygen -C test@rekor.dev -f id_rsa"
|
||||||
|
sshPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||||
|
NhAAAAAwEAAQAAAYEA16H5ImoRO7mr41r8Z8JFBdu6jIM+6XU8M0r9F81RuhLYqzr9zw1n
|
||||||
|
LeGCqFxPXNBKm8ZyH2BCsBHsbXbwe85IMHM3SUh8X/9fI0Lpi5/xbqAproFUpNR+UJYv6s
|
||||||
|
8AaWk5zpN1rmpBrqGFJfGQKJCioDiiwNGmSdVkUNmQmYIANxJMDWYmNe8vUOh6nYEHB+lz
|
||||||
|
fGgDAAzVSXTACW994UkSY47AD05swU4rIT/JWA6BkUrEhO//F0QQhFeROCPJiPRhJXGcFf
|
||||||
|
9SicffJqR/ELzM1zNYnRXMD0bbdTUwDrIcIFFNBbtcfJVOUUCGumSlt+qjUC7y8cvwbHAu
|
||||||
|
wf5nS6baA7P6LfTYplF2XIAkdWtkN6O1ouoyIHICXMlddDW2vNaJeEXTeKjx51WSM7qPnQ
|
||||||
|
ZKsBtwjLQeEY/OPkIvu88lNNYSD63qMUA12msohjwVFCIgJVvYLIrkViczZ7t3L7lgy1X0
|
||||||
|
CJI4e1roOfM/r9jTieyDHchEYpZYcw3L1R2qtePlAAAFiHdJQKl3SUCpAAAAB3NzaC1yc2
|
||||||
|
EAAAGBANeh+SJqETu5q+Na/GfCRQXbuoyDPul1PDNK/RfNUboS2Ks6/c8NZy3hgqhcT1zQ
|
||||||
|
SpvGch9gQrAR7G128HvOSDBzN0lIfF//XyNC6Yuf8W6gKa6BVKTUflCWL+rPAGlpOc6Tda
|
||||||
|
5qQa6hhSXxkCiQoqA4osDRpknVZFDZkJmCADcSTA1mJjXvL1Doep2BBwfpc3xoAwAM1Ul0
|
||||||
|
wAlvfeFJEmOOwA9ObMFOKyE/yVgOgZFKxITv/xdEEIRXkTgjyYj0YSVxnBX/UonH3yakfx
|
||||||
|
C8zNczWJ0VzA9G23U1MA6yHCBRTQW7XHyVTlFAhrpkpbfqo1Au8vHL8GxwLsH+Z0um2gOz
|
||||||
|
+i302KZRdlyAJHVrZDejtaLqMiByAlzJXXQ1trzWiXhF03io8edVkjO6j50GSrAbcIy0Hh
|
||||||
|
GPzj5CL7vPJTTWEg+t6jFANdprKIY8FRQiICVb2CyK5FYnM2e7dy+5YMtV9AiSOHta6Dnz
|
||||||
|
P6/Y04nsgx3IRGKWWHMNy9UdqrXj5QAAAAMBAAEAAAGAJyaOcFQnuttUPRxY9ZHNLGofrc
|
||||||
|
Fqm8KgYoO7/iVWMF2Zn0U/rec2E5t9OIpCEozy7uOR9uZoVUV70sgkk6X5b2qL4C9b/aYF
|
||||||
|
JQbSFnq8wCQuTTPIJYE7SfBq1Mwuu/TR/RLC7B74u/cxkJkSXnscO9Dso+ussH0hEJjf6y
|
||||||
|
8yUM1up4Qjbel2gs8i7BPwLdySDkVoPgsWcpbTAyOODGhTAWZ6soy/rD1AEXJeYTGJDtMv
|
||||||
|
aR+WBihig1TO1g2RWt9bqqiG7PIlljd3ZsjSSU5y3t6ZN/8j5keKD032EtxbZB0WFD3Ar4
|
||||||
|
FbFwlW+urb2MQ0JyNKOio3nhdjolXYkJa+C6LXdaaml/8BhMR1eLoMe8nS45w76o8mdJWX
|
||||||
|
wsirB8tvjCLY0QBXgGv/1DTsKu/wEFCW2/Y0e50gF7pHAlYFNmKDcgI9OyORRYhFbV4D82
|
||||||
|
fI8JLQ42ZJkS/0t6xQma8WC88pbHGEuVSB6CE/p25fyYRX+UPTQ79tWFvLV4kNQAaBAAAA
|
||||||
|
wEvyd6H8ePyBXImg8JzGxthufB0eXSfZBrabjf6e6bR2ivpJsHmB64gbMkV6MFV7EWYX1B
|
||||||
|
wYPQxf4gA2Ez7aJvDtfE7uV6pa0WJS3hW1+be8DHEftmLSbTy/TEvDujNb2gqoi7uWQXWJ
|
||||||
|
yYWZlYO65r1a6HucryQ8+78fTuTRbZALO43vNGz0oXH1hPSddkcbNAhZTsD0rQKNwqVTe5
|
||||||
|
wl+6Cduy/CQwjHLYrY73MyWy1Vh1LXhAdGMPnWZwGIu/dnkgAAAMEA9KuaoGnfnLQkrjeR
|
||||||
|
tO4RCRS2quNRvm4L6i4vHgTDsYtoSlR1ujge7SGOOmIPS4XVjZN5zzCOA7+EDVnuz3WWmx
|
||||||
|
hmkjpG1YxzmJGaWoYdeo3a6UgJtisfMp8eUKqjJT1mhsCliCWtaOQNRoQieDQmgwZzSX/v
|
||||||
|
ZiGsOIKa6cR37eKvOJSjVrHsAUzdtYrmi8P2gvAUFWyzXobAtpzHcWrwWkOEIm04G0OGXb
|
||||||
|
J46hfIX3f45E5EKXvFzexGgVOD2I7hAAAAwQDhniYAizfW9YfG7UJWekkl42xMP7Cb8b0W
|
||||||
|
SindSIuE8bFTukV1yxbmNZp/f0pKvn/DWc2n0I0bwSGZpy8BCY46RKKB2DYQavY/tGcC1N
|
||||||
|
AynKuvbtWs11A0mTXmq3WwHVXQDozMwJ2nnHpm0UHspPuHqkYpurlP+xoFsocaQ9QwITyp
|
||||||
|
lL4qHtXBEzaT8okkcGZBHdSx3gk4TzCsEDOP7ZZPLq42lpKMK10zFPTMd0maXtJDYKU/b4
|
||||||
|
gAATvvPoylyYUAAAAOdGVzdEByZWtvci5kZXYBAgMEBQ==
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
sshPublicKey = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDXofkiahE7uavjWvxnwkUF27qMgz7pdTwzSv0XzVG6EtirOv3PDWct4YKoXE9c0EqbxnIfYEKwEextdvB7zkgwczdJSHxf/18jQumLn/FuoCmugVSk1H5Qli/qzwBpaTnOk3WuakGuoYUl8ZAokKKgOKLA0aZJ1WRQ2ZCZggA3EkwNZiY17y9Q6HqdgQcH6XN8aAMADNVJdMAJb33hSRJjjsAPTmzBTishP8lYDoGRSsSE7/8XRBCEV5E4I8mI9GElcZwV/1KJx98mpH8QvMzXM1idFcwPRtt1NTAOshwgUU0Fu1x8lU5RQIa6ZKW36qNQLvLxy/BscC7B/mdLptoDs/ot9NimUXZcgCR1a2Q3o7Wi6jIgcgJcyV10Nba81ol4RdN4qPHnVZIzuo+dBkqwG3CMtB4Rj84+Qi+7zyU01hIPreoxQDXaayiGPBUUIiAlW9gsiuRWJzNnu3cvuWDLVfQIkjh7Wug58z+v2NOJ7IMdyERillhzDcvVHaq14+U= test@rekor.dev
|
||||||
|
`
|
||||||
|
// Generated with "ssh-keygen -C other-test@rekor.dev -f id_rsa"
|
||||||
|
otherSSHPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||||
|
NhAAAAAwEAAQAAAYEAw/WCSWC9TEvCQOwO+T68EvNa3OSIv1Y0+sT8uSvyjPyEO0+p0t8C
|
||||||
|
g/zy67vOxiQpU5jN6MItjXAjMmeCm8GKMt6gk+cDoaAev/ZfjuzSL7RayExpmhBleh2X3G
|
||||||
|
KLkkXF9ABFNchlTqSLOZiEjDoNpbFv16KT1sE6CqW8DjxXQkQk9JK65hLH+BxeWMNCEJVa
|
||||||
|
Cma4X04aJmC7zJAi5yGeeT0SKVqMohavF90O6XiYFCQHuwXPPyHfocqgudmXnozz+6D6ax
|
||||||
|
JKZMwQsNp3WKumOjlzWnxBCCB1l2jN6Rag8aJ2277iMFXRwjTL/8jaEsW4KkysDf0GjV2/
|
||||||
|
iqbr0q5b0arDYbv7CrGBR+uH0wGz/Zog1x5iZANObhZULpDrLVJidEMc27HXBb7PMsNDy7
|
||||||
|
BGYRB1yc0d0y83p8mUqvOlWSArxn1WnAZO04pAgTrclrhEh4ZXOkn2Sn82eu3DpQ8inkol
|
||||||
|
Y4IfnhIfbOIeemoUNq1tOUquhow9GLRM6INieHLBAAAFkPPnA1jz5wNYAAAAB3NzaC1yc2
|
||||||
|
EAAAGBAMP1gklgvUxLwkDsDvk+vBLzWtzkiL9WNPrE/Lkr8oz8hDtPqdLfAoP88uu7zsYk
|
||||||
|
KVOYzejCLY1wIzJngpvBijLeoJPnA6GgHr/2X47s0i+0WshMaZoQZXodl9xii5JFxfQART
|
||||||
|
XIZU6kizmYhIw6DaWxb9eik9bBOgqlvA48V0JEJPSSuuYSx/gcXljDQhCVWgpmuF9OGiZg
|
||||||
|
u8yQIuchnnk9EilajKIWrxfdDul4mBQkB7sFzz8h36HKoLnZl56M8/ug+msSSmTMELDad1
|
||||||
|
irpjo5c1p8QQggdZdozekWoPGidtu+4jBV0cI0y//I2hLFuCpMrA39Bo1dv4qm69KuW9Gq
|
||||||
|
w2G7+wqxgUfrh9MBs/2aINceYmQDTm4WVC6Q6y1SYnRDHNux1wW+zzLDQ8uwRmEQdcnNHd
|
||||||
|
MvN6fJlKrzpVkgK8Z9VpwGTtOKQIE63Ja4RIeGVzpJ9kp/Nnrtw6UPIp5KJWOCH54SH2zi
|
||||||
|
HnpqFDatbTlKroaMPRi0TOiDYnhywQAAAAMBAAEAAAGAYycx4oEhp55Zz1HijblxnsEmQ8
|
||||||
|
kbbH1pV04fdm7HTxFis0Qu8PVIp5JxNFiWWunnQ1Z5MgI23G9WT+XST4+RpwXBCLWGv9xu
|
||||||
|
UsGOPpqUC/FdUiZf9MXBIxYgRjJS3xORA1KzsnAQ2sclb2I+B1pEl4d9yQWJesvQ25xa2H
|
||||||
|
Utzej/LgWkrk/ogSGRl6ZNImj/421wc0DouGyP+gUgtATt0/jT3LrlmAqUVCXVqssLYH2O
|
||||||
|
r9JTuGUibBJEW2W/c0lsM0jaHa5bGAdL3nhDuF1Q6KFB87mZoNw8c2znYoTzQ3FyWtIEZI
|
||||||
|
V/9oWrkS7V6242SKSR9tJoEzK0jtrKC/FZwBiI4hPcwoqY6fZbT1701i/n50xWEfEUOLVm
|
||||||
|
d6VqNKyAbIaZIPN0qfZuD+xdrHuM3V6k/rgFxGl4XTrp/N4AsruiQs0nRQKNTw3fHE0zPq
|
||||||
|
UTxSeMvjywRCepxhBFCNh8NHydapclHtEPEGdTVHohL3krJehstPO/IuRyKLfSVtL1AAAA
|
||||||
|
wQCmGA8k+uW6mway9J3jp8mlMhhp3DCX6DAcvalbA/S5OcqMyiTM3c/HD5OJ6OYFDldcqu
|
||||||
|
MPEgLRL2HfxL29LsbQSzjyOIrfp5PLJlo70P5lXS8u2QPbo4/KQJmQmsIX18LDyU2zRtNA
|
||||||
|
C2WfBiHSZV+guLhmHms9S5gQYKt2T5OnY/W0tmnInx9lmFCMC+XKS1iSQ2o433IrtCPQJp
|
||||||
|
IXZd59OQpO9QjJABgJIDtXxFIXt45qpXduDPJuggrhg81stOwAAADBAPX73u/CY+QUPts+
|
||||||
|
LV185Z4mZ2y+qu2ZMCAU3BnpHktGZZ1vFN1Xq9o8KdnuPZ+QJRdO8eKMWpySqrIdIbTYLm
|
||||||
|
9nXmVH0uNECIEAvdU+wgKeR+BSHxCRVuTF4YSygmNadgH/z+oRWLgOblGo2ywFBoXsIAKQ
|
||||||
|
paNu1MFGRUmhz67+dcpkkBUDRU9loAgBKexMo8D9vkR0YiHLOUjCrtmEZRNm0YRZt0gQhD
|
||||||
|
ZSD1fOH0fZDcCVNpGP2zqAKos4EGLnkwAAAMEAy/AuLtPKA2u9oCA8e18ZnuQRAi27FBVU
|
||||||
|
rU2D7bMg1eS0IakG8v0gE9K6WdYzyArY1RoKB3ZklK5VmJ1cOcWc2x3Ejc5jcJgc8cC6lZ
|
||||||
|
wwjpE8HfWL1kIIYgPdcexqFc+l6MdgH6QMKU3nLg1LsM4v5FEldtk/2dmnw620xnFfstpF
|
||||||
|
VxSZNdKrYfM/v9o6sRaDRqSfH1dG8BvkUxPznTAF+JDxBENcKXYECcq9f6dcl1w5IEnNTD
|
||||||
|
Wry/EKQvgvOUjbAAAAFG90aGVyLXRlc3RAcmVrb3IuZGV2AQIDBAUG
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
otherSSHPublicKey = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDD9YJJYL1MS8JA7A75PrwS81rc5Ii/VjT6xPy5K/KM/IQ7T6nS3wKD/PLru87GJClTmM3owi2NcCMyZ4KbwYoy3qCT5wOhoB6/9l+O7NIvtFrITGmaEGV6HZfcYouSRcX0AEU1yGVOpIs5mISMOg2lsW/XopPWwToKpbwOPFdCRCT0krrmEsf4HF5Yw0IQlVoKZrhfThomYLvMkCLnIZ55PRIpWoyiFq8X3Q7peJgUJAe7Bc8/Id+hyqC52ZeejPP7oPprEkpkzBCw2ndYq6Y6OXNafEEIIHWXaM3pFqDxonbbvuIwVdHCNMv/yNoSxbgqTKwN/QaNXb+KpuvSrlvRqsNhu/sKsYFH64fTAbP9miDXHmJkA05uFlQukOstUmJ0QxzbsdcFvs8yw0PLsEZhEHXJzR3TLzenyZSq86VZICvGfVacBk7TikCBOtyWuESHhlc6SfZKfzZ67cOlDyKeSiVjgh+eEh9s4h56ahQ2rW05Sq6GjD0YtEzog2J4csE= other-test@rekor.dev
|
||||||
|
`
|
||||||
|
|
||||||
|
// Generated with ssh-keygen -C test@rekor.dev -t ed25519 -f id_ed25519
|
||||||
|
ed25519PrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||||
|
QyNTUxOQAAACBB45zRHxPPFtabwS3Vd6Lb9vMe+tIHZj2qN5VQ+bgLfQAAAJgyRa3cMkWt
|
||||||
|
3AAAAAtzc2gtZWQyNTUxOQAAACBB45zRHxPPFtabwS3Vd6Lb9vMe+tIHZj2qN5VQ+bgLfQ
|
||||||
|
AAAED7y4N/DsVnRQiBZNxEWdsJ9RmbranvtQ3X9jnb6gFed0HjnNEfE88W1pvBLdV3otv2
|
||||||
|
8x760gdmPao3lVD5uAt9AAAADnRlc3RAcmVrb3IuZGV2AQIDBAUGBw==
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
`
|
||||||
|
ed25519PublicKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEHjnNEfE88W1pvBLdV3otv28x760gdmPao3lVD5uAt9 test@rekor.dev
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFromOpenSSH(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
pub string
|
||||||
|
priv string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "rsa",
|
||||||
|
pub: sshPublicKey,
|
||||||
|
priv: sshPrivateKey,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ed25519",
|
||||||
|
pub: ed25519PublicKey,
|
||||||
|
priv: ed25519PrivateKey,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
if _, err := exec.LookPath("ssh-keygen"); err != nil {
|
||||||
|
t.Skip("skip TestFromOpenSSH: missing ssh-keygen in PATH")
|
||||||
|
}
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt := tt
|
||||||
|
|
||||||
|
// Test that a signature from the cli can validate here.
|
||||||
|
td := t.TempDir()
|
||||||
|
|
||||||
|
data := []byte("hello, ssh world")
|
||||||
|
dataPath := write(t, []byte(data), td, "data")
|
||||||
|
|
||||||
|
privPath := write(t, []byte(tt.priv), td, "id")
|
||||||
|
write(t, []byte(tt.pub), td, "id.pub")
|
||||||
|
|
||||||
|
sigPath := dataPath + ".sig"
|
||||||
|
run(t, nil, "ssh-keygen", "-Y", "sign", "-n", "file", "-f", privPath, dataPath)
|
||||||
|
|
||||||
|
sigBytes, err := ioutil.ReadFile(sigPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := sshsig.Verify(bytes.NewReader(data), sigBytes, []byte(tt.pub), "file"); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// It should not verify if we check against another public key
|
||||||
|
if err := sshsig.Verify(bytes.NewReader(data), sigBytes, []byte(otherSSHPublicKey), "file"); err == nil {
|
||||||
|
t.Error("expected error with incorrect key")
|
||||||
|
}
|
||||||
|
|
||||||
|
// It should not verify if the data is tampered
|
||||||
|
if err := sshsig.Verify(strings.NewReader("bad data"), sigBytes, []byte(sshPublicKey), "file"); err == nil {
|
||||||
|
t.Error("expected error with incorrect data")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToOpenSSH(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
pub string
|
||||||
|
priv string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "rsa",
|
||||||
|
pub: sshPublicKey,
|
||||||
|
priv: sshPrivateKey,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ed25519",
|
||||||
|
pub: ed25519PublicKey,
|
||||||
|
priv: ed25519PrivateKey,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
if _, err := exec.LookPath("ssh-keygen"); err != nil {
|
||||||
|
t.Skip("skip TestToOpenSSH: missing ssh-keygen in PATH")
|
||||||
|
}
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt := tt
|
||||||
|
// Test that a signature from here can validate in the CLI.
|
||||||
|
td := t.TempDir()
|
||||||
|
|
||||||
|
data := []byte("hello, ssh world")
|
||||||
|
write(t, []byte(data), td, "data")
|
||||||
|
|
||||||
|
armored, err := sshsig.Sign([]byte(tt.priv), bytes.NewReader(data), "file")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sigPath := write(t, []byte(armored), td, "oursig")
|
||||||
|
|
||||||
|
// Create an allowed_signers file with two keys to check against.
|
||||||
|
allowedSigner := "test@rekor.dev " + tt.pub + "\n"
|
||||||
|
allowedSigner += "othertest@rekor.dev " + otherSSHPublicKey + "\n"
|
||||||
|
allowedSigners := write(t, []byte(allowedSigner), td, "allowed_signer")
|
||||||
|
|
||||||
|
// We use the correct principal here so it should work.
|
||||||
|
run(t, data, "ssh-keygen", "-Y", "verify", "-f", allowedSigners,
|
||||||
|
"-I", "test@rekor.dev", "-n", "file", "-s", sigPath)
|
||||||
|
|
||||||
|
// Just to be sure, check against the other public key as well.
|
||||||
|
runErr(t, data, "ssh-keygen", "-Y", "verify", "-f", allowedSigners,
|
||||||
|
"-I", "othertest@rekor.dev", "-n", "file", "-s", sigPath)
|
||||||
|
|
||||||
|
// It should error if we run it against other data
|
||||||
|
data = []byte("other data!")
|
||||||
|
runErr(t, data, "ssh-keygen", "-Y", "check-novalidate", "-n", "file", "-s", sigPath)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRoundTrip(t *testing.T) {
|
||||||
|
data := []byte("my good data to be signed!")
|
||||||
|
|
||||||
|
// Create one extra signature for all the tests.
|
||||||
|
otherSig, err := sshsig.Sign([]byte(otherSSHPrivateKey), bytes.NewReader(data), "file")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
pub string
|
||||||
|
priv string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "rsa",
|
||||||
|
pub: sshPublicKey,
|
||||||
|
priv: sshPrivateKey,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ed25519",
|
||||||
|
pub: ed25519PublicKey,
|
||||||
|
priv: ed25519PrivateKey,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt := tt
|
||||||
|
sig, err := sshsig.Sign([]byte(tt.priv), bytes.NewReader(data), "file")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the signature against that data and public key
|
||||||
|
if err := sshsig.Verify(bytes.NewReader(data), sig, []byte(tt.pub), "file"); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check it against invalid data.
|
||||||
|
if err := sshsig.Verify(strings.NewReader("invalid data!"), sig, []byte(tt.pub), "file"); err == nil {
|
||||||
|
t.Error("expected error!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check it against the wrong key.
|
||||||
|
if err := sshsig.Verify(bytes.NewReader(data), sig, []byte(otherSSHPublicKey), "file"); err == nil {
|
||||||
|
t.Error("expected error!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check it against an invalid signature data.
|
||||||
|
if err := sshsig.Verify(bytes.NewReader(data), []byte("invalid signature!"), []byte(tt.pub), "file"); err == nil {
|
||||||
|
t.Error("expected error!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once more, use the wrong signature and check it against the original (wrong public key)
|
||||||
|
if err := sshsig.Verify(bytes.NewReader(data), otherSig, []byte(tt.pub), "file"); err == nil {
|
||||||
|
t.Error("expected error!")
|
||||||
|
}
|
||||||
|
// It should work against the correct public key.
|
||||||
|
if err := sshsig.Verify(bytes.NewReader(data), otherSig, []byte(otherSSHPublicKey), "file"); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func write(t *testing.T, d []byte, fp ...string) string {
|
||||||
|
p := filepath.Join(fp...)
|
||||||
|
if err := ioutil.WriteFile(p, d, 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func run(t *testing.T, stdin []byte, args ...string) {
|
||||||
|
t.Helper()
|
||||||
|
/* #nosec */
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
cmd.Stdin = bytes.NewReader(stdin)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
t.Logf("cmd %v: %s", cmd, string(out))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runErr(t *testing.T, stdin []byte, args ...string) {
|
||||||
|
t.Helper()
|
||||||
|
/* #nosec */
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
cmd.Stdin = bytes.NewReader(stdin)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
t.Logf("cmd %v: %s", cmd, string(out))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package asymkey
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"github.com/42wim/sshsig"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VerifySSHKey marks a SSH key as verified
|
||||||
|
func VerifySSHKey(ownerID int64, fingerprint, token, signature string) (string, error) {
|
||||||
|
ctx, committer, err := db.TxContext()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer committer.Close()
|
||||||
|
|
||||||
|
key := new(PublicKey)
|
||||||
|
|
||||||
|
has, err := db.GetEngine(ctx).Where("owner_id = ? AND fingerprint = ?", ownerID, fingerprint).Get(key)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
} else if !has {
|
||||||
|
return "", ErrKeyNotExist{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sshsig.Verify(bytes.NewBuffer([]byte(token)), []byte(signature), []byte(key.Content), "gitea"); err != nil {
|
||||||
|
log.Error("Unable to validate token signature. Error: %v", err)
|
||||||
|
return "", ErrSSHInvalidTokenSignature{
|
||||||
|
Fingerprint: key.Fingerprint,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key.Verified = true
|
||||||
|
if _, err := db.GetEngine(ctx).ID(key.ID).Cols("verified").Update(key); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := committer.Commit(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return key.Fingerprint, nil
|
||||||
|
}
|
|
@ -361,6 +361,8 @@ var migrations = []Migration{
|
||||||
NewMigration("Create key/value table for user settings", createUserSettingsTable),
|
NewMigration("Create key/value table for user settings", createUserSettingsTable),
|
||||||
// v203 -> v204
|
// v203 -> v204
|
||||||
NewMigration("Add Sorting to ProjectIssue table", addProjectIssueSorting),
|
NewMigration("Add Sorting to ProjectIssue table", addProjectIssueSorting),
|
||||||
|
// v204 -> v205
|
||||||
|
NewMigration("Add key is verified to ssh key", addSSHKeyIsVerified),
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentDBVersion returns the current db version
|
// GetCurrentDBVersion returns the current db version
|
||||||
|
|
|
@ -21,5 +21,4 @@ func createUserSettingsTable(x *xorm.Engine) error {
|
||||||
return fmt.Errorf("sync2: %v", err)
|
return fmt.Errorf("sync2: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import "xorm.io/xorm"
|
||||||
|
|
||||||
|
func addSSHKeyIsVerified(x *xorm.Engine) error {
|
||||||
|
type PublicKey struct {
|
||||||
|
Verified bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.Sync(new(PublicKey))
|
||||||
|
}
|
|
@ -629,7 +629,18 @@ gpg_token_help = You can generate a signature using:
|
||||||
gpg_token_code = echo "%s" | gpg -a --default-key %s --detach-sig
|
gpg_token_code = echo "%s" | gpg -a --default-key %s --detach-sig
|
||||||
gpg_token_signature = Armored GPG signature
|
gpg_token_signature = Armored GPG signature
|
||||||
key_signature_gpg_placeholder = Begins with '-----BEGIN PGP SIGNATURE-----'
|
key_signature_gpg_placeholder = Begins with '-----BEGIN PGP SIGNATURE-----'
|
||||||
verify_gpg_key_success = The GPG key '%s' has been verified.
|
verify_gpg_key_success = GPG key '%s' has been verified.
|
||||||
|
ssh_key_verified=Verified Key
|
||||||
|
ssh_key_verified_long=Key has been verified with a token and can be used to verify commits matching any activated email addresses for this user.
|
||||||
|
ssh_key_verify=Verify
|
||||||
|
ssh_invalid_token_signature = The provided SSH key, signature or token do not match or token is out-of-date.
|
||||||
|
ssh_token_required = You must provide a signature for the below token
|
||||||
|
ssh_token = Token
|
||||||
|
ssh_token_help = You can generate a signature using:
|
||||||
|
ssh_token_code = echo -n "%s" | ssh-keygen -Y sign -n gitea -f /path_to_your_pubkey
|
||||||
|
ssh_token_signature = Armored SSH signature
|
||||||
|
key_signature_ssh_placeholder = Begins with '-----BEGIN SSH SIGNATURE-----'
|
||||||
|
verify_ssh_key_success = SSH key '%s' has been verified.
|
||||||
subkeys = Subkeys
|
subkeys = Subkeys
|
||||||
key_id = Key ID
|
key_id = Key ID
|
||||||
key_name = Key Name
|
key_name = Key Name
|
||||||
|
@ -1084,6 +1095,7 @@ commits.signed_by = Signed by
|
||||||
commits.signed_by_untrusted_user = Signed by untrusted user
|
commits.signed_by_untrusted_user = Signed by untrusted user
|
||||||
commits.signed_by_untrusted_user_unmatched = Signed by untrusted user who does not match committer
|
commits.signed_by_untrusted_user_unmatched = Signed by untrusted user who does not match committer
|
||||||
commits.gpg_key_id = GPG Key ID
|
commits.gpg_key_id = GPG Key ID
|
||||||
|
commits.ssh_key_fingerprint = SSH Key Fingerprint
|
||||||
|
|
||||||
ext_issues = Ext. Issues
|
ext_issues = Ext. Issues
|
||||||
ext_issues.desc = Link to an external issue tracker.
|
ext_issues.desc = Link to an external issue tracker.
|
||||||
|
|
|
@ -184,6 +184,28 @@ func KeysPost(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
|
ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
|
||||||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||||
|
case "verify_ssh":
|
||||||
|
token := asymkey_model.VerificationToken(ctx.User, 1)
|
||||||
|
lastToken := asymkey_model.VerificationToken(ctx.User, 0)
|
||||||
|
|
||||||
|
fingerprint, err := asymkey_model.VerifySSHKey(ctx.User.ID, form.Fingerprint, token, form.Signature)
|
||||||
|
if err != nil && asymkey_model.IsErrSSHInvalidTokenSignature(err) {
|
||||||
|
fingerprint, err = asymkey_model.VerifySSHKey(ctx.User.ID, form.Fingerprint, lastToken, form.Signature)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
ctx.Data["HasSSHVerifyError"] = true
|
||||||
|
switch {
|
||||||
|
case asymkey_model.IsErrSSHInvalidTokenSignature(err):
|
||||||
|
loadKeysData(ctx)
|
||||||
|
ctx.Data["Err_Signature"] = true
|
||||||
|
ctx.Data["Fingerprint"] = err.(asymkey_model.ErrSSHInvalidTokenSignature).Fingerprint
|
||||||
|
ctx.RenderWithErr(ctx.Tr("settings.ssh_invalid_token_signature"), tplSettingsKeys, &form)
|
||||||
|
default:
|
||||||
|
ctx.ServerError("VerifySSH", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.Flash.Success(ctx.Tr("settings.verify_ssh_key_success", fingerprint))
|
||||||
|
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ctx.Flash.Warning("Function not implemented")
|
ctx.Flash.Warning("Function not implemented")
|
||||||
|
@ -268,4 +290,5 @@ func loadKeysData(ctx *context.Context) {
|
||||||
ctx.Data["Principals"] = principals
|
ctx.Data["Principals"] = principals
|
||||||
|
|
||||||
ctx.Data["VerifyingID"] = ctx.FormString("verify_gpg")
|
ctx.Data["VerifyingID"] = ctx.FormString("verify_gpg")
|
||||||
|
ctx.Data["VerifyingFingerprint"] = ctx.FormString("verify_ssh")
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,12 +349,13 @@ func (f *AddOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding
|
||||||
|
|
||||||
// AddKeyForm form for adding SSH/GPG key
|
// AddKeyForm form for adding SSH/GPG key
|
||||||
type AddKeyForm struct {
|
type AddKeyForm struct {
|
||||||
Type string `binding:"OmitEmpty"`
|
Type string `binding:"OmitEmpty"`
|
||||||
Title string `binding:"Required;MaxSize(50)"`
|
Title string `binding:"Required;MaxSize(50)"`
|
||||||
Content string `binding:"Required"`
|
Content string `binding:"Required"`
|
||||||
Signature string `binding:"OmitEmpty"`
|
Signature string `binding:"OmitEmpty"`
|
||||||
KeyID string `binding:"OmitEmpty"`
|
KeyID string `binding:"OmitEmpty"`
|
||||||
IsWritable bool
|
Fingerprint string `binding:"OmitEmpty"`
|
||||||
|
IsWritable bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the fields
|
// Validate validates the fields
|
||||||
|
|
|
@ -109,17 +109,32 @@
|
||||||
{{if .Verification.Verified}}
|
{{if .Verification.Verified}}
|
||||||
{{if ne .Verification.SigningUser.ID 0}}
|
{{if ne .Verification.SigningUser.ID 0}}
|
||||||
{{svg "octicon-shield-check" 16 "mr-3"}}
|
{{svg "octicon-shield-check" 16 "mr-3"}}
|
||||||
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
|
{{if .Verification.SigningSSHKey}}
|
||||||
{{.Verification.SigningKey.KeyID}}
|
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.ssh_key_fingerprint"}}:</span>
|
||||||
|
{{.Verification.SigningSSHKey.Fingerprint}}
|
||||||
|
{{else}}
|
||||||
|
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
|
||||||
|
{{.Verification.SigningKey.KeyID}}
|
||||||
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{svg "octicon-shield-lock" 16 "mr-3"}}
|
{{svg "octicon-shield-lock" 16 "mr-3"}}
|
||||||
<span class="ui text mr-3 tooltip" data-content="{{.i18n.Tr "gpg.default_key"}}">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
|
{{if .Verification.SigningSSHKey}}
|
||||||
{{.Verification.SigningKey.KeyID}}
|
<span class="ui text mr-3 tooltip" data-content="{{.i18n.Tr "gpg.default_key"}}">{{.i18n.Tr "repo.commits.ssh_key_fingerprint"}}:</span>
|
||||||
|
{{.Verification.SigningSSHKey.Fingerprint}}
|
||||||
|
{{else}}
|
||||||
|
<span class="ui text mr-3 tooltip" data-content="{{.i18n.Tr "gpg.default_key"}}">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
|
||||||
|
{{.Verification.SigningKey.KeyID}}
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if .Verification.Warning}}
|
{{else if .Verification.Warning}}
|
||||||
{{svg "octicon-shield" 16 "mr-3"}}
|
{{svg "octicon-shield" 16 "mr-3"}}
|
||||||
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
|
{{if .Verification.SigningSSHKey}}
|
||||||
{{.Verification.SigningKey.KeyID}}
|
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.ssh_key_fingerprint"}}:</span>
|
||||||
|
{{.Verification.SigningSSHKey.Fingerprint}}
|
||||||
|
{{else}}
|
||||||
|
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
|
||||||
|
{{.Verification.SigningKey.KeyID}}
|
||||||
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{if .Verification.SigningKey}}
|
{{if .Verification.SigningKey}}
|
||||||
{{if ne .Verification.SigningKey.KeyID ""}}
|
{{if ne .Verification.SigningKey.KeyID ""}}
|
||||||
|
@ -128,6 +143,13 @@
|
||||||
{{.Verification.SigningKey.KeyID}}
|
{{.Verification.SigningKey.KeyID}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if .Verification.SigningSSHKey}}
|
||||||
|
{{if ne .Verification.SigningSSHKey.Fingerprint ""}}
|
||||||
|
{{svg "octicon-shield" 16 "mr-3"}}
|
||||||
|
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.ssh_key_fingerprint"}}:</span>
|
||||||
|
{{.Verification.SigningSSHKey.Fingerprint}}
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -41,11 +41,18 @@
|
||||||
<button class="ui red tiny button delete-button{{if index $.ExternalKeys $index}} disabled{{end}}" data-modal-id="delete-ssh" data-url="{{$.Link}}/delete?type=ssh" data-id="{{.ID}}"{{if index $.ExternalKeys $index}} title="{{$.i18n.Tr "settings.ssh_externally_managed"}}"{{end}}>
|
<button class="ui red tiny button delete-button{{if index $.ExternalKeys $index}} disabled{{end}}" data-modal-id="delete-ssh" data-url="{{$.Link}}/delete?type=ssh" data-id="{{.ID}}"{{if index $.ExternalKeys $index}} title="{{$.i18n.Tr "settings.ssh_externally_managed"}}"{{end}}>
|
||||||
{{$.i18n.Tr "settings.delete_key"}}
|
{{$.i18n.Tr "settings.delete_key"}}
|
||||||
</button>
|
</button>
|
||||||
|
{{if and (not .Verified) (ne $.VerifyingFingerprint .Fingerprint)}}
|
||||||
|
<a class="ui blue tiny show-panel button" href="{{$.Link}}?verify_ssh={{.Fingerprint}}">{{$.i18n.Tr "settings.ssh_key_verify"}}</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="left floated content">
|
<div class="left floated content">
|
||||||
<span class="{{if .HasRecentActivity}}green{{end}}" {{if .HasRecentActivity}}data-content="{{$.i18n.Tr "settings.key_state_desc"}}" data-variation="inverted tiny"{{end}}>{{svg "octicon-key" 32}}</span>
|
<span class="{{if .HasRecentActivity}}green{{end}}" {{if .HasRecentActivity}}data-content="{{$.i18n.Tr "settings.key_state_desc"}}" data-variation="inverted tiny"{{end}}>{{svg "octicon-key" 32}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
{{if .Verified}}
|
||||||
|
<span class="tooltip" data-content="{{$.i18n.Tr "settings.ssh_key_verified_long"}}">{{svg "octicon-shield-check"}} <strong>{{$.i18n.Tr "settings.ssh_key_verified"}}</strong></span>
|
||||||
|
{{end}}
|
||||||
<strong>{{.Name}}</strong>
|
<strong>{{.Name}}</strong>
|
||||||
<div class="print meta">
|
<div class="print meta">
|
||||||
{{.Fingerprint}}
|
{{.Fingerprint}}
|
||||||
|
@ -55,6 +62,37 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{if and (not .Verified) (eq $.VerifyingFingerprint .Fingerprint)}}
|
||||||
|
<div class="ui segment">
|
||||||
|
<h4>{{$.i18n.Tr "settings.ssh_token_required"}}</h4>
|
||||||
|
<form class="ui form{{if $.HasSSHVerifyError}} error{{end}}" action="{{$.Link}}" method="post">
|
||||||
|
{{$.CsrfTokenHtml}}
|
||||||
|
<input type="hidden" name="title" value="none">
|
||||||
|
<input type="hidden" name="content" value="{{.Content}}">
|
||||||
|
<input type="hidden" name="fingerprint" value="{{.Fingerprint}}">
|
||||||
|
<div class="field">
|
||||||
|
<label for="token">{{$.i18n.Tr "settings.ssh_token"}}</label>
|
||||||
|
<input readonly="" value="{{$.TokenToSign}}">
|
||||||
|
<div class="help">
|
||||||
|
<p>{{$.i18n.Tr "settings.ssh_token_help"}}</p>
|
||||||
|
<p><code>{{$.i18n.Tr "settings.ssh_token_code" $.TokenToSign}}</code></p>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label for="signature">{{$.i18n.Tr "settings.ssh_token_signature"}}</label>
|
||||||
|
<textarea id="ssh-key-signature" name="signature" placeholder="{{$.i18n.Tr "settings.key_signature_ssh_placeholder"}}" required>{{$.signature}}</textarea>
|
||||||
|
</div>
|
||||||
|
<input name="type" type="hidden" value="verify_ssh">
|
||||||
|
<button class="ui green button">
|
||||||
|
{{$.i18n.Tr "settings.ssh_key_verify"}}
|
||||||
|
</button>
|
||||||
|
<a class="ui red button" href="{{$.Link}}">
|
||||||
|
{{$.i18n.Tr "settings.cancel"}}
|
||||||
|
</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Armored ssh signatures in go
|
||||||
|
|
||||||
|
[![Go Reference](https://pkg.go.dev/badge/github.com/42wim/sshsig.svg)](https://pkg.go.dev/github.com/42wim/sshsig#section-documentation)
|
||||||
|
|
||||||
|
Package sshsig implements signing/verifying armored SSH signatures.
|
||||||
|
You can use this package to sign data and verify signatures using your ssh private keys or your ssh agent.
|
||||||
|
It gives the same output as using `ssh-keygen`, eg when signing `ssh-keygen -Y sign -f keyfile -n namespace data`
|
||||||
|
|
||||||
|
This code is based upon work by <https://github.com/sigstore/rekor>
|
||||||
|
|
||||||
|
References: <https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig>
|
||||||
|
|
||||||
|
You can find some examples on how to use this library on: <https://pkg.go.dev/github.com/42wim/sshsig#pkg-examples>
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```golang
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/42wim/sshsig"
|
||||||
|
"golang.org/x/crypto/ssh/agent"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleSignWithAgent() {
|
||||||
|
// This example will panic when you don't have a ssh-agent running.
|
||||||
|
conn, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ag := agent.NewClient(conn)
|
||||||
|
|
||||||
|
// This public key must match in your agent (use `ssh-add -L` to get the public key)
|
||||||
|
pubkey := []byte(`ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAo3D7CGN01tTYY/dLKXEv8RxRyxa32c51X0uKMhnMab wim@localhost`)
|
||||||
|
//
|
||||||
|
data := []byte("hello world")
|
||||||
|
|
||||||
|
res, err := sshsig.SignWithAgent(pubkey, ag, bytes.NewBuffer(data), "file")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(string(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleSign() {
|
||||||
|
privkey := []byte(`-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||||
|
QyNTUxOQAAACCOjP6i4Pm/pYAAmpAMNZ6xrbHl9RW8xdul6kzIWuKMMAAAAIhoQm34aEJt
|
||||||
|
+AAAAAtzc2gtZWQyNTUxOQAAACCOjP6i4Pm/pYAAmpAMNZ6xrbHl9RW8xdul6kzIWuKMMA
|
||||||
|
AAAEBfIl93TLj6qHeg37GnPuZ00h8OVv1mzlhy0rhuO4Y0do6M/qLg+b+lgACakAw1nrGt
|
||||||
|
seX1FbzF26XqTMha4owwAAAAAAECAwQF
|
||||||
|
-----END OPENSSH PRIVATE KEY-----`)
|
||||||
|
|
||||||
|
data := []byte("hello world")
|
||||||
|
|
||||||
|
res, err := sshsig.Sign(privkey, bytes.NewBuffer(data), "file")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(string(res))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// -----BEGIN SSH SIGNATURE-----
|
||||||
|
// U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgjoz+ouD5v6WAAJqQDDWesa2x5f
|
||||||
|
// UVvMXbpepMyFrijDAAAAAEZmlsZQAAAAAAAAAGc2hhNTEyAAAAUwAAAAtzc2gtZWQyNTUx
|
||||||
|
// OQAAAEBeu9Z+vLxBORysiqEbTzJP0EZKG0/aE5HpTtvimjQS6mHZCAGFg+kimNatBE0Y1j
|
||||||
|
// gS4pfD73TlML1SyB5lb/YO
|
||||||
|
// -----END SSH SIGNATURE-----
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ExampleSign()
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
Package sshsig implements signing/verifying armored SSH signatures.
|
||||||
|
You can use this package to sign data and verify signatures using your ssh private keys or your ssh agent.
|
||||||
|
It gives the same output as using `ssh-keygen`, eg when signing `ssh-keygen -Y sign -f keyfile -n namespace data`
|
||||||
|
|
||||||
|
This code is based upon work by https://github.com/sigstore/rekor
|
||||||
|
|
||||||
|
References:
|
||||||
|
- https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig
|
||||||
|
*/
|
||||||
|
package sshsig
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Modified by 42wim
|
||||||
|
//
|
||||||
|
// Copyright 2021 The Sigstore Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sshsig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/42wim/sshsig/pem"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
pemType = "SSH SIGNATURE"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Armored returns the signature in an armored format.
|
||||||
|
func Armor(s *ssh.Signature, p ssh.PublicKey, ns string) []byte {
|
||||||
|
sig := WrappedSig{
|
||||||
|
Version: 1,
|
||||||
|
PublicKey: string(p.Marshal()),
|
||||||
|
Namespace: ns,
|
||||||
|
HashAlgorithm: defaultHashAlgorithm,
|
||||||
|
Signature: string(ssh.Marshal(s)),
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(sig.MagicHeader[:], magicHeader)
|
||||||
|
|
||||||
|
enc := pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: pemType,
|
||||||
|
Bytes: ssh.Marshal(sig),
|
||||||
|
})
|
||||||
|
return enc
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode parses an armored signature.
|
||||||
|
func Decode(b []byte) (*Signature, error) {
|
||||||
|
pemBlock, _ := pem.Decode(b)
|
||||||
|
if pemBlock == nil {
|
||||||
|
return nil, errors.New("unable to decode pem file")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pemBlock.Type != pemType {
|
||||||
|
return nil, fmt.Errorf("wrong pem block type: %s. Expected SSH-SIGNATURE", pemBlock.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we unmarshal it into the Signature block
|
||||||
|
sig := WrappedSig{}
|
||||||
|
if err := ssh.Unmarshal(pemBlock.Bytes, &sig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if sig.Version != 1 {
|
||||||
|
return nil, fmt.Errorf("unsupported signature version: %d", sig.Version)
|
||||||
|
}
|
||||||
|
if string(sig.MagicHeader[:]) != magicHeader {
|
||||||
|
return nil, fmt.Errorf("invalid magic header: %s", sig.MagicHeader[:])
|
||||||
|
}
|
||||||
|
if _, ok := supportedHashAlgorithms[sig.HashAlgorithm]; !ok {
|
||||||
|
return nil, fmt.Errorf("unsupported hash algorithm: %s", sig.HashAlgorithm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we can unpack the Signature and PublicKey blocks
|
||||||
|
sshSig := ssh.Signature{}
|
||||||
|
if err := ssh.Unmarshal([]byte(sig.Signature), &sshSig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// TODO: check the format here (should be rsa-sha512)
|
||||||
|
|
||||||
|
pk, err := ssh.ParsePublicKey([]byte(sig.PublicKey))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Signature{
|
||||||
|
signature: &sshSig,
|
||||||
|
pk: pk,
|
||||||
|
hashAlg: sig.HashAlgorithm,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
module github.com/42wim/sshsig
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect
|
|
@ -0,0 +1,12 @@
|
||||||
|
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
|
||||||
|
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI=
|
||||||
|
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
@ -0,0 +1,346 @@
|
||||||
|
// Modified by 42wim
|
||||||
|
//
|
||||||
|
// Copyright 2009 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 pem implements the PEM data encoding, which originated in Privacy
|
||||||
|
// Enhanced Mail. The most common use of PEM encoding today is in TLS keys and
|
||||||
|
// certificates. See RFC 1421.
|
||||||
|
package pem
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Block represents a PEM encoded structure.
|
||||||
|
//
|
||||||
|
// The encoded form is:
|
||||||
|
// -----BEGIN Type-----
|
||||||
|
// Headers
|
||||||
|
// base64-encoded Bytes
|
||||||
|
// -----END Type-----
|
||||||
|
// where Headers is a possibly empty sequence of Key: Value lines.
|
||||||
|
type Block struct {
|
||||||
|
Type string // The type, taken from the preamble (i.e. "RSA PRIVATE KEY").
|
||||||
|
Headers map[string]string // Optional headers.
|
||||||
|
Bytes []byte // The decoded bytes of the contents. Typically a DER encoded ASN.1 structure.
|
||||||
|
}
|
||||||
|
|
||||||
|
// getLine results the first \r\n or \n delineated line from the given byte
|
||||||
|
// array. The line does not include trailing whitespace or the trailing new
|
||||||
|
// line bytes. The remainder of the byte array (also not including the new line
|
||||||
|
// bytes) is also returned and this will always be smaller than the original
|
||||||
|
// argument.
|
||||||
|
func getLine(data []byte) (line, rest []byte) {
|
||||||
|
i := bytes.IndexByte(data, '\n')
|
||||||
|
var j int
|
||||||
|
if i < 0 {
|
||||||
|
i = len(data)
|
||||||
|
j = i
|
||||||
|
} else {
|
||||||
|
j = i + 1
|
||||||
|
if i > 0 && data[i-1] == '\r' {
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytes.TrimRight(data[0:i], " \t"), data[j:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeSpacesAndTabs returns a copy of its input with all spaces and tabs
|
||||||
|
// removed, if there were any. Otherwise, the input is returned unchanged.
|
||||||
|
//
|
||||||
|
// The base64 decoder already skips newline characters, so we don't need to
|
||||||
|
// filter them out here.
|
||||||
|
func removeSpacesAndTabs(data []byte) []byte {
|
||||||
|
if !bytes.ContainsAny(data, " \t") {
|
||||||
|
// Fast path; most base64 data within PEM contains newlines, but
|
||||||
|
// no spaces nor tabs. Skip the extra alloc and work.
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
result := make([]byte, len(data))
|
||||||
|
n := 0
|
||||||
|
|
||||||
|
for _, b := range data {
|
||||||
|
if b == ' ' || b == '\t' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result[n] = b
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
|
||||||
|
return result[0:n]
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pemStart = []byte("\n-----BEGIN ")
|
||||||
|
pemEnd = []byte("\n-----END ")
|
||||||
|
pemEndOfLine = []byte("-----")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Decode will find the next PEM formatted block (certificate, private key
|
||||||
|
// etc) in the input. It returns that block and the remainder of the input. If
|
||||||
|
// no PEM data is found, p is nil and the whole of the input is returned in
|
||||||
|
// rest.
|
||||||
|
func Decode(data []byte) (p *Block, rest []byte) {
|
||||||
|
// pemStart begins with a newline. However, at the very beginning of
|
||||||
|
// the byte array, we'll accept the start string without it.
|
||||||
|
rest = data
|
||||||
|
if bytes.HasPrefix(data, pemStart[1:]) {
|
||||||
|
rest = rest[len(pemStart)-1 : len(data)]
|
||||||
|
} else if i := bytes.Index(data, pemStart); i >= 0 {
|
||||||
|
rest = rest[i+len(pemStart) : len(data)]
|
||||||
|
} else {
|
||||||
|
return nil, data
|
||||||
|
}
|
||||||
|
|
||||||
|
typeLine, rest := getLine(rest)
|
||||||
|
if !bytes.HasSuffix(typeLine, pemEndOfLine) {
|
||||||
|
return decodeError(data, rest)
|
||||||
|
}
|
||||||
|
typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
|
||||||
|
|
||||||
|
p = &Block{
|
||||||
|
Headers: make(map[string]string),
|
||||||
|
Type: string(typeLine),
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
// This loop terminates because getLine's second result is
|
||||||
|
// always smaller than its argument.
|
||||||
|
if len(rest) == 0 {
|
||||||
|
return nil, data
|
||||||
|
}
|
||||||
|
line, next := getLine(rest)
|
||||||
|
|
||||||
|
i := bytes.IndexByte(line, ':')
|
||||||
|
if i == -1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(agl): need to cope with values that spread across lines.
|
||||||
|
key, val := line[:i], line[i+1:]
|
||||||
|
key = bytes.TrimSpace(key)
|
||||||
|
val = bytes.TrimSpace(val)
|
||||||
|
p.Headers[string(key)] = string(val)
|
||||||
|
rest = next
|
||||||
|
}
|
||||||
|
|
||||||
|
var endIndex, endTrailerIndex int
|
||||||
|
|
||||||
|
// If there were no headers, the END line might occur
|
||||||
|
// immediately, without a leading newline.
|
||||||
|
if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
|
||||||
|
endIndex = 0
|
||||||
|
endTrailerIndex = len(pemEnd) - 1
|
||||||
|
} else {
|
||||||
|
endIndex = bytes.Index(rest, pemEnd)
|
||||||
|
endTrailerIndex = endIndex + len(pemEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
if endIndex < 0 {
|
||||||
|
return decodeError(data, rest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// After the "-----" of the ending line, there should be the same type
|
||||||
|
// and then a final five dashes.
|
||||||
|
endTrailer := rest[endTrailerIndex:]
|
||||||
|
endTrailerLen := len(typeLine) + len(pemEndOfLine)
|
||||||
|
if len(endTrailer) < endTrailerLen {
|
||||||
|
return decodeError(data, rest)
|
||||||
|
}
|
||||||
|
|
||||||
|
restOfEndLine := endTrailer[endTrailerLen:]
|
||||||
|
endTrailer = endTrailer[:endTrailerLen]
|
||||||
|
if !bytes.HasPrefix(endTrailer, typeLine) ||
|
||||||
|
!bytes.HasSuffix(endTrailer, pemEndOfLine) {
|
||||||
|
return decodeError(data, rest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The line must end with only whitespace.
|
||||||
|
if s, _ := getLine(restOfEndLine); len(s) != 0 {
|
||||||
|
return decodeError(data, rest)
|
||||||
|
}
|
||||||
|
|
||||||
|
base64Data := removeSpacesAndTabs(rest[:endIndex])
|
||||||
|
p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
|
||||||
|
n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
|
||||||
|
if err != nil {
|
||||||
|
return decodeError(data, rest)
|
||||||
|
}
|
||||||
|
p.Bytes = p.Bytes[:n]
|
||||||
|
|
||||||
|
// the -1 is because we might have only matched pemEnd without the
|
||||||
|
// leading newline if the PEM block was empty.
|
||||||
|
_, rest = getLine(rest[endIndex+len(pemEnd)-1:])
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeError(data, rest []byte) (*Block, []byte) {
|
||||||
|
// If we get here then we have rejected a likely looking, but
|
||||||
|
// ultimately invalid PEM block. We need to start over from a new
|
||||||
|
// position. We have consumed the preamble line and will have consumed
|
||||||
|
// any lines which could be header lines. However, a valid preamble
|
||||||
|
// line is not a valid header line, therefore we cannot have consumed
|
||||||
|
// the preamble line for the any subsequent block. Thus, we will always
|
||||||
|
// find any valid block, no matter what bytes precede it.
|
||||||
|
//
|
||||||
|
// For example, if the input is
|
||||||
|
//
|
||||||
|
// -----BEGIN MALFORMED BLOCK-----
|
||||||
|
// junk that may look like header lines
|
||||||
|
// or data lines, but no END line
|
||||||
|
//
|
||||||
|
// -----BEGIN ACTUAL BLOCK-----
|
||||||
|
// realdata
|
||||||
|
// -----END ACTUAL BLOCK-----
|
||||||
|
//
|
||||||
|
// we've failed to parse using the first BEGIN line
|
||||||
|
// and now will try again, using the second BEGIN line.
|
||||||
|
p, rest := Decode(rest)
|
||||||
|
if p == nil {
|
||||||
|
rest = data
|
||||||
|
}
|
||||||
|
return p, rest
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig#L20-L21
|
||||||
|
// Should be on 76 chars, but strangely enough ssh breaks on 70
|
||||||
|
const pemLineLength = 70
|
||||||
|
|
||||||
|
type lineBreaker struct {
|
||||||
|
line [pemLineLength]byte
|
||||||
|
used int
|
||||||
|
out io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
var nl = []byte{'\n'}
|
||||||
|
|
||||||
|
func (l *lineBreaker) Write(b []byte) (n int, err error) {
|
||||||
|
if l.used+len(b) < pemLineLength {
|
||||||
|
copy(l.line[l.used:], b)
|
||||||
|
l.used += len(b)
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = l.out.Write(l.line[0:l.used])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
excess := pemLineLength - l.used
|
||||||
|
l.used = 0
|
||||||
|
|
||||||
|
n, err = l.out.Write(b[0:excess])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = l.out.Write(nl)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.Write(b[excess:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *lineBreaker) Close() (err error) {
|
||||||
|
if l.used > 0 {
|
||||||
|
_, err = l.out.Write(l.line[0:l.used])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = l.out.Write(nl)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeHeader(out io.Writer, k, v string) error {
|
||||||
|
_, err := out.Write([]byte(k + ": " + v + "\n"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode writes the PEM encoding of b to out.
|
||||||
|
func Encode(out io.Writer, b *Block) error {
|
||||||
|
// Check for invalid block before writing any output.
|
||||||
|
for k := range b.Headers {
|
||||||
|
if strings.Contains(k, ":") {
|
||||||
|
return errors.New("pem: cannot encode a header key that contains a colon")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All errors below are relayed from underlying io.Writer,
|
||||||
|
// so it is now safe to write data.
|
||||||
|
|
||||||
|
if _, err := out.Write(pemStart[1:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := out.Write([]byte(b.Type + "-----\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(b.Headers) > 0 {
|
||||||
|
const procType = "Proc-Type"
|
||||||
|
h := make([]string, 0, len(b.Headers))
|
||||||
|
hasProcType := false
|
||||||
|
for k := range b.Headers {
|
||||||
|
if k == procType {
|
||||||
|
hasProcType = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
h = append(h, k)
|
||||||
|
}
|
||||||
|
// The Proc-Type header must be written first.
|
||||||
|
// See RFC 1421, section 4.6.1.1
|
||||||
|
if hasProcType {
|
||||||
|
if err := writeHeader(out, procType, b.Headers[procType]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For consistency of output, write other headers sorted by key.
|
||||||
|
sort.Strings(h)
|
||||||
|
for _, k := range h {
|
||||||
|
if err := writeHeader(out, k, b.Headers[k]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := out.Write(nl); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var breaker lineBreaker
|
||||||
|
breaker.out = out
|
||||||
|
|
||||||
|
b64 := base64.NewEncoder(base64.StdEncoding, &breaker)
|
||||||
|
if _, err := b64.Write(b.Bytes); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b64.Close()
|
||||||
|
breaker.Close()
|
||||||
|
|
||||||
|
if _, err := out.Write(pemEnd[1:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err := out.Write([]byte(b.Type + "-----\n"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeToMemory returns the PEM encoding of b.
|
||||||
|
//
|
||||||
|
// If b has invalid headers and cannot be encoded,
|
||||||
|
// EncodeToMemory returns nil. If it is important to
|
||||||
|
// report details about this error case, use Encode instead.
|
||||||
|
func EncodeToMemory(b *Block) []byte {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := Encode(&buf, b); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
// Modifications by 42wim
|
||||||
|
//
|
||||||
|
// Copyright 2021 The Sigstore Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sshsig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"errors"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
"golang.org/x/crypto/ssh/agent"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig#L81
|
||||||
|
type MessageWrapper struct {
|
||||||
|
Namespace string
|
||||||
|
Reserved string
|
||||||
|
HashAlgorithm string
|
||||||
|
Hash string
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig#L34
|
||||||
|
type WrappedSig struct {
|
||||||
|
MagicHeader [6]byte
|
||||||
|
Version uint32
|
||||||
|
PublicKey string
|
||||||
|
Namespace string
|
||||||
|
Reserved string
|
||||||
|
HashAlgorithm string
|
||||||
|
Signature string
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
magicHeader = "SSHSIG"
|
||||||
|
defaultHashAlgorithm = "sha512"
|
||||||
|
)
|
||||||
|
|
||||||
|
var supportedHashAlgorithms = map[string]func() hash.Hash{
|
||||||
|
"sha256": sha256.New,
|
||||||
|
"sha512": sha512.New,
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapData(m io.Reader, ns string) ([]byte, error) {
|
||||||
|
hf := sha512.New()
|
||||||
|
if _, err := io.Copy(hf, m); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mh := hf.Sum(nil)
|
||||||
|
|
||||||
|
sp := MessageWrapper{
|
||||||
|
Namespace: ns,
|
||||||
|
HashAlgorithm: defaultHashAlgorithm,
|
||||||
|
Hash: string(mh),
|
||||||
|
}
|
||||||
|
|
||||||
|
dataMessageWrapper := ssh.Marshal(sp)
|
||||||
|
dataMessageWrapper = append([]byte(magicHeader), dataMessageWrapper...)
|
||||||
|
|
||||||
|
return dataMessageWrapper, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sign(s ssh.AlgorithmSigner, m io.Reader, ns string) (*ssh.Signature, error) {
|
||||||
|
dataMessageWrapper, err := wrapData(m, ns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// ssh-rsa is not supported for RSA keys:
|
||||||
|
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig#L71
|
||||||
|
// We can use the default value of "" for other key types though.
|
||||||
|
algo := ""
|
||||||
|
if s.PublicKey().Type() == ssh.KeyAlgoRSA {
|
||||||
|
algo = ssh.SigAlgoRSASHA2512
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.SignWithAlgorithm(rand.Reader, dataMessageWrapper, algo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func signAgent(pk ssh.PublicKey, ag agent.Agent, m io.Reader, ns string) (*ssh.Signature, error) {
|
||||||
|
dataMessageWrapper, err := wrapData(m, ns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var sigFlag agent.SignatureFlags
|
||||||
|
if pk.Type() == ssh.KeyAlgoRSA {
|
||||||
|
sigFlag = agent.SignatureFlagRsaSha512
|
||||||
|
}
|
||||||
|
|
||||||
|
agExt, ok := ag.(agent.ExtendedAgent)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("couldn't cast to ExtendedAgent")
|
||||||
|
}
|
||||||
|
|
||||||
|
return agExt.SignWithFlags(pk, dataMessageWrapper, sigFlag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignWithAgent asks the ssh Agent to sign the data with the signer matching the given publicKey and returns an armored signature.
|
||||||
|
// The purpose of the namespace value is to specify a unambiguous
|
||||||
|
// interpretation domain for the signature, e.g. file signing.
|
||||||
|
// This prevents cross-protocol attacks caused by signatures
|
||||||
|
// intended for one intended domain being accepted in another.
|
||||||
|
// If empty, the default is "file".
|
||||||
|
// This can be compared with `ssh-keygen -Y sign -f keyfile -n namespace data`
|
||||||
|
func SignWithAgent(publicKey []byte, ag agent.Agent, data io.Reader, namespace string) ([]byte, error) {
|
||||||
|
pk, _, _, _, err := ssh.ParseAuthorizedKey(publicKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if namespace == "" {
|
||||||
|
namespace = defaultNamespace
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := signAgent(pk, ag, data, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
armored := Armor(sig, pk, namespace)
|
||||||
|
return armored, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the data with the given private key in PEM format and returns an armored signature.
|
||||||
|
// The purpose of the namespace value is to specify a unambiguous
|
||||||
|
// interpretation domain for the signature, e.g. file signing.
|
||||||
|
// This prevents cross-protocol attacks caused by signatures
|
||||||
|
// intended for one intended domain being accepted in another.
|
||||||
|
// If empty, the default is "file".
|
||||||
|
// This can be compared with `ssh-keygen -Y sign -f keyfile -n namespace data`
|
||||||
|
func Sign(pemBytes []byte, data io.Reader, namespace string) ([]byte, error) {
|
||||||
|
s, err := ssh.ParsePrivateKey(pemBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
as, ok := s.(ssh.AlgorithmSigner)
|
||||||
|
if !ok {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if namespace == "" {
|
||||||
|
namespace = defaultNamespace
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := sign(as, data, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
armored := Armor(sig, s.PublicKey(), namespace)
|
||||||
|
return armored, nil
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// modified by 42wim
|
||||||
|
//
|
||||||
|
// Copyright 2021 The Sigstore Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sshsig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Signature struct {
|
||||||
|
signature *ssh.Signature
|
||||||
|
pk ssh.PublicKey
|
||||||
|
hashAlg string
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultNamespace = "file"
|
|
@ -0,0 +1,56 @@
|
||||||
|
//
|
||||||
|
// Copyright 2021 The Sigstore Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sshsig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verify verifies the signature of the given data and the armored signature using the given public key and the namespace.
|
||||||
|
// If the namespace is empty, the default namespace (file) is used.
|
||||||
|
func Verify(message io.Reader, armoredSignature []byte, publicKey []byte, namespace string) error {
|
||||||
|
if namespace == "" {
|
||||||
|
namespace = defaultNamespace
|
||||||
|
}
|
||||||
|
|
||||||
|
decodedSignature, err := Decode(armoredSignature)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
desiredPk, _, _, _, err := ssh.ParseAuthorizedKey(publicKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash the message so we can verify it against the signature.
|
||||||
|
h := supportedHashAlgorithms[decodedSignature.hashAlg]()
|
||||||
|
if _, err := io.Copy(h, message); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
hm := h.Sum(nil)
|
||||||
|
|
||||||
|
toVerify := MessageWrapper{
|
||||||
|
Namespace: namespace,
|
||||||
|
HashAlgorithm: decodedSignature.hashAlg,
|
||||||
|
Hash: string(hm),
|
||||||
|
}
|
||||||
|
signedMessage := ssh.Marshal(toVerify)
|
||||||
|
signedMessage = append([]byte(magicHeader), signedMessage...)
|
||||||
|
return desiredPk.Verify(signedMessage, decodedSignature.signature)
|
||||||
|
}
|
|
@ -15,7 +15,7 @@
|
||||||
// used with a fixed key in order to generate one-time keys from an nonce.
|
// used with a fixed key in order to generate one-time keys from an nonce.
|
||||||
// However, in this package AES isn't used and the one-time key is specified
|
// However, in this package AES isn't used and the one-time key is specified
|
||||||
// directly.
|
// directly.
|
||||||
package poly1305 // import "golang.org/x/crypto/poly1305"
|
package poly1305
|
||||||
|
|
||||||
import "crypto/subtle"
|
import "crypto/subtle"
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
// value. These limbs are, for the most part, zero extended and
|
// value. These limbs are, for the most part, zero extended and
|
||||||
// placed into 64-bit vector register elements. Each vector
|
// placed into 64-bit vector register elements. Each vector
|
||||||
// register is 128-bits wide and so holds 2 of these elements.
|
// register is 128-bits wide and so holds 2 of these elements.
|
||||||
// Using 26-bit limbs allows us plenty of headroom to accomodate
|
// Using 26-bit limbs allows us plenty of headroom to accommodate
|
||||||
// accumulations before and after multiplication without
|
// accumulations before and after multiplication without
|
||||||
// overflowing either 32-bits (before multiplication) or 64-bits
|
// overflowing either 32-bits (before multiplication) or 64-bits
|
||||||
// (after multiplication).
|
// (after multiplication).
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These constants from [PROTOCOL.certkeys] represent the algorithm names
|
// These constants from [PROTOCOL.certkeys] represent the key algorithm names
|
||||||
// for certificate types supported by this package.
|
// for certificate types supported by this package.
|
||||||
const (
|
const (
|
||||||
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
||||||
|
@ -27,6 +27,14 @@ const (
|
||||||
CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
|
CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// These constants from [PROTOCOL.certkeys] represent additional signature
|
||||||
|
// algorithm names for certificate types supported by this package.
|
||||||
|
const (
|
||||||
|
CertSigAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
||||||
|
CertSigAlgoRSASHA2256v01 = "rsa-sha2-256-cert-v01@openssh.com"
|
||||||
|
CertSigAlgoRSASHA2512v01 = "rsa-sha2-512-cert-v01@openssh.com"
|
||||||
|
)
|
||||||
|
|
||||||
// Certificate types distinguish between host and user
|
// Certificate types distinguish between host and user
|
||||||
// certificates. The values can be set in the CertType field of
|
// certificates. The values can be set in the CertType field of
|
||||||
// Certificate.
|
// Certificate.
|
||||||
|
@ -423,6 +431,12 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
||||||
}
|
}
|
||||||
c.SignatureKey = authority.PublicKey()
|
c.SignatureKey = authority.PublicKey()
|
||||||
|
|
||||||
|
if v, ok := authority.(AlgorithmSigner); ok {
|
||||||
|
if v.PublicKey().Type() == KeyAlgoRSA {
|
||||||
|
authority = &rsaSigner{v, SigAlgoRSASHA2512}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sig, err := authority.Sign(rand, c.bytesForSigning())
|
sig, err := authority.Sign(rand, c.bytesForSigning())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -431,8 +445,14 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// certAlgoNames includes a mapping from signature algorithms to the
|
||||||
|
// corresponding certificate signature algorithm. When a key type (such
|
||||||
|
// as ED25516) is associated with only one algorithm, the KeyAlgo
|
||||||
|
// constant is used instead of the SigAlgo.
|
||||||
var certAlgoNames = map[string]string{
|
var certAlgoNames = map[string]string{
|
||||||
KeyAlgoRSA: CertAlgoRSAv01,
|
SigAlgoRSA: CertSigAlgoRSAv01,
|
||||||
|
SigAlgoRSASHA2256: CertSigAlgoRSASHA2256v01,
|
||||||
|
SigAlgoRSASHA2512: CertSigAlgoRSASHA2512v01,
|
||||||
KeyAlgoDSA: CertAlgoDSAv01,
|
KeyAlgoDSA: CertAlgoDSAv01,
|
||||||
KeyAlgoECDSA256: CertAlgoECDSA256v01,
|
KeyAlgoECDSA256: CertAlgoECDSA256v01,
|
||||||
KeyAlgoECDSA384: CertAlgoECDSA384v01,
|
KeyAlgoECDSA384: CertAlgoECDSA384v01,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"golang.org/x/crypto/chacha20"
|
"golang.org/x/crypto/chacha20"
|
||||||
"golang.org/x/crypto/poly1305"
|
"golang.org/x/crypto/internal/poly1305"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -115,12 +115,25 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e
|
||||||
|
|
||||||
// verifyHostKeySignature verifies the host key obtained in the key
|
// verifyHostKeySignature verifies the host key obtained in the key
|
||||||
// exchange.
|
// exchange.
|
||||||
func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error {
|
func verifyHostKeySignature(hostKey PublicKey, algo string, result *kexResult) error {
|
||||||
sig, rest, ok := parseSignatureBody(result.Signature)
|
sig, rest, ok := parseSignatureBody(result.Signature)
|
||||||
if len(rest) > 0 || !ok {
|
if len(rest) > 0 || !ok {
|
||||||
return errors.New("ssh: signature parse error")
|
return errors.New("ssh: signature parse error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For keys, underlyingAlgo is exactly algo. For certificates,
|
||||||
|
// we have to look up the underlying key algorithm that SSH
|
||||||
|
// uses to evaluate signatures.
|
||||||
|
underlyingAlgo := algo
|
||||||
|
for sigAlgo, certAlgo := range certAlgoNames {
|
||||||
|
if certAlgo == algo {
|
||||||
|
underlyingAlgo = sigAlgo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sig.Format != underlyingAlgo {
|
||||||
|
return fmt.Errorf("ssh: invalid signature algorithm %q, expected %q", sig.Format, underlyingAlgo)
|
||||||
|
}
|
||||||
|
|
||||||
return hostKey.Verify(result.H, sig)
|
return hostKey.Verify(result.H, sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,11 +69,13 @@ var preferredKexAlgos = []string{
|
||||||
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
|
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
|
||||||
// of authenticating servers) in preference order.
|
// of authenticating servers) in preference order.
|
||||||
var supportedHostKeyAlgos = []string{
|
var supportedHostKeyAlgos = []string{
|
||||||
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
|
CertSigAlgoRSASHA2512v01, CertSigAlgoRSASHA2256v01,
|
||||||
|
CertSigAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
|
||||||
CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
|
CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
|
||||||
|
|
||||||
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
|
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
|
||||||
KeyAlgoRSA, KeyAlgoDSA,
|
SigAlgoRSASHA2512, SigAlgoRSASHA2256,
|
||||||
|
SigAlgoRSA, KeyAlgoDSA,
|
||||||
|
|
||||||
KeyAlgoED25519,
|
KeyAlgoED25519,
|
||||||
}
|
}
|
||||||
|
@ -90,16 +92,20 @@ var supportedCompressions = []string{compressionNone}
|
||||||
// hashFuncs keeps the mapping of supported algorithms to their respective
|
// hashFuncs keeps the mapping of supported algorithms to their respective
|
||||||
// hashes needed for signature verification.
|
// hashes needed for signature verification.
|
||||||
var hashFuncs = map[string]crypto.Hash{
|
var hashFuncs = map[string]crypto.Hash{
|
||||||
KeyAlgoRSA: crypto.SHA1,
|
SigAlgoRSA: crypto.SHA1,
|
||||||
KeyAlgoDSA: crypto.SHA1,
|
SigAlgoRSASHA2256: crypto.SHA256,
|
||||||
KeyAlgoECDSA256: crypto.SHA256,
|
SigAlgoRSASHA2512: crypto.SHA512,
|
||||||
KeyAlgoECDSA384: crypto.SHA384,
|
KeyAlgoDSA: crypto.SHA1,
|
||||||
KeyAlgoECDSA521: crypto.SHA512,
|
KeyAlgoECDSA256: crypto.SHA256,
|
||||||
CertAlgoRSAv01: crypto.SHA1,
|
KeyAlgoECDSA384: crypto.SHA384,
|
||||||
CertAlgoDSAv01: crypto.SHA1,
|
KeyAlgoECDSA521: crypto.SHA512,
|
||||||
CertAlgoECDSA256v01: crypto.SHA256,
|
CertSigAlgoRSAv01: crypto.SHA1,
|
||||||
CertAlgoECDSA384v01: crypto.SHA384,
|
CertSigAlgoRSASHA2256v01: crypto.SHA256,
|
||||||
CertAlgoECDSA521v01: crypto.SHA512,
|
CertSigAlgoRSASHA2512v01: crypto.SHA512,
|
||||||
|
CertAlgoDSAv01: crypto.SHA1,
|
||||||
|
CertAlgoECDSA256v01: crypto.SHA256,
|
||||||
|
CertAlgoECDSA384v01: crypto.SHA384,
|
||||||
|
CertAlgoECDSA521v01: crypto.SHA512,
|
||||||
}
|
}
|
||||||
|
|
||||||
// unexpectedMessageError results when the SSH message that we received didn't
|
// unexpectedMessageError results when the SSH message that we received didn't
|
||||||
|
|
|
@ -457,8 +457,15 @@ func (t *handshakeTransport) sendKexInit() error {
|
||||||
|
|
||||||
if len(t.hostKeys) > 0 {
|
if len(t.hostKeys) > 0 {
|
||||||
for _, k := range t.hostKeys {
|
for _, k := range t.hostKeys {
|
||||||
msg.ServerHostKeyAlgos = append(
|
algo := k.PublicKey().Type()
|
||||||
msg.ServerHostKeyAlgos, k.PublicKey().Type())
|
switch algo {
|
||||||
|
case KeyAlgoRSA:
|
||||||
|
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, []string{SigAlgoRSASHA2512, SigAlgoRSASHA2256, SigAlgoRSA}...)
|
||||||
|
case CertAlgoRSAv01:
|
||||||
|
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, []string{CertSigAlgoRSASHA2512v01, CertSigAlgoRSASHA2256v01, CertSigAlgoRSAv01}...)
|
||||||
|
default:
|
||||||
|
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
|
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
|
||||||
|
@ -614,8 +621,22 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||||
func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
|
func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
|
||||||
var hostKey Signer
|
var hostKey Signer
|
||||||
for _, k := range t.hostKeys {
|
for _, k := range t.hostKeys {
|
||||||
if algs.hostKey == k.PublicKey().Type() {
|
kt := k.PublicKey().Type()
|
||||||
|
if kt == algs.hostKey {
|
||||||
hostKey = k
|
hostKey = k
|
||||||
|
} else if signer, ok := k.(AlgorithmSigner); ok {
|
||||||
|
// Some signature algorithms don't show up as key types
|
||||||
|
// so we have to manually check for a compatible host key.
|
||||||
|
switch kt {
|
||||||
|
case KeyAlgoRSA:
|
||||||
|
if algs.hostKey == SigAlgoRSASHA2256 || algs.hostKey == SigAlgoRSASHA2512 {
|
||||||
|
hostKey = &rsaSigner{signer, algs.hostKey}
|
||||||
|
}
|
||||||
|
case CertAlgoRSAv01:
|
||||||
|
if algs.hostKey == CertSigAlgoRSASHA2256v01 || algs.hostKey == CertSigAlgoRSASHA2512v01 {
|
||||||
|
hostKey = &rsaSigner{signer, certToPrivAlgo(algs.hostKey)}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +655,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := verifyHostKeySignature(hostKey, result); err != nil {
|
if err := verifyHostKeySignature(hostKey, algs.hostKey, result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -939,6 +939,15 @@ func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
|
||||||
return &dsaPrivateKey{key}, nil
|
return &dsaPrivateKey{key}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type rsaSigner struct {
|
||||||
|
AlgorithmSigner
|
||||||
|
defaultAlgorithm string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *rsaSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
||||||
|
return s.AlgorithmSigner.SignWithAlgorithm(rand, data, s.defaultAlgorithm)
|
||||||
|
}
|
||||||
|
|
||||||
type wrappedSigner struct {
|
type wrappedSigner struct {
|
||||||
signer crypto.Signer
|
signer crypto.Signer
|
||||||
pubKey PublicKey
|
pubKey PublicKey
|
||||||
|
|
|
@ -284,7 +284,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
|
||||||
|
|
||||||
func isAcceptableAlgo(algo string) bool {
|
func isAcceptableAlgo(algo string) bool {
|
||||||
switch algo {
|
switch algo {
|
||||||
case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
|
case SigAlgoRSA, SigAlgoRSASHA2256, SigAlgoRSASHA2512, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
|
||||||
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
|
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
//go:build go1.18
|
||||||
|
// +build go1.18
|
||||||
|
|
||||||
|
package idna
|
||||||
|
|
||||||
|
// Transitional processing is disabled by default in Go 1.18.
|
||||||
|
// https://golang.org/issue/47510
|
||||||
|
const transitionalLookup = false
|
|
@ -59,10 +59,10 @@ type Option func(*options)
|
||||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||||
// compatibility. It is used by most browsers when resolving domain names. This
|
// compatibility. It is used by some browsers when resolving domain names. This
|
||||||
// option is only meaningful if combined with MapForLookup.
|
// option is only meaningful if combined with MapForLookup.
|
||||||
func Transitional(transitional bool) Option {
|
func Transitional(transitional bool) Option {
|
||||||
return func(o *options) { o.transitional = true }
|
return func(o *options) { o.transitional = transitional }
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||||
|
@ -284,7 +284,7 @@ var (
|
||||||
|
|
||||||
punycode = &Profile{}
|
punycode = &Profile{}
|
||||||
lookup = &Profile{options{
|
lookup = &Profile{options{
|
||||||
transitional: true,
|
transitional: transitionalLookup,
|
||||||
useSTD3Rules: true,
|
useSTD3Rules: true,
|
||||||
checkHyphens: true,
|
checkHyphens: true,
|
||||||
checkJoiners: true,
|
checkJoiners: true,
|
||||||
|
|
|
@ -58,10 +58,10 @@ type Option func(*options)
|
||||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||||
// compatibility. It is used by most browsers when resolving domain names. This
|
// compatibility. It is used by some browsers when resolving domain names. This
|
||||||
// option is only meaningful if combined with MapForLookup.
|
// option is only meaningful if combined with MapForLookup.
|
||||||
func Transitional(transitional bool) Option {
|
func Transitional(transitional bool) Option {
|
||||||
return func(o *options) { o.transitional = true }
|
return func(o *options) { o.transitional = transitional }
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
//go:build !go1.18
|
||||||
|
// +build !go1.18
|
||||||
|
|
||||||
|
package idna
|
||||||
|
|
||||||
|
const transitionalLookup = true
|
|
@ -49,6 +49,7 @@ func decode(encoded string) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i, n, bias := int32(0), initialN, initialBias
|
i, n, bias := int32(0), initialN, initialBias
|
||||||
|
overflow := false
|
||||||
for pos < len(encoded) {
|
for pos < len(encoded) {
|
||||||
oldI, w := i, int32(1)
|
oldI, w := i, int32(1)
|
||||||
for k := base; ; k += base {
|
for k := base; ; k += base {
|
||||||
|
@ -60,29 +61,32 @@ func decode(encoded string) (string, error) {
|
||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
pos++
|
pos++
|
||||||
i += digit * w
|
i, overflow = madd(i, digit, w)
|
||||||
if i < 0 {
|
if overflow {
|
||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
t := k - bias
|
t := k - bias
|
||||||
if t < tmin {
|
if k <= bias {
|
||||||
t = tmin
|
t = tmin
|
||||||
} else if t > tmax {
|
} else if k >= bias+tmax {
|
||||||
t = tmax
|
t = tmax
|
||||||
}
|
}
|
||||||
if digit < t {
|
if digit < t {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w *= base - t
|
w, overflow = madd(0, w, base-t)
|
||||||
if w >= math.MaxInt32/base {
|
if overflow {
|
||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(output) >= 1024 {
|
||||||
|
return "", punyError(encoded)
|
||||||
|
}
|
||||||
x := int32(len(output) + 1)
|
x := int32(len(output) + 1)
|
||||||
bias = adapt(i-oldI, x, oldI == 0)
|
bias = adapt(i-oldI, x, oldI == 0)
|
||||||
n += i / x
|
n += i / x
|
||||||
i %= x
|
i %= x
|
||||||
if n > utf8.MaxRune || len(output) >= 1024 {
|
if n < 0 || n > utf8.MaxRune {
|
||||||
return "", punyError(encoded)
|
return "", punyError(encoded)
|
||||||
}
|
}
|
||||||
output = append(output, 0)
|
output = append(output, 0)
|
||||||
|
@ -115,6 +119,7 @@ func encode(prefix, s string) (string, error) {
|
||||||
if b > 0 {
|
if b > 0 {
|
||||||
output = append(output, '-')
|
output = append(output, '-')
|
||||||
}
|
}
|
||||||
|
overflow := false
|
||||||
for remaining != 0 {
|
for remaining != 0 {
|
||||||
m := int32(0x7fffffff)
|
m := int32(0x7fffffff)
|
||||||
for _, r := range s {
|
for _, r := range s {
|
||||||
|
@ -122,8 +127,8 @@ func encode(prefix, s string) (string, error) {
|
||||||
m = r
|
m = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delta += (m - n) * (h + 1)
|
delta, overflow = madd(delta, m-n, h+1)
|
||||||
if delta < 0 {
|
if overflow {
|
||||||
return "", punyError(s)
|
return "", punyError(s)
|
||||||
}
|
}
|
||||||
n = m
|
n = m
|
||||||
|
@ -141,9 +146,9 @@ func encode(prefix, s string) (string, error) {
|
||||||
q := delta
|
q := delta
|
||||||
for k := base; ; k += base {
|
for k := base; ; k += base {
|
||||||
t := k - bias
|
t := k - bias
|
||||||
if t < tmin {
|
if k <= bias {
|
||||||
t = tmin
|
t = tmin
|
||||||
} else if t > tmax {
|
} else if k >= bias+tmax {
|
||||||
t = tmax
|
t = tmax
|
||||||
}
|
}
|
||||||
if q < t {
|
if q < t {
|
||||||
|
@ -164,6 +169,15 @@ func encode(prefix, s string) (string, error) {
|
||||||
return string(output), nil
|
return string(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// madd computes a + (b * c), detecting overflow.
|
||||||
|
func madd(a, b, c int32) (next int32, overflow bool) {
|
||||||
|
p := int64(b) * int64(c)
|
||||||
|
if p > math.MaxInt32-int64(a) {
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
return a + int32(p), false
|
||||||
|
}
|
||||||
|
|
||||||
func decodeDigit(x byte) (digit int32, ok bool) {
|
func decodeDigit(x byte) (digit int32, ok bool) {
|
||||||
switch {
|
switch {
|
||||||
case '0' <= x && x <= '9':
|
case '0' <= x && x <= '9':
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build darwin && go1.12
|
||||||
// +build darwin,go1.12
|
// +build darwin,go1.12
|
||||||
|
|
||||||
// This exists solely so we can linkname in symbols from syscall.
|
// This exists solely so we can linkname in symbols from syscall.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -90,9 +90,10 @@ func archInit() {
|
||||||
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
||||||
|
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
// Check darwin commpage for AVX512 support. Necessary because:
|
// Darwin doesn't save/restore AVX-512 mask registers correctly across signal handlers.
|
||||||
// https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/osfmk/i386/fpu.c#L175-L201
|
// Since users can't rely on mask register contents, let's not advertise AVX-512 support.
|
||||||
osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512()
|
// See issue 49233.
|
||||||
|
osSupportsAVX512 = false
|
||||||
} else {
|
} else {
|
||||||
// Check if OPMASK and ZMM registers have OS support.
|
// Check if OPMASK and ZMM registers have OS support.
|
||||||
osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
|
osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
|
||||||
|
|
|
@ -26,27 +26,3 @@ TEXT ·xgetbv(SB),NOSPLIT,$0-8
|
||||||
MOVL AX, eax+0(FP)
|
MOVL AX, eax+0(FP)
|
||||||
MOVL DX, edx+4(FP)
|
MOVL DX, edx+4(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// func darwinSupportsAVX512() bool
|
|
||||||
TEXT ·darwinSupportsAVX512(SB), NOSPLIT, $0-1
|
|
||||||
MOVB $0, ret+0(FP) // default to false
|
|
||||||
#ifdef GOOS_darwin // return if not darwin
|
|
||||||
#ifdef GOARCH_amd64 // return if not amd64
|
|
||||||
// These values from:
|
|
||||||
// https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
|
|
||||||
#define commpage64_base_address 0x00007fffffe00000
|
|
||||||
#define commpage64_cpu_capabilities64 (commpage64_base_address+0x010)
|
|
||||||
#define commpage64_version (commpage64_base_address+0x01E)
|
|
||||||
#define hasAVX512F 0x0000004000000000
|
|
||||||
MOVQ $commpage64_version, BX
|
|
||||||
CMPW (BX), $13 // cpu_capabilities64 undefined in versions < 13
|
|
||||||
JL no_avx512
|
|
||||||
MOVQ $commpage64_cpu_capabilities64, BX
|
|
||||||
MOVQ $hasAVX512F, CX
|
|
||||||
TESTQ (BX), CX
|
|
||||||
JZ no_avx512
|
|
||||||
MOVB $1, ret+0(FP)
|
|
||||||
no_avx512:
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
RET
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ To add a constant, add the header that includes it to the appropriate variable.
|
||||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||||
the regex too broad to avoid matching unintended constants.
|
the regex too broad to avoid matching unintended constants.
|
||||||
|
|
||||||
### mkmerge.go
|
### internal/mkmerge
|
||||||
|
|
||||||
This program is used to extract duplicate const, func, and type declarations
|
This program is used to extract duplicate const, func, and type declarations
|
||||||
from the generated architecture-specific files listed below, and merge these
|
from the generated architecture-specific files listed below, and merge these
|
||||||
|
|
|
@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then
|
||||||
# Use the Docker-based build system
|
# Use the Docker-based build system
|
||||||
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
|
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
|
||||||
$cmd docker build --tag generate:$GOOS $GOOS
|
$cmd docker build --tag generate:$GOOS $GOOS
|
||||||
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS
|
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && /bin/pwd):/build generate:$GOOS
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ includes_AIX='
|
||||||
|
|
||||||
includes_Darwin='
|
includes_Darwin='
|
||||||
#define _DARWIN_C_SOURCE
|
#define _DARWIN_C_SOURCE
|
||||||
#define KERNEL
|
#define KERNEL 1
|
||||||
#define _DARWIN_USE_64_BIT_INODE
|
#define _DARWIN_USE_64_BIT_INODE
|
||||||
#define __APPLE_USE_RFC_3542
|
#define __APPLE_USE_RFC_3542
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -75,6 +75,7 @@ includes_Darwin='
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/xattr.h>
|
#include <sys/xattr.h>
|
||||||
|
#include <sys/vsock.h>
|
||||||
#include <net/bpf.h>
|
#include <net/bpf.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_types.h>
|
#include <net/if_types.h>
|
||||||
|
@ -82,6 +83,9 @@ includes_Darwin='
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
|
// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk.
|
||||||
|
#define TIOCREMOTE 0x80047469
|
||||||
'
|
'
|
||||||
|
|
||||||
includes_DragonFly='
|
includes_DragonFly='
|
||||||
|
@ -229,11 +233,13 @@ struct ltchars {
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/kexec.h>
|
#include <linux/kexec.h>
|
||||||
#include <linux/keyctl.h>
|
#include <linux/keyctl.h>
|
||||||
|
#include <linux/landlock.h>
|
||||||
#include <linux/loop.h>
|
#include <linux/loop.h>
|
||||||
#include <linux/lwtunnel.h>
|
#include <linux/lwtunnel.h>
|
||||||
#include <linux/magic.h>
|
#include <linux/magic.h>
|
||||||
#include <linux/memfd.h>
|
#include <linux/memfd.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/mount.h>
|
||||||
#include <linux/netfilter/nfnetlink.h>
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/net_namespace.h>
|
#include <linux/net_namespace.h>
|
||||||
|
@ -465,7 +471,6 @@ ccflags="$@"
|
||||||
$2 !~ /^EQUIV_/ &&
|
$2 !~ /^EQUIV_/ &&
|
||||||
$2 !~ /^EXPR_/ &&
|
$2 !~ /^EXPR_/ &&
|
||||||
$2 !~ /^EVIOC/ &&
|
$2 !~ /^EVIOC/ &&
|
||||||
$2 !~ /^EV_/ &&
|
|
||||||
$2 ~ /^E[A-Z0-9_]+$/ ||
|
$2 ~ /^E[A-Z0-9_]+$/ ||
|
||||||
$2 ~ /^B[0-9_]+$/ ||
|
$2 ~ /^B[0-9_]+$/ ||
|
||||||
$2 ~ /^(OLD|NEW)DEV$/ ||
|
$2 ~ /^(OLD|NEW)DEV$/ ||
|
||||||
|
@ -497,6 +502,7 @@ ccflags="$@"
|
||||||
$2 ~ /^O?XTABS$/ ||
|
$2 ~ /^O?XTABS$/ ||
|
||||||
$2 ~ /^TC[IO](ON|OFF)$/ ||
|
$2 ~ /^TC[IO](ON|OFF)$/ ||
|
||||||
$2 ~ /^IN_/ ||
|
$2 ~ /^IN_/ ||
|
||||||
|
$2 ~ /^LANDLOCK_/ ||
|
||||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
||||||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
|
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
|
||||||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
|
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
|
||||||
|
@ -515,7 +521,7 @@ ccflags="$@"
|
||||||
$2 ~ /^HW_MACHINE$/ ||
|
$2 ~ /^HW_MACHINE$/ ||
|
||||||
$2 ~ /^SYSCTL_VERS/ ||
|
$2 ~ /^SYSCTL_VERS/ ||
|
||||||
$2 !~ "MNT_BITS" &&
|
$2 !~ "MNT_BITS" &&
|
||||||
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
|
$2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ ||
|
||||||
$2 ~ /^NS_GET_/ ||
|
$2 ~ /^NS_GET_/ ||
|
||||||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
||||||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||
|
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||
|
||||||
|
|
|
@ -34,3 +34,52 @@ func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
|
||||||
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
|
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
|
||||||
return &ucred, nil
|
return &ucred, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
|
||||||
|
func PktInfo4(info *Inet4Pktinfo) []byte {
|
||||||
|
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_IP
|
||||||
|
h.Type = IP_PKTINFO
|
||||||
|
h.SetLen(CmsgLen(SizeofInet4Pktinfo))
|
||||||
|
*(*Inet4Pktinfo)(h.data(0)) = *info
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
|
||||||
|
func PktInfo6(info *Inet6Pktinfo) []byte {
|
||||||
|
b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_IPV6
|
||||||
|
h.Type = IPV6_PKTINFO
|
||||||
|
h.SetLen(CmsgLen(SizeofInet6Pktinfo))
|
||||||
|
*(*Inet6Pktinfo)(h.data(0)) = *info
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseOrigDstAddr decodes a socket control message containing the original
|
||||||
|
// destination address. To receive such a message the IP_RECVORIGDSTADDR or
|
||||||
|
// IPV6_RECVORIGDSTADDR option must be enabled on the socket.
|
||||||
|
func ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) {
|
||||||
|
switch {
|
||||||
|
case m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR:
|
||||||
|
pp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0]))
|
||||||
|
sa := new(SockaddrInet4)
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
|
sa.Addr = pp.Addr
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
case m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR:
|
||||||
|
pp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0]))
|
||||||
|
sa := new(SockaddrInet6)
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
|
sa.ZoneId = pp.Scope_id
|
||||||
|
sa.Addr = pp.Addr
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -70,9 +70,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +83,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
sa.raw.Scope_id = sa.ZoneId
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,9 +257,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa := new(SockaddrInet4)
|
sa := new(SockaddrInet4)
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
@ -272,9 +266,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
sa.ZoneId = pp.Scope_id
|
sa.ZoneId = pp.Scope_id
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
return nil, EAFNOSUPPORT
|
return nil, EAFNOSUPPORT
|
||||||
|
@ -385,6 +377,11 @@ func (w WaitStatus) TrapCause() int { return -1 }
|
||||||
|
|
||||||
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||||
|
|
||||||
|
//sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range
|
||||||
|
func Fsync(fd int) error {
|
||||||
|
return fsyncRange(fd, O_SYNC, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Direct access
|
* Direct access
|
||||||
*/
|
*/
|
||||||
|
@ -401,7 +398,6 @@ func (w WaitStatus) TrapCause() int { return -1 }
|
||||||
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
|
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
|
||||||
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
|
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
|
||||||
//sys Fdatasync(fd int) (err error)
|
//sys Fdatasync(fd int) (err error)
|
||||||
//sys Fsync(fd int) (err error)
|
|
||||||
// readdir_r
|
// readdir_r
|
||||||
//sysnb Getpgid(pid int) (pgid int, err error)
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||||
|
|
||||||
|
|
|
@ -163,9 +163,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,9 +177,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
sa.raw.Scope_id = sa.ZoneId
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,9 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
sa.raw.Nlen = sa.Nlen
|
sa.raw.Nlen = sa.Nlen
|
||||||
sa.raw.Alen = sa.Alen
|
sa.raw.Alen = sa.Alen
|
||||||
sa.raw.Slen = sa.Slen
|
sa.raw.Slen = sa.Slen
|
||||||
for i := 0; i < len(sa.raw.Data); i++ {
|
sa.raw.Data = sa.Data
|
||||||
sa.raw.Data[i] = sa.Data[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,9 +222,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa.Nlen = pp.Nlen
|
sa.Nlen = pp.Nlen
|
||||||
sa.Alen = pp.Alen
|
sa.Alen = pp.Alen
|
||||||
sa.Slen = pp.Slen
|
sa.Slen = pp.Slen
|
||||||
for i := 0; i < len(sa.Data); i++ {
|
sa.Data = pp.Data
|
||||||
sa.Data[i] = pp.Data[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
|
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
|
@ -262,9 +254,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa := new(SockaddrInet4)
|
sa := new(SockaddrInet4)
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
@ -273,9 +263,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
sa.ZoneId = pp.Scope_id
|
sa.ZoneId = pp.Scope_id
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
return anyToSockaddrGOOS(fd, rsa)
|
return anyToSockaddrGOOS(fd, rsa)
|
||||||
|
|
|
@ -48,6 +48,30 @@ func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
|
||||||
|
// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables
|
||||||
|
// bidirectional communication between a hypervisor and its guest virtual
|
||||||
|
// machines.
|
||||||
|
type SockaddrVM struct {
|
||||||
|
// CID and Port specify a context ID and port address for a VM socket.
|
||||||
|
// Guests have a unique CID, and hosts may have a well-known CID of:
|
||||||
|
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
|
||||||
|
// - VMADDR_CID_LOCAL: refers to local communication (loopback).
|
||||||
|
// - VMADDR_CID_HOST: refers to other processes on the host.
|
||||||
|
CID uint32
|
||||||
|
Port uint32
|
||||||
|
raw RawSockaddrVM
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
sa.raw.Len = SizeofSockaddrVM
|
||||||
|
sa.raw.Family = AF_VSOCK
|
||||||
|
sa.raw.Port = sa.Port
|
||||||
|
sa.raw.Cid = sa.CID
|
||||||
|
|
||||||
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
|
||||||
|
}
|
||||||
|
|
||||||
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
switch rsa.Addr.Family {
|
switch rsa.Addr.Family {
|
||||||
case AF_SYSTEM:
|
case AF_SYSTEM:
|
||||||
|
@ -58,6 +82,13 @@ func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa.Unit = pp.Sc_unit
|
sa.Unit = pp.Sc_unit
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
|
case AF_VSOCK:
|
||||||
|
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
|
||||||
|
sa := &SockaddrVM{
|
||||||
|
CID: pp.Cid,
|
||||||
|
Port: pp.Port,
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
}
|
}
|
||||||
return nil, EAFNOSUPPORT
|
return nil, EAFNOSUPPORT
|
||||||
}
|
}
|
||||||
|
@ -399,8 +430,25 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
|
||||||
return x, err
|
return x, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
|
func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
|
||||||
mib, err := sysctlmib(name)
|
mib, err := sysctlmib(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var kinfo KinfoProc
|
||||||
|
n := uintptr(SizeofKinfoProc)
|
||||||
|
if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n != SizeofKinfoProc {
|
||||||
|
return nil, EIO
|
||||||
|
}
|
||||||
|
return &kinfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
|
||||||
|
mib, err := sysctlmib(name, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -433,6 +481,11 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
|
||||||
|
|
||||||
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
||||||
|
|
||||||
|
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
|
||||||
|
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
|
||||||
|
//sys shmdt(addr uintptr) (err error)
|
||||||
|
//sys shmget(key int, size int, flag int) (id int, err error)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exposed directly
|
* Exposed directly
|
||||||
*/
|
*/
|
||||||
|
@ -590,10 +643,6 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
|
||||||
// Msgget
|
// Msgget
|
||||||
// Msgsnd
|
// Msgsnd
|
||||||
// Msgrcv
|
// Msgrcv
|
||||||
// Shmat
|
|
||||||
// Shmctl
|
|
||||||
// Shmdt
|
|
||||||
// Shmget
|
|
||||||
// Shm_open
|
// Shm_open
|
||||||
// Shm_unlink
|
// Shm_unlink
|
||||||
// Sem_open
|
// Sem_open
|
||||||
|
|
|
@ -162,6 +162,14 @@ func (l *Lifreq) GetLifruInt() int {
|
||||||
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
|
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) SetLifruUint(d uint) {
|
||||||
|
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) GetLifruUint() uint {
|
||||||
|
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
|
||||||
|
}
|
||||||
|
|
||||||
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
|
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
|
||||||
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
|
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"runtime"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -38,6 +37,13 @@ func Creat(path string, mode uint32) (fd int, err error) {
|
||||||
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
|
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EpollCreate(size int) (fd int, err error) {
|
||||||
|
if size <= 0 {
|
||||||
|
return -1, EINVAL
|
||||||
|
}
|
||||||
|
return EpollCreate1(0)
|
||||||
|
}
|
||||||
|
|
||||||
//sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error)
|
//sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error)
|
||||||
//sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error)
|
//sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error)
|
||||||
|
|
||||||
|
@ -66,6 +72,10 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
|
||||||
return fchmodat(dirfd, path, mode)
|
return fchmodat(dirfd, path, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InotifyInit() (fd int, err error) {
|
||||||
|
return InotifyInit1(0)
|
||||||
|
}
|
||||||
|
|
||||||
//sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL
|
//sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL
|
||||||
//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL
|
//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL
|
||||||
|
|
||||||
|
@ -109,6 +119,23 @@ func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
|
||||||
return openat2(dirfd, path, how, SizeofOpenHow)
|
return openat2(dirfd, path, how, SizeofOpenHow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Pipe(p []int) error {
|
||||||
|
return Pipe2(p, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
||||||
|
|
||||||
|
func Pipe2(p []int, flags int) error {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err := pipe2(&pp, flags)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
|
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
|
||||||
|
|
||||||
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
||||||
|
@ -118,6 +145,15 @@ func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error
|
||||||
return ppoll(&fds[0], len(fds), timeout, sigmask)
|
return ppoll(&fds[0], len(fds), timeout, sigmask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||||
|
var ts *Timespec
|
||||||
|
if timeout >= 0 {
|
||||||
|
ts = new(Timespec)
|
||||||
|
*ts = NsecToTimespec(int64(timeout) * 1e6)
|
||||||
|
}
|
||||||
|
return Ppoll(fds, ts, nil)
|
||||||
|
}
|
||||||
|
|
||||||
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
|
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
|
||||||
|
|
||||||
func Readlink(path string, buf []byte) (n int, err error) {
|
func Readlink(path string, buf []byte) (n int, err error) {
|
||||||
|
@ -168,27 +204,7 @@ func Utimes(path string, tv []Timeval) error {
|
||||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
|
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
|
||||||
|
|
||||||
func UtimesNano(path string, ts []Timespec) error {
|
func UtimesNano(path string, ts []Timespec) error {
|
||||||
if ts == nil {
|
return UtimesNanoAt(AT_FDCWD, path, ts, 0)
|
||||||
err := utimensat(AT_FDCWD, path, nil, 0)
|
|
||||||
if err != ENOSYS {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return utimes(path, nil)
|
|
||||||
}
|
|
||||||
if len(ts) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
|
||||||
if err != ENOSYS {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// If the utimensat syscall isn't available (utimensat was added to Linux
|
|
||||||
// in 2.6.22, Released, 8 July 2007) then fall back to utimes
|
|
||||||
var tv [2]Timeval
|
|
||||||
for i := 0; i < 2; i++ {
|
|
||||||
tv[i] = NsecToTimeval(TimespecToNsec(ts[i]))
|
|
||||||
}
|
|
||||||
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
|
func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
|
||||||
|
@ -356,9 +372,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,9 +385,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
sa.raw.Scope_id = sa.ZoneId
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,9 +434,7 @@ func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
sa.raw.Hatype = sa.Hatype
|
sa.raw.Hatype = sa.Hatype
|
||||||
sa.raw.Pkttype = sa.Pkttype
|
sa.raw.Pkttype = sa.Pkttype
|
||||||
sa.raw.Halen = sa.Halen
|
sa.raw.Halen = sa.Halen
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,12 +849,10 @@ func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
if sa.Addr == nil {
|
if sa.Addr == nil {
|
||||||
return nil, 0, EINVAL
|
return nil, 0, EINVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.raw.Family = AF_TIPC
|
sa.raw.Family = AF_TIPC
|
||||||
sa.raw.Scope = int8(sa.Scope)
|
sa.raw.Scope = int8(sa.Scope)
|
||||||
sa.raw.Addrtype = sa.Addr.tipcAddrtype()
|
sa.raw.Addrtype = sa.Addr.tipcAddrtype()
|
||||||
sa.raw.Addr = sa.Addr.tipcAddr()
|
sa.raw.Addr = sa.Addr.tipcAddr()
|
||||||
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,9 +866,7 @@ type SockaddrL2TPIP struct {
|
||||||
func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
sa.raw.Family = AF_INET
|
sa.raw.Family = AF_INET
|
||||||
sa.raw.Conn_id = sa.ConnId
|
sa.raw.Conn_id = sa.ConnId
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,9 +882,7 @@ func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
sa.raw.Family = AF_INET6
|
sa.raw.Family = AF_INET6
|
||||||
sa.raw.Conn_id = sa.ConnId
|
sa.raw.Conn_id = sa.ConnId
|
||||||
sa.raw.Scope_id = sa.ZoneId
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,9 +978,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa.Hatype = pp.Hatype
|
sa.Hatype = pp.Hatype
|
||||||
sa.Pkttype = pp.Pkttype
|
sa.Pkttype = pp.Pkttype
|
||||||
sa.Halen = pp.Halen
|
sa.Halen = pp.Halen
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
|
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
|
@ -1015,18 +1017,14 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
|
pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
|
||||||
sa := new(SockaddrL2TPIP)
|
sa := new(SockaddrL2TPIP)
|
||||||
sa.ConnId = pp.Conn_id
|
sa.ConnId = pp.Conn_id
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
default:
|
default:
|
||||||
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
|
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
|
||||||
sa := new(SockaddrInet4)
|
sa := new(SockaddrInet4)
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1042,9 +1040,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa := new(SockaddrL2TPIP6)
|
sa := new(SockaddrL2TPIP6)
|
||||||
sa.ConnId = pp.Conn_id
|
sa.ConnId = pp.Conn_id
|
||||||
sa.ZoneId = pp.Scope_id
|
sa.ZoneId = pp.Scope_id
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
default:
|
default:
|
||||||
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
|
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
|
||||||
|
@ -1052,9 +1048,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
sa.ZoneId = pp.Scope_id
|
sa.ZoneId = pp.Scope_id
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,11 +1223,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
||||||
var rsa RawSockaddrAny
|
var rsa RawSockaddrAny
|
||||||
var len _Socklen = SizeofSockaddrAny
|
var len _Socklen = SizeofSockaddrAny
|
||||||
// Try accept4 first for Android, then try accept for kernel older than 2.6.28
|
|
||||||
nfd, err = accept4(fd, &rsa, &len, 0)
|
nfd, err = accept4(fd, &rsa, &len, 0)
|
||||||
if err == ENOSYS {
|
|
||||||
nfd, err = accept(fd, &rsa, &len)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1785,6 +1775,16 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
|
||||||
return mount(source, target, fstype, flags, datap)
|
return mount(source, target, fstype, flags, datap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sys mountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) = SYS_MOUNT_SETATTR
|
||||||
|
|
||||||
|
// MountSetattr is a wrapper for mount_setattr(2).
|
||||||
|
// https://man7.org/linux/man-pages/man2/mount_setattr.2.html
|
||||||
|
//
|
||||||
|
// Requires kernel >= 5.12.
|
||||||
|
func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error {
|
||||||
|
return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr))
|
||||||
|
}
|
||||||
|
|
||||||
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
if raceenabled {
|
if raceenabled {
|
||||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||||
|
@ -1816,11 +1816,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
||||||
//sys Dup(oldfd int) (fd int, err error)
|
//sys Dup(oldfd int) (fd int, err error)
|
||||||
|
|
||||||
func Dup2(oldfd, newfd int) error {
|
func Dup2(oldfd, newfd int) error {
|
||||||
// Android O and newer blocks dup2; riscv and arm64 don't implement dup2.
|
return Dup3(oldfd, newfd, 0)
|
||||||
if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" {
|
|
||||||
return Dup3(oldfd, newfd, 0)
|
|
||||||
}
|
|
||||||
return dup2(oldfd, newfd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys Dup3(oldfd int, newfd int, flags int) (err error)
|
//sys Dup3(oldfd int, newfd int, flags int) (err error)
|
||||||
|
@ -2308,6 +2304,14 @@ type RemoteIovec struct {
|
||||||
//sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV
|
//sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV
|
||||||
//sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV
|
//sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV
|
||||||
|
|
||||||
|
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
|
||||||
|
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
|
||||||
|
|
||||||
|
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
|
||||||
|
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
|
||||||
|
//sys shmdt(addr uintptr) (err error)
|
||||||
|
//sys shmget(key int, size int, flag int) (id int, err error)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unimplemented
|
* Unimplemented
|
||||||
*/
|
*/
|
||||||
|
@ -2389,10 +2393,6 @@ type RemoteIovec struct {
|
||||||
// SetRobustList
|
// SetRobustList
|
||||||
// SetThreadArea
|
// SetThreadArea
|
||||||
// SetTidAddress
|
// SetTidAddress
|
||||||
// Shmat
|
|
||||||
// Shmctl
|
|
||||||
// Shmdt
|
|
||||||
// Shmget
|
|
||||||
// Sigaltstack
|
// Sigaltstack
|
||||||
// Swapoff
|
// Swapoff
|
||||||
// Swapon
|
// Swapon
|
||||||
|
|
|
@ -19,36 +19,8 @@ func setTimeval(sec, usec int64) Timeval {
|
||||||
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe(p *[2]_C_int) (err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe(&pp)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 64-bit file system and 32-bit uid calls
|
// 64-bit file system and 32-bit uid calls
|
||||||
// (386 default is 32-bit file system and 16-bit uid).
|
// (386 default is 32-bit file system and 16-bit uid).
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
|
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
|
||||||
|
@ -59,7 +31,6 @@ func Pipe2(p []int, flags int) (err error) {
|
||||||
//sysnb Geteuid() (euid int) = SYS_GETEUID32
|
//sysnb Geteuid() (euid int) = SYS_GETEUID32
|
||||||
//sysnb Getgid() (gid int) = SYS_GETGID32
|
//sysnb Getgid() (gid int) = SYS_GETGID32
|
||||||
//sysnb Getuid() (uid int) = SYS_GETUID32
|
//sysnb Getuid() (uid int) = SYS_GETUID32
|
||||||
//sysnb InotifyInit() (fd int, err error)
|
|
||||||
//sys Ioperm(from int, num int, on int) (err error)
|
//sys Ioperm(from int, num int, on int) (err error)
|
||||||
//sys Iopl(level int) (err error)
|
//sys Iopl(level int) (err error)
|
||||||
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
||||||
|
@ -381,12 +352,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint32(length)
|
rsa.Service_name_len = uint32(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
@ -21,17 +19,6 @@ package unix
|
||||||
//sysnb Getgid() (gid int)
|
//sysnb Getgid() (gid int)
|
||||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Getuid() (uid int)
|
//sysnb Getuid() (uid int)
|
||||||
//sysnb inotifyInit() (fd int, err error)
|
|
||||||
|
|
||||||
func InotifyInit() (fd int, err error) {
|
|
||||||
// First try inotify_init1, because Android's seccomp policy blocks the latter.
|
|
||||||
fd, err = InotifyInit1(0)
|
|
||||||
if err == ENOSYS {
|
|
||||||
fd, err = inotifyInit()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys Ioperm(from int, num int, on int) (err error)
|
//sys Ioperm(from int, num int, on int) (err error)
|
||||||
//sys Iopl(level int) (err error)
|
//sys Iopl(level int) (err error)
|
||||||
//sys Lchown(path string, uid int, gid int) (err error)
|
//sys Lchown(path string, uid int, gid int) (err error)
|
||||||
|
@ -126,32 +113,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||||
return Timeval{Sec: sec, Usec: usec}
|
return Timeval{Sec: sec, Usec: usec}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe(p *[2]_C_int) (err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe(&pp)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PtraceRegs) PC() uint64 { return r.Rip }
|
func (r *PtraceRegs) PC() uint64 { return r.Rip }
|
||||||
|
|
||||||
func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
|
func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
|
||||||
|
@ -176,15 +137,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint64(length)
|
rsa.Service_name_len = uint64(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
|
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
|
||||||
|
|
||||||
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
|
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
|
||||||
|
|
|
@ -19,36 +19,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||||
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe(p *[2]_C_int) (err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
// Try pipe2 first for Android O, then try pipe for kernel 2.6.23.
|
|
||||||
err = pipe2(&pp, 0)
|
|
||||||
if err == ENOSYS {
|
|
||||||
err = pipe(&pp)
|
|
||||||
}
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||||
newoffset, errno := seek(fd, offset, whence)
|
newoffset, errno := seek(fd, offset, whence)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
|
@ -76,8 +46,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||||
|
|
||||||
// 64-bit file system and 32-bit uid calls
|
// 64-bit file system and 32-bit uid calls
|
||||||
// (16-bit uid calls are not always supported in newer kernels)
|
// (16-bit uid calls are not always supported in newer kernels)
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
|
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
|
||||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||||
|
@ -86,7 +54,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||||
//sysnb Geteuid() (euid int) = SYS_GETEUID32
|
//sysnb Geteuid() (euid int) = SYS_GETEUID32
|
||||||
//sysnb Getgid() (gid int) = SYS_GETGID32
|
//sysnb Getgid() (gid int) = SYS_GETGID32
|
||||||
//sysnb Getuid() (uid int) = SYS_GETUID32
|
//sysnb Getuid() (uid int) = SYS_GETUID32
|
||||||
//sysnb InotifyInit() (fd int, err error)
|
|
||||||
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
||||||
//sys Listen(s int, n int) (err error)
|
//sys Listen(s int, n int) (err error)
|
||||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||||
|
@ -260,15 +227,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint32(length)
|
rsa.Service_name_len = uint32(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE
|
//sys armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE
|
||||||
|
|
||||||
func SyncFileRange(fd int, off int64, n int64, flags int) error {
|
func SyncFileRange(fd int, off int64, n int64, flags int) error {
|
||||||
|
|
|
@ -9,13 +9,6 @@ package unix
|
||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
func EpollCreate(size int) (fd int, err error) {
|
|
||||||
if size <= 0 {
|
|
||||||
return -1, EINVAL
|
|
||||||
}
|
|
||||||
return EpollCreate1(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
@ -145,30 +138,6 @@ func utimes(path string, tv *[2]Timeval) (err error) {
|
||||||
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, 0)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getrlimit prefers the prlimit64 system call. See issue 38604.
|
// Getrlimit prefers the prlimit64 system call. See issue 38604.
|
||||||
func Getrlimit(resource int, rlim *Rlimit) error {
|
func Getrlimit(resource int, rlim *Rlimit) error {
|
||||||
err := Prlimit(0, resource, nil, rlim)
|
err := Prlimit(0, resource, nil, rlim)
|
||||||
|
@ -211,31 +180,11 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint64(length)
|
rsa.Service_name_len = uint64(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
func InotifyInit() (fd int, err error) {
|
|
||||||
return InotifyInit1(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// dup2 exists because func Dup3 in syscall_linux.go references
|
|
||||||
// it in an unreachable path. dup2 isn't available on arm64.
|
|
||||||
func dup2(oldfd int, newfd int) error
|
|
||||||
|
|
||||||
func Pause() error {
|
func Pause() error {
|
||||||
_, err := ppoll(nil, 0, nil, nil)
|
_, err := ppoll(nil, 0, nil, nil)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
var ts *Timespec
|
|
||||||
if timeout >= 0 {
|
|
||||||
ts = new(Timespec)
|
|
||||||
*ts = NsecToTimespec(int64(timeout) * 1e6)
|
|
||||||
}
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return ppoll(nil, 0, ts, nil)
|
|
||||||
}
|
|
||||||
return ppoll(&fds[0], len(fds), ts, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
|
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
|
||||||
|
|
||||||
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
|
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
@ -94,30 +92,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||||
return Timeval{Sec: sec, Usec: usec}
|
return Timeval{Sec: sec, Usec: usec}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, 0)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ioperm(from int, num int, on int) (err error) {
|
func Ioperm(from int, num int, on int) (err error) {
|
||||||
return ENOSYS
|
return ENOSYS
|
||||||
}
|
}
|
||||||
|
@ -220,16 +194,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint64(length)
|
rsa.Service_name_len = uint64(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
func InotifyInit() (fd int, err error) {
|
|
||||||
return InotifyInit1(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,8 +15,6 @@ import (
|
||||||
|
|
||||||
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
@ -60,7 +58,6 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
|
||||||
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
|
||||||
//sysnb InotifyInit() (fd int, err error)
|
|
||||||
//sys Ioperm(from int, num int, on int) (err error)
|
//sys Ioperm(from int, num int, on int) (err error)
|
||||||
//sys Iopl(level int) (err error)
|
//sys Iopl(level int) (err error)
|
||||||
|
|
||||||
|
@ -113,29 +110,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||||
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
return Timeval{Sec: int32(sec), Usec: int32(usec)}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe() (p1 int, p2 int, err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
p[0], p[1], err = pipe()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
|
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
|
||||||
|
|
||||||
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
|
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
|
||||||
|
@ -232,12 +206,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint32(length)
|
rsa.Service_name_len = uint32(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,8 +12,6 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||||
|
@ -23,7 +21,6 @@ import (
|
||||||
//sysnb Geteuid() (euid int)
|
//sysnb Geteuid() (euid int)
|
||||||
//sysnb Getgid() (gid int)
|
//sysnb Getgid() (gid int)
|
||||||
//sysnb Getuid() (uid int)
|
//sysnb Getuid() (uid int)
|
||||||
//sysnb InotifyInit() (fd int, err error)
|
|
||||||
//sys Ioperm(from int, num int, on int) (err error)
|
//sys Ioperm(from int, num int, on int) (err error)
|
||||||
//sys Iopl(level int) (err error)
|
//sys Iopl(level int) (err error)
|
||||||
//sys Lchown(path string, uid int, gid int) (err error)
|
//sys Lchown(path string, uid int, gid int) (err error)
|
||||||
|
@ -218,41 +215,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint32(length)
|
rsa.Service_name_len = uint32(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe(p *[2]_C_int) (err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe(&pp)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
|
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
|
||||||
|
|
||||||
func SyncFileRange(fd int, off int64, n int64, flags int) error {
|
func SyncFileRange(fd int, off int64, n int64, flags int) error {
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
@ -22,7 +20,6 @@ package unix
|
||||||
//sysnb Getgid() (gid int)
|
//sysnb Getgid() (gid int)
|
||||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT
|
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT
|
||||||
//sysnb Getuid() (uid int)
|
//sysnb Getuid() (uid int)
|
||||||
//sysnb InotifyInit() (fd int, err error)
|
|
||||||
//sys Ioperm(from int, num int, on int) (err error)
|
//sys Ioperm(from int, num int, on int) (err error)
|
||||||
//sys Iopl(level int) (err error)
|
//sys Iopl(level int) (err error)
|
||||||
//sys Lchown(path string, uid int, gid int) (err error)
|
//sys Lchown(path string, uid int, gid int) (err error)
|
||||||
|
@ -104,41 +101,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint64(length)
|
rsa.Service_name_len = uint64(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe(p *[2]_C_int) (err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe(&pp)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
|
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
|
||||||
|
|
||||||
func SyncFileRange(fd int, off int64, n int64, flags int) error {
|
func SyncFileRange(fd int, off int64, n int64, flags int) error {
|
||||||
|
|
|
@ -9,13 +9,6 @@ package unix
|
||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
func EpollCreate(size int) (fd int, err error) {
|
|
||||||
if size <= 0 {
|
|
||||||
return -1, EINVAL
|
|
||||||
}
|
|
||||||
return EpollCreate1(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
@ -144,30 +137,6 @@ func utimes(path string, tv *[2]Timeval) (err error) {
|
||||||
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, 0)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PtraceRegs) PC() uint64 { return r.Pc }
|
func (r *PtraceRegs) PC() uint64 { return r.Pc }
|
||||||
|
|
||||||
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
|
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
|
||||||
|
@ -192,27 +161,11 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint64(length)
|
rsa.Service_name_len = uint64(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
func InotifyInit() (fd int, err error) {
|
|
||||||
return InotifyInit1(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Pause() error {
|
func Pause() error {
|
||||||
_, err := ppoll(nil, 0, nil, nil)
|
_, err := ppoll(nil, 0, nil, nil)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
var ts *Timespec
|
|
||||||
if timeout >= 0 {
|
|
||||||
ts = new(Timespec)
|
|
||||||
*ts = NsecToTimespec(int64(timeout) * 1e6)
|
|
||||||
}
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return ppoll(nil, 0, ts, nil)
|
|
||||||
}
|
|
||||||
return ppoll(&fds[0], len(fds), ts, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
|
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
|
||||||
return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)
|
return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)
|
||||||
}
|
}
|
||||||
|
@ -229,7 +182,3 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error
|
||||||
}
|
}
|
||||||
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
|
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// dup2 exists because func Dup3 in syscall_linux.go references
|
|
||||||
// it in an unreachable path. dup2 isn't available on arm64.
|
|
||||||
func dup2(oldfd int, newfd int) error
|
|
||||||
|
|
|
@ -11,8 +11,6 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sysnb EpollCreate(size int) (fd int, err error)
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
@ -25,7 +23,6 @@ import (
|
||||||
//sysnb Getgid() (gid int)
|
//sysnb Getgid() (gid int)
|
||||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Getuid() (uid int)
|
//sysnb Getuid() (uid int)
|
||||||
//sysnb InotifyInit() (fd int, err error)
|
|
||||||
//sys Lchown(path string, uid int, gid int) (err error)
|
//sys Lchown(path string, uid int, gid int) (err error)
|
||||||
//sys Lstat(path string, stat *Stat_t) (err error)
|
//sys Lstat(path string, stat *Stat_t) (err error)
|
||||||
//sys Pause() (err error)
|
//sys Pause() (err error)
|
||||||
|
@ -77,30 +74,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||||
return Timeval{Sec: sec, Usec: usec}
|
return Timeval{Sec: sec, Usec: usec}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, 0) // pipe2 is the same as pipe when flags are set to 0.
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ioperm(from int, num int, on int) (err error) {
|
func Ioperm(from int, num int, on int) (err error) {
|
||||||
return ENOSYS
|
return ENOSYS
|
||||||
}
|
}
|
||||||
|
@ -324,15 +297,6 @@ func Shutdown(s, how int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
|
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
|
||||||
|
|
||||||
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
|
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
|
||||||
|
|
|
@ -9,7 +9,6 @@ package unix
|
||||||
|
|
||||||
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
//sys dup2(oldfd int, newfd int) (err error)
|
|
||||||
//sys Fchown(fd int, uid int, gid int) (err error)
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
//sys Fstat(fd int, stat *Stat_t) (err error)
|
//sys Fstat(fd int, stat *Stat_t) (err error)
|
||||||
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
||||||
|
@ -20,7 +19,6 @@ package unix
|
||||||
//sysnb Getgid() (gid int)
|
//sysnb Getgid() (gid int)
|
||||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Getuid() (uid int)
|
//sysnb Getuid() (uid int)
|
||||||
//sysnb InotifyInit() (fd int, err error)
|
|
||||||
//sys Lchown(path string, uid int, gid int) (err error)
|
//sys Lchown(path string, uid int, gid int) (err error)
|
||||||
//sys Listen(s int, n int) (err error)
|
//sys Listen(s int, n int) (err error)
|
||||||
//sys Lstat(path string, stat *Stat_t) (err error)
|
//sys Lstat(path string, stat *Stat_t) (err error)
|
||||||
|
@ -119,38 +117,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
|
||||||
rsa.Service_name_len = uint64(length)
|
rsa.Service_name_len = uint64(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb pipe(p *[2]_C_int) (err error)
|
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe(&pp)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
|
||||||
|
|
||||||
func Pipe2(p []int, flags int) (err error) {
|
|
||||||
if len(p) != 2 {
|
|
||||||
return EINVAL
|
|
||||||
}
|
|
||||||
var pp [2]_C_int
|
|
||||||
err = pipe2(&pp, flags)
|
|
||||||
p[0] = int(pp[0])
|
|
||||||
p[1] = int(pp[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
|
||||||
|
|
||||||
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
|
||||||
if len(fds) == 0 {
|
|
||||||
return poll(nil, 0, timeout)
|
|
||||||
}
|
|
||||||
return poll(&fds[0], len(fds), timeout)
|
|
||||||
}
|
|
||||||
|
|
|
@ -92,9 +92,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,9 +105,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
sa.raw.Scope_id = sa.ZoneId
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,9 +413,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa := new(SockaddrInet4)
|
sa := new(SockaddrInet4)
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
@ -428,9 +422,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
sa.ZoneId = pp.Scope_id
|
sa.ZoneId = pp.Scope_id
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
return nil, EAFNOSUPPORT
|
return nil, EAFNOSUPPORT
|
||||||
|
|
|
@ -67,9 +67,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,9 +81,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
p[0] = byte(sa.Port >> 8)
|
p[0] = byte(sa.Port >> 8)
|
||||||
p[1] = byte(sa.Port)
|
p[1] = byte(sa.Port)
|
||||||
sa.raw.Scope_id = sa.ZoneId
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.raw.Addr = sa.Addr
|
||||||
sa.raw.Addr[i] = sa.Addr[i]
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,9 +140,7 @@ func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
sa := new(SockaddrInet4)
|
sa := new(SockaddrInet4)
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
@ -155,9 +149,7 @@ func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
sa.Port = int(p[0])<<8 + int(p[1])
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
sa.ZoneId = pp.Scope_id
|
sa.ZoneId = pp.Scope_id
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
sa.Addr = pp.Addr
|
||||||
sa.Addr[i] = pp.Addr[i]
|
|
||||||
}
|
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
return nil, EAFNOSUPPORT
|
return nil, EAFNOSUPPORT
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
// SysvShmCtl performs control operations on the shared memory segment
|
||||||
|
// specified by id.
|
||||||
|
func SysvShmCtl(id, cmd int, desc *SysvShmDesc) (result int, err error) {
|
||||||
|
if runtime.GOARCH == "arm" ||
|
||||||
|
runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" {
|
||||||
|
cmd |= ipc_64
|
||||||
|
}
|
||||||
|
|
||||||
|
return shmctl(id, cmd, desc)
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
//go:build (darwin && !ios) || linux
|
||||||
|
// +build darwin,!ios linux
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/internal/unsafeheader"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SysvShmAttach attaches the Sysv shared memory segment associated with the
|
||||||
|
// shared memory identifier id.
|
||||||
|
func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
|
||||||
|
addr, errno := shmat(id, addr, flag)
|
||||||
|
if errno != nil {
|
||||||
|
return nil, errno
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the size of the shared memory to enable slice creation
|
||||||
|
var info SysvShmDesc
|
||||||
|
|
||||||
|
_, err := SysvShmCtl(id, IPC_STAT, &info)
|
||||||
|
if err != nil {
|
||||||
|
// release the shared memory if we can't find the size
|
||||||
|
|
||||||
|
// ignoring error from shmdt as there's nothing sensible to return here
|
||||||
|
shmdt(addr)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use unsafe to convert addr into a []byte.
|
||||||
|
// TODO: convert to unsafe.Slice once we can assume Go 1.17
|
||||||
|
var b []byte
|
||||||
|
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
|
||||||
|
hdr.Data = unsafe.Pointer(addr)
|
||||||
|
hdr.Cap = int(info.Segsz)
|
||||||
|
hdr.Len = int(info.Segsz)
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SysvShmDetach unmaps the shared memory slice returned from SysvShmAttach.
|
||||||
|
//
|
||||||
|
// It is not safe to use the slice after calling this function.
|
||||||
|
func SysvShmDetach(data []byte) error {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
return shmdt(uintptr(unsafe.Pointer(&data[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SysvShmGet returns the Sysv shared memory identifier associated with key.
|
||||||
|
// If the IPC_CREAT flag is specified a new segment is created.
|
||||||
|
func SysvShmGet(key, size, flag int) (id int, err error) {
|
||||||
|
return shmget(key, size, flag)
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
//go:build darwin && !ios
|
||||||
|
// +build darwin,!ios
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
// SysvShmCtl performs control operations on the shared memory segment
|
||||||
|
// specified by id.
|
||||||
|
func SysvShmCtl(id, cmd int, desc *SysvShmDesc) (result int, err error) {
|
||||||
|
return shmctl(id, cmd, desc)
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
// Code generated by mkmerge.go; DO NOT EDIT.
|
// Code generated by mkmerge; DO NOT EDIT.
|
||||||
|
|
||||||
//go:build linux
|
//go:build linux
|
||||||
// +build linux
|
// +build linux
|
||||||
|
@ -116,6 +116,7 @@ const (
|
||||||
ARPHRD_LAPB = 0x204
|
ARPHRD_LAPB = 0x204
|
||||||
ARPHRD_LOCALTLK = 0x305
|
ARPHRD_LOCALTLK = 0x305
|
||||||
ARPHRD_LOOPBACK = 0x304
|
ARPHRD_LOOPBACK = 0x304
|
||||||
|
ARPHRD_MCTP = 0x122
|
||||||
ARPHRD_METRICOM = 0x17
|
ARPHRD_METRICOM = 0x17
|
||||||
ARPHRD_NETLINK = 0x338
|
ARPHRD_NETLINK = 0x338
|
||||||
ARPHRD_NETROM = 0x0
|
ARPHRD_NETROM = 0x0
|
||||||
|
@ -231,6 +232,8 @@ const (
|
||||||
BPF_PSEUDO_FUNC = 0x4
|
BPF_PSEUDO_FUNC = 0x4
|
||||||
BPF_PSEUDO_KFUNC_CALL = 0x2
|
BPF_PSEUDO_KFUNC_CALL = 0x2
|
||||||
BPF_PSEUDO_MAP_FD = 0x1
|
BPF_PSEUDO_MAP_FD = 0x1
|
||||||
|
BPF_PSEUDO_MAP_IDX = 0x5
|
||||||
|
BPF_PSEUDO_MAP_IDX_VALUE = 0x6
|
||||||
BPF_PSEUDO_MAP_VALUE = 0x2
|
BPF_PSEUDO_MAP_VALUE = 0x2
|
||||||
BPF_RET = 0x6
|
BPF_RET = 0x6
|
||||||
BPF_RSH = 0x70
|
BPF_RSH = 0x70
|
||||||
|
@ -470,6 +473,7 @@ const (
|
||||||
DM_DEV_WAIT = 0xc138fd08
|
DM_DEV_WAIT = 0xc138fd08
|
||||||
DM_DIR = "mapper"
|
DM_DIR = "mapper"
|
||||||
DM_GET_TARGET_VERSION = 0xc138fd11
|
DM_GET_TARGET_VERSION = 0xc138fd11
|
||||||
|
DM_IMA_MEASUREMENT_FLAG = 0x80000
|
||||||
DM_INACTIVE_PRESENT_FLAG = 0x40
|
DM_INACTIVE_PRESENT_FLAG = 0x40
|
||||||
DM_INTERNAL_SUSPEND_FLAG = 0x40000
|
DM_INTERNAL_SUSPEND_FLAG = 0x40000
|
||||||
DM_IOCTL = 0xfd
|
DM_IOCTL = 0xfd
|
||||||
|
@ -714,6 +718,7 @@ const (
|
||||||
ETH_P_LOOPBACK = 0x9000
|
ETH_P_LOOPBACK = 0x9000
|
||||||
ETH_P_MACSEC = 0x88e5
|
ETH_P_MACSEC = 0x88e5
|
||||||
ETH_P_MAP = 0xf9
|
ETH_P_MAP = 0xf9
|
||||||
|
ETH_P_MCTP = 0xfa
|
||||||
ETH_P_MOBITEX = 0x15
|
ETH_P_MOBITEX = 0x15
|
||||||
ETH_P_MPLS_MC = 0x8848
|
ETH_P_MPLS_MC = 0x8848
|
||||||
ETH_P_MPLS_UC = 0x8847
|
ETH_P_MPLS_UC = 0x8847
|
||||||
|
@ -749,6 +754,21 @@ const (
|
||||||
ETH_P_WCCP = 0x883e
|
ETH_P_WCCP = 0x883e
|
||||||
ETH_P_X25 = 0x805
|
ETH_P_X25 = 0x805
|
||||||
ETH_P_XDSA = 0xf8
|
ETH_P_XDSA = 0xf8
|
||||||
|
EV_ABS = 0x3
|
||||||
|
EV_CNT = 0x20
|
||||||
|
EV_FF = 0x15
|
||||||
|
EV_FF_STATUS = 0x17
|
||||||
|
EV_KEY = 0x1
|
||||||
|
EV_LED = 0x11
|
||||||
|
EV_MAX = 0x1f
|
||||||
|
EV_MSC = 0x4
|
||||||
|
EV_PWR = 0x16
|
||||||
|
EV_REL = 0x2
|
||||||
|
EV_REP = 0x14
|
||||||
|
EV_SND = 0x12
|
||||||
|
EV_SW = 0x5
|
||||||
|
EV_SYN = 0x0
|
||||||
|
EV_VERSION = 0x10001
|
||||||
EXABYTE_ENABLE_NEST = 0xf0
|
EXABYTE_ENABLE_NEST = 0xf0
|
||||||
EXT2_SUPER_MAGIC = 0xef53
|
EXT2_SUPER_MAGIC = 0xef53
|
||||||
EXT3_SUPER_MAGIC = 0xef53
|
EXT3_SUPER_MAGIC = 0xef53
|
||||||
|
@ -787,9 +807,11 @@ const (
|
||||||
FAN_DELETE_SELF = 0x400
|
FAN_DELETE_SELF = 0x400
|
||||||
FAN_DENY = 0x2
|
FAN_DENY = 0x2
|
||||||
FAN_ENABLE_AUDIT = 0x40
|
FAN_ENABLE_AUDIT = 0x40
|
||||||
|
FAN_EPIDFD = -0x2
|
||||||
FAN_EVENT_INFO_TYPE_DFID = 0x3
|
FAN_EVENT_INFO_TYPE_DFID = 0x3
|
||||||
FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2
|
FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2
|
||||||
FAN_EVENT_INFO_TYPE_FID = 0x1
|
FAN_EVENT_INFO_TYPE_FID = 0x1
|
||||||
|
FAN_EVENT_INFO_TYPE_PIDFD = 0x4
|
||||||
FAN_EVENT_METADATA_LEN = 0x18
|
FAN_EVENT_METADATA_LEN = 0x18
|
||||||
FAN_EVENT_ON_CHILD = 0x8000000
|
FAN_EVENT_ON_CHILD = 0x8000000
|
||||||
FAN_MARK_ADD = 0x1
|
FAN_MARK_ADD = 0x1
|
||||||
|
@ -809,6 +831,7 @@ const (
|
||||||
FAN_MOVE_SELF = 0x800
|
FAN_MOVE_SELF = 0x800
|
||||||
FAN_NOFD = -0x1
|
FAN_NOFD = -0x1
|
||||||
FAN_NONBLOCK = 0x2
|
FAN_NONBLOCK = 0x2
|
||||||
|
FAN_NOPIDFD = -0x1
|
||||||
FAN_ONDIR = 0x40000000
|
FAN_ONDIR = 0x40000000
|
||||||
FAN_OPEN = 0x20
|
FAN_OPEN = 0x20
|
||||||
FAN_OPEN_EXEC = 0x1000
|
FAN_OPEN_EXEC = 0x1000
|
||||||
|
@ -819,6 +842,7 @@ const (
|
||||||
FAN_REPORT_DIR_FID = 0x400
|
FAN_REPORT_DIR_FID = 0x400
|
||||||
FAN_REPORT_FID = 0x200
|
FAN_REPORT_FID = 0x200
|
||||||
FAN_REPORT_NAME = 0x800
|
FAN_REPORT_NAME = 0x800
|
||||||
|
FAN_REPORT_PIDFD = 0x80
|
||||||
FAN_REPORT_TID = 0x100
|
FAN_REPORT_TID = 0x100
|
||||||
FAN_UNLIMITED_MARKS = 0x20
|
FAN_UNLIMITED_MARKS = 0x20
|
||||||
FAN_UNLIMITED_QUEUE = 0x10
|
FAN_UNLIMITED_QUEUE = 0x10
|
||||||
|
@ -1331,6 +1355,20 @@ const (
|
||||||
KEY_SPEC_THREAD_KEYRING = -0x1
|
KEY_SPEC_THREAD_KEYRING = -0x1
|
||||||
KEY_SPEC_USER_KEYRING = -0x4
|
KEY_SPEC_USER_KEYRING = -0x4
|
||||||
KEY_SPEC_USER_SESSION_KEYRING = -0x5
|
KEY_SPEC_USER_SESSION_KEYRING = -0x5
|
||||||
|
LANDLOCK_ACCESS_FS_EXECUTE = 0x1
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_BLOCK = 0x800
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_CHAR = 0x40
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_DIR = 0x80
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_FIFO = 0x400
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_REG = 0x100
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_SOCK = 0x200
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_SYM = 0x1000
|
||||||
|
LANDLOCK_ACCESS_FS_READ_DIR = 0x8
|
||||||
|
LANDLOCK_ACCESS_FS_READ_FILE = 0x4
|
||||||
|
LANDLOCK_ACCESS_FS_REMOVE_DIR = 0x10
|
||||||
|
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
|
||||||
|
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
|
||||||
|
LANDLOCK_CREATE_RULESET_VERSION = 0x1
|
||||||
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
||||||
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
||||||
LINUX_REBOOT_CMD_HALT = 0xcdef0123
|
LINUX_REBOOT_CMD_HALT = 0xcdef0123
|
||||||
|
@ -1381,6 +1419,8 @@ const (
|
||||||
MADV_NOHUGEPAGE = 0xf
|
MADV_NOHUGEPAGE = 0xf
|
||||||
MADV_NORMAL = 0x0
|
MADV_NORMAL = 0x0
|
||||||
MADV_PAGEOUT = 0x15
|
MADV_PAGEOUT = 0x15
|
||||||
|
MADV_POPULATE_READ = 0x16
|
||||||
|
MADV_POPULATE_WRITE = 0x17
|
||||||
MADV_RANDOM = 0x1
|
MADV_RANDOM = 0x1
|
||||||
MADV_REMOVE = 0x9
|
MADV_REMOVE = 0x9
|
||||||
MADV_SEQUENTIAL = 0x2
|
MADV_SEQUENTIAL = 0x2
|
||||||
|
@ -1436,6 +1476,18 @@ const (
|
||||||
MNT_FORCE = 0x1
|
MNT_FORCE = 0x1
|
||||||
MODULE_INIT_IGNORE_MODVERSIONS = 0x1
|
MODULE_INIT_IGNORE_MODVERSIONS = 0x1
|
||||||
MODULE_INIT_IGNORE_VERMAGIC = 0x2
|
MODULE_INIT_IGNORE_VERMAGIC = 0x2
|
||||||
|
MOUNT_ATTR_IDMAP = 0x100000
|
||||||
|
MOUNT_ATTR_NOATIME = 0x10
|
||||||
|
MOUNT_ATTR_NODEV = 0x4
|
||||||
|
MOUNT_ATTR_NODIRATIME = 0x80
|
||||||
|
MOUNT_ATTR_NOEXEC = 0x8
|
||||||
|
MOUNT_ATTR_NOSUID = 0x2
|
||||||
|
MOUNT_ATTR_NOSYMFOLLOW = 0x200000
|
||||||
|
MOUNT_ATTR_RDONLY = 0x1
|
||||||
|
MOUNT_ATTR_RELATIME = 0x0
|
||||||
|
MOUNT_ATTR_SIZE_VER0 = 0x20
|
||||||
|
MOUNT_ATTR_STRICTATIME = 0x20
|
||||||
|
MOUNT_ATTR__ATIME = 0x70
|
||||||
MSDOS_SUPER_MAGIC = 0x4d44
|
MSDOS_SUPER_MAGIC = 0x4d44
|
||||||
MSG_BATCH = 0x40000
|
MSG_BATCH = 0x40000
|
||||||
MSG_CMSG_CLOEXEC = 0x40000000
|
MSG_CMSG_CLOEXEC = 0x40000000
|
||||||
|
@ -1635,11 +1687,12 @@ const (
|
||||||
NFNL_MSG_BATCH_END = 0x11
|
NFNL_MSG_BATCH_END = 0x11
|
||||||
NFNL_NFA_NEST = 0x8000
|
NFNL_NFA_NEST = 0x8000
|
||||||
NFNL_SUBSYS_ACCT = 0x7
|
NFNL_SUBSYS_ACCT = 0x7
|
||||||
NFNL_SUBSYS_COUNT = 0xc
|
NFNL_SUBSYS_COUNT = 0xd
|
||||||
NFNL_SUBSYS_CTHELPER = 0x9
|
NFNL_SUBSYS_CTHELPER = 0x9
|
||||||
NFNL_SUBSYS_CTNETLINK = 0x1
|
NFNL_SUBSYS_CTNETLINK = 0x1
|
||||||
NFNL_SUBSYS_CTNETLINK_EXP = 0x2
|
NFNL_SUBSYS_CTNETLINK_EXP = 0x2
|
||||||
NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8
|
NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8
|
||||||
|
NFNL_SUBSYS_HOOK = 0xc
|
||||||
NFNL_SUBSYS_IPSET = 0x6
|
NFNL_SUBSYS_IPSET = 0x6
|
||||||
NFNL_SUBSYS_NFTABLES = 0xa
|
NFNL_SUBSYS_NFTABLES = 0xa
|
||||||
NFNL_SUBSYS_NFT_COMPAT = 0xb
|
NFNL_SUBSYS_NFT_COMPAT = 0xb
|
||||||
|
@ -1929,6 +1982,12 @@ const (
|
||||||
PR_PAC_GET_ENABLED_KEYS = 0x3d
|
PR_PAC_GET_ENABLED_KEYS = 0x3d
|
||||||
PR_PAC_RESET_KEYS = 0x36
|
PR_PAC_RESET_KEYS = 0x36
|
||||||
PR_PAC_SET_ENABLED_KEYS = 0x3c
|
PR_PAC_SET_ENABLED_KEYS = 0x3c
|
||||||
|
PR_SCHED_CORE = 0x3e
|
||||||
|
PR_SCHED_CORE_CREATE = 0x1
|
||||||
|
PR_SCHED_CORE_GET = 0x0
|
||||||
|
PR_SCHED_CORE_MAX = 0x4
|
||||||
|
PR_SCHED_CORE_SHARE_FROM = 0x3
|
||||||
|
PR_SCHED_CORE_SHARE_TO = 0x2
|
||||||
PR_SET_CHILD_SUBREAPER = 0x24
|
PR_SET_CHILD_SUBREAPER = 0x24
|
||||||
PR_SET_DUMPABLE = 0x4
|
PR_SET_DUMPABLE = 0x4
|
||||||
PR_SET_ENDIAN = 0x14
|
PR_SET_ENDIAN = 0x14
|
||||||
|
@ -1972,6 +2031,7 @@ const (
|
||||||
PR_SPEC_ENABLE = 0x2
|
PR_SPEC_ENABLE = 0x2
|
||||||
PR_SPEC_FORCE_DISABLE = 0x8
|
PR_SPEC_FORCE_DISABLE = 0x8
|
||||||
PR_SPEC_INDIRECT_BRANCH = 0x1
|
PR_SPEC_INDIRECT_BRANCH = 0x1
|
||||||
|
PR_SPEC_L1D_FLUSH = 0x2
|
||||||
PR_SPEC_NOT_AFFECTED = 0x0
|
PR_SPEC_NOT_AFFECTED = 0x0
|
||||||
PR_SPEC_PRCTL = 0x1
|
PR_SPEC_PRCTL = 0x1
|
||||||
PR_SPEC_STORE_BYPASS = 0x0
|
PR_SPEC_STORE_BYPASS = 0x0
|
||||||
|
@ -2295,6 +2355,7 @@ const (
|
||||||
SECCOMP_MODE_DISABLED = 0x0
|
SECCOMP_MODE_DISABLED = 0x0
|
||||||
SECCOMP_MODE_FILTER = 0x2
|
SECCOMP_MODE_FILTER = 0x2
|
||||||
SECCOMP_MODE_STRICT = 0x1
|
SECCOMP_MODE_STRICT = 0x1
|
||||||
|
SECRETMEM_MAGIC = 0x5345434d
|
||||||
SECURITYFS_MAGIC = 0x73636673
|
SECURITYFS_MAGIC = 0x73636673
|
||||||
SEEK_CUR = 0x1
|
SEEK_CUR = 0x1
|
||||||
SEEK_DATA = 0x3
|
SEEK_DATA = 0x3
|
||||||
|
@ -2406,12 +2467,15 @@ const (
|
||||||
SMART_WRITE_THRESHOLDS = 0xd7
|
SMART_WRITE_THRESHOLDS = 0xd7
|
||||||
SMB_SUPER_MAGIC = 0x517b
|
SMB_SUPER_MAGIC = 0x517b
|
||||||
SOCKFS_MAGIC = 0x534f434b
|
SOCKFS_MAGIC = 0x534f434b
|
||||||
|
SOCK_BUF_LOCK_MASK = 0x3
|
||||||
SOCK_DCCP = 0x6
|
SOCK_DCCP = 0x6
|
||||||
SOCK_IOC_TYPE = 0x89
|
SOCK_IOC_TYPE = 0x89
|
||||||
SOCK_PACKET = 0xa
|
SOCK_PACKET = 0xa
|
||||||
SOCK_RAW = 0x3
|
SOCK_RAW = 0x3
|
||||||
|
SOCK_RCVBUF_LOCK = 0x2
|
||||||
SOCK_RDM = 0x4
|
SOCK_RDM = 0x4
|
||||||
SOCK_SEQPACKET = 0x5
|
SOCK_SEQPACKET = 0x5
|
||||||
|
SOCK_SNDBUF_LOCK = 0x1
|
||||||
SOL_AAL = 0x109
|
SOL_AAL = 0x109
|
||||||
SOL_ALG = 0x117
|
SOL_ALG = 0x117
|
||||||
SOL_ATM = 0x108
|
SOL_ATM = 0x108
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build 386,linux
|
// +build 386,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -293,6 +293,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -309,6 +310,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x10
|
SO_PASSCRED = 0x10
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build amd64,linux
|
// +build amd64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -294,6 +294,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -310,6 +311,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x10
|
SO_PASSCRED = 0x10
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build arm,linux
|
// +build arm,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -300,6 +300,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -316,6 +317,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x10
|
SO_PASSCRED = 0x10
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build arm64,linux
|
// +build arm64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -290,6 +290,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -306,6 +307,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x10
|
SO_PASSCRED = 0x10
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build mips,linux
|
// +build mips,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -293,6 +293,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x20
|
SO_BROADCAST = 0x20
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -309,6 +310,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0x100
|
SO_OOBINLINE = 0x100
|
||||||
SO_PASSCRED = 0x11
|
SO_PASSCRED = 0x11
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build mips64,linux
|
// +build mips64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -293,6 +293,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x20
|
SO_BROADCAST = 0x20
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -309,6 +310,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0x100
|
SO_OOBINLINE = 0x100
|
||||||
SO_PASSCRED = 0x11
|
SO_PASSCRED = 0x11
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build mips64le,linux
|
// +build mips64le,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -293,6 +293,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x20
|
SO_BROADCAST = 0x20
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -309,6 +310,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0x100
|
SO_OOBINLINE = 0x100
|
||||||
SO_PASSCRED = 0x11
|
SO_PASSCRED = 0x11
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build mipsle,linux
|
// +build mipsle,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -293,6 +293,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x20
|
SO_BROADCAST = 0x20
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -309,6 +310,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0x100
|
SO_OOBINLINE = 0x100
|
||||||
SO_PASSCRED = 0x11
|
SO_PASSCRED = 0x11
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build ppc,linux
|
// +build ppc,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -348,6 +348,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -364,6 +365,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x14
|
SO_PASSCRED = 0x14
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build ppc64,linux
|
// +build ppc64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -352,6 +352,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -368,6 +369,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x14
|
SO_PASSCRED = 0x14
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build ppc64le,linux
|
// +build ppc64le,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -352,6 +352,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -368,6 +369,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x14
|
SO_PASSCRED = 0x14
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build riscv64,linux
|
// +build riscv64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -281,6 +281,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -297,6 +298,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x10
|
SO_PASSCRED = 0x10
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build s390x,linux
|
// +build s390x,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -356,6 +356,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x30
|
SO_BPF_EXTENSIONS = 0x30
|
||||||
SO_BROADCAST = 0x6
|
SO_BROADCAST = 0x6
|
||||||
SO_BSDCOMPAT = 0xe
|
SO_BSDCOMPAT = 0xe
|
||||||
|
SO_BUF_LOCK = 0x48
|
||||||
SO_BUSY_POLL = 0x2e
|
SO_BUSY_POLL = 0x2e
|
||||||
SO_BUSY_POLL_BUDGET = 0x46
|
SO_BUSY_POLL_BUDGET = 0x46
|
||||||
SO_CNX_ADVICE = 0x35
|
SO_CNX_ADVICE = 0x35
|
||||||
|
@ -372,6 +373,7 @@ const (
|
||||||
SO_MARK = 0x24
|
SO_MARK = 0x24
|
||||||
SO_MAX_PACING_RATE = 0x2f
|
SO_MAX_PACING_RATE = 0x2f
|
||||||
SO_MEMINFO = 0x37
|
SO_MEMINFO = 0x37
|
||||||
|
SO_NETNS_COOKIE = 0x47
|
||||||
SO_NOFCS = 0x2b
|
SO_NOFCS = 0x2b
|
||||||
SO_OOBINLINE = 0xa
|
SO_OOBINLINE = 0xa
|
||||||
SO_PASSCRED = 0x10
|
SO_PASSCRED = 0x10
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// +build sparc64,linux
|
// +build sparc64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
@ -347,6 +347,7 @@ const (
|
||||||
SO_BPF_EXTENSIONS = 0x32
|
SO_BPF_EXTENSIONS = 0x32
|
||||||
SO_BROADCAST = 0x20
|
SO_BROADCAST = 0x20
|
||||||
SO_BSDCOMPAT = 0x400
|
SO_BSDCOMPAT = 0x400
|
||||||
|
SO_BUF_LOCK = 0x51
|
||||||
SO_BUSY_POLL = 0x30
|
SO_BUSY_POLL = 0x30
|
||||||
SO_BUSY_POLL_BUDGET = 0x49
|
SO_BUSY_POLL_BUDGET = 0x49
|
||||||
SO_CNX_ADVICE = 0x37
|
SO_CNX_ADVICE = 0x37
|
||||||
|
@ -363,6 +364,7 @@ const (
|
||||||
SO_MARK = 0x22
|
SO_MARK = 0x22
|
||||||
SO_MAX_PACING_RATE = 0x31
|
SO_MAX_PACING_RATE = 0x31
|
||||||
SO_MEMINFO = 0x39
|
SO_MEMINFO = 0x39
|
||||||
|
SO_NETNS_COOKIE = 0x50
|
||||||
SO_NOFCS = 0x27
|
SO_NOFCS = 0x27
|
||||||
SO_OOBINLINE = 0x100
|
SO_OOBINLINE = 0x100
|
||||||
SO_PASSCRED = 0x2
|
SO_PASSCRED = 0x2
|
||||||
|
|
|
@ -17,6 +17,7 @@ int getdirent(int, uintptr_t, size_t);
|
||||||
int wait4(int, uintptr_t, int, uintptr_t);
|
int wait4(int, uintptr_t, int, uintptr_t);
|
||||||
int ioctl(int, int, uintptr_t);
|
int ioctl(int, int, uintptr_t);
|
||||||
int fcntl(uintptr_t, int, uintptr_t);
|
int fcntl(uintptr_t, int, uintptr_t);
|
||||||
|
int fsync_range(int, int, long long, long long);
|
||||||
int acct(uintptr_t);
|
int acct(uintptr_t);
|
||||||
int chdir(uintptr_t);
|
int chdir(uintptr_t);
|
||||||
int chroot(uintptr_t);
|
int chroot(uintptr_t);
|
||||||
|
@ -29,7 +30,6 @@ int fchmod(int, unsigned int);
|
||||||
int fchmodat(int, uintptr_t, unsigned int, int);
|
int fchmodat(int, uintptr_t, unsigned int, int);
|
||||||
int fchownat(int, uintptr_t, int, int, int);
|
int fchownat(int, uintptr_t, int, int, int);
|
||||||
int fdatasync(int);
|
int fdatasync(int);
|
||||||
int fsync(int);
|
|
||||||
int getpgid(int);
|
int getpgid(int);
|
||||||
int getpgrp();
|
int getpgrp();
|
||||||
int getpid();
|
int getpid();
|
||||||
|
@ -255,6 +255,16 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func fsyncRange(fd int, how int, start int64, length int64) (err error) {
|
||||||
|
r0, er := C.fsync_range(C.int(fd), C.int(how), C.longlong(start), C.longlong(length))
|
||||||
|
if r0 == -1 && er != nil {
|
||||||
|
err = er
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Acct(path string) (err error) {
|
func Acct(path string) (err error) {
|
||||||
_p0 := uintptr(unsafe.Pointer(C.CString(path)))
|
_p0 := uintptr(unsafe.Pointer(C.CString(path)))
|
||||||
r0, er := C.acct(C.uintptr_t(_p0))
|
r0, er := C.acct(C.uintptr_t(_p0))
|
||||||
|
@ -379,16 +389,6 @@ func Fdatasync(fd int) (err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Fsync(fd int) (err error) {
|
|
||||||
r0, er := C.fsync(C.int(fd))
|
|
||||||
if r0 == -1 && er != nil {
|
|
||||||
err = er
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Getpgid(pid int) (pgid int, err error) {
|
func Getpgid(pid int) (pgid int, err error) {
|
||||||
r0, er := C.getpgid(C.int(pid))
|
r0, er := C.getpgid(C.int(pid))
|
||||||
pgid = int(r0)
|
pgid = int(r0)
|
||||||
|
|
|
@ -135,6 +135,16 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func fsyncRange(fd int, how int, start int64, length int64) (err error) {
|
||||||
|
_, e1 := callfsync_range(fd, how, start, length)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Acct(path string) (err error) {
|
func Acct(path string) (err error) {
|
||||||
var _p0 *byte
|
var _p0 *byte
|
||||||
_p0, err = BytePtrFromString(path)
|
_p0, err = BytePtrFromString(path)
|
||||||
|
@ -283,16 +293,6 @@ func Fdatasync(fd int) (err error) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Fsync(fd int) (err error) {
|
|
||||||
_, e1 := callfsync(fd)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func Getpgid(pid int) (pgid int, err error) {
|
func Getpgid(pid int) (pgid int, err error) {
|
||||||
r0, e1 := callgetpgid(pid)
|
r0, e1 := callgetpgid(pid)
|
||||||
pgid = int(r0)
|
pgid = int(r0)
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
//go:cgo_import_dynamic libc_wait4 wait4 "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_wait4 wait4 "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_ioctl ioctl "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_ioctl ioctl "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_fcntl fcntl "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_fcntl fcntl "libc.a/shr_64.o"
|
||||||
|
//go:cgo_import_dynamic libc_fsync_range fsync_range "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_acct acct "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_acct acct "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_chdir chdir "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_chdir chdir "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_chroot chroot "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_chroot chroot "libc.a/shr_64.o"
|
||||||
|
@ -30,7 +31,6 @@ import (
|
||||||
//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_fchownat fchownat "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_fchownat fchownat "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_fdatasync fdatasync "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_fdatasync fdatasync "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_fsync fsync "libc.a/shr_64.o"
|
|
||||||
//go:cgo_import_dynamic libc_getpgid getpgid "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_getpgid getpgid "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.a/shr_64.o"
|
||||||
//go:cgo_import_dynamic libc_getpid getpid "libc.a/shr_64.o"
|
//go:cgo_import_dynamic libc_getpid getpid "libc.a/shr_64.o"
|
||||||
|
@ -136,6 +136,7 @@ import (
|
||||||
//go:linkname libc_wait4 libc_wait4
|
//go:linkname libc_wait4 libc_wait4
|
||||||
//go:linkname libc_ioctl libc_ioctl
|
//go:linkname libc_ioctl libc_ioctl
|
||||||
//go:linkname libc_fcntl libc_fcntl
|
//go:linkname libc_fcntl libc_fcntl
|
||||||
|
//go:linkname libc_fsync_range libc_fsync_range
|
||||||
//go:linkname libc_acct libc_acct
|
//go:linkname libc_acct libc_acct
|
||||||
//go:linkname libc_chdir libc_chdir
|
//go:linkname libc_chdir libc_chdir
|
||||||
//go:linkname libc_chroot libc_chroot
|
//go:linkname libc_chroot libc_chroot
|
||||||
|
@ -148,7 +149,6 @@ import (
|
||||||
//go:linkname libc_fchmodat libc_fchmodat
|
//go:linkname libc_fchmodat libc_fchmodat
|
||||||
//go:linkname libc_fchownat libc_fchownat
|
//go:linkname libc_fchownat libc_fchownat
|
||||||
//go:linkname libc_fdatasync libc_fdatasync
|
//go:linkname libc_fdatasync libc_fdatasync
|
||||||
//go:linkname libc_fsync libc_fsync
|
|
||||||
//go:linkname libc_getpgid libc_getpgid
|
//go:linkname libc_getpgid libc_getpgid
|
||||||
//go:linkname libc_getpgrp libc_getpgrp
|
//go:linkname libc_getpgrp libc_getpgrp
|
||||||
//go:linkname libc_getpid libc_getpid
|
//go:linkname libc_getpid libc_getpid
|
||||||
|
@ -257,6 +257,7 @@ var (
|
||||||
libc_wait4,
|
libc_wait4,
|
||||||
libc_ioctl,
|
libc_ioctl,
|
||||||
libc_fcntl,
|
libc_fcntl,
|
||||||
|
libc_fsync_range,
|
||||||
libc_acct,
|
libc_acct,
|
||||||
libc_chdir,
|
libc_chdir,
|
||||||
libc_chroot,
|
libc_chroot,
|
||||||
|
@ -269,7 +270,6 @@ var (
|
||||||
libc_fchmodat,
|
libc_fchmodat,
|
||||||
libc_fchownat,
|
libc_fchownat,
|
||||||
libc_fdatasync,
|
libc_fdatasync,
|
||||||
libc_fsync,
|
|
||||||
libc_getpgid,
|
libc_getpgid,
|
||||||
libc_getpgrp,
|
libc_getpgrp,
|
||||||
libc_getpid,
|
libc_getpid,
|
||||||
|
@ -430,6 +430,13 @@ func callfcntl(fd uintptr, cmd int, arg uintptr) (r1 uintptr, e1 Errno) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func callfsync_range(fd int, how int, start int64, length int64) (r1 uintptr, e1 Errno) {
|
||||||
|
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fsync_range)), 4, uintptr(fd), uintptr(how), uintptr(start), uintptr(length), 0, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
|
func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
|
||||||
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_acct)), 1, _p0, 0, 0, 0, 0, 0)
|
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_acct)), 1, _p0, 0, 0, 0, 0, 0)
|
||||||
return
|
return
|
||||||
|
@ -514,13 +521,6 @@ func callfdatasync(fd int) (r1 uintptr, e1 Errno) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func callfsync(fd int) (r1 uintptr, e1 Errno) {
|
|
||||||
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_fsync)), 1, uintptr(fd), 0, 0, 0, 0, 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
|
func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
|
||||||
r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0)
|
r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_getpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0)
|
||||||
return
|
return
|
||||||
|
|
|
@ -16,6 +16,7 @@ int getdirent(int, uintptr_t, size_t);
|
||||||
int wait4(int, uintptr_t, int, uintptr_t);
|
int wait4(int, uintptr_t, int, uintptr_t);
|
||||||
int ioctl(int, int, uintptr_t);
|
int ioctl(int, int, uintptr_t);
|
||||||
int fcntl(uintptr_t, int, uintptr_t);
|
int fcntl(uintptr_t, int, uintptr_t);
|
||||||
|
int fsync_range(int, int, long long, long long);
|
||||||
int acct(uintptr_t);
|
int acct(uintptr_t);
|
||||||
int chdir(uintptr_t);
|
int chdir(uintptr_t);
|
||||||
int chroot(uintptr_t);
|
int chroot(uintptr_t);
|
||||||
|
@ -28,7 +29,6 @@ int fchmod(int, unsigned int);
|
||||||
int fchmodat(int, uintptr_t, unsigned int, int);
|
int fchmodat(int, uintptr_t, unsigned int, int);
|
||||||
int fchownat(int, uintptr_t, int, int, int);
|
int fchownat(int, uintptr_t, int, int, int);
|
||||||
int fdatasync(int);
|
int fdatasync(int);
|
||||||
int fsync(int);
|
|
||||||
int getpgid(int);
|
int getpgid(int);
|
||||||
int getpgrp();
|
int getpgrp();
|
||||||
int getpid();
|
int getpid();
|
||||||
|
@ -199,6 +199,14 @@ func callfcntl(fd uintptr, cmd int, arg uintptr) (r1 uintptr, e1 Errno) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func callfsync_range(fd int, how int, start int64, length int64) (r1 uintptr, e1 Errno) {
|
||||||
|
r1 = uintptr(C.fsync_range(C.int(fd), C.int(how), C.longlong(start), C.longlong(length)))
|
||||||
|
e1 = syscall.GetErrno()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
|
func callacct(_p0 uintptr) (r1 uintptr, e1 Errno) {
|
||||||
r1 = uintptr(C.acct(C.uintptr_t(_p0)))
|
r1 = uintptr(C.acct(C.uintptr_t(_p0)))
|
||||||
e1 = syscall.GetErrno()
|
e1 = syscall.GetErrno()
|
||||||
|
@ -295,14 +303,6 @@ func callfdatasync(fd int) (r1 uintptr, e1 Errno) {
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func callfsync(fd int) (r1 uintptr, e1 Errno) {
|
|
||||||
r1 = uintptr(C.fsync(C.int(fd)))
|
|
||||||
e1 = syscall.GetErrno()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
|
func callgetpgid(pid int) (r1 uintptr, e1 Errno) {
|
||||||
r1 = uintptr(C.getpgid(C.int(pid)))
|
r1 = uintptr(C.getpgid(C.int(pid)))
|
||||||
e1 = syscall.GetErrno()
|
e1 = syscall.GetErrno()
|
||||||
|
|
|
@ -734,6 +734,65 @@ var libc_sendfile_trampoline_addr uintptr
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) {
|
||||||
|
r0, _, e1 := syscall_syscall(libc_shmat_trampoline_addr, uintptr(id), uintptr(addr), uintptr(flag))
|
||||||
|
ret = uintptr(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_shmat_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_shmat shmat "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) {
|
||||||
|
r0, _, e1 := syscall_syscall(libc_shmctl_trampoline_addr, uintptr(id), uintptr(cmd), uintptr(unsafe.Pointer(buf)))
|
||||||
|
result = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_shmctl_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_shmctl shmctl "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func shmdt(addr uintptr) (err error) {
|
||||||
|
_, _, e1 := syscall_syscall(libc_shmdt_trampoline_addr, uintptr(addr), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_shmdt_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_shmdt shmdt "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func shmget(key int, size int, flag int) (id int, err error) {
|
||||||
|
r0, _, e1 := syscall_syscall(libc_shmget_trampoline_addr, uintptr(key), uintptr(size), uintptr(flag))
|
||||||
|
id = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_shmget_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_shmget shmget "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Access(path string, mode uint32) (err error) {
|
func Access(path string, mode uint32) (err error) {
|
||||||
var _p0 *byte
|
var _p0 *byte
|
||||||
_p0, err = BytePtrFromString(path)
|
_p0, err = BytePtrFromString(path)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue