Skip to content

Commit

Permalink
Adds support for mode, uid & gid
Browse files Browse the repository at this point in the history
  • Loading branch information
tlm committed Sep 26, 2018
1 parent 80cc28c commit bacae87
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 23 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ dest specific options. Options specific to the dest type choosen.
`certBundleFile` - optional location to output issued certificate bundle to

`privKeyFile` - optional location to output private key to

All file options support a Mode, Gid and Uid options appended at the end. Example `privKeyFileMode`

`action` - required

Expand Down
50 changes: 42 additions & 8 deletions cmd/config/dest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package config
import (
"encoding/json"
"fmt"
"os"
"strconv"

"github.com/pkg/errors"

"github.com/tlmiller/disttrust/dest"
"github.com/tlmiller/disttrust/file"
)

func ToDest(id string, opts json.RawMessage) (dest.Dest, error) {
Expand All @@ -19,17 +22,48 @@ func ToDest(id string, opts json.RawMessage) (dest.Dest, error) {
return nil, errors.Wrap(err, "parsing dest json")
}
fdest := dest.File{}
if cafile, exists := uopts["caFile"]; exists {
fdest.CAFile = cafile

caFile, err := destBuilder(uopts["caFile"], uopts["caFileMode"],
uopts["caFileGid"], uopts["caFileUid"])
if err != nil {
return nil, errors.Wrap(err, "caFile")
}
if cfile, exists := uopts["certFile"]; exists {
fdest.CertificateFile = cfile
fdest.CA = caFile

cFile, err := destBuilder(uopts["certFile"], uopts["certFileMode"],
uopts["certFileGid"], uopts["certFileUid"])
if err != nil {
return nil, errors.Wrap(err, "certFile")
}
if cbfile, exists := uopts["certBundleFile"]; exists {
fdest.CertificateBundleFile = cbfile
fdest.Certificate = cFile

cbFile, err := destBuilder(uopts["certBundleFile"], uopts["certBundleFileMode"],
uopts["certBundleFileGid"], uopts["certBundleFileUid"])
if err != nil {
return nil, errors.Wrap(err, "certBundleFile")
}
if pkfile, exists := uopts["privKeyFile"]; exists {
fdest.PrivateKeyFile = pkfile
fdest.CertificateBundle = cbFile

pkfile, err := destBuilder(uopts["privKeyFile"], uopts["privKeyFileMode"],
uopts["privKeyFileGid"], uopts["privKeyFileUid"])
if err != nil {
return nil, errors.Wrap(err, "privKeyFile")
}
fdest.PrivateKey = pkfile

return &fdest, nil
}

func destBuilder(path, mode, gid, uid string) (file.File, error) {
builder := file.New(path)
if mode != "" {
conv, err := strconv.ParseUint(mode, 8, 32)
if err != nil {
return file.File{}, errors.Wrap(err, "invalid mode uint")
}
builder.Mode = os.FileMode(conv)
}
builder.Gid = gid
builder.Uid = uid
return builder, nil
}
49 changes: 34 additions & 15 deletions dest/file_dest.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,69 @@ import (

"github.com/pkg/errors"

"github.com/tlmiller/disttrust/file"
"github.com/tlmiller/disttrust/provider"
)

type File struct {
CAFile string
CertificateFile string
CertificateBundleFile string
PrivateKeyFile string
CA file.File
Certificate file.File
CertificateBundle file.File
PrivateKey file.File
}

func (f *File) Send(res *provider.Response) error {

if res.CA != "" && f.CAFile != "" {
err := ioutil.WriteFile(f.CAFile, []byte(res.CA), os.FileMode(0644))
if res.CA != "" && f.CA.HasPath() {
err := ioutil.WriteFile(f.CA.Path, []byte(res.CA), f.CA.Mode)
if err != nil {
return errors.Wrap(err, "writing ca file")
}
err = f.CA.Chown()
if err != nil {
return errors.Wrap(err, "chown ca file")
}
}

if res.Certificate != "" && f.CertificateFile != "" {
err := ioutil.WriteFile(f.CertificateFile, []byte(res.Certificate), os.FileMode(0644))
if res.Certificate != "" && f.Certificate.HasPath() {
err := ioutil.WriteFile(f.Certificate.Path, []byte(res.Certificate),
f.Certificate.Mode)
if err != nil {
return errors.Wrap(err, "writing certificate file")
}
err = f.Certificate.Chown()
if err != nil {
return errors.Wrap(err, "chown certificate file")
}
}

if res.CABundle != "" && f.CertificateBundleFile != "" {
f, err := os.OpenFile(f.CertificateBundleFile,
os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.FileMode(0644))
defer f.Close()
if res.CABundle != "" && f.CertificateBundle.HasPath() {
s, err := os.OpenFile(f.CertificateBundle.Path,
os.O_WRONLY|os.O_TRUNC|os.O_CREATE, f.CertificateBundle.Mode)
defer s.Close()
if err != nil {
return errors.Wrap(err, "writing certificate bundle file")
}
_, err = f.WriteString(res.CABundle + "\n" + res.Certificate)
_, err = s.WriteString(res.CABundle + "\n" + res.Certificate)
if err != nil {
return errors.Wrap(err, "writing certificate bundle file")
}
err = f.CertificateBundle.Chown()
if err != nil {
return errors.Wrap(err, "chown certificate bundle file")
}
}

if res.PrivateKey != "" && f.PrivateKeyFile != "" {
err := ioutil.WriteFile(f.PrivateKeyFile, []byte(res.PrivateKey), os.FileMode(0600))
if res.PrivateKey != "" && f.PrivateKey.HasPath() {
err := ioutil.WriteFile(f.PrivateKey.Path, []byte(res.PrivateKey),
f.PrivateKey.Mode)
if err != nil {
return errors.Wrap(err, "writing private key file")
}
err = f.PrivateKey.Chown()
if err != nil {
return errors.Wrap(err, "chown private key file")
}
}
return nil
}
66 changes: 66 additions & 0 deletions file/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package file

import (
"os"
"os/user"
"strconv"

"github.com/pkg/errors"
)

type File struct {
Gid string
Path string
Mode os.FileMode
Uid string
}

func (f File) Chown() error {
var gid, uid int
if f.Gid == "" {
gid = -1
} else if conv, err := strconv.ParseInt(f.Gid, 10, 32); err == nil {
gid = int(conv)
} else {
group, err := user.LookupGroup(f.Gid)
if err != nil {
return errors.Wrapf(err, "looking up group for id %s", f.Gid)
}
conv, err := strconv.ParseInt(group.Gid, 10, 32)
if err != nil {
return errors.Wrapf(err, "parsing group lookup gid for id %s", group.Gid)
}
gid = int(conv)
}

if f.Uid == "" {
uid = -1
} else if conv, err := strconv.ParseInt(f.Uid, 10, 32); err == nil {
uid = int(conv)
} else {
user, err := user.Lookup(f.Uid)
if err != nil {
return errors.Wrapf(err, "looking up user for id %s", f.Uid)
}
conv, err := strconv.ParseInt(user.Uid, 10, 32)
if err != nil {
return errors.Wrapf(err, "parsing user lookup gid for id %s", user.Uid)
}
uid = int(conv)
}

return os.Chown(f.Path, uid, gid)
}

func (f File) HasPath() bool {
return f.Path != ""
}

func New(path string) File {
return File{
Path: path,
Mode: os.FileMode(0644),
Gid: "",
Uid: "",
}
}

0 comments on commit bacae87

Please sign in to comment.