Skip to content

Instantly share code, notes, and snippets.

@jbweber
Created November 28, 2023 02:12
Show Gist options
  • Save jbweber/f31e3a49eb9546469a25c6d46a06aa18 to your computer and use it in GitHub Desktop.
Save jbweber/f31e3a49eb9546469a25c6d46a06aa18 to your computer and use it in GitHub Desktop.
package main
import (
"archive/tar"
"archive/zip"
"bytes"
"compress/gzip"
"errors"
"fmt"
"io"
"log"
"os"
)
// grab a tar.gz file with a binary called "bootstrap" inside
// assume this is a lambda function handler
// extract the 'bootstrap' binary and write it to a zip file suitable for upload to lambda
func main() {
f, err := os.Open("c:\\users\\jweber\\gringotts-lambda.tar.gz")
if err != nil {
log.Fatal(err)
}
defer func() { _ = f.Close() }()
b, err := extractBootstrapFromTGZ(f)
if err != nil {
if errors.Is(err, gzip.ErrHeader) {
log.Fatalf("file is not gzipped: %v", err)
}
log.Fatalf("unknown error: %v", err)
}
err = os.WriteFile("c:\\users\\jweber\\bootstrap", b, 0755)
if err != nil {
log.Fatal(err)
}
o, err := createLambdaZip(b)
if err != nil {
log.Fatal(err)
}
fmt.Println(len(o))
err = os.WriteFile("c:\\users\\jweber\\bootstrap.zip", o, 0666)
if err != nil {
log.Fatal(err)
}
}
func extractBootstrapFromTGZ(r io.Reader) ([]byte, error) {
gzr, err := gzip.NewReader(r)
if err != nil {
return nil, err
}
defer func() { _ = gzr.Close() }()
tr := tar.NewReader(gzr)
for {
header, err := tr.Next()
switch {
// no more files in tar
case err == io.EOF:
return nil, nil
// error
case err != nil:
return nil, err
// skip if header is nil
case header == nil:
continue
}
if header.Typeflag == tar.TypeReg {
fmt.Println(header.Name)
}
var bsBuf bytes.Buffer
if _, err := io.Copy(&bsBuf, tr); err != nil {
return nil, err
}
return bsBuf.Bytes(), nil
}
}
func createLambdaZip(in []byte) ([]byte, error) {
var buf bytes.Buffer
writer := zip.NewWriter(&buf)
// https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
// version made by -> upper byte
// external attr
// https://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute
fw, err := writer.CreateHeader(&zip.FileHeader{
Name: "bootstrap",
Method: zip.Deflate,
CreatorVersion: 3 << 8,
ExternalAttrs: 0777 << 16,
})
if err != nil {
return nil, err
}
_, err = fw.Write(in)
if err != nil {
return nil, err
}
// not closed under a defer because it doesn't close the underlying writer only finishes the zip file
// if we return bytes before close the zip is bad, if we don't close it doesn't matter anyway since zip build failed
err = writer.Close()
if err != nil {
return nil, err
}
return buf.Bytes(), err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment