| 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].
|
|
With help of spdxconv tool [1], we able to bulk update all files license
and copyright format to comply with SPDX formats.
[1] https://kilabit.info/project/spdxconv/
|
|
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.
|
|
Instead of annotating the lines that caught by linters, fix it to comply
with the recommendations.
This causes several breaking changes, especially related to naming,
* api/slack: [Message.IconUrl] become [Message.IconURL]
* lib/dns: DefaultSoaMinumumTtl become DefaultSoaMinimumTTL
* lib/email: [Message.SetBodyHtml] become [Message.SetBodyHTML]
* lib/http: [Client.GenerateHttpRequest] become
[Client.GenerateHTTPRequest]
* lib/http: [ClientOptions.ServerUrl] become [ClientOptions.ServerURL]
* lib/http: [EndpointRequest.HttpWriter] become
[EndpointRequest.HTTPWriter]
* lib/http: [EndpointRequest.HttpRequest] become
[EndpointRequest.HTTPRequest]
* lib/http: [ServerOptions.EnableIndexHtml] become
[ServerOptions.EnableIndexHTML]
* lib/http: [SSEConn.HttpRequest] become [SSEConn.HTTPRequest]
* lib/smtp: [ClientOptions.ServerUrl] become [ClientOptions.ServerURL]
* lib/ssh/sftp: [FileAttrs.SetUid] become [FileAttrs.SetUID]
* lib/ssh/sftp: [FileAttrs.Uid] become [FileAttrs.UID]
|
|
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 rename method [Config.Prepend] to [Config.Merge].
The way that how the other Config merged is changed.
Instead of appending all of other's sections into the current Config,
append the other Config instance to the current instance of Config.
During [Config.Get] the top Config will be evaluated first, and then the
other Config is evaluated in order of Merge.
|
|
Instead of using [Section.Set], set the key-value directly.
While at it, merge the certificateFile, IdentityFile, knownHostFiles,
and sendEnv.
|
|
While at it, unfold each value of IdentityFile and UserKnownHostsFile
in setDefaults, by expanding "~" into user's home directory or joining
with "config" directory if its relative.
|
|
Make it clear that the passed parameter is a host name and the returned
section will contains default values if no host or match found.
|
|
This changes how the Section and parser initialized.
Previously, the Config depends on the parser to set the workDir and
homeDir and Section depends on Config only on Get; now its the other
way around, from top to bottom.
Config initialized first, then parser initialized using Config instance,
and then Section initialized also using Config instance.
|
|
The field default value should be set on Get, after all the Host or
Match fields merged.
In this way, if the field key already set, its not overridden by the
default value or subsequent Host or Match vaue.
|
|
This changes require the fork of our golang.org/x/crypto.
|
|
Per manual ssh_config(5) on Hostname,
The default is the name given on the command line.
So, if the requested host name match with one of Host or Match, but
Hostname is not set, it should be default to the requested parameter
name.
|
|
Using test.Data make the output easy to audit and modified.
|
|
|
|
|
|
The MarshalText method encode the Section back to ssh_config format
with two spaces as indentation in key.
The WriteTo method marshal the Section into text and write it to
[io.Writer] w.
|
|
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.
|
|
The MkdirAll create directory on the server, from left to right.
Each directory is separated by '/', where the left part is the parent of
the right part.
This method is similar to [os.MkdirAll].
|
|
The implementation of SSH server for Stat is not consistent with
the RFC.
The RFC mentioned that
An empty path name is valid, and it refers to the user's default
directory (usually the user's home directory).
But this only working on some command, like Mkdir, but not Stat.
|
|
This is to make sure that the passed value is in the correct, expected
size.
|
|
|
|
|
|
There are some reports that I disagree with revive, in example, code
should not declare the type after variables.
In my opinion, on some cases, declaring the type make the code more
readable and explicit.
Since I did not want to add new configuration file, we changes it and
follow revive for now.
|
|
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
|
|
The goal of config package is to store the configuration key and value
from ssh_config(5), everything else should be stored by user of this
package, including the valid private key file and object or parsed
identity file.
|
|
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".
|
|
The Close method close the client sftp session and release all its
resources.
|
|
Since the method accept FileHandle, that is returned from OpenFIle,
then the method should changes with the same suffix.
This is also to make the method ambigous later when we add Close method
to close clinet connection.
|
|
|
|
Using the maximum int64 allow the section key contains value larger than
int.
|
|
The shadow tool [1] report a variable where its name is declared twice
or more, in different scope.
[1] https://pkg.go.dev/golang.org/x/tools@v0.13.0/go/analysis/passes/shadow
|
|
|
|
|
|
The realignment reduce the cost of the following struct,
* Client: from 88 to 80 bytes (-8)
* dirEntry: from 40 to 32 bytes (-8)
* FileAttrs: from 72 to 64 bytes (-8)
* packet: from 128 to 88 bytes (-40)
While at it, add missing comment to FileHandle type.
|
|
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
|
|
The NewSection function are required to test NewClientInteractive later.
|
|
The UserKnownHostsFile define list of the known_hosts files to be read,
separated by spaces.
If not set default to "~/.ssh/known_hosts" and "~/.ssh/known_hosts2".
|
|
An example of CASignatureAlgorithms is ssh-ed25519, so it make senses to
convert it to lowercase.
The value of Hostname is either a domain or IP address so it also make
senses to convert it to lowercase.
The value of User is not case insensitive since we can create user name
"Foo" and "foo" in the same system.
|
|
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.
|