toolbox

package
v0.0.0-...-44b4573 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2024 License: MPL-2.0 Imports: 40 Imported by: 0

Documentation

Overview

An Internet function or system function that takes a text command as input and responds with string text.

filter package contains transformation functions that may be combined in order to enrich command input and result.

Index

Constants

View Source
const (
	TestAESDecryptFileAlphaName = "alpha"
	TestAESDecryptFileBetaName  = "beta"
)
View Source
const (
	MailboxList    = "l" // Prefix string to trigger listing messages.
	MailboxRead    = "r" // Prefix string to trigger reading message body.
	IMAPTimeoutSec = 30  // IMAPTimeoutSec is the IO timeout (in seconds) used for each IMAP conversation.
)
View Source
const (
	MessageBankMaxMessagesPerDirection = 100
	MessageDirectionIncoming           = "in"
	MessageDirectionOutgoing           = "out"
	MessageBankTagDefault              = "default"
	MessageBankTagLoRaWAN              = "LoRaWAN"
	MessageBankDefaultStoreResponse    = "message has been stored"
)
View Source
const (
	// NBEResponseNoOutstandingIntents is the text response made by the network-bound file encryption app, when a command request asks for
	// outstanding unlocking intents but there are none.
	NBEResponseNoOutstandingIntents = "there are no outstanding unlocking intents"
	// NBETrigger is the network bound file encryption app's trigger prefix string.
	NBETrigger = ".nbe"
)
View Source
const (
	TwilioMakeCall = "c" // Prefix string to trigger outgoing call
	TwilioSendSMS  = "t" // Prefix string to trigger outgoing SMS
)
View Source
const (
	CombinedTextSeparator = "|" // Separate error and command output in the combined output
	SelfTestTimeoutSec    = 15  // Timeout for outgoing connections among those involved in feature self tests
)
View Source
const (
	//ErrBadProcessorConfig is used as the prefix string in all errors returned by "IsSaneForInternet" function.
	ErrBadProcessorConfig = "bad configuration: "

	/*
		PrefixCommandPLT is the magic string to prefix command input, in order to navigate around among the output and
		temporarily alter execution timeout. PLT stands for "position, length, timeout".
	*/
	PrefixCommandPLT = ".plt"

	// TestCommandProcessorPIN is the PIN secret used in test command processor, as returned by GetTestCommandProcessor.
	TestCommandProcessorPIN = "verysecret"

	// MaxCmdPerSecHardLimit is the hard uppper limit of the approximate maximum number of commands a command processor will process in a second.
	MaxCmdPerSecHardLimit = 1000
	// MaxCmdLength is the maximum length of a single command (including password PIN and other prefixes) that the command processor will accept.
	MaxCmdLength = 16 * 1024
	// MinPasswordLength is the minimum password length accepted by IsSaneForInternet.
	MinPasswordLength = 7
)
View Source
const (
	/*
		ReportIntervalSec is the recommended interval at which subjects are to send their reports to a daemon.
		This is only a recommendation - subjects may freely exceed or relax the interval as they see fit.
	*/
	ReportIntervalSec = 10 * 60
	// AppCommandResponseRetentionSec is the maximum duration to retain an app
	// command execution result per host.
	// During the retention period the command execution result will be
	// available for retrieval when the subject requests the identical identical
	// toolbox command to be executed.
	// After the retention period the result will be available for retrieval one
	// last time, and then removed from memory.
	// The command execution timeout shares the same number.
	CommandResponseRetentionSec = ReportIntervalSec * 10
	// SubjectExpirySecond is the number of seconds after which clean-up routine will remove a subject and its reports if it has not been heard since.
	SubjectExpirySecond = 48 * 3600
	/*
		StoreAndForwardMessageProcessorTrigger is the toolbox app command invocation prefix for the store&forward message processor.
		"mp" would have been more suitable, however "m" letter is already taken by send-mail app.
	*/
	StoreAndForwardMessageProcessorTrigger = ".0m"
)
View Source
const (
	// SubjectReportSerialisedFieldSeparator is a separator character, ASCII Unit Separator, used to compact a subject report request into a single string.
	SubjectReportSerialisedFieldSeparator = '\x1f'

	// SubjectReportSerialisedLineSeparator is a separator character, ASCII Record Separator, used in between lines of a compacted subject report request.
	SubjectReportSerialisedLineSeparator = '\x1e'

	// MaxSubjectCommentStringLen is the maximum length of a comment coming in from a subject report request.
	// If a comment exceeds this length, then it will be truncated to the length before it is stored in memory.
	// Should truncation occurr, the truncated comment will be stored as a string, instead of a deserialised JSON object.
	MaxSubjectCommentStringLen = 4 * 1024
)
View Source
const AESDecryptTrigger = ".a" // AESDecryptTrigger is the trigger prefix string of AESDecrypt feature.
View Source
const EmptyOutputText = "EMPTY OUTPUT" // Text to substitute empty combined output with (SayEmptyOutput)
View Source
const OpensslSaltedContentOffset = 16 // openssl writes down irrelevant salt in position 8:16
View Source
const (
	RSSDownloadTimeoutSec = 10 // RSSDownloadTimeoutSec is the IO timeout used for testing RSS sources.
)
View Source
const TextSearchTrigger = ".g" // TextSearchTrigger the trigger prefix string of TextSearch feature.
View Source
const TwoFATrigger = ".2" // TwoFATrigger is the trigger prefix string of TwoFACodeGenerator feature.

Variables

View Source
var (
	// RegexAESShortcutKeySearch finds a shortcut name, encryption key, and search string.
	RegexAESShortcutKeySearch = regexp.MustCompile(`(\w+)[^\w]+(\w+)[^\w]+(.*)`)
	ErrBadAESDecryptParam     = errors.New(`example: shortcut key to_search`)
)
View Source
var (
	RegexMailboxAndNumber     = regexp.MustCompile(`(\w+)[^\w]+(\d+)`)            // Capture one mailbox shortcut name and a number
	RegexMailboxAndTwoNumbers = regexp.MustCompile(`(\w+)[^\w]+(\d+)[^\d]+(\d+)`) // Capture one mailbox shortcut name and two numbers
	ErrBadMailboxParam        = fmt.Errorf("%s box skip# count# | %s box to-read#", MailboxList, MailboxRead)
)
View Source
var (
	MessageBankRegexStore = regexp.MustCompile(`s[^\w]+([\w]+)[^\w]+([\w]+)[^\w]+(.*)`)
	MessageBankRegexGet   = regexp.MustCompile(`g[^\w]+([\w]+)[^\w]+([\w]+)`)

	MessageBankDateFormat = "20060102T150405Z"
)
View Source
var (
	// ErrBadRSSParam is the error response for incorrectly entering numeric parameters for retrieving RSS feeds.
	ErrBadRSSParam = errors.New("example: .r skip# count#")

	// DefaultRSSSources is a list of RSS of news headlines published by major news agencies around the world.
	DefaultRSSSources = []string{

		"http://www.abc.net.au/news/feed/45910/rss.xml",

		"http://feeds.bbci.co.uk/news/rss.xml",

		"https://www.theguardian.com/uk/rss",

		"https://www.cnbc.com/id/100003114/device/rss/rss.html",
	}
)
View Source
var (
	// RegexMailCommand captures mail command (address@domain.tld "this is email subject" this is email body) into three string groups.
	RegexMailCommand = regexp.MustCompile(`([a-zA-Z0-9!#$%&'*+-/=?_{|}~.^]+@[a-zA-Z0-9!#$%&'*+-/=?_{|}~.^]+.[a-zA-Z0-9!#$%&'*+-/=?_{|}~.^]+)\s*"(.*)"\s*(.*)`)
	/*
		SOSEmailRecipientMagic is the magic email recipient that corresponds to a built-in list of rescue coordinate
		centre Emails.
	*/
	SOSEmailRecipientMagic = "sos@sos"
	// ErrBadSendMailParam is the command execution result from an incomplete or malformed input command.
	ErrBadSendMailParam = errors.New(`example: addr@dom.tld "subj" body (send SOS to sos@sos)`)
)
View Source
var (
	RegexPhoneNumberAndMessage = regexp.MustCompile(`(\+\d+)[^\w]+(.*)`) // Capture one phone number and one text message
	ErrBadTwilioParam          = fmt.Errorf("example: %s|%s +##number message", TwilioMakeCall, TwilioSendSMS)
)
View Source
var (
	// RegexKeyAndAccountName finds a suffix encryption key and account name.
	RegexKeyAndAccountName = regexp.MustCompile(`(\w+)[^\w]+(.*)`)
	ErrBadTwoFAParam       = errors.New(`example: key account_name`)
)
View Source
var (
	// RegexTextSearch finds a shortcut name and a search string.
	RegexTextSearch       = regexp.MustCompile(`(\w+)[^\w]+(.*)`)
	ErrBadTextSearchParam = errors.New(`example: shortcut text_to_search`)
)
View Source
var (
	ErrEmptyCommand     = errors.New("empty command")
	ErrIncompleteConfig = errors.New("incomplete configuration")
)
View Source
var DTMFDecodeTable = map[string]string{
	` `:   ` `,
	`111`: `!`, `112`: `@`, `113`: `#`, `114`: `$`, `115`: `%`, `116`: `^`, `117`: `&`, `118`: `*`, `119`: `(`,
	`121`: "`", `122`: `~`, `123`: `)`, `124`: `-`, `125`: `_`, `126`: `=`, `127`: `+`, `128`: `[`, `129`: `{`,
	`131`: `]`, `132`: `}`, `133`: `\`, `134`: `|`, `135`: `;`, `136`: `:`, `137`: `'`, `138`: `"`, `139`: `,`,
	`141`: `<`, `142`: `.`, `143`: `>`, `144`: `/`, `145`: `?`,

	`146`: fmt.Sprintf("%c", SubjectReportSerialisedFieldSeparator),
	`147`: fmt.Sprintf("%c", SubjectReportSerialisedLineSeparator),

	`1`: `0`, `11`: `1`, `12`: `2`, `13`: `3`, `14`: `4`, `15`: `5`, `16`: `6`, `17`: `7`, `18`: `8`, `19`: `9`,
	`2`: "a", `22`: `b`, `222`: `c`,
	`3`: "d", `33`: `e`, `333`: `f`,
	`4`: "g", `44`: `h`, `444`: `i`,
	`5`: "j", `55`: `k`, `555`: `l`,
	`6`: "m", `66`: `n`, `666`: `o`,
	`7`: "p", `77`: `q`, `777`: `r`, `7777`: `s`,
	`8`: "t", `88`: `u`, `888`: `v`,
	`9`: "w", `99`: `x`, `999`: `y`, `9999`: `z`,
}

DTMFDecodeTable is the mapping between DTMF character sequences and the symbol/number/letter that they translate into.

View Source
var ErrBadEnvInfoChoice = errors.New(`lock | stop | kill | log | warn | runtime | stack | tune`)
View Source
var ErrBadPLT = errors.New(PrefixCommandPLT + " P L T command")

ErrBadPLT reminds user of the proper syntax to invoke PLT magic.

View Source
var ErrBadPrefix = errors.New("bad prefix or feature is not configured")

ErrBadPrefix is a command execution error triggered if the command does not contain a valid toolbox feature trigger.

View Source
var ErrCommandTooLong = fmt.Errorf("command input exceeds the maximum length of %d characters", MaxCmdLength)

ErrCommandTooLong is a command execution error indicating that the input is too long and cannot be accepted.

View Source
var ErrPINAndShortcutNotFound = errors.New("invalid password PIN or shortcut")
View Source
var ErrRateLimitExceeded = errors.New("command processor internal rate limit has been exceeded")

ErrRateLimitExceeded is a command execution error indicating that the internal command processing rate limit has been exceeded

View Source
var ErrRestrictedShell = errors.New("restricted shell refuses to run the command")
View Source
var ErrSubjectReportTruncated = errors.New("the subject report request or response appears to have been truncated")

ErrSubjectReportTruncated is returned when a subject report has been truncated during its transport, therefore not all of the fields were decoded successfully. See also "DeserialiseFromCompact".

View Source
var ErrTOTPAlreadyUsed = errors.New("the TOTP has already been used with a different command")
View Source
var RegexCommandWithPLT = regexp.MustCompile(`[^\d]*(\d+)[^\d]+(\d+)[^\d]*(\d+)(.*)`)

RegexCommandWithPLT parses PLT magic parameters position, length, and timeout, all of which are integers.

View Source
var RegexConsecutiveSpaces = regexp.MustCompile(`[ \a\f\t\v]+`)

RegexConsecutiveSpaces matches one or more whitespace characters excluding line breaks.

View Source
var RegexGraphChar = regexp.MustCompile("[[:graph:]]") // Match any visible character
View Source
var RegexNoRecursion = regexp.MustCompile(`\` + StoreAndForwardMessageProcessorTrigger + `\s*{\s*"`)

RegexNoRecursion matches an app command that invokes store&forward processor app itself. It helps to stop a recursion.

View Source
var RegexSubjectReportUsing2FA = regexp.MustCompile(`[\d]{12}[\s]*\` + StoreAndForwardMessageProcessorTrigger)

RegexSubjectReportUsing2FA matches the content of an app command (2FA password & command content) that invoke the store&forward messaging processor. The regex helps identify such commands *before* they are processed by command filters, which is useful for suppressing the result filters (e.g. email notification).

View Source
var RegexTwoNumbers = regexp.MustCompile(`(\d+)[^\d]+(\d+)`)
View Source
var SARContacts = []SARContact{

	{"INT", "GEOS", "+19365823190", ""},
	{"US", "GEOS", "+18554442937", ""},

	{"HK", "ARCC", "+85229106821", "aid@cad.gov.hk"},

	{"HK", "MRCC", "+85222337999", "hkmrcc@mardep.gov.hk"},

	{"AU", "MSAR", "+61262306811", "rccaus@amsa.gov.au"},
	{"AU", "ASAR", "+61262306899", "rccaus@amsa.gov.au"},

	{"CA", "JRCC", "+19024278200", "jrcchalifax@sarnet.dnd.ca"},
	{"CN", "MCC", "+861065293298", "cnmcc@cttic.cn"},
	{"JP", "MCC", "+81335919000", "op@kaiho.mlit.go.jp"},
	{"GR", "JRCC", "+302104112500", "jrccpgr@yen.gr"},
	{"UK", "MCC", "+443443820902", "ukmcc@hmcg.gov.uk"},

	{"FI", "MRCC", "+3582941000", "mrcc@raja.fi"},

	{"RU", "MRCC", "+74956261052", "odsmrcc@morflot.ru"},

	{"CN", "MRCC", "+861065292221", "cnmrcc@mot.gov.cn"},
	{"IL", "RCC", "+97248632145", "rcc@mot.gov.il"},
	{"NO", "JRCC", "+4751517000", "operations@jrcc-stavanger.no"},
	{"KR", "MRCC", "+82328352594", "mrcckorea@korea.kr"},
	{"UK", "MRCC", "+441326317575", "falmouthcoastguard@mcga.gov.uk"},
	{"US", "ACC", "+17573986700", "lantwatch@uscg.mil"},
}

SARContacts are pre-programmed SAR contact information.

View Source
var SafeShellCommands = map[string]bool{

	"arch": true, "arp": true, "blkid": true, "cal": true, "date": true,
	"df": true, "dmesg": true, "dnsdomainname": true, "false": true,
	"free": true, "groups": true, "hostid": true, "hostname": true,
	"id": true, "ifconfig": true, "ipconfig": true, "iostat": true,
	"ipcs": true, "kbd_mode": true, "ls": true, "lsof": true, "lspci": true,
	"lsusb": true, "mpstat": true, "netstat": true, "nproc": true, "ps": true,
	"pstree": true, "pwd": true, "route": true, "stty": true, "tty": true,
	"uname": true, "uptime": true, "whoami": true,
}

SafeShellCommands is a set of simple shell commands that are deemed safe for execution even for the restricted shell.

View Source
var SpellTable = map[rune]string{
	'`': "back tick", '~': "tilde", '!': "exclamation", '@': "at", '#': "hash", '$': "dollar", '%': "percentage",
	'^': "caret", '&': "ampersand", '*': "asterisk", '(': "left parentheses", ')': "right parentheses",
	'-': "dash",
	'_': "underscore",
	'=': "equal",
	'+': "plus",

	'[':  "left square bracket",
	'{':  "left curly bracket",
	']':  "right square bracket",
	'}':  "right curly bracket",
	'\\': "back slash",
	'|':  "pipe",
	';':  "semicolon",
	':':  "colon",
	'\'': "single quote",
	'"':  "double quote",
	',':  "comma",
	'<':  "left angle bracket",
	'.':  "dot",
	'>':  "right angle bracket",
	'/':  "slash",
	'?':  "question",

	'1': "one",
	'2': "two",
	'3': "three",
	'4': "four",
	'5': "five",
	'6': "six",
	'7': "seven",
	'8': "eight",
	'9': "nine",
	'0': "zero",

	'a': "alpha",
	'b': "beta",
	'c': "charlie",
	'd': "delta",
	'e': "echo",
	'f': "foxtrot",
	'g': "golf",
	'h': "hotel",
	'i': "india",
	'j': "juliet",
	'k': "kilo",
	'l': "lima",
	'm': "mike",
	'n': "november",
	'o': "oscar",
	'p': "papa",
	'q': "quebec",
	'r': "romeo",
	's': "sierra",
	't': "tango",
	'u': "uniform",
	'v': "victor",
	'w': "whiskey",
	'x': "xray",
	'y': "yankee",
	'z': "zulu",

} // SpellTable helps to spell out individual letters and symbols in piece of text.
View Source
var TestIMAPAccounts = IMAPAccounts{} // Account details are set by init_feature_test.go
View Source
var TestSendMail = SendMail{} // Details are set by init_feature_test.go
View Source
var TestTwilio = Twilio{} // API credentials are set by init_feature_test.go
View Source
var TestWolframAlpha = WolframAlpha{} // AppID is set by init_feature_test.go

Functions

func AtLeast

func AtLeast(i, atLeast int) int

AtLeast returns i only if it is larger than atLeast. If not, it returns atLeast.

func DTMFDecode

func DTMFDecode(digits string) string

DTMFDecode decodes a sequence of character string sent via DTMF. Input is a sequence of key names (0-9 and *).

func GetAllSAREmails

func GetAllSAREmails() []string

GetAllSAREmails returns all SAR institution Email addresses.

func GetGoroutineStacktraces

func GetGoroutineStacktraces() string

Return stack traces of all currently running goroutines.

func GetLatestLog

func GetLatestLog() string

Return latest log entry of all kinds in a multi-line text, one log entry per line. Latest log entry comes first.

func GetLatestWarnings

func GetLatestWarnings() string

Return latest warning entries in a multi-line text, one log entry per line. Latest entry comes first.

func GetTwoFACodeForTimeDivision

func GetTwoFACodeForTimeDivision(secret string, time int64) (string, error)

GetTwoFACodeForTimeDivision returns two factor authentication code calculated for the specific time division using SHA1 method. The caller is responsible for linting the input secret. The function is heavily inspired by Pierre Carrier's "gauth" (https://github.com/pcarrier/gauth).

func GetTwoFACodes

func GetTwoFACodes(secret string) (previous, current, next string, err error)

GetTwoFACodes calculates two factor authentication codes using system clock and secret seed as input. Return previous, current, and next authentication codes in strings.

func MessagesToString

func MessagesToString(messages []Message) string

MessagesToString constructs a multi-line string from the input message slice, with one message on each line.

func SpellPhonetically

func SpellPhonetically(text string) string

SpellPhonetically returns input text with every letter, number, and symbol spelt phonetically. E.g. given input "abc123", the function returns "alpha, beta, charlie, one, two, three". Spaces and consecutive spaces are simply spelt "space".

func TuneLinux

func TuneLinux() string

TuneLinux tweaks Linux-specific system parameters to ensure optimal operation and maximum utilisation of system resources. Returns human-readable description of how values have been tweaked (i.e. the differences).

Types

type AESDecrypt

type AESDecrypt struct {
	EncryptedFiles map[string]*AESEncryptedFile `json:"EncryptedFiles"` // shortcut (\w+) vs file attributes
}

Decrypt AES-encrypted file and return lines sought by incoming command.

func GetTestAESDecrypt

func GetTestAESDecrypt() AESDecrypt

Return a configured but uninitialised AESDecrypt.

func (*AESDecrypt) Execute

func (crypt *AESDecrypt) Execute(ctx context.Context, cmd Command) (ret *Result)

func (*AESDecrypt) Initialise

func (crypt *AESDecrypt) Initialise() error

func (*AESDecrypt) IsConfigured

func (crypt *AESDecrypt) IsConfigured() bool

func (*AESDecrypt) SelfTest

func (crypt *AESDecrypt) SelfTest() error

func (*AESDecrypt) Trigger

func (crypt *AESDecrypt) Trigger() Trigger

type AESEncryptedFile

type AESEncryptedFile struct {
	FilePath     string `json:"FilePath"`     // Path to the AES-256-CBC file encrypted by openssl-enc with salt
	FileContent  []byte `json:"-"`            // Encrypted file content
	HexIV        string `json:"HexIV"`        // Hex-encoded AES IV
	IV           []byte `json:"-"`            // IV in bytes
	HexKeyPrefix string `json:"HexKeyPrefix"` // Hex-encoded encryption key, to be prepended to the key given in the command.
	KeyPrefix    []byte `json:"-"`            // Key prefix in bytes
}

Attributes about an AES-256-CBC encrypted file. The file must be encrypted by openssl using password and password salt, e.g.: openssl enc -aes256 -in <file_to_encrypt> -out <encrypted_file>

func (*AESEncryptedFile) Decrypt

func (file *AESEncryptedFile) Decrypt(keySuffix []byte) (plainContent []byte, err error)

Decrypt uses combination of encryption key from configuration and parameter to decrypt the entire file.

func (*AESEncryptedFile) Initialise

func (file *AESEncryptedFile) Initialise() error

Initialise reads encrypted file into memory.

type AppCommandRequest

type AppCommandRequest struct {
	Command string // Command is a complete app command following the conventional format.
}

AppCommandRequest describes an app command that message processor (local) would like monitored subject (remote to run). The app command follows the conventional format, e.g. "PasswordPIN.e info".

type AppCommandResponse

type AppCommandResponse struct {
	// Command is the app command that was run.
	Command string
	// ReceivedAt is the timestamp of the command that was received.
	ReceivedAt time.Time
	// Response is the execution result of a previously executed app command.
	Result string
	// Duration is the number of seconds the app command took to run.
	RunDurationSec int
}

AppCommandResponse is the result of app command executed by this message processor (local), as a result of request made by a subject (remote). The result field is updated upon completion of the command execution.

type Command

type Command struct {
	// ClientTag is the name (or identity) of the origin/actor that made this command input (e.g. caller's phone number or client IP).
	// By convention, if the report came from IP network, then the client tag should be the client IP address.
	ClientTag string
	// DaemonName is the name of daemon that received this command, this is used for logging.
	DaemonName string
	// TimeoutSec is what the daemon thinks the timeout of command execution shall be.
	TimeoutSec int
	// Content is the app command input.
	Content string
}

Command is a text representing app command input, collected by a daemon.

func (*Command) FindAndRemovePrefix

func (cmd *Command) FindAndRemovePrefix(prefix string) (hasPrefix bool)

Remove a prefix string from command content and then trim white spaces. Return true only if the prefix was found and removed.

func (*Command) Lines

func (cmd *Command) Lines() []string

func (*Command) Trim

func (cmd *Command) Trim() *Result

Modify command content to remove leading and trailing white spaces. Return error result if command becomes empty afterwards.

type CommandFilter

type CommandFilter interface {
	Transform(Command) (Command, error)
}

CommandFilter applies transformations to any aspect of input command, such as its content or timeout. The transform function returns transformed command instead of modifying the command in-place.

type CommandProcessor

type CommandProcessor struct {
	Features       *FeatureSet     // Features is the aggregation of initialised toolbox feature routines.
	CommandFilters []CommandFilter // CommandFilters are applied one by one to alter input command content and/or timeout.
	ResultFilters  []ResultFilter  // ResultFilters are applied one by one to alter command execution result.

	/*
		MaxCmdPerSec is the approximate maximum number of commands allowed to be processed per second.
		The limit is a defensive measure against an attacker trying to guess the correct password by using visiting a daemon
		from large range of source IP addresses in an attempt to bypass daemon's own per-IP rate limit mechanism.
	*/
	MaxCmdPerSec int
	// contains filtered or unexported fields
}

Pre-configured environment and configuration for processing feature commands.

func GetEmptyCommandProcessor

func GetEmptyCommandProcessor() *CommandProcessor

Return a do-nothing yet sane command processor that has a random long password, rendering it unable to invoke any feature.

func GetInsaneCommandProcessor

func GetInsaneCommandProcessor() *CommandProcessor

GetInsaneCommandProcessor returns a command processor that does not have a sane configuration for general usage. This is a test case helper.

func GetTestCommandProcessor

func GetTestCommandProcessor() *CommandProcessor

Return a realistic command processor for test cases. The only feature made available and initialised is shell execution.

func (*CommandProcessor) IsEmpty

func (proc *CommandProcessor) IsEmpty() bool

IsEmpty returns true only if the command processor does not appear to have a meaningful configuration, which means: - It does not have a PIN filter (the password protection). - There are no filters configured at all.

func (*CommandProcessor) IsSaneForInternet

func (proc *CommandProcessor) IsSaneForInternet() (errs []error)

From the prospect of Internet-facing mail processor and Twilio hooks, check that parameters are within sane range. Return a zero-length slice if everything looks OK.

func (*CommandProcessor) Process

func (proc *CommandProcessor) Process(ctx context.Context, cmd Command, runResultFilters bool) (ret *Result)

Process applies filters to the command, invokes toolbox feature functions to process the content, and then applies filters to the execution result and return. A special content prefix called "PLT prefix" alters filter settings to temporarily override timeout and max.length settings, and it may optionally discard a number of characters from the beginning.

func (*CommandProcessor) SetLogger

func (proc *CommandProcessor) SetLogger(logger *lalog.Logger)

SetLogger uses the input logger to prepare the command processor and its filters.

type EnvControl

type EnvControl struct {
}

Retrieve environment information and trigger emergency stop upon request.

func (*EnvControl) Execute

func (info *EnvControl) Execute(ctx context.Context, cmd Command) *Result

func (*EnvControl) Initialise

func (info *EnvControl) Initialise() error

func (*EnvControl) IsConfigured

func (info *EnvControl) IsConfigured() bool

func (*EnvControl) SelfTest

func (info *EnvControl) SelfTest() error

func (*EnvControl) Trigger

func (info *EnvControl) Trigger() Trigger

type Feature

type Feature interface {
	IsConfigured() bool                       // Return true only if configuration is present, this is called prior to Initialise().
	SelfTest() error                          // Validate and test configuration. It may work only after Initialise() succeeds.
	Initialise() error                        // Prepare internal states.
	Trigger() Trigger                         // Return a prefix string that is matched against command input to trigger a feature, each feature has a unique trigger.
	Execute(context.Context, Command) *Result // Execute the command with trigger prefix removed, and return execution result.
}

Represent a useful feature that is capable of execution and provide execution result as feedback.

type FeatureSet

type FeatureSet struct {
	LookupByTrigger map[Trigger]Feature `json:"-"`

	AESDecrypt             AESDecrypt             `json:"AESDecrypt"`
	EnvControl             EnvControl             `json:"EnvControl"`
	IMAPAccounts           IMAPAccounts           `json:"IMAPAccounts"`
	Joke                   Joke                   `json:"Joke"`
	MessageBank            MessageBank            `json:"MessageBank"`
	NetBoundFileEncryption NetBoundFileEncryption `json:"NetBoundFileEncryption"`
	PublicContact          PublicContact          `json:"PublicContact"`
	RSS                    RSS                    `json:"RSS"`
	SendMail               SendMail               `json:"SendMail"`
	Shell                  Shell                  `json:"Shell"`
	TextSearch             TextSearch             `json:"TextSearch"`
	Twilio                 Twilio                 `json:"Twilio"`
	TwoFACodeGenerator     TwoFACodeGenerator     `json:"TwoFACodeGenerator"`
	WolframAlpha           WolframAlpha           `json:"WolframAlpha"`

	MessageProcessor MessageProcessor `json:"MessageProcessor"`
}

FeatureSet contains an instance of every available toolbox feature. Together they may initialise, run self tests, and receive configuration from JSON.

func (*FeatureSet) DeserialiseFromJSON

func (fs *FeatureSet) DeserialiseFromJSON(configJSON json.RawMessage) error

Deserialise feature configuration from JSON configuration. The function does not initialise features automatically.

func (*FeatureSet) GetTriggers

func (fs *FeatureSet) GetTriggers() []string

Return all configured & initialised triggers, sorted in alphabetical order.

func (*FeatureSet) Initialise

func (fs *FeatureSet) Initialise() error

Run initialisation routine on all features, and then populate lookup table for all configured features.

func (*FeatureSet) SelfTest

func (fs *FeatureSet) SelfTest() error

Run self test of all configured features in parallel. Return test errors if any.

type IMAPAccounts

type IMAPAccounts struct {
	Accounts map[string]*IMAPS `json:"Accounts"` // IMAP account name vs account connectivity details
}

Correspond IMAP account connection details to account names.

func (*IMAPAccounts) Execute

func (imap *IMAPAccounts) Execute(ctx context.Context, cmd Command) (ret *Result)

func (*IMAPAccounts) Initialise

func (imap *IMAPAccounts) Initialise() error

func (*IMAPAccounts) IsConfigured

func (imap *IMAPAccounts) IsConfigured() bool

func (*IMAPAccounts) ListMails

func (imap *IMAPAccounts) ListMails(cmd Command) *Result

func (*IMAPAccounts) ReadMessage

func (imap *IMAPAccounts) ReadMessage(cmd Command) *Result

func (*IMAPAccounts) SelfTest

func (imap *IMAPAccounts) SelfTest() error

func (*IMAPAccounts) Trigger

func (imap *IMAPAccounts) Trigger() Trigger

type IMAPS

type IMAPS struct {
	Host               string `json:"Host"`               // Server name or IP address of IMAPS server
	Port               int    `json:"Port"`               // Port number of IMAPS service
	MailboxName        string `json:"MailboxName"`        // Name of mailbox (e.g. "INBOX")
	InsecureSkipVerify bool   `json:"InsecureSkipVerify"` // Do not verify server name against its certificate
	AuthUsername       string `json:"AuthUsername"`       // Username for plain authentication
	AuthPassword       string `json:"AuthPassword"`       // Password for plain authentication
}

Retrieve emails via IMAPS.

func (*IMAPS) ConnectLoginSelect

func (mbox *IMAPS) ConnectLoginSelect() (conn *IMAPSConnection, err error)

Set up TLS connection to IMAPS server and log the user in.

type IMAPSConnection

type IMAPSConnection struct {
	// contains filtered or unexported fields
}

IMAPSConnection is an established TLS client connection that is ready for IMAP conversations.

func (*IMAPSConnection) Converse

func (conn *IMAPSConnection) Converse(request string) (status, body string, err error)

converse sends an IMAP request and waits for a response, then return IMAP response status and body. If the response status is not OK, an error will be returned. If IO error occurs, client connection will be closed and an error will be returned. A mutex prevents more than one conversation from taking place at the same time.

func (*IMAPSConnection) GetHeaders

func (conn *IMAPSConnection) GetHeaders(from, to int) (ret map[int]string, err error)

GetHeaders retrieves mail headers from the specified message number range.

func (*IMAPSConnection) GetMessage

func (conn *IMAPSConnection) GetMessage(num int) (message string, err error)

GetMessage retrieves one mail message, including its entire headers, body content, and attachments if any.

func (*IMAPSConnection) GetNumberMessages

func (conn *IMAPSConnection) GetNumberMessages(mailboxName string) (int, error)

GetNumberMessages returns total number of messages in the specified mail box.

func (*IMAPSConnection) LogoutDisconnect

func (conn *IMAPSConnection) LogoutDisconnect()

LogoutDisconnect sends logout command to IMAP server, and then closes client connection.

type IncomingAppCommand

type IncomingAppCommand struct {
	Request        SubjectReportRequest
	RunDurationSec int
	Result         Result
}

OutstandingCommand is an application command that a subject requested store&forward message processor to run. A message processor keeps track of maximum of one outstanding command per host name, where the host name is self-reported by a subject. Upon completion, the command execution result will be updated in this structure.

type Joke

type Joke struct {
}

Joke as a toolbox feature takes no input and responds with one joke text downloaded from a list of known sources.

func (*Joke) Execute

func (joke *Joke) Execute(ctx context.Context, cmd Command) *Result

Execute takes timeout from input command and uses it when retrieving joke text. It retrieves exactly one joke text from a randomly chosen source. It retries up to 5 times in case a source does not respond.

func (*Joke) Initialise

func (joke *Joke) Initialise() error

Initialise does nothing because initialisation is not required for this feature.

func (*Joke) IsConfigured

func (joke *Joke) IsConfigured() bool

IsConfigured always returns true because configuration is not required for this feature.

func (*Joke) SelfTest

func (joke *Joke) SelfTest() error

SelfTest tries to grab a joke text, and returns an error only if it fails in doing so.

func (*Joke) Trigger

func (joke *Joke) Trigger() Trigger

Trigger returns the trigger prefix string ".j", consistent with the feature name.

type LintText

type LintText struct {
	TrimSpaces              bool `json:"TrimSpaces"`
	CompressToSingleLine    bool `json:"CompressToSingleLine"`
	KeepVisible7BitCharOnly bool `json:"KeepVisible7BitCharOnly"`
	CompressSpaces          bool `json:"CompressSpaces"`
	BeginPosition           int  `json:"BeginPosition"`
	MaxLength               int  `json:"MaxLength"`
}

Lint combined text string in the following order (each step is turned on by respective attribute) 1. Trim all leading and trailing spaces from lines. 2. Compress all lines into a single line, joint by a semicolon. 3. Retain only printable & visible, 7-bit ASCII characters. 4. Compress consecutive spaces into single space - this will also cause all lines to squeeze. 5. Remove a number of leading character. 6. Remove excessive characters at end of the string.

func (*LintText) SetLogger

func (_ *LintText) SetLogger(_ *lalog.Logger)

func (*LintText) Transform

func (lint *LintText) Transform(result *Result) error

type Message

type Message struct {
	Time    time.Time
	Content interface{}
}

Message is a timestamped text message.

type MessageBank

type MessageBank struct {
	// contains filtered or unexported fields
}

MessageBank stores two-way text messages for on-demand retrieval.

func (*MessageBank) Execute

func (bank *MessageBank) Execute(ctx context.Context, cmd Command) *Result

func (*MessageBank) Get

func (bank *MessageBank) Get(tag, direction string) []Message

Get retrieves the messages currently stored under the specified tag and direction.

func (*MessageBank) Initialise

func (bank *MessageBank) Initialise() error

Initialise initialises the internal states of the app.

func (*MessageBank) IsConfigured

func (*MessageBank) IsConfigured() bool

IsConfigured always returns true.

func (*MessageBank) SelfTest

func (*MessageBank) SelfTest() error

SelfTest always returns nil.

func (*MessageBank) Store

func (bank *MessageBank) Store(tag, direction string, timestamp time.Time, content interface{}) error

Store memorises the message of arbitrary type. If the maximum number of messages is reached for the combination of tag and direction, then the oldest message will be evicted prior to storing this message.

func (*MessageBank) Trigger

func (*MessageBank) Trigger() Trigger

Trigger returns the string ".b".

type MessageProcessor

type MessageProcessor struct {
	// SubjectReports is a map of subject's self-reported host name and its most recent reports. The reports are sorted from earliest to latest.
	SubjectReports map[string]*[]SubjectReport `json:"-"`
	// SubjectClientTags is a set of all subject tags collected from the subjects kept in memory.
	// By convention, reports collected over IP network will use the client IP addresses as tag content.
	SubjectClientTags map[string]struct{} `json:"-"`
	// IncomingAppCommands is a map of subject's self reported host name and an app command the subject would like the message processor to run.
	IncomingAppCommands map[string]*IncomingAppCommand `json:"-"`
	/*
		OutgoingAppCommands is a map of subject's self reported host name and an app command that this message processor would like the subject to run.
		This command is delivered to the subject when it sends the next report.
	*/
	OutgoingAppCommands map[string]string `json:"-"`
	// CmdProcessor processes app commands as requested by a remote server.
	CmdProcessor *CommandProcessor `json:"-"`

	/*
		MaxReportsPerHostName is the maximum number of reports to be kept in memory per each subject, each report is identified by the subject's
		self reported host name.
	*/
	MaxReportsPerHostName int `json:"MaxReportsPerHostName"`
	// OwnerName is the name of the component that carries this message processor. This is used for logging purpose.
	OwnerName string `json:"-"`
	// ForwardReportsToKinesis is an optional kinesis client that will get a copy of every subject report.
	ForwardReportsToKinesisFirehose *awsinteg.KinesisHoseClient `json:"-"`
	// KinesisFirehoseStreamName is an optional name of kinesis firehose stream that will get a copy of every subject report.
	KinesisFirehoseStreamName string `json:"-"`
	// ForwardReportsToSNS is an optional SNS client that will get a copy of every subject report.
	ForwardReportsToSNS *awsinteg.SNSClient `json:"-"`
	// SNSTopicARN is an optional ARN (Amazon Resource Name) of an SNS topic that will get a copy of every subject report.
	SNSTopicARN string `json:"-"`
	// contains filtered or unexported fields
}

MessageProcessor collects subject reports and relays outstanding app command requests and responses using the store&forward technique. It also implements the usual toolbox app interface so that monitored subjects can reach it via app-compatible daemons to send their reports.

func (*MessageProcessor) Execute

func (proc *MessageProcessor) Execute(ctx context.Context, cmd Command) *Result

func (*MessageProcessor) GetAllOutgoingCommands

func (proc *MessageProcessor) GetAllOutgoingCommands() map[string]string

GetAllOutgoingCommands returns a copy of all app commands that are about to be delivered to reporting subjects.

func (*MessageProcessor) GetLatestReports

func (proc *MessageProcessor) GetLatestReports(maxLimit int) (ret []SubjectReport)

GetLatestReportsFromSubject returns the latest subject reports received by this message processor from all subjects. The maximum number of reports to retrieve must be a positive integer. The returned values are sorted from latest to oldest, in contrast to the order they were stored internally (oldest to latest). When there are insufficient number of subject reports to retrieve, the number of returned values will be less than the maximum limit.

func (*MessageProcessor) GetLatestReportsFromSubject

func (proc *MessageProcessor) GetLatestReportsFromSubject(hostName string, maxLimit int) (ret []SubjectReport)

GetLatestReportsFromSubject returns the latest subject reports sent by the specified host name. The maximum number of reports to retrieve must be a positive integer. The returned values are sorted from latest to oldest, in contrast to the order they were stored internally (oldest to latest). When there are insufficient number of reports arrived from that subject, the number of returned values will be less than the maximum limit.

func (*MessageProcessor) GetSubjectReportCount

func (proc *MessageProcessor) GetSubjectReportCount() (ret map[string]int)

GetSubjectReportCount returns the count of reports held in memory, collected from each subject.

func (*MessageProcessor) HasClientTag

func (proc *MessageProcessor) HasClientTag(tag string) bool

HasClientTag returns true only if the specified client tag belongs to any of the monitoried subjects currently kept in memory.

func (*MessageProcessor) Initialise

func (proc *MessageProcessor) Initialise() error

func (*MessageProcessor) IsConfigured

func (proc *MessageProcessor) IsConfigured() bool

func (*MessageProcessor) SelfTest

func (proc *MessageProcessor) SelfTest() error

func (*MessageProcessor) SetOutgoingCommand

func (proc *MessageProcessor) SetOutgoingCommand(hostName, cmdContent string)

SetOutgoingCommand stores an app command that the message processor carries in a reply to a subject report.

func (*MessageProcessor) StoreReport

func (proc *MessageProcessor) StoreReport(ctx context.Context, request SubjectReportRequest, clientTag, daemonName string) SubjectReportResponse

StoreReports stores the most recent report from a subject and evicts older report automatically. If the report carries an app command, then the command will run in the background. By convention, if the daemon collected this report over IP network, then the client tag should be the client IP address.

func (*MessageProcessor) Trigger

func (proc *MessageProcessor) Trigger() Trigger

type NetBoundFileEncryption

type NetBoundFileEncryption struct {
	// MaxIntents is the maximum number of password unlocking intents that will be kept in memory to be fulfilled.
	MaxIntents int `json:"MaxIntents"`
	// MaxCallsPerSec is the approximate number of RPC calls a client (identified by its IP) may make in a second.
	MaxCallsPerSec int `json:"MaxCallsPerSec"`
	*netboundfileenc.PasswordRegister
}

NetBoundFileEncryption hosts facilities for another instance of laitos program to register an intent of obtaining unlocking password for its config/data files. The app interface implementation allows a user to query outstanding unlocking intents and record passwords for them to retrieve, the app is closely tied to the embedded gRPC service, which provides RPC transport for the other laitos program instances to post unlocking intents and retrieve passwords.

func (*NetBoundFileEncryption) Execute

func (nbe *NetBoundFileEncryption) Execute(_ context.Context, cmd Command) *Result

Execute interprets the text command from the input, the command may query for the outstanding unlocking intents, or supply password text to fulfil an outstanding intent.

func (*NetBoundFileEncryption) Initialise

func (nbe *NetBoundFileEncryption) Initialise() error

Initialise always returns nil.

func (*NetBoundFileEncryption) IsConfigured

func (nbe *NetBoundFileEncryption) IsConfigured() bool

IsConfigured always returns true because this app does not use app-specific configuration.

func (*NetBoundFileEncryption) SelfTest

func (nbe *NetBoundFileEncryption) SelfTest() error

SelfTest always returns nil.

func (*NetBoundFileEncryption) Trigger

func (nbe *NetBoundFileEncryption) Trigger() Trigger

Trigger returns the app's trigger prefix string ".nbe", used by app command processor to associate a command with this app.

type NotifyViaEmail

type NotifyViaEmail struct {
	Recipients []string        `json:"Recipients"` // Email recipient addresses
	MailClient inet.MailClient `json:"-"`          // MTA that delivers outgoing notification email
	// contains filtered or unexported fields
}

Send email notification for command result.

func (*NotifyViaEmail) IsConfigured

func (notify *NotifyViaEmail) IsConfigured() bool

Return true only if all mail parameters are present.

func (*NotifyViaEmail) SetLogger

func (notify *NotifyViaEmail) SetLogger(logger *lalog.Logger)

func (*NotifyViaEmail) Transform

func (notify *NotifyViaEmail) Transform(result *Result) error

type PINAndShortcuts

type PINAndShortcuts struct {
	Passwords []string          `json:"Passwords"`
	Shortcuts map[string]string `json:"Shortcuts"`
}

PINAndShortcuts looks for: - Any of the recognised password PIN found at the beginning of any of the input lines. - Any of the recognised shortcut strings that matches the entirety of any of the input lines. The filter's Transform function will return an error if nothing is found.

func (*PINAndShortcuts) Transform

func (pin *PINAndShortcuts) Transform(cmd Command) (Command, error)

type PublicContact

type PublicContact struct {
	// contains filtered or unexported fields
}

PublicContact serves contact information from well known institutions. At this moment, it only serves pre-programmed information about SAR (search-and-rescue) institutions.

Note to developer: in the future, consider serving more public institution contacts.

func (*PublicContact) Execute

func (cs *PublicContact) Execute(ctx context.Context, cmd Command) *Result

func (*PublicContact) Initialise

func (cs *PublicContact) Initialise() error

func (*PublicContact) IsConfigured

func (cs *PublicContact) IsConfigured() bool

func (*PublicContact) SelfTest

func (cs *PublicContact) SelfTest() error

func (*PublicContact) Trigger

func (cs *PublicContact) Trigger() Trigger

type RSS

type RSS struct {
	/*
		Sources are URLs pointing toward RSS feeds in XML format. If left unspecified, the built-in list of sources that
		point to news headlines will be used.
	*/
	Sources []string `json:"Sources"`
}

func (*RSS) Execute

func (rss *RSS) Execute(ctx context.Context, cmd Command) *Result

func (*RSS) Initialise

func (rss *RSS) Initialise() error

func (*RSS) IsConfigured

func (rss *RSS) IsConfigured() bool

func (*RSS) SelfTest

func (rss *RSS) SelfTest() error

func (*RSS) Trigger

func (rss *RSS) Trigger() Trigger

type RSSChannel

type RSSChannel struct {
	Items []RSSItem `xml:"item"`
}

RSSChannel represents an information channel in RSS XML document.

type RSSItem

type RSSItem struct {
	Title       string     `xml:"title"`
	Description string     `xml:"description"`
	PubDate     RSSPubDate `xml:"pubDate"`
}

RSSItem represents a news item in RSS XML document.

func DeserialiseRSSItems

func DeserialiseRSSItems(input []byte) (items []RSSItem, err error)

DeserialiseRSSItems deserialises RSS feeds from input XML and returns news items among them in their original order. In case of an error, the error along with an empty array will be returned.

func DownloadRSSFeeds

func DownloadRSSFeeds(ctx context.Context, timeoutSec int, xmlURLs ...string) (items []RSSItem, err error)

DownloadRSSFeeds downloads RSS feed items from multiple URLs, then orders them from latest to oldest.

type RSSPubDate

type RSSPubDate struct {
	time.Time
}

RSSPubDate represents a publication date/time stamp in RSS XML document.

func (*RSSPubDate) UnmarshalXML

func (pubDate *RSSPubDate) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type RSSRoot

type RSSRoot struct {
	Channel RSSChannel `xml:"channel"`
}

RSSRoot is the root element in an RSS XML document.

type Result

type Result struct {
	Command        Command // Help CommandProcessor to keep track of command in execution result
	Error          error   // Result error if there is any
	Output         string  // Human readable normal output excluding error text
	CombinedOutput string  // Human readable error text + normal output. This is set when calling SetCombinedText() function.
}

Feature's execution result that includes human readable output and error (if any).

func HTTPErrorToResult

func HTTPErrorToResult(resp inet.HTTPResponse, err error) *Result

If HTTP status is not 2xx or HTTP response already has an error, return an error result. Otherwise return nil.

func (*Result) ErrText

func (result *Result) ErrText() string

Return error text or empty string if error is absent.

func (*Result) ResetCombinedText

func (result *Result) ResetCombinedText() string

Set and return combined error text and output text.

type ResultFilter

type ResultFilter interface {
	Transform(*Result) error // Operate on the command result. Return an error if no further transformation shall be done.
	SetLogger(*lalog.Logger) // Assign a logger to use
}

ResultFilter applies transformations to command execution result, the result is modified in-place.

type SARContact

type SARContact struct {
	RegionAbbr string // RegionAbbr is the abbreviation of region name managed/represented by the institution.

	/*
		Type is the institution type:
		GEOS - the home of the International Emergency Response Coordination Centre (IERCC)
		ARCC - aeronautical rescue coordination centre
		MRCC - marine rescue coordination centre
		NMOC - national maritime operation centre
		MSAR - maritime search and rescue
		ASAR - aeronautical search and rescue
		JRCC - joint rescue coordination centre
		MCC - mission control centre
		RCC - rescue coordination centre
	*/
	Type string

	Telephone string // Telephone number of the institution. This is only for voice calls, not for SMS texts.
	Email     string // Email address of the institution.
}

SARContact has contact information about a search-and-rescue institution.

type SayEmptyOutput

type SayEmptyOutput struct {
}

If there is no graph character among the combined output, replace it by "EMPTY OUTPUT".

func (*SayEmptyOutput) SetLogger

func (_ *SayEmptyOutput) SetLogger(_ *lalog.Logger)

func (*SayEmptyOutput) Transform

func (empty *SayEmptyOutput) Transform(result *Result) error

type SendMail

type SendMail struct {
	MailClient      inet.MailClient `json:"MailClient"`      // MailClient offers mail transport configuration for this toolbox feature.
	SOSPersonalInfo string          `json:"SOSPersonalInfo"` // SOSPersonalInfo is a free-style human-readable text to be sent along with rest of SOS email body.
	// contains filtered or unexported fields
}

SendMail is a toolbox feature for sending ordinary and SOS emails.

func (*SendMail) Execute

func (email *SendMail) Execute(ctx context.Context, cmd Command) *Result

func (*SendMail) Initialise

func (email *SendMail) Initialise() error

func (*SendMail) IsConfigured

func (email *SendMail) IsConfigured() bool

func (*SendMail) SelfTest

func (email *SendMail) SelfTest() error

func (*SendMail) SendSOS

func (email *SendMail) SendSOS(subject, body string)

SendSOS delivers an SOS email to public search-and-rescue institutions.

func (*SendMail) Trigger

func (email *SendMail) Trigger() Trigger

type Shell

type Shell struct {
	// Unrestricted enables execution of all free-form shell statements without
	// limitation.
	// By default only the commands in SafeShellCommands set are permitted.
	Unrestricted bool `json:"Unrestricted"`
	// InterpreterPath is the executable of shell interpreter.
	// It defaults to the shell interpreter auto-discovered from the OS host.
	InterpreterPath string `json:"InterpreterPath"`
}

Shell is a toolbox command that executes a shell statement.

func (*Shell) Execute

func (sh *Shell) Execute(ctx context.Context, cmd Command) *Result

func (*Shell) Initialise

func (sh *Shell) Initialise() error

func (*Shell) IsConfigured

func (sh *Shell) IsConfigured() bool

func (*Shell) SelfTest

func (sh *Shell) SelfTest() error

func (*Shell) Trigger

func (sh *Shell) Trigger() Trigger

type SubjectReport

type SubjectReport struct {
	OriginalRequest SubjectReportRequest // OriginalRequest is the agent's report received by the message processor.

	// SubjectClientTag is the name or identity of the subject as observed by the server daemon (e.g. caller's phone number or client IP).
	// By convention, if the report was collected by the daemon over IP network, then the client tag should be the client IP address.
	SubjectClientTag string
	ServerTime       time.Time // ServerClock is the system time of this computer upon receiving the report.
	DaemonName       string    // DaemonName is the name of server daemon that received this report.
}

SubjectReport is a system status report arrived at the store&forward message processor, it contains the original report along with additional subject information collected by the message processor.

type SubjectReportRequest

type SubjectReportRequest struct {
	// SubjectHostName is the self-reported host name of the subject's computer. Message processor uses the name to uniquely identify the monitored subject.
	SubjectHostName string
	// SubjectIP is the subject's self-reported public IP address. It may potentially differ from the client IP observed by the server daemon receiving this report.
	SubjectIP string
	// SubjectPlatform is the OS and CPU architecture of the subject's computer (GOOS/GOARCH).
	SubjectPlatform string
	// SubjectComment is a free from JSON object/string the subject voluntarily includes in this report.
	SubjectComment interface{}

	// ServerTime is overwritten by server upon receiving the request, it is not supplied by a subject, and only used by the server internally.
	ServerTime time.Time `json:"-"`

	// CommandRequest is an app command that the subject (remote) would like this message processor (local) to run, if any.
	CommandRequest AppCommandRequest
	// CommandResponse is result of app command execution the subject (remote) made in response to command request originated from this message processor (local).
	CommandResponse AppCommandResponse
}

SubjectReportRequest is a subject's (remote's) system description and status report transmitted at regular interval to this message processor (local).

func (*SubjectReportRequest) DeserialiseFromCompact

func (req *SubjectReportRequest) DeserialiseFromCompact(in string) error

DeserialiseFromCompact deserialises the report request from the compact input string. If the input string is incomplete or truncated during its transport, the function will try to decode as much information as possible while returning ErrSubjectReportRequestTruncated.

func (*SubjectReportRequest) Lint

func (req *SubjectReportRequest) Lint()

Lint truncates attributes of the request to ensure that none of the attributes are exceedingly long.

func (*SubjectReportRequest) SerialiseCompact

func (req *SubjectReportRequest) SerialiseCompact() string

SerialiseCompact serialises the request into a compact string. The fields carried by the serialised string rank from most important to least important.

type SubjectReportResponse

type SubjectReportResponse struct {
	// CommandRequest is an app command that this message processor (local) would like subject (remote) to run.
	CommandRequest AppCommandRequest
	// CommandResponse is the result from app command that subject (remote) previously asked local to execute.
	CommandResponse AppCommandResponse
}

SubjectReportResponse is a reply made in response to a subject (remote) report. It may embed a command request that this message processor (local) would like the subject (remote) to execute, and/or result from app command execution this message processor (local) made in response to a previous command request from subject (remote).

type TOTPWithCommand

type TOTPWithCommand struct {
	TOTP           string
	ToolboxCommand string
}

TOTPWithCommand contains a TOTP (6+6=12 digits) and a toolbox command that is authenticated to execute with that TOTP.

type TextSearch

type TextSearch struct {
	FilePaths map[string]string `json:"FilePaths"` // FilePaths contains shortcut name VS text file path
}

TextSearch locates a string among lines in a text file.

func (*TextSearch) Execute

func (txt *TextSearch) Execute(ctx context.Context, cmd Command) (ret *Result)

func (*TextSearch) Initialise

func (txt *TextSearch) Initialise() error

func (*TextSearch) IsConfigured

func (txt *TextSearch) IsConfigured() bool

func (*TextSearch) SelfTest

func (txt *TextSearch) SelfTest() error

func (*TextSearch) Trigger

func (txt *TextSearch) Trigger() Trigger

type TranslateSequences

type TranslateSequences struct {
	Sequences [][]string `json:"Sequences"`
}

Translate character sequences to something different.

func (*TranslateSequences) Transform

func (tr *TranslateSequences) Transform(cmd Command) (Command, error)

type Trigger

type Trigger string // Trigger is a prefix string that is matched against command input to trigger a feature, each feature has a unique trigger.

type Twilio

type Twilio struct {
	PhoneNumber string `json:"PhoneNumber"` // Twilio telephone country code and number (the number you purchased from Twilio)
	AccountSID  string `json:"AccountSID"`  // Twilio account SID ("Account Settings - LIVE Credentials - Account SID")
	AuthToken   string `json:"AuthToken"`   // Twilio authentication secret token ("Account Settings - LIVE Credentials - Auth Token")

	TestPhoneNumber string `json:"-"` // Set by init_test.go for running test case, not a configuration.
}

func (*Twilio) Execute

func (twi *Twilio) Execute(ctx context.Context, cmd Command) (ret *Result)

func (*Twilio) Initialise

func (twi *Twilio) Initialise() error

func (*Twilio) IsConfigured

func (twi *Twilio) IsConfigured() bool

func (*Twilio) MakeCall

func (twi *Twilio) MakeCall(cmd Command) *Result

func (*Twilio) SelfTest

func (twi *Twilio) SelfTest() error

func (*Twilio) SendSMS

func (twi *Twilio) SendSMS(cmd Command) *Result

func (*Twilio) Trigger

func (twi *Twilio) Trigger() Trigger

type TwoFACodeGenerator

type TwoFACodeGenerator struct {
	SecretFile *AESEncryptedFile `json:"SecretFile"` // SecretFile has encrypted account name and 2fa secrets
}

TwoFACodeGenerator generates two factor authentication codes upon request. The generator takes an AES encrypted secret seed file as input, that looks like "account_name: secret\n...".

func GetTestTwoFACodeGenerator

func GetTestTwoFACodeGenerator() TwoFACodeGenerator

GetTestTwoFACodeGenerator returns a configured but uninitialised code generator.

func (*TwoFACodeGenerator) Execute

func (codegen *TwoFACodeGenerator) Execute(ctx context.Context, cmd Command) (ret *Result)

func (*TwoFACodeGenerator) Initialise

func (codegen *TwoFACodeGenerator) Initialise() error

func (*TwoFACodeGenerator) IsConfigured

func (codegen *TwoFACodeGenerator) IsConfigured() bool

func (*TwoFACodeGenerator) SelfTest

func (codegen *TwoFACodeGenerator) SelfTest() error

func (*TwoFACodeGenerator) Trigger

func (codegen *TwoFACodeGenerator) Trigger() Trigger

type WolframAlpha

type WolframAlpha struct {
	AppID string `json:"AppID"` // WolframAlpha API AppID ("Developer Portal - My Apps - <name> - AppID")
}

Send query to WolframAlpha.

func (*WolframAlpha) Execute

func (wa *WolframAlpha) Execute(ctx context.Context, cmd Command) *Result

func (*WolframAlpha) ExtractResponse

func (wa *WolframAlpha) ExtractResponse(xmlBody []byte) (string, error)

Extract information "pods" from WolframAlpha API response in XML.

func (*WolframAlpha) Initialise

func (wa *WolframAlpha) Initialise() error

func (*WolframAlpha) IsConfigured

func (wa *WolframAlpha) IsConfigured() bool

func (*WolframAlpha) Query

func (wa *WolframAlpha) Query(ctx context.Context, timeoutSec int, query string) (resp inet.HTTPResponse, err error)

Call WolframAlpha API to run a query. Return HTTP status, response, and error if any.

func (*WolframAlpha) SelfTest

func (wa *WolframAlpha) SelfTest() error

func (*WolframAlpha) Trigger

func (wa *WolframAlpha) Trigger() Trigger

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL