Skip to content

Commit

Permalink
feat: Added ssh namespace
Browse files Browse the repository at this point in the history
Signed-off-by: Daniil Stepanenko <daniil.stepanenko.96@gmail.com>
  • Loading branch information
libmonsoon-dev committed Oct 20, 2024
1 parent bcb33a2 commit 7d9034e
Show file tree
Hide file tree
Showing 9 changed files with 713 additions and 8 deletions.
41 changes: 41 additions & 0 deletions docs-src/content/functions/crypto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,47 @@ preamble: |
recommended to have your resident security experts inspect gomplate's code
before using gomplate for critical security infrastructure!_
funcs:
- name: crypto.SSH
released: v4.2.0 # I hope so
description: |
Namespace for ssh functions
pipeline: false
examples:
- |
$ gomplate -i '{{ crypto.ssh }}'
<namespace SSH [PublicKey]>
- name: crypto.SSH.PublicKey
released: v4.2.0
description: |
Loads [Secure Shell](https://en.wikipedia.org/wiki/Secure_Shell) public key
pipeline: true
arguments:
- name: name
required: false
description: the name of the key in `~/.ssh` or the absolute path to it. The default value is defined by `IdentityFile` in `~/.ssh/config`. If not specified, `~/.ssh/id_rsa.pub` is used.
examples:
- |
$ cat ~/.ssh/id_rsa.pub
gxAedO6GSFC7X+feNqKydIqKlq82R9cnjJPuPLbVvWPB+r08PeJobl++6d9m8EQorpokS+ntqnr35QnIBDWLHk139KhWkOjDOvUHJd6pjOOLhSVapmKPOz1dST4QCweET59STvLHHjNVQfJtWI9zVl4X9S4SoiLDkUUyge+9UnqyA9bAr2P4NkVWZYgf3QnrqoWpRGHz1F7JgV+VmGOlh/Kmc6Q== email@example.com
$ gomplate -i '{{ crypto.SSH.PublicKey }}'
<namespace PublicKey [Blob Comment Format Marshal]>
- |
$ gomplate -i '{{ crypto.SSH.PublicKey.Marshal }}'
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnEosV4dTgI6CL4YgM4Tfzs6CKdvLL/tarxipWrgEcdwn0TqFn3PmvxSOQWXbQci1Rl2I+U6X3Z4qQ3fafEOlF/bDbwfnY/eUpr9dHnVe1FCbX0tVzCR7OMHg7vGnF3Mta5E9MXMBKupiukgH51hH6fosr90Cvuhj0vsmO3jQL+i1yQxgbc14RCMQuIUZqAA/1Y9JWtucYe4X2uRyby/m2qtHA08kjPTREVd1cMSTM6rCdxnjXgJn7I416ybWnNIwwYeU8q2aKNPIhndSnIBMdDQnnxRCQHgWZXGjF8K8dVl1r3lJWbg/XMXKDWwLXbhRXZwR7/6HDamsV9fkY5Sld9VfKesNiCjaWLlnbe3d6NbdveBcBO6DgDFcshvvtOyu4quBly8EJFpyfeo5V8XQTIVMcLxehXMZNlk0C0PGKQx4xHdxTwFw9IFPbuGNRqRIRwC0YEH3TR4+xBp/gxAedO6GSFC7X+feNqKydIqKlq82R9cnjJPuPLbVvWPB+r08PeJobl++6d9m8EQorpokS+ntqnr35QnIBDWLHk139KhWkOjDOvUHJd6pjOOLhSVapmKPOz1dST4QCweET59STvLHHjNVQfJtWI9zVl4X9S4SoiLDkUUyge+9UnqyA9bAr2P4NkVWZYgf3QnrqoWpRGHz1F7JgV+VmGOlh/Kmc6Q== email@example.com
- |
$ gomplate -i '{{ crypto.SSH.PublicKey.Blob | base64.Encode }}'
AAAAB3NzaC1yc2EAAAADAQABAAACAQCnEosV4dTgI6CL4YgM4Tfzs6CKdvLL/tarxipWrgEcdwn0TqFn3PmvxSOQWXbQci1Rl2I+U6X3Z4qQ3fafEOlF/bDbwfnY/eUpr9dHnVe1FCbX0tVzCR7OMHg7vGnF3Mta5E9MXMBKupiukgH51hH6fosr90Cvuhj0vsmO3jQL+i1yQxgbc14RCMQuIUZqAA/1Y9JWtucYe4X2uRyby/m2qtHA08kjPTREVd1cMSTM6rCdxnjXgJn7I416ybWnNIwwYeU8q2aKNPIhndSnIBMdDQnnxRCQHgWZXGjF8K8dVl1r3lJWbg/XMXKDWwLXbhRXZwR7/6HDamsV9fkY5Sld9VfKesNiCjaWLlnbe3d6NbdveBcBO6DgDFcshvvtOyu4quBly8EJFpyfeo5V8XQTIVMcLxehXMZNlk0C0PGKQx4xHdxTwFw9IFPbuGNRqRIRwC0YEH3TR4+xBp/gxAedO6GSFC7X+feNqKydIqKlq82R9cnjJPuPLbVvWPB+r08PeJobl++6d9m8EQorpokS+ntqnr35QnIBDWLHk139KhWkOjDOvUHJd6pjOOLhSVapmKPOz1dST4QCweET59STvLHHjNVQfJtWI9zVl4X9S4SoiLDkUUyge+9UnqyA9bAr2P4NkVWZYgf3QnrqoWpRGHz1F7JgV+VmGOlh/Kmc6Q==
- |
$ gomplate -i '{{ crypto.SSH.PublicKey.Comment }}'
email@example.com
- |
$ gomplate -i '{{ crypto.SSH.PublicKey.Format }}'
ssh-rsa
- |
$ gomplate -i '{{ (crypto.SSH.PublicKey "e2e_id_ed25519").Marshal }}'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBCLlDopq1aotlRUMw6oJ7Snr+qa+r5X8qxADTuYJumN e2e_key
- name: crypto.Bcrypt
released: v2.6.0
description: |
Expand Down
69 changes: 69 additions & 0 deletions docs/content/functions/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,75 @@ however, and so can not guarantee correctness of implementation. It is
recommended to have your resident security experts inspect gomplate's code
before using gomplate for critical security infrastructure!_

## `crypto.SSH`

Namespace for ssh functions

_Added in gomplate [v4.2.0](https://github.com/hairyhenderson/gomplate/releases/tag/v4.2.0)_
### Usage

```
crypto.SSH
```


### Examples

```console
$ gomplate -i '{{ crypto.ssh }}'
<namespace SSH [PublicKey]>
```

## `crypto.SSH.PublicKey`

Loads [Secure Shell](https://en.wikipedia.org/wiki/Secure_Shell) public key

_Added in gomplate [v4.2.0](https://github.com/hairyhenderson/gomplate/releases/tag/v4.2.0)_
### Usage

```
crypto.SSH.PublicKey [name]
```
```
name | crypto.SSH.PublicKey
```

### Arguments

| name | description |
|------|-------------|
| `name` | _(optional)_ the name of the key in `~/.ssh` or the absolute path to it. The default value is defined by `IdentityFile` in `~/.ssh/config`. If not specified, `~/.ssh/id_rsa.pub` is used. |

### Examples

```console
$ cat ~/.ssh/id_rsa.pub
gxAedO6GSFC7X+feNqKydIqKlq82R9cnjJPuPLbVvWPB+r08PeJobl++6d9m8EQorpokS+ntqnr35QnIBDWLHk139KhWkOjDOvUHJd6pjOOLhSVapmKPOz1dST4QCweET59STvLHHjNVQfJtWI9zVl4X9S4SoiLDkUUyge+9UnqyA9bAr2P4NkVWZYgf3QnrqoWpRGHz1F7JgV+VmGOlh/Kmc6Q== email@example.com

$ gomplate -i '{{ crypto.SSH.PublicKey }}'
<namespace PublicKey [Blob Comment Format Marshal]>
```
```console
$ gomplate -i '{{ crypto.SSH.PublicKey.Marshal }}'
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnEosV4dTgI6CL4YgM4Tfzs6CKdvLL/tarxipWrgEcdwn0TqFn3PmvxSOQWXbQci1Rl2I+U6X3Z4qQ3fafEOlF/bDbwfnY/eUpr9dHnVe1FCbX0tVzCR7OMHg7vGnF3Mta5E9MXMBKupiukgH51hH6fosr90Cvuhj0vsmO3jQL+i1yQxgbc14RCMQuIUZqAA/1Y9JWtucYe4X2uRyby/m2qtHA08kjPTREVd1cMSTM6rCdxnjXgJn7I416ybWnNIwwYeU8q2aKNPIhndSnIBMdDQnnxRCQHgWZXGjF8K8dVl1r3lJWbg/XMXKDWwLXbhRXZwR7/6HDamsV9fkY5Sld9VfKesNiCjaWLlnbe3d6NbdveBcBO6DgDFcshvvtOyu4quBly8EJFpyfeo5V8XQTIVMcLxehXMZNlk0C0PGKQx4xHdxTwFw9IFPbuGNRqRIRwC0YEH3TR4+xBp/gxAedO6GSFC7X+feNqKydIqKlq82R9cnjJPuPLbVvWPB+r08PeJobl++6d9m8EQorpokS+ntqnr35QnIBDWLHk139KhWkOjDOvUHJd6pjOOLhSVapmKPOz1dST4QCweET59STvLHHjNVQfJtWI9zVl4X9S4SoiLDkUUyge+9UnqyA9bAr2P4NkVWZYgf3QnrqoWpRGHz1F7JgV+VmGOlh/Kmc6Q== email@example.com
```
```console
$ gomplate -i '{{ crypto.SSH.PublicKey.Blob | base64.Encode }}'
AAAAB3NzaC1yc2EAAAADAQABAAACAQCnEosV4dTgI6CL4YgM4Tfzs6CKdvLL/tarxipWrgEcdwn0TqFn3PmvxSOQWXbQci1Rl2I+U6X3Z4qQ3fafEOlF/bDbwfnY/eUpr9dHnVe1FCbX0tVzCR7OMHg7vGnF3Mta5E9MXMBKupiukgH51hH6fosr90Cvuhj0vsmO3jQL+i1yQxgbc14RCMQuIUZqAA/1Y9JWtucYe4X2uRyby/m2qtHA08kjPTREVd1cMSTM6rCdxnjXgJn7I416ybWnNIwwYeU8q2aKNPIhndSnIBMdDQnnxRCQHgWZXGjF8K8dVl1r3lJWbg/XMXKDWwLXbhRXZwR7/6HDamsV9fkY5Sld9VfKesNiCjaWLlnbe3d6NbdveBcBO6DgDFcshvvtOyu4quBly8EJFpyfeo5V8XQTIVMcLxehXMZNlk0C0PGKQx4xHdxTwFw9IFPbuGNRqRIRwC0YEH3TR4+xBp/gxAedO6GSFC7X+feNqKydIqKlq82R9cnjJPuPLbVvWPB+r08PeJobl++6d9m8EQorpokS+ntqnr35QnIBDWLHk139KhWkOjDOvUHJd6pjOOLhSVapmKPOz1dST4QCweET59STvLHHjNVQfJtWI9zVl4X9S4SoiLDkUUyge+9UnqyA9bAr2P4NkVWZYgf3QnrqoWpRGHz1F7JgV+VmGOlh/Kmc6Q==
```
```console
$ gomplate -i '{{ crypto.SSH.PublicKey.Comment }}'
email@example.com
```
```console
$ gomplate -i '{{ crypto.SSH.PublicKey.Format }}'
ssh-rsa
```
```console
$ gomplate -i '{{ (crypto.SSH.PublicKey "e2e_id_ed25519").Marshal }}'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBCLlDopq1aotlRUMw6oJ7Snr+qa+r5X8qxADTuYJumN e2e_key
```

## `crypto.Bcrypt`

Uses the [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) password hashing algorithm to generate the hash of a given string. Wraps the [`golang.org/x/crypto/brypt`](https://godoc.org/golang.org/x/crypto/bcrypt) package.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
github.com/itchyny/gojq v0.12.16
github.com/johannesboyne/gofakes3 v0.0.0-20240217095638-c55a48f17be6
github.com/joho/godotenv v1.5.1
github.com/kevinburke/ssh_config v1.2.0
github.com/lmittmann/tint v1.0.5
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -124,7 +125,6 @@ require (
github.com/itchyny/timefmt-go v0.1.6 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
Expand Down
14 changes: 13 additions & 1 deletion internal/funcs/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,27 @@ import (
func CreateCryptoFuncs(ctx context.Context) map[string]interface{} {
f := map[string]interface{}{}

ns := &CryptoFuncs{ctx}
ns := &CryptoFuncs{
ctx: ctx,
ssh: newSSHFuncs(ctx),
}
ns.self = ns

f["crypto"] = func() interface{} { return ns }
return f
}

// CryptoFuncs -
type CryptoFuncs struct {
namespace

ctx context.Context
ssh *SSHFuncs
}

// SSH -
func (f CryptoFuncs) SSH() *SSHFuncs {
return f.ssh
}

// PBKDF2 - Run the Password-Based Key Derivation Function #2 as defined in
Expand Down
25 changes: 19 additions & 6 deletions internal/funcs/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,43 @@ import (
"context"
"io/fs"
"path/filepath"
"sync"

osfs "github.com/hack-pad/hackpadfs/os"
"github.com/hairyhenderson/gomplate/v4/conv"
"github.com/hairyhenderson/gomplate/v4/internal/datafs"
"github.com/hairyhenderson/gomplate/v4/internal/iohelpers"
)

var (
fsys fs.FS
fsysOnce sync.Once
)

// CreateFileFuncs -
func CreateFileFuncs(ctx context.Context) map[string]interface{} {
fsys, err := datafs.FSysForPath(ctx, "/")
if err != nil {
fsys = datafs.WrapWdFS(osfs.NewFS())
}

ns := &FileFuncs{
ctx: ctx,
fs: fsys,
fs: getFS(ctx),
}

return map[string]interface{}{
"file": func() interface{} { return ns },
}
}

func getFS(ctx context.Context) fs.FS {
fsysOnce.Do(func() {
var err error
fsys, err = datafs.FSysForPath(ctx, "/")
if err != nil {
fsys = datafs.WrapWdFS(osfs.NewFS())
}
})

return fsys
}

// FileFuncs -
type FileFuncs struct {
ctx context.Context
Expand Down
12 changes: 12 additions & 0 deletions internal/funcs/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package funcs

import (
"context"
"log/slog"
)

const TraceFuncsLevel = slog.LevelDebug - 1

func trace(ctx context.Context, msg string, attrs ...slog.Attr) {
slog.LogAttrs(ctx, TraceFuncsLevel, msg, attrs...)
}
65 changes: 65 additions & 0 deletions internal/funcs/namespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package funcs

import (
"fmt"
"reflect"
"strings"
)

var _ fmt.Stringer = (*namespace)(nil)

type namespace struct {
self any //must be pointer to outer struct
}

func (n *namespace) String() string {
ns := n.self
if ns == nil {
return "<namespace>"
}

nsType := reflect.TypeOf(ns)
if nsType.Kind() != reflect.Pointer || nsType.Elem().Kind() != reflect.Struct {
panic("invalid namespace type " + nsType.String() + ": must be pointer to struct")
}

var public []string
public = appendPublicMethods(nsType, public)
nsType = nsType.Elem()
public = appendPublicFields(nsType, public)

nsName := nsType.String()
nsName = strings.TrimPrefix(nsName, "funcs.")
nsName = strings.TrimSuffix(nsName, "Funcs")

return fmt.Sprintf("<namespace %s %s>", nsName, public)
}

func appendPublicFields(nsType reflect.Type, public []string) []string {
for _, field := range reflect.VisibleFields(nsType) {
if !field.IsExported() {
continue
}

public = append(public, field.Name)
}

return public
}

func appendPublicMethods(nsType reflect.Type, public []string) []string {
for i := range nsType.NumMethod() {
method := nsType.Method(i)
if !method.IsExported() {
continue
}

if method.Name == "String" && nsType.Implements(reflect.TypeFor[fmt.Stringer]()) {
continue
}

public = append(public, method.Name)
}

return public
}
Loading

0 comments on commit 7d9034e

Please sign in to comment.