Got error SSH_FX_FAILURE when download file from sftp - go

I use sftp library to download file from sftp to local drive. I use copy function to copy content from remote to local, but I got error SSH_FX_FAILURE when downloading many files. I dont know what mean this error. My go service deployed in kubernetes
for _, file := range remoteFiles {
if file.IsDir() {
continue
}
remoteFilePath := path.Join("/download", file.Name())
remoteFile, err := ftp.Conn.Open(remoteFilePath)
if err != nil {
continue
}
localFilePath := path.Join(/"local/downloaded", file.Name())
localFile, err := os.Create(localFilePath)
if err != nil {
remoteFile.Close()
continue
}
_, err = io.Copy(localFile, remoteFile)
if err != nil {
remoteFile.Close()
localFile.Close()
continue
}
if err := ftp.Conn.Remove(remoteFilePath); err != nil {
continue
}
}

Related

Unzipping from a shared smb folder golang

I'm using the code below to iterate through a folder (unzipping .zip files locally, performing actions on them etc).
func extractZipWithPassword(localPath string, pathToServer string) {
filepath.Walk(localPath, func(path string, info os.FileInfo, err error) error {
extension := filepath.Ext(path)
fileName := filepath.Base(path)
if extension == ".zip" {
zip_password := "password"
outDirZIP := filepath.Dir(path) + "/" + strings.TrimSuffix(fileName, extension)
os.Mkdir(outDirZIP, 0777)
commandString := fmt.Sprintf(`unzip -P %s %s -d %s`, zip_password, path, outDirZIP)
commandSlice := strings.Fields(commandString)
fmt.Println(commandString)
c := exec.Command(commandSlice[0], commandSlice[1:]...)
c.Run()
zipCount++
iterateThroughPE(outDirZIP)
parsePKCS7(outDirZIP)
splitter(start_string, end_string, outDirZIP)
return nil
} else {
fmt.Println("")
return nil
}
})
}
However now I need to extract archives from an SMB folder that requires login+password combination to access.
I tried using this lib github.com/hirochachacha/go-smb2 to access the shared folder, but to no success.
Is there a way to straight up unzip .zip files to a local folder of my choice with Go?
If there's not, what are my options?
UPDATE
Got the share mounted with go-smb2, not sure how to proceed next.
func listShares(path string) {
conn, err := net.Dial("tcp", "ip:port")
if err != nil {
panic(err)
}
defer conn.Close()
d := &smb2.Dialer{
Initiator: &smb2.NTLMInitiator{
User: "user",
Password: "pw",
},
}
s, err := d.Dial(conn)
if err != nil {
panic(err)
}
defer s.Logoff()
names, err := s.ListSharenames()
if err != nil {
panic(err)
}
for _, name := range names {
fmt.Println(name)
}
fs, err := s.Mount("sharename")
if err != nil {
panic(err)
}
defer fs.Umount()
}

Unable to properly decompress a binary in a tar.gz

The below code tries to download and decompress a tar.gz file which in turn packs a binary inside it. The decompression seems to be going wrong since after the decompression is done and the file is there, the file is not being recognized as a binary executable by the system (Mac OS X). I would really appreciate it if anyone can help me identify what is going wrong here.
Here's the code
resp, err := svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String(S3Bucket),
Key: aws.String(s3Key),
})
if err != nil { return err }
defer resp.Body.Close()
ExtractTarGz(resp.Body)
func ExtractTarGz(gzipStream io.Reader) {
uncompressedStream, err := gzip.NewReader(gzipStream)
if err != nil {
log.Fatal("ExtractTarGz: NewReader failed")
}
tarReader := tar.NewReader(uncompressedStream)
for true {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatalf("ExtractTarGz: Next() failed: %s", err.Error())
}
switch header.Typeflag {
case tar.TypeDir:
if err := os.Mkdir(header.Name, 0755); err != nil {
log.Fatalf("ExtractTarGz: Mkdir() failed: %s", err.Error())
}
case tar.TypeReg:
outFile, err := os.Create(header.Name)
if err != nil {
log.Fatalf("ExtractTarGz: Create() failed: %s", err.Error())
}
if _, err := io.Copy(outFile, tarReader); err != nil {
log.Fatalf("ExtractTarGz: Copy() failed: %s", err.Error())
}
outFile.Close()
default:
log.Fatalf(
"ExtractTarGz: uknown type: %s in %s",
header.Typeflag,
header.Name)
}
}
}
(Normal unzipping the file from the tar file using Keka for Mac works fine and the resulting unzipped file is recognized as a binary. I have checked the file size, it's the same as that of the expected binary.
)

Go SMB2 , reading and listing directory

I'm trying to list directory contents on a share from Linux to Windows using Go.
So far I've managed to Create/Remove new files inside a share with full Read/Write permissions.
Go module: https://godoc.org/github.com/hirochachacha/go-smb2#Client
Functions:
func connect_client(host string, share string, session map[string]string) *smb2.Client {
//Checks for a connection on port
conn, err := net.Dial("tcp", host+":445")
if err != nil {
panic(err)
}
//smb auth
d := &smb2.Dialer{
Initiator: &smb2.NTLMInitiator{
User: session["Username"],
Password: session["Password"],
Domain: session["Domain"],
},
}
//Returns a client session
client, err := d.Dial(conn)
if err != nil {
fmt.Println("Connection failed")
client.Logoff()
} else {
fmt.Println("Connection Succeeded")
}
return client
}
func check_write(host string, client *smb2.Client) {
file := "asdasdas.txt"
fs, err := client.Mount(host)
if err != nil {
fmt.Println(err)
os.Exit(0)
}
defer fs.Umount()
share := strings.Split(host, `\\`)
f, err := fs.Create(file)
if err != nil {
fmt.Println("You do not have write permissions on directory:%s ! \n", strings.Split(share[1], `\`)[1])
os.Exit(0)
}
defer fs.Remove(file)
defer f.Close()
fmt.Printf("You have write permissions to directory: %s \n", strings.Split(share[1], `\`)[1]))
}
func list_all(client *smb2.Client, host string) {
fs, err := client.Mount(host)
if err != nil {
fmt.Println(err)
os.Exit(0)
}
defer fs.Umount()
_, err = fs.Open(`Test.txt`)
if err != nil {
fmt.Println(err)
os.Exit(0)
}
}
func main() {
host, share, action, session := get_flags()
client := connect_client(host, share, session)
full_host := `\\` + host + `\` + share
//File create
if action == "check_write" {
check_write(full_host, client)
}
if action == "list_files" {
list_all(client, full_host)
}
}
In the function list_all() everything works, but when I am trying to access \\192.168.1.19\Sharing only..
When I input just a host with directory name it seas it can not list the directory path because it can not find the object specified.
I can't understand how I can get pointer used for *RemoteFile in order to use the functions:
f.Readdir()
f.Name()
etc....
So far I managed to use *RemoteFileSystem only for all other actions but I want to list all contents of the directory..
Help would be much appreciated!
Edit:
If it wasn't clear enough, in order to use functions like:
f.Readdir()
f.Name()
I need to get a pointer for *RemoteFile, this is my main issue
https://godoc.org/github.com/hirochachacha/go-smb2#RemoteFileSystem.Open
Use Open on a RemoteFileSystem and either a directory name, or empty string for the directory at the root of the filesystem.
e.g.
client, err := d.Dial(conn)
if err != nil {
return err
}
rfs, err := client.Mount("jrwren")
if err != nil {
return err
}
// cat the NOTES file.
f, err := rfs.Open("NOTES")
if err != nil {
return err
}
defer f.Close()
io.Copy(os.Stdout, f)
// List all the files
dir, err := rfs.Open("")
if err != nil {
return err
}
fis, err := dir.Readdir(10)
if err != nil {
return err
}
for i := range fis {
fmt.Println(fis[i].Name())
}
func list_all(client *smb2.Client, host string) {
fs, err := client.Mount(host)
if err != nil {
fmt.Println(err)
os.Exit(0)
}
dir, err := fs.Open("")
if err != nil {
fmt.Println(err)
os.Exit(0)
}
fis, err := dir.Readdir(-1)
if err != nil {
fmt.Println(err)
os.Exit(0)
}
for i := range fis {
fmt.Println(fis[i].Name())
}
}
This would be the answer thank you!

GO zip.NewWriter() creating empty zip archives

I have the following function I'v tried to simplify to just adding a single file to a .zip archive.
Whatever I try, the resulting .zip file has no files listed in it. The size of the archive is correct. But when I try to extract all (windows), the archive is empty.
go version go1.10.1 windows/amd64
func Zip(src string, dst string) error {
destinationFile, err := os.Create(dst)
if err != nil {
return err
}
myZip := zip.NewWriter(destinationFile)
file := `C:\MA\testing\cldeploy-local.json`
zipFile, err := myZip.Create(file)
fsFile, err := os.Open(file)
if err != nil {
return err
}
_, err = io.Copy(zipFile, fsFile)
if err != nil {
return err
}
return nil
if err != nil {
return err
}
err = myZip.Close()
if err != nil {
return err
}
return nil
}
When I extract the file an error message appears: The compressed (zipped) Folder ... is invalid.
As answered by #JimB: file needs to be added as relative path
only forward slashes. can not start with slash
func Zip(src string, dst string) error {
destinationFile, err := os.Create(dst)
if err != nil {
return err
}
myZip := zip.NewWriter(destinationFile)
file := `C:\MA\testing\cldeploy-local.json`
// file needs to be added as relative path
// only forward slashes. can not start with slash
relPath := strings.TrimPrefix(file, filepath.Dir(src))
relPath = strings.Replace(relPath, `\`, `/`, -1)
relPath = strings.TrimLeft(relPath, `/`)
zipFile, err := myZip.Create(relPath)
fsFile, err := os.Open(file)
if err != nil {
return err
}
_, err = io.Copy(zipFile, fsFile)
if err != nil {
return err
}
return nil
if err != nil {
return err
}
err = myZip.Close()
if err != nil {
return err
}
return nil
}
I faced same issue.
Zipfile created, but empty if you open it with Windows Explorer. But if you open it with 7-zip filename looks like
Actual:
C:\Users\user\AppData\Local\Temp\products_list_432735630.zip\C:\Users\user\AppData\Local\Temp
Expected
C:\Users\user\AppData\Local\Temp\products_list_432735630.zip\
So if zip file and CSV file in one folder you must use relative path.
For Example
relativeFilename := filepath.Base(csvFile.Name())
zippedFile, err := zipper.Create(relativeFilename)

Copy executable golang file to another folder

I wonder if possible to copy running .exe file to another folder. I am trying to do this using usual copy approach in Go like that.
func copy(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
}
...
copyErr := copy(os.Args[0], "D:"+"\\"+"whs.exe")
if copyErr != nil {
log.Panicf("copy -> %v", copyErr)
}
The file copied with the same size but I can't open it correctly. I have only a fast cmd flash. After several milliseconds, cmd is closing and I can't see even any errors.
I was trying to write errors to log file but it's empty.
f, err := os.OpenFile("debug.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0777)
if err != nil {
log.Panicf("setLogOutput -> %v", err)
}
defer f.Close()
log.SetOutput(f)
If I open not copied .exe file everything works correctly.
I've reduced my program to only one main method. The result was the same.
func main() {
log.Println("Starting...")
copyErr := copy(os.Args[0], "F:"+"\\"+"whs.exe")
if copyErr != nil {
log.Panicf("copy -> %v", copyErr)
}
os.Stdin.Read([]byte{0})
}
I have found an error.
The process cannot access the file because it is being used by another process.
I was trying to copy the .exe file to its own path.
func copy(src, dst string) error {
if _, err := os.Stat(dst); os.IsNotExist(err) {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
}
return nil
}

Resources