aboutsummaryrefslogtreecommitdiff
path: root/lib/ssh
AgeCommit message (Collapse)Author
11 daysall: apply go fixShulhan
2026-03-27lib/ssh: set client config HostKeyAlgorithms from known_hosts filesShulhan
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].
2026-01-15all: convert license and copyright to use SPDX identifiersShulhan
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/
2025-02-04all: remove the nolint tagsShulhan
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.
2025-01-23all: replace "interface{}" with "any"Shulhan
2024-12-28lib/ssh: implement Run with contextShulhan
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
2024-03-09lib: move package "ssh/config" to "lib/sshconfig"Shulhan
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).
2024-03-05all: comply with linter recommendations #3Shulhan
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.
2024-03-05all: comply with linter recommendations #2Shulhan
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.
2024-03-05all: comply with linter recommendations #1Shulhan
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]
2024-03-02all: move the repository to "git.sr.ht/~shulhan/pakakeh.go"Shulhan
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
2023-12-26ssh/config: refactoring the Config mergeShulhan
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.
2023-12-26ssh/config: merge the Section slice values on [Section.merge]Shulhan
Instead of using [Section.Set], set the key-value directly. While at it, merge the certificateFile, IdentityFile, knownHostFiles, and sendEnv.
2023-12-25ssh/config: set the default UserKnownHostsFile in setDefaultsShulhan
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.
2023-12-25ssh/config: update comment on [Config.Get]Shulhan
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.
2023-12-25ssh/config: add parameter Config to NewSectionShulhan
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.
2023-12-25ssh/config: fix setting the default valuesShulhan
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.
2023-12-22lib/ssh: add parameter context to Execute methodShulhan
This changes require the fork of our golang.org/x/crypto.
2023-12-19ssh/config: set the Hostname if its not set on [Config.Get]Shulhan
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.
2023-12-19ssh/config: rewrite unit tests for [Config.Get] using [lib.test.Data]Shulhan
Using test.Data make the output easy to audit and modified.
2023-12-19ssh/config: set default section name to '*' if parameter is emptyShulhan
2023-12-18ssh/config: fix negate not resetted when parsing new section MatchShulhan
2023-12-18ssh/config: add method MarshalText and WriteToShulhan
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.
2023-12-17lib/ssh: implement method Output on ClientShulhan
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.
2023-12-17ssh/sftp: implement method MkdirAll on ClientShulhan
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].
2023-12-17ssh/sftp: fix Stat on empty remote file nameShulhan
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.
2023-12-17ssh/sftp: use fixed slice length when converting in unpackFileAttrsShulhan
This is to make sure that the passed value is in the correct, expected size.
2023-12-17ssh/sftp: update comments to use references [...]Shulhan
2023-12-13ssh/sftp: fix non-nil returned error on CloseShulhan
2023-12-13all: fix linter warnings reported by reviveShulhan
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.
2023-11-18lib/crypto: add support for reading passphrase using SSH_ASKPASSShulhan
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.
2023-09-27lib/ssh: fix missing error check from previous changes 8d0720f6Shulhan
2023-09-26go.mod: remove replace directive for golang.org/x/cryptoShulhan
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
2023-09-24shsh/config: remove field PrivateKeys and PrivateKeyFileShulhan
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.
2023-09-24lib/ssh: store and use the connected identity file for ScpPut and ScpGetShulhan
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.
2023-09-24lib/ssh: add method Close to ClientShulhan
The Close method close the client connection and release all resources.
2023-09-24lib/ssh: rename internal field cfg to sectionShulhan
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".
2023-09-24ssh/sftp: add method to close client connectionShulhan
The Close method close the client sftp session and release all its resources.
2023-09-24ssh/sftp: rename method Close to CloseFileShulhan
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.
2023-09-20lib/ssh: replace LoadPrivateKeyInteractive with the one from lib/cryptoShulhan
2023-09-14ssh/config: change the FieldInt to FieldInt64 that return int64Shulhan
Using the maximum int64 allow the section key contains value larger than int.
2023-09-14all: fix variable shadowing as reported by shadow toolShulhan
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
2023-09-11lib/ssh: remove unused field configHostKeyCallback in ClientShulhan
2023-09-11ssh/config: add missing comment to type PermittedCNAMEsShulhan
2023-09-11ssh/sftp: realign struct for better size allocationShulhan
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.
2023-08-29lib/ssh: use UserKnownHostFile from configuration in NewClientInteractiveShulhan
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
2023-08-08ssh/config: export the function to create new SectionShulhan
The NewSection function are required to test NewClientInteractive later.
2023-08-07ssh/config: handle key UserKnownHostsFileShulhan
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".
2023-08-07ssh/config: convert value of CASignatureAlgorithms and Hostname to lowercaseShulhan
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.
2023-07-26lib/ssh: refactoring NewClientFromConfig, renamed to NewClientInteractiveShulhan
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.