Skip to content

Commit 5b62a0f

Browse files
authored
feat: Add file verification for SSH file transfers (#9998)
1 parent 1374656 commit 5b62a0f

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

core/utils/ssh/ssh.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package ssh
22

33
import (
4+
"errors"
45
"fmt"
56
"net"
7+
"path"
68
"strings"
79
"time"
810

11+
"github.com/1Panel-dev/1Panel/core/global"
912
gossh "golang.org/x/crypto/ssh"
1013
)
1114

@@ -79,6 +82,35 @@ func (c *SSHClient) Run(shell string) (string, error) {
7982
return string(buf), err
8083
}
8184

85+
func (c *SSHClient) CpFileWithCheck(src, dst string) error {
86+
localMd5, err := c.Runf("md5sum %s | awk '{print $1}'", src)
87+
if err != nil {
88+
global.LOG.Debugf("load md5sum with src for %s failed, std: %s, err: %v", path.Base(src), localMd5, err)
89+
localMd5 = ""
90+
}
91+
for i := 0; i < 3; i++ {
92+
std, cpErr := c.Runf("cp %s %s", src, dst)
93+
if err != nil {
94+
err = fmt.Errorf("cp file %s failed, std: %s, err: %v", src, std, cpErr)
95+
continue
96+
}
97+
if len(strings.TrimSpace(localMd5)) == 0 {
98+
return nil
99+
}
100+
remoteMd5, errDst := c.Runf("md5sum %s | awk '{print $1}'", dst)
101+
if errDst != nil {
102+
global.LOG.Debugf("load md5sum with dst for %s failed, std: %s, err: %v", path.Base(src), remoteMd5, errDst)
103+
return nil
104+
}
105+
if strings.TrimSpace(localMd5) == strings.TrimSpace(remoteMd5) {
106+
return nil
107+
}
108+
err = errors.New("cp file failed, file is not match!")
109+
}
110+
111+
return err
112+
}
113+
82114
func (c *SSHClient) SudoHandleCmd() string {
83115
if _, err := c.Run("sudo -n ls"); err == nil {
84116
return "sudo "
@@ -108,7 +140,9 @@ func (c *SSHClient) Runf(shell string, args ...interface{}) (string, error) {
108140
}
109141

110142
func (c *SSHClient) Close() {
111-
_ = c.Client.Close()
143+
if c.Client != nil {
144+
_ = c.Client.Close()
145+
}
112146
}
113147

114148
func makePrivateKeySigner(privateKey []byte, passPhrase []byte) (gossh.Signer, error) {

0 commit comments

Comments
 (0)