File: process.go

package info (click to toggle)
browserpass 3.7.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 4,836 kB
  • sloc: javascript: 80,027; makefile: 544
file content (102 lines) | stat: -rw-r--r-- 2,632 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package request

import (
	"encoding/binary"
	"encoding/json"
	"io"
	"os"

	"github.com/browserpass/browserpass-native/errors"
	"github.com/browserpass/browserpass-native/response"
	log "github.com/sirupsen/logrus"
)

type StoreSettings struct {
	GpgPath string `json:"gpgPath"`
}

type store struct {
	ID       string        `json:"id"`
	Name     string        `json:"name"`
	Path     string        `json:"path"`
	Settings StoreSettings `json:"settings"`
}

type settings struct {
	GpgPath string           `json:"gpgPath"`
	Stores  map[string]store `json:"stores"`
}

type request struct {
	Action       string      `json:"action"`
	Settings     settings    `json:"settings"`
	File         string      `json:"file"`
	StoreID      string      `json:"storeId"`
	EchoResponse interface{} `json:"echoResponse"`
}

// Process handles browser request
func Process() {
	requestLength, err := parseRequestLength(os.Stdin)
	if err != nil {
		log.Error("Unable to parse the length of the browser request: ", err)
		response.SendErrorAndExit(
			errors.CodeParseRequestLength,
			&map[errors.Field]string{
				errors.FieldMessage: "Unable to parse the length of the browser request",
				errors.FieldError:   err.Error(),
			},
		)
	}

	request, err := parseRequest(requestLength, os.Stdin)
	if err != nil {
		log.Error("Unable to parse the browser request: ", err)
		response.SendErrorAndExit(
			errors.CodeParseRequest,
			&map[errors.Field]string{
				errors.FieldMessage: "Unable to parse the browser request",
				errors.FieldError:   err.Error(),
			},
		)
	}

	switch request.Action {
	case "configure":
		configure(request)
	case "list":
		listFiles(request)
	case "fetch":
		fetchDecryptedContents(request)
	case "echo":
		response.SendRaw(request.EchoResponse)
	default:
		log.Errorf("Received a browser request with an unknown action: %+v", request)
		response.SendErrorAndExit(
			errors.CodeInvalidRequestAction,
			&map[errors.Field]string{
				errors.FieldMessage: "Invalid request action",
				errors.FieldAction:  request.Action,
			},
		)
	}
}

// Request length is the first 4 bytes in LittleEndian encoding
func parseRequestLength(input io.Reader) (uint32, error) {
	var length uint32
	if err := binary.Read(input, binary.LittleEndian, &length); err != nil {
		return 0, err
	}
	return length, nil
}

// Request is a json with a predefined structure
func parseRequest(messageLength uint32, input io.Reader) (*request, error) {
	var parsed request
	reader := &io.LimitedReader{R: input, N: int64(messageLength)}
	if err := json.NewDecoder(reader).Decode(&parsed); err != nil {
		return nil, err
	}
	return &parsed, nil
}