Change Permission Bits Google Cloud Functions - go

I create a function to get data from SQL database using SSL in Go 1.13 and upload these files
So I set the connectionString to:
connString := fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=verify-ca sslrootcert=%s sslkey=%s sslcert=%s", os.Getenv("HOST"), os.Getenv("PORT1"), os.Getenv("DBNAME"), os.Getenv("USER"), os.Getenv("PASSWORD"), "pathto/server-ca.pem", "pathto/client-cert.pem", "pathto/client-key.pem")
I think the connectionstring is right, but then i got an error like this:
pq: Private key file has group or world access. Permissions should be u=rw (0600) or less
is there a way to modify the permission bits in Cloud Functions file?

You can't achieve this, the files are not mutable. The solution is to copy it in the /tmp directory
f, err := os.Open("pathto/client-key.pem")
if err != nil {
log.Fatal(err)
}
defer f.Close()
d, err := os.Open("/tmp/client-key.pem")
if err != nil {
log.Fatal(err)
}
defer d.Close()
_, err = io.Copy(d, f)
if err != nil {
log.Fatal(err)
}
err = d.Chmod( 0600)
if err != nil {
log.Fatal(err)
}
And then use the /tmp/client-key.pem instead of pathto/client-key.pem

Related

How can iI transfer EWS get item body to PST file via golang or other language but C#

Now, I am trying to export email data. The data exported will be import to outlook to check locally but server.
I have read the doc enter link description here.
Can I transfer EWS data (export-item/get-item) to PST file using golang or cmd tools?
Thank you!
I have success.The method LogonPstStore params Encryption should be 0 so that mac outlook can import it.
Golang code:
func main() {
ole.CoInitialize(0)
session, err := oleutil.CreateObject("Redemption.RDOSession")
if err != nil {
fmt.Println(err)
return
}
s, err := session.QueryInterface(ole.IID_IDispatch)
if err != nil {
fmt.Println(err)
return
}
// create a pst file
p := `E:\go_project\src\github.com\outlook-ical-export\redemption\t22.pst`
store, err := oleutil.CallMethod(s, "LogonPstStore", p, 1, "", "", 0)
if err != nil {
fmt.Println(store, err)
return
}
// get a folder object
inbox, err := s.CallMethod("GetDefaultFolder", 6)
if err != nil {
fmt.Println(inbox, err)
return
}
stores := oleutil.MustGetProperty(s, "Stores").ToIDispatch()
defaultStore := oleutil.MustGetProperty(stores, "DefaultStore").ToIDispatch()
IPMRootFolder := oleutil.MustGetProperty(defaultStore, "IPMRootFolder").ToIDispatch()
IPMFolders := oleutil.MustGetProperty(IPMRootFolder, "Folders").ToIDispatch()
newFolder := oleutil.MustCallMethod(IPMFolders, "Add", "test22").ToIDispatch()
newFolderItems := oleutil.MustGetProperty(newFolder, "Items").ToIDispatch()
RDOMail, err := newFolderItems.CallMethod("Add", "IPM.Note")
if err != nil{
fmt.Println(RDOMail, err)
return
}
data := "base64"
ftsDataPath:= `E:\go_project\src\github.com\outlook-ical-export\redemption\test22.txt`
d, err := base64.StdEncoding.DecodeString(data)
err = ioutil.WriteFile(ftsDataPath, d, 0644)
if err != nil {
panic(err)
}
_, err = RDOMail.ToIDispatch().CallMethod("Import", ftsDataPath, 1034)
if err != nil{
panic(err)
}
_, err = RDOMail.ToIDispatch().CallMethod("Save")
if err != nil{
panic(err)
}
_, err = defaultStore.CallMethod("Remove")
if err != nil{
panic(err)
}
v, err := s.GetProperty("FastShutdownSupported")
if err != nil{
fmt.Println(err)
}
if v.Value() != nil && v.Value().(bool){
_, err = s.CallMethod("DoFastShutdown")
if err != nil{
fmt.Println(err)
}
}else {
_, err = s.CallMethod("Logoff")
if err != nil{
fmt.Println(err)
}
}
return
}
Not in EWS directly. You can export the MIME content using EWS and then import it into a PST file either using your own MIME parser, IConverterSession built-in MIME converter (C++ or Delphi only, only works when tuning inside the outlook.exe process) or Redemption (any language, I am its author, use RDOMail.Import(..., olRfc822)).
Note however that MIME is not a high fidelity format, all MAPI-specific properties will be lost. Fast Transfer Stream format preserves all properties, but it is not documented. You can export the items using the ExportItems EWS request, and import them into a PST (or any other message) using Redemption and RDOMail.Import(..., olFTS). A PST file can be created using RDOSession.LogonPstStore, you can then create folders (RDOFolder.Folders.Add starting with RDOStore.RootIPMFolder) and messages (RDOFolder.Items.Add).

How to zip symlinks in Golang using "archive/zip" package?

I need to zip/unzip folder that contains symlinks in a way that the structure will be saved and symlinks will be written as symlinks.
Is there a way doing this using Golang package "archive/zip"? or any other alternative way?
I tried to use this code, but 'io.Copy()' copies the target file content and we "lose" the symlink.
archive, err := os.Create("archive.zip")
if err != nil {
panic(err)
}
defer archive.Close()
zipWriter := zip.NewWriter(archive)
localPath := "../testdata/sym"
file, err := os.Open(localPath)
defer file.Close()
if err != nil {
panic(err)
}
w1 , err:= zipWriter.Create("w1")
if _, err = io.Copy(w1, file); err !=nil{
panic(err)
}
zipWriter.Close()
I used this PR : https://github.com/mholt/archiver/pull/92
and wrote symlink's target to writer.
I tested it on Linux and Windows.
archive, err := os.Create("archive.zip")
if err != nil {
panic(err)
}
defer archive.Close()
zipWriter := zip.NewWriter(archive)
defer zipWriter.Close()
localPath := "../testdata/sym"
symlinksTarget = "../a/b.in"
file, err := os.Open(localPath)
defer file.Close()
if err != nil {
panic(err)
}
info, err := os.Lstat(file.Name())
if err != nil {
panic(err)
}
header, err := zip.FileInfoHeader(info)
if err != nil {
panic(err)
}
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
if err != nil {
panic(err)
}
// Write symlink's target to writer - file's body for symlinks is the symlink target.
_, err = writer.Write([]byte(filepath.ToSlash(symlinksTarget)))
if err != nil {
panic(err)
}

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!

How do I close a sheet opened with golang lib excelize?

I followed the repo (https://github.com/360EntSecGroup-Skylar/excelize) tutorial to open a file:
f, err := excelize.OpenFile("./Book1.xlsx")
if err != nil {
fmt.Println(err)
return
}enter code here
But i couldn't find a tutorial about closing, something like:
defer f.Close()
Is there a way to do that?
You don't have to close it.
Just open it, and save it if you need to.
myFile, err := excelize.OpenFile("./Book1.xlsx")
if err != nil {
fmt.Println(err)
return
}
Then, do what you want.
Finally, just save it with the origin path :
err = myFile.Save()
if err != nil {
fmt.Println(err)
}
Or, an other path :
err := myFile.SaveAs("./myFolder/Book2.xlsx")
if err != nil {
fmt.Println(err)
}

golang scp file using crypto/ssh

I'm trying to download a remote file over ssh
The following approach works fine on shell
ssh hostname "tar cz /opt/local/folder" > folder.tar.gz
However the same approach on golang giving some difference in output artifact size. For example the same folders with pure shell produce artifact gz file 179B and same with go script 178B.
I assume that something has been missed from io.Reader or session got closed earlier. Kindly ask you guys to help.
Here is the example of my script:
func executeCmd(cmd, hostname string, config *ssh.ClientConfig, path string) error {
conn, _ := ssh.Dial("tcp", hostname+":22", config)
session, err := conn.NewSession()
if err != nil {
panic("Failed to create session: " + err.Error())
}
r, _ := session.StdoutPipe()
scanner := bufio.NewScanner(r)
go func() {
defer session.Close()
name := fmt.Sprintf("%s/backup_folder_%v.tar.gz", path, time.Now().Unix())
file, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
panic(err)
}
defer file.Close()
for scanner.Scan() {
fmt.Println(scanner.Bytes())
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
if _, err = file.Write(scanner.Bytes()); err != nil {
log.Fatal(err)
}
}
}()
if err := session.Run(cmd); err != nil {
fmt.Println(err.Error())
panic("Failed to run: " + err.Error())
}
return nil
}
Thanks!
bufio.Scanner is for newline delimited text. According to the documentation, the scanner will remove the newline characters, stripping any 10s out of your binary file.
You don't need a goroutine to do the copy, because you can use session.Start to start the process asynchronously.
You probably don't need to use bufio either. You should be using io.Copy to copy the file, which has an internal buffer already on top of any buffering already done in the ssh client itself. If an additional buffer is needed for performance, wrap the session output in a bufio.Reader
Finally, you return an error value, so use it rather than panic'ing on regular error conditions.
conn, err := ssh.Dial("tcp", hostname+":22", config)
if err != nil {
return err
}
session, err := conn.NewSession()
if err != nil {
return err
}
defer session.Close()
r, err := session.StdoutPipe()
if err != nil {
return err
}
name := fmt.Sprintf("%s/backup_folder_%v.tar.gz", path, time.Now().Unix())
file, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return err
}
defer file.Close()
if err := session.Start(cmd); err != nil {
return err
}
n, err := io.Copy(file, r)
if err != nil {
return err
}
if err := session.Wait(); err != nil {
return err
}
return nil
You can try doing something like this:
r, _ := session.StdoutPipe()
reader := bufio.NewReader(r)
go func() {
defer session.Close()
// open file etc
// 10 is the number of bytes you'd like to copy in one write operation
p := make([]byte, 10)
for {
n, err := reader.Read(p)
if err == io.EOF {
break
}
if err != nil {
log.Fatal("err", err)
}
if _, err = file.Write(p[:n]); err != nil {
log.Fatal(err)
}
}
}()
Make sure your goroutines are synchronized properly so output is completeky written to the file.

Resources