| Age | Commit message (Collapse) | Author |
|
There is an issue with current SSH client implementation.
Given a single host public key in the known_hosts file,
host ssh-ed25519 key...
Calling ssh.Dial(`tcp`, "host", ...) will return an error
knownhosts: key mismatch
from [handshakeTransport.enterKeyExchange], because only key
"mlkem768x25519-sha256" is checked on the client side.
This changes add DB interface for knownhosts that have two methods:
- HostKeyAlgorithms: return the host key that matches in known_hosts
based on the "host" name or address for
[ssh.ClientConfig.HostKeyAlgorithms].
- HostKeyCallback: return the ssh.HostKeyCallback for
[ssh.ClientConfig.HostKeyCallback].
|
|
The "nolint" tag is used to ignore lines from being processed by
golangci-lint.
Since we are not using golangci-lint anymore, now and in the
future, those lines can be removed.
|
|
Instead of depends on fork of crypto with CL that needs [proposal],
implement them in here so we can update crypto to the latest release.
[proposal]: https://go-review.googlesource.com/c/crypto/+/552435
|
|
Previously the "ssh/config" is used by the parent package "ssh" and
"ssh/sftp" which is break the rule of package layer (the top package
should be imported by sub package, not the other way around).
|
|
For HTTP server that use TLS, set the minimum TLS version and
ReadHeaderTimeout to mitigate slowloris attack.
For HTTP client or server that parameterize the use of InsecureSkipVerify,
annotate the line with "nolint:gosec" to allow the code pass the check.
Library that still use sha1, in example in DKIM and TOTP, skip the
warnings by annotating the line with "nolint:gosec".
A pointer variable now allocated their address before assigning its
value.
Any error that returned now wrapped using "%w".
Also, replace error checking using [errors.Is] or [errors.As] instead of
using equal or not-equal operators.
In "lib/http", replace any usage of "math/rand" with "crypto/rand".
Any call of [math/big.Rat.SetString] now annotated with "nolint:gosec"
since its false positive, the issue has been fixed in Go >= 1.17.7.
Any switch case that does not cover the rest of the possible values now
handled by adding the cases or by replacing the "default" case with
the rest of values.
|
|
HTTP request now implicitly create request with context.
Any false positive related to not closing HTTP response body has been
annotated with "nolint:bodyclose".
In the example code, use consistent "// Output:" comment format, by
prefixing with single space.
Any comment on code now also prefixing with single space.
An error returned without variables now use [errors.New] instead of
[fmt.Errorf].
Any error returned using [fmt.Errorf] now wrapped using "%w" instead of
"%s".
Also, replace error checking using [errors.Is] or [errors.As], instead
of using equal/not-equal operator.
Any statement like "x = x OP y" now replaced with "x OP= y".
Also, swap statement is simplified using "x, y = y, x".
Any switch statement with single case now replaced with if-condition.
Any call to defer on function or program that call [os.Exit], now
replaced by calling the deferred function directly.
Any if-else condition now replaced with switch statement, if possible.
|
|
There are several reasons that why we move from github.com.
First, related to the name of package.
We accidentally name the package with "share" a common word in English
that does not reflect the content of repository.
By moving to other repository, we can rename it to better and unique
name, in this "pakakeh.go".
Pakakeh is Minang word for tools, and ".go" suffix indicate that the
repository related to Go programming language.
Second, supporting open source.
The new repository is hosted under sourcehut.org, the founder is known
to support open source, and all their services are licensed under AGPL,
unlike GitHub that are closed sources.
Third, regarding GitHub CoPilot.
The GitHub Terms of Service [1], allow any public content that are hosted
there granted them to parse the content.
On one side, GitHub helps and flourish the open source, but on another
side have an issues regarding scraping the copyleft license [2].
[1]: https://docs.github.com/en/site-policy/github-terms/github-terms-of-service#4-license-grant-to-us
[2]: https://githubcopilotinvestigation.com
|
|
This changes require the fork of our golang.org/x/crypto.
|
|
The Output method run the command and return its standard output and
error as is.
Any other error beside standard error, like connection, will be returned
as error.
|
|
If the library failed to changes os.Stdin to raw, it will try to use
a program defined in SSH_ASKPASS environment variable.
The SSH_ASKPASS is controlled by environment SSH_ASKPASS_REQUIRE.
- If SSH_ASKPASS_REQUIRE is empty the passphrase will read from
terminal first, if not possible then using SSH_ASKPASS program.
- If SSH_ASKPASS_REQUIRE is set to "never" the passphrase will read
from terminal only.
- If SSH_ASKPASS_REQUIRE is set to "prefer", the passphrase will read
using SSH_ASKPASS program not from terminal, but require
DISPLAY environment to be set.
- If SSH_ASKPASS_REQUIRE is set to "force", the passphrase will read
using SSH_ASKPASS program not from terminal, without checking DISPLAY
environment.
This changes affect the [ssh.NewClientInteractive] indirectly.
|
|
|
|
Using replace directive does not works well if we install binary using
"go install".
One of the case that we found is when user installing awwan [1] that use
"share" module [2] with replace directive, the binary is not build with
git.sr.ht/~shulhan/go-x-crypto.
/Users/xxx/go/bin/awwan: go1.21.0
path git.sr.ht/~shulhan/awwan/cmd/awwan
mod git.sr.ht/~shulhan/awwan v0.7.1-0.20230925173020-40b9fe9b854c h1:629djcSfqM8ITX+CtgGyrybPnKQPpwJ/EceN967bKps=
dep git.sr.ht/~shulhan/asciidoctor-go v0.5.0 h1:TfcAjv+7EwBZ83ef8OhX9vfQ4vRFcaJh0P1XXgbsJv0=
dep git.sr.ht/~shulhan/ciigo v0.10.0 h1:s1SJ3/NzBcbOLmEZ4z1Cx9Vf7ZdDIvm45b7KMCZKzEY=
dep github.com/evanw/esbuild v0.19.3 h1:foPr0xwQM3lBWKBtscauTN9FrmJzRDVI2+EGOs82H/I=
dep github.com/shuLhan/share v0.49.2-0.20230923081600-77c41ce992e6 h1:REQDC2UKLaWT1WGd/Iw/rfKLkXb7vtKtyObkeZeHZRk=
dep github.com/yuin/goldmark v1.5.6 h1:COmQAWTCcGetChm3Ig7G/t8AFAN00t+o8Mt4cf7JpwA=
dep github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
dep golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
dep golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
dep golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
dep golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
dep gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
build -buildmode=exe
build -compiler=gc
build DefaultGODEBUG=panicnil=1
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=arm64
build GOOS=darwin
This changes require use to modify lib/cryto and lib/ssh that depends
on our patches.
[1] https://git.sr.ht/~shulhan/awwan
[2] https://github.com/shuLhan/share/commit/77c41ce992e6
|
|
Previously, the ScpPut and ScpGet use the first IdentityFile in section
to use in "-i" argument.
This is not correct
If the section contains two or more IdentityFile and the one that can
connect are the last one, the ScpPut and ScpGet method may return an
error when executing the "scp" command.
|
|
The Close method close the client connection and release all resources.
|
|
The ssh Client have two configurations, one configuration for Dial from
parent package crypto/ssh.ClientConfig and one from
lib/ssh/config.Section.
In order to distinguish it better, we change the second configuration
from "cfg" to "section".
|
|
|
|
|
|
Previously, the ssh Client always use InsecureIgnoreHostKey in
HostKeyCallback.
This may post security issue, like man-in-the-middle attack, since we
did not check the server host key with one of key that known by client
from UserKnownHostFile (for example ~/.ssh/known_hosts).
This changes use the SSH section UserKnownHostFile from configuration
(default to ~/.ssh/known_hosts) to check if the server host key is
valid.
The NewClientInteractive will return an error, "key is unknown", if host
key not exist in UserKnownHostFile or "key is mismatch" if host key
not match with one registered in UserKnownHostFile.
This changes depends on patch of golang.org/x/crypto [1] that has not
reviewed yet, so we need to replace it with one that contains the patch.
[1] https://go-review.googlesource.com/c/crypto/+/523555
|
|
Previously, the NewClientInteractive blindly use the signers from
Section.Signers.
If one of the IdentityFile valid, it will add all the keys in
IdentityFile to SSH agent.
In this changes we try each IdentityFile independently.
If the key is valid, client connected to remote machine, then only that
key will be added to SSH agent.
While at it we also rename the method to NewClientInteractive to
indicate that the function will prompt for passphrase if one of the
IdentityFile is encrypted.
|
|
Instead of storing each Section value in separate field, store them
inside a map, Field.
This reduce the size of Section and simplify adding or getting the
key that we are not supported but maybe usable by user in the future.
This changes introduce several new methods as replacement of field:
* CASignatureAlgorithms: a method that return list of signature
algorithms that Section set or the default
* CanonicalDomains: a method that return CanonicalDomains set in Section
* CanonicalizePermittedCNames: return the permitted CNAMEs set in Section,
from KeyCanonicalizePermittedCNames.
* CertificateFile: return list of certificate file
* Environments: return system and/or custom environment that will be
passed to remote machine.
The key and value is derived from "SendEnv" and "SetEnv".
* FieldBool: return field value as boolean
* FieldInt: return the field value as int
* Hostname: return the Hostname in this Section
* IdentityAgent: return the path to SSH agent socket to be used
* Port: return the remote machine port
* User: return the remote user name
* Set: set the Field using key and value
|
|
This is for clarity in the code, better to be explicit by typing where
the field or methods come from.
|
|
In NewClientFromConfig, if Client connect using IdentityFile instead of
agent and its success, we add the private key to agent directly.
Unfortunately, since we did not know which key is being negotiated, we
add all private keys parsed from IdentityFile.
|
|
This is to make the method compatible with ssh.PublicKeysCallback.
Each parsed and unsigned IdentityFile is stored in field PrivateKeys,
replacing the Signers field (which is conflict with method names).
|
|
If ~/.ssh/config contains a Host section with IdentityFile directive specified
and SSH_AUTH_SOCK environment variable is also set, but ssh_config
section does not specify "IdentityAgent none" explicitly, the NewClientFromConfig
returns an error saying
NewClient: ssh: handshake failed: ssh: unable to authenticate, attempted
methods [none publickey], no supported methods remain.
This changes fix this by dialing remote server twice.
Fix #1
|
|
|
|
Previously, we only check the environment variable SSH_AUTH_SOCK
to decide whether the client identity will fetched from agent or
from private key file.
This changes use the GetIdentityAgent from config Section to derive the
path to unix socket. It will return an empty string if the IdentityAgent
is set to "none" in the Section or when SSH_AUTH_SOCK is not exist or
empty.
|
|
Previously, all of the SSH output and error goes to os.Stdout and
os.Stderr.
This changes add method SetSessionOutputError to change the output and
error for future remote execution.
|
|
This changes is to make clear that the methods to copy the files, either
from local or from remote, is using the "scp" through exec package,
not using the native SSH file transfer protocol.
While at it, use consistent log prefix for error message.
|
|
This will allow seamless integration with the x/crypto/ssh Client type.
|
|
This is to differentiate it with x/crypto ssh package that have the same
function name.
|
|
There are two reasons for moving to sub-package. First, the code for
parsing the ssh_config(5) take almost 99% of the lines in the ssh package.
Second, in case we want to submit the code to upstream,
golang.org/x/crypto, we need the package to be independent, less external
dependencies as possible.
|
|
If the private key file is empty, skip it for being added as parameter
of scp command. This is to prevent warning message on user side.
|
|
Previously, the client use the IdentityFile on ConfigSection to
authenticate with the remote SSH server. In case the IdentityFile is
encrypted with passphrase, each time NewClient is invoked it will ask
for passphrase.
To minimize inputing the passphrase, we check if current use run the
SSH agent through SSH_AUTH_SOCK environment variable and use the agent
to generate signers.
This method need manual key added by user to SSH agent before calling
NewClient to make it works.
|
|
In case the private key defined in IdentityFile is encrypted, prompt
for the passphrase on the screen and read it from stdin using
term.ReadPassword().
This changes also remove call to generateSigners on postConfig(),
instead invoke it from NewClient() to minimize multiple calls to
generateSigners().
|
|
|
|
Now that the Config can parse Host and required fields (User, Hostname,
Port, and IdentityFile), we can use the ConfigSection to be passed
to parameter when creating new Client.
|
|
|
|
The valid syntax to suppress linter warnings is "//nolint:<name>" with
no space between comment and "nolint" and between ":". Also, we move the
placement of nolint directive to the top of statements for multiple
nolint in the same scope.
While at it, fix and supress some linter warnings.
|
|
|
|
The field Environments contains system environment variables that will
be passed to Execute.
|
|
This package provide a simple client initialization with additional
methods to copy file from local or remote using scp.
|