├── LICENSE
├── README.md
├── config.json
├── core
├── config
│ └── config.go
├── encryption
│ └── encryption.go
├── environment
│ └── environment.go
├── interpreter
│ └── interpreter.go
├── log
│ └── log.go
├── obfuscation
│ └── obfuscation.go
├── relay
│ └── relay.go
├── session
│ └── session.go
├── shell
│ └── shell.go
├── transport
│ └── transport.go
└── ui
│ └── ui.go
├── main.go
├── modules
├── interpreters
│ ├── android
│ │ └── raw.go
│ ├── ios
│ │ └── raw.go
│ ├── linux
│ │ └── raw.go
│ ├── macos
│ │ └── raw.go
│ └── windows
│ │ └── raw.go
├── plugins
│ └── .gitkeep
├── relays
│ ├── go
│ │ ├── android
│ │ │ └── raw.go
│ │ ├── compat
│ │ │ └── raw.go
│ │ ├── ios
│ │ │ └── raw.go
│ │ ├── linux
│ │ │ └── raw.go
│ │ ├── macos
│ │ │ └── raw.go
│ │ └── windows
│ │ │ └── raw.go
│ └── php
│ │ ├── debug.php
│ │ └── raw.php
└── stagers
│ ├── android
│ └── .gitkeep
│ ├── ios
│ └── .gitkeep
│ ├── macos
│ └── .gitkeep
│ └── windows
│ └── .gitkeep
└── ui
├── assets
├── audio
│ └── bell.mp3
├── css
│ ├── animations-terminal.css
│ ├── colors.css
│ ├── fonts.css
│ ├── index.css
│ ├── mediaplayer.css
│ ├── menu.css
│ ├── shadow.css
│ └── terminal.css
├── fonts
│ ├── Consolas.ttf
│ ├── OpenSans-Bold.ttf
│ ├── OpenSans-BoldItalic.ttf
│ ├── OpenSans-ExtraBold.ttf
│ ├── OpenSans-ExtraBoldItalic.ttf
│ ├── OpenSans-Italic.ttf
│ ├── OpenSans-Light.ttf
│ ├── OpenSans-LightItalic.ttf
│ ├── OpenSans-Regular.ttf
│ ├── OpenSans-Semibold.ttf
│ └── OpenSans-SemiboldItalic.ttf
├── images
│ ├── appearance.svg
│ ├── back.svg
│ ├── books.svg
│ ├── box.svg
│ ├── brand_acer.svg
│ ├── brand_thinkpad.svg
│ ├── cards.svg
│ ├── chip.svg
│ ├── clear.svg
│ ├── close.svg
│ ├── controls.svg
│ ├── expresser-logo.svg
│ ├── expresser.svg
│ ├── eye.svg
│ ├── favicon.png
│ ├── fetch.svg
│ ├── fingerprint.svg
│ ├── home.svg
│ ├── io.svg
│ ├── javascript.svg
│ ├── key.svg
│ ├── laptop.svg
│ ├── laptop2.svg
│ ├── laptop3.svg
│ ├── link-unsafe.svg
│ ├── link.svg
│ ├── loader.svg
│ ├── loadline.svg
│ ├── lock.svg
│ ├── mandelbrot.svg
│ ├── message-corner.svg
│ ├── newwindow.svg
│ ├── os_android.svg
│ ├── os_apple.svg
│ ├── os_linux.svg
│ ├── os_windows.svg
│ ├── padlock.svg
│ ├── pause.svg
│ ├── phone.svg
│ ├── phone2.svg
│ ├── phone2.svg.2018_11_12_15_16_54.0.svg
│ ├── plug.svg
│ ├── plus.svg
│ ├── proxy-icon.svg
│ ├── proxy.svg
│ ├── quit.svg
│ ├── relay.svg
│ ├── relaysbg.svg
│ ├── route.svg
│ ├── router.svg
│ ├── script.svg
│ ├── selectall.svg
│ ├── server.svg
│ ├── session.svg
│ ├── settings.svg
│ ├── snapmon.svg
│ ├── stop.svg
│ ├── streammic.svg
│ ├── streammon.svg
│ ├── tablet.svg
│ ├── toggle.svg
│ ├── tor.png
│ ├── tplink.svg
│ ├── tplink_black.svg
│ ├── tplink_white.svg
│ ├── unknown.svg
│ ├── wand.svg
│ └── whirl.svg
└── js
│ ├── http.js
│ ├── index.js
│ ├── index
│ ├── environment.js
│ ├── events.js
│ ├── functions.js
│ └── sockets.js
│ ├── mediaplayer.js
│ ├── mediaplayer
│ └── .gitkeep
│ ├── menu.js
│ ├── popup.js
│ ├── terminal.js
│ └── terminal
│ ├── commands.js
│ ├── environment.js
│ ├── events.js
│ └── functions.js
├── console_log.html
├── help.html
├── index.html
├── mediaplayer.html
└── terminal.html
/README.md:
--------------------------------------------------------------------------------
1 |
2 | :warning: Work in progress, do not use.
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "connections": {
3 | "127.0.0.1": {
4 | "active": "07-02-2018 11:14:12",
5 | "user-agents": []
6 | }
7 | },
8 | "console_height": "137",
9 | "idle_timeout": "600",
10 | "open_browser": false,
11 | "scroll_on_output": true
12 | }
13 |
--------------------------------------------------------------------------------
/core/config/config.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | /*
4 |
5 | Handles JSON configuration files.
6 |
7 | */
8 |
9 | import (
10 | "io/ioutil"
11 | "encoding/json"
12 |
13 | "github.com/buffermet/sewers/core/log"
14 | )
15 |
16 | func Configure(json_path string, new_json_data map[string][]string) {
17 | // Read old config
18 | json_encoded, e := ioutil.ReadFile(json_path)
19 | if e != nil {
20 | log.Fatal(e.Error())
21 | }
22 |
23 | // Encode old config
24 | var json_decoded map[string]interface{}
25 | if e := json.Unmarshal([]byte(json_encoded), &json_decoded); e != nil {
26 | log.Error("invalid JSON file: " + log.BOLD + json_path + log.RESET + "\n[" + log.BOLD_RED + "STACK TRACE" + log.RESET + "]" + "\n" + e.Error())
27 | }
28 |
29 | // Set new config
30 | for param, value := range new_json_data {
31 | json_decoded[param] = value[0]
32 | }
33 |
34 | // Indent config
35 | json_indented, e := json.MarshalIndent(json_decoded, "", "\t")
36 | if e != nil {
37 | log.Error("could not indent JSON data.\n[" + log.BOLD_RED + "STACK TRACE" + log.RESET + "]" + "\n" + e.Error())
38 | }
39 |
40 | // Write new config
41 | ioutil.WriteFile(json_path, json_indented, 0600)
42 | }
43 |
--------------------------------------------------------------------------------
/core/encryption/encryption.go:
--------------------------------------------------------------------------------
1 | package encryption
2 |
3 | /*
4 |
5 | Handles encryption protocol.
6 |
7 | */
8 |
9 | import (
10 | "crypto/aes"
11 | "crypto/cipher"
12 | "crypto/rand"
13 | "encoding/base64"
14 | "errors"
15 | "io"
16 | "log"
17 | )
18 |
19 | func NewKey() []byte {
20 | return []byte("")
21 | }
22 |
23 | func Encrypt(key, payload []byte) ([]byte, error) {
24 | blockcipher, err := aes.NewCipher(key)
25 | if err != nil {
26 | return nil, err
27 | }
28 |
29 | encoded_payload := base64.StdEncoding.EncodeToString(payload)
30 | ciphertext := make([]byte, aes.BlockSize + len(encoded_payload))
31 |
32 | iv := ciphertext[:aes.BlockSize]
33 | if _, err := io.ReadFull(rand.Reader, iv); err != nil {
34 | return nil, err
35 | }
36 |
37 | cfb := cipher.NewCFBEncrypter(blockcipher, iv)
38 | cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(encoded_payload))
39 |
40 | return []byte(base64.StdEncoding.EncodeToString(ciphertext)), nil
41 | }
42 |
43 | func Decrypt(key, payload []byte) ([]byte, error) {
44 | blockcipher, err := aes.NewCipher(key)
45 | if err != nil {
46 | return nil, err
47 | }
48 |
49 | payload, err = base64.StdEncoding.DecodeString(string(payload))
50 | if err != nil {
51 | log.Fatal(err)
52 | }
53 |
54 | if len(payload) < aes.BlockSize {
55 | return nil, errors.New("ciphertext too short")
56 | }
57 |
58 | iv := payload[:aes.BlockSize]
59 | payload = payload[aes.BlockSize:]
60 |
61 | cfb := cipher.NewCFBDecrypter(blockcipher, iv)
62 | cfb.XORKeyStream(payload, payload)
63 |
64 | return payload, nil
65 | }
66 |
--------------------------------------------------------------------------------
/core/environment/environment.go:
--------------------------------------------------------------------------------
1 | package environment
2 |
3 | /*
4 |
5 | Handles installed environment.
6 |
7 | */
8 |
9 | import (
10 | "fmt"
11 | "os"
12 | "regexp"
13 |
14 | "github.com/buffermet/sewers/core/shell"
15 | )
16 |
17 | var (
18 | PATH_GO string
19 | PATH_RELAYS string
20 | PATH_MODULES_RELAYS string
21 | PATH_MODULES_STAGERS string
22 | PATH_MODULES_INTERPRETERS string
23 | PATH_MODULES_PLUGINS string
24 | PATH_SEWERS = "/src/github.com/buffermet/sewers"
25 | PATH_UI string
26 | VERSION = "1.0"
27 | WHOAMI string
28 | )
29 |
30 | func goPath() string {
31 | go_path := os.Getenv("GOPATH")
32 | if go_path == "" {
33 | stdout_bytes, err := shell.Output("go env")
34 | if err != nil {
35 | fmt.Println("error: could not determine GOPATH: " + err.Error())
36 | os.Exit(1)
37 | }
38 | stdout_bytes = regexp.MustCompile(`(?s).*GOPATH="([^"]+)".*`).ReplaceAll(stdout_bytes, []byte("${1}"))
39 | if len(stdout_bytes) == 0 {
40 | fmt.Println("error: could not find GOPATH of go environment")
41 | os.Exit(1)
42 | }
43 | return string(stdout_bytes)
44 | }
45 | return go_path
46 | }
47 |
48 | func whoAmI() string {
49 | user, _ := shell.Output("whoami")
50 | hostname, _ := shell.Output("hostname")
51 | regexp_whitespace := regexp.MustCompile(`(?s)\s`)
52 | user = regexp_whitespace.ReplaceAll(user, []byte(""))
53 | hostname = regexp_whitespace.ReplaceAll(hostname, []byte(""))
54 | return string(user) + "@" + string(hostname)
55 | }
56 |
57 | func Init() {
58 | PATH_GO = goPath()
59 | PATH_UI = PATH_GO + PATH_SEWERS + "/ui"
60 | PATH_RELAYS = PATH_GO + PATH_SEWERS + "/relays"
61 | PATH_MODULES_RELAYS = PATH_GO + PATH_SEWERS + "/modules/relays"
62 | PATH_MODULES_STAGERS = PATH_GO + PATH_SEWERS + "/modules/stagers"
63 | PATH_MODULES_INTERPRETERS = PATH_GO + PATH_SEWERS + "/modules/interpreters"
64 | PATH_MODULES_PLUGINS = PATH_GO + PATH_SEWERS + "/modules/plugins"
65 | WHOAMI = whoAmI()
66 | }
67 |
--------------------------------------------------------------------------------
/core/interpreter/interpreter.go:
--------------------------------------------------------------------------------
1 | package interpreter
2 |
3 | /*
4 |
5 | Raw interpreter handlers.
6 |
7 | */
8 |
9 | import (
10 | "errors"
11 | "io/ioutil"
12 | "regexp"
13 |
14 | "github.com/buffermet/sewers/core/environment"
15 | )
16 |
17 | type Interpreter struct {
18 | Device string
19 | EncryptionKey []byte
20 | FetchRate []int
21 | FetchRateTag string
22 | Hostname string
23 | Icon string
24 | InterpreterGetTag string
25 | InterpreterPostTag string
26 | InterpreterStreamTag string
27 | Logo string
28 | OS string
29 | Payload []byte
30 | RelayAddress string
31 | SessionID string
32 | SewersGetTag string
33 | SewersPostTag string
34 | SewersStreamTag string
35 | StreamRate []int
36 | StreamTag string
37 | TerminalSize []int
38 | UserAgent string
39 | }
40 |
41 | func New(platform string) (*[]byte, error) {
42 | if "" != regexp.MustCompile(`^(android|ios|linux|macos|windows)$`).FindString(platform) {
43 | return nil, errors.New("tried to generate payload for invalid platform: " + platform)
44 | }
45 | payload_path := environment.PATH_MODULES_INTERPRETERS + "/" + platform + "/raw.go"
46 | payload, err := ioutil.ReadFile(payload_path)
47 | if err != nil {
48 | return nil, errors.New(err.Error())
49 | }
50 | return &payload, nil
51 | }
52 |
--------------------------------------------------------------------------------
/core/log/log.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | /*
4 |
5 | Handles StdOut and HTML console output.
6 |
7 | */
8 |
9 | import (
10 | "fmt"
11 | "io/ioutil"
12 | "os"
13 | "strings"
14 | "time"
15 |
16 | "github.com/buffermet/sewers/core/environment"
17 | )
18 |
19 | const (
20 | BLACK_ON_YELLOW = "\x1b[30;43m"
21 | BOLD = "\x1b[1m"
22 | BOLD_BLACK_ON_GREY = "\x1b[1;7;30m"
23 | BOLD_BLUE = "\x1b[1;34m"
24 | BOLD_GREEN = "\x1b[1;32m"
25 | BOLD_GREY = "\x1b[1;30m"
26 | BOLD_RED = "\x1b[1;31m"
27 | BOLD_YELLOW = "\x1b[1;33m"
28 | ON_GREEN = "\x1b[30;42m"
29 | ON_YELLOW = "\x1b[30;43m"
30 | RESET = "\x1b[0m"
31 | WHITE_ON_RED = "\x1b[1;41m"
32 | HTML_BLACK_ON_YELLOW = ""
33 | HTML_BOLD = ""
34 | HTML_BOLD_BLACK_ON_GREY = ""
35 | HTML_BOLD_BLUE = ""
36 | HTML_BOLD_GREEN = ""
37 | HTML_BOLD_GREY = ""
38 | HTML_BOLD_RED = ""
39 | HTML_BOLD_YELLOW = ""
40 | HTML_ON_GREEN = ""
41 | HTML_ON_YELLOW = ""
42 | HTML_RESET = ""
43 | HTML_WHITE_ON_RED = ""
44 | )
45 |
46 | func Timestamp() string {
47 | return string(time.Now().Format("02-01-2006 15:04:05"))
48 | }
49 |
50 | func Info(message string) {
51 | timestamp := BOLD_GREY + Timestamp() + RESET + " "
52 | fmt.Println(timestamp + message)
53 | logToConsole(timestamp + message)
54 | }
55 |
56 | func Warn(message string) {
57 | timestamp := BOLD_GREY + Timestamp() + RESET + " "
58 | fmt.Println(timestamp + BLACK_ON_YELLOW + "WARNING" + RESET + " " + message)
59 | logToConsole(timestamp + BLACK_ON_YELLOW + "WARNING" + RESET + " " + message)
60 | }
61 |
62 | func Error(message string) {
63 | timestamp := BOLD_GREY + Timestamp() + RESET + " "
64 | fmt.Println(timestamp + BOLD_RED + "ERROR" + RESET + " " + message)
65 | logToConsole(timestamp + BOLD_RED + "ERROR" + RESET + " " + message)
66 | }
67 |
68 | func Fatal(message string) {
69 | fmt.Println(WHITE_ON_RED + "!!!" + RESET + " " + message)
70 | logToConsole(WHITE_ON_RED + "!!!" + RESET + " " + message)
71 | os.Exit(1)
72 | }
73 |
74 | func Raw(message string) {
75 | fmt.Println(message)
76 | logToConsole(message)
77 | }
78 |
79 | func logToConsole(message string) {
80 | html_string := strings.Replace(message, " ", " ", -1)
81 | html_string = strings.Replace(html_string, RESET, HTML_RESET, -1)
82 | html_string = strings.Replace(html_string, BOLD, HTML_BOLD, -1)
83 | html_string = strings.Replace(html_string, ON_GREEN, HTML_ON_GREEN, -1)
84 | html_string = strings.Replace(html_string, ON_YELLOW, HTML_ON_YELLOW, -1)
85 | html_string = strings.Replace(html_string, WHITE_ON_RED, HTML_WHITE_ON_RED, -1)
86 | html_string = strings.Replace(html_string, BLACK_ON_YELLOW, HTML_BLACK_ON_YELLOW, -1)
87 | html_string = strings.Replace(html_string, BOLD_GREY, HTML_BOLD_GREY, -1)
88 | html_string = strings.Replace(html_string, BOLD_RED, HTML_BOLD_RED, -1)
89 | html_string = strings.Replace(html_string, BOLD_GREEN, HTML_BOLD_GREEN, -1)
90 | html_string = strings.Replace(html_string, BOLD_BLUE, HTML_BOLD_BLUE, -1)
91 | html_string = strings.Replace(html_string, BOLD_YELLOW, HTML_BOLD_YELLOW, -1)
92 | html_string = strings.Replace(html_string, BOLD_BLACK_ON_GREY, HTML_BOLD_BLACK_ON_GREY, -1)
93 | html_string += "\n"
94 |
95 | logfile, err := os.OpenFile(
96 | environment.PATH_UI + "/console_log.html",
97 | os.O_APPEND | os.O_WRONLY,
98 | 0600)
99 | if err != nil {
100 | fmt.Println(err.Error())
101 | }
102 |
103 | defer logfile.Close()
104 |
105 | if _, err = logfile.WriteString(html_string); err != nil {
106 | fmt.Println(err.Error())
107 | }
108 | }
109 |
110 | func ClearConsole(ip string) {
111 | err := ioutil.WriteFile(
112 | environment.PATH_UI + "/console_log.html",
113 | []byte(""),
114 | 0600)
115 | if err != nil {
116 | fmt.Println(err.Error())
117 | }
118 | Info(ip + " cleared the console log")
119 | }
120 |
--------------------------------------------------------------------------------
/core/obfuscation/obfuscation.go:
--------------------------------------------------------------------------------
1 | package obfuscation
2 |
3 | /*
4 |
5 | Handles payload obfuscation.
6 |
7 | */
8 |
9 | import (
10 | // "errors"
11 | "math/rand"
12 | "regexp"
13 | // "strconv"
14 | "time"
15 | )
16 |
17 | type CodeSet struct {
18 | AfterSets []int
19 | BeforeSets []int
20 | ChildSets []int
21 | ID int
22 | Imports []string
23 | ParentSet int
24 | Variants []string
25 | }
26 |
27 | var (
28 | CodeSetInterpreterAndroid []CodeSet
29 | CodeSetInterpreterIOS []CodeSet
30 | CodeSetInterpreterLinux []CodeSet
31 | CodeSetInterpreterMacOS []CodeSet
32 | CodeSetInterpreterWindows []CodeSet
33 | CodeSetRelayPhp []CodeSet
34 | CodeSetStagerAndroid []CodeSet
35 | CodeSetStagerIOS []CodeSet
36 | CodeSetStagerLinux []CodeSet
37 | CodeSetStagerMacOS []CodeSet
38 | CodeSetStagerWindows []CodeSet
39 | )
40 |
41 | func RandomString(length int) string {
42 | rand.Seed(time.Now().UnixNano())
43 |
44 | chars := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
45 | buffer := ""
46 | for i := 0; i < length; i++ {
47 | index := rand.Intn(length)
48 | buffer += string(chars[index])
49 | }
50 |
51 | return buffer
52 | }
53 |
54 | func ObfuscateSource(payload []byte, wordlist []string, shuffle bool) ([]byte, error) {
55 | // Count amount of obfuscatable strings
56 | r := regexp.MustCompile("obf_[a-zA-Z_]*")
57 | obf_matches := r.FindAll(payload, -1)
58 |
59 | count := 0
60 | p := payload
61 | for i := 0; i < len(obf_matches); i++ {
62 | r = regexp.MustCompile(string(obf_matches[i]))
63 | if len(r.FindAll(p, -1)) > 0 {
64 | p = r.ReplaceAll(p, []byte(""))
65 | count += 1
66 | }
67 | }
68 |
69 | // Make sure enough obfuscation strings are provided
70 | if len(wordlist) >= count {
71 | // Shuffle wordlist if shuffling is enabled
72 | if shuffle == true {
73 | //
74 | }
75 | for i := 0; i < len(obf_matches); i++ {
76 | r = regexp.MustCompile(string(obf_matches[i]))
77 | payload = r.ReplaceAll(payload, []byte(wordlist[i]))
78 | }
79 | }
80 |
81 | return payload, nil
82 | }
83 | /* <<<<<<<<<<<<<<<
84 | func getCodeSet(codeSets []*CodeSet, id int) (*CodeSet, error) {
85 | for i := 0; i < len(codeSets); i++ {
86 | this_set := codeSets[i]
87 | if this_set.ID == id {
88 | return this_set, nil
89 | }
90 | }
91 | return nil, errors.New("sets of code did not include set " + strconv.Itoa(id))
92 | }
93 |
94 | func getMainSets(codeSets []*CodeSet) []int {
95 | var main_sets []int
96 | for i := 0; i < len(codeSets); i++ {
97 | if codeSets[i].ParentSet != -1 {
98 |
99 | }
100 | }
101 | }
102 |
103 | func assemble(codeSets []*CodeSet, order []int, thisSet *CodeSet) string {
104 | index := rand.Intn(len(thisSet.ChildSets) + 1)
105 | child_id := thisSet.ChildSets[index]
106 | child_set, err := getCodeSet(codeSets, child_id)
107 | if err != nil {
108 | if len(child_set.ChildSets) > 0 {
109 |
110 | }
111 | }
112 | }
113 |
114 | // AfterSets []int
115 | // BeforeSets []int
116 | // ChildSets []int
117 | // ID int
118 | // Imports []string
119 | // ParentSet int
120 | // Variants []string
121 |
122 | func ShuffleSource(codeSets []*CodeSet) ([]byte, error) {
123 | var assembled []byte
124 | var imports []string
125 | source_prefix := []byte("package main\n\nimport (\n{{IMPORTS}}\n)\n\n{{ASSEMBLED}}")
126 |
127 | rand.Seed(time.Now().UnixNano())
128 | this_set := codeSets[a]
129 |
130 | this_source := assemble(codeSets, this_set)
131 |
132 | // return nil, errors.New("code set " + strconv.Itoa(this_set.ID) + " is missing the following nested set of code: " + strconv.Itoa(...))
133 |
134 | return b, nil
135 | }
136 |
137 | /*
138 |
139 | []
140 | []
141 | []
142 | i
143 | []
144 | -
145 | [""]
146 |
147 | [2,3,4,5,6,7]
148 | []
149 | []
150 | 8
151 | []
152 | [1]
153 | ["return buffer;"]
154 |
155 | [6]
156 | [8]
157 | []
158 | 7
159 | []
160 | [5]
161 | ["buffer += string(chars[index]);"]
162 |
163 | []
164 | [7,8]
165 | []
166 | 6
167 | ["math/rand"]
168 | [5]
169 | ["index := rand.Intn(length);","index := int(rand.Float64() * length);","index := int(length * rand.Float64());"]
170 |
171 | []
172 | [8]
173 | [6,7]
174 | 5
175 | []
176 | [1]
177 | ["for i := 0; i < length; i++ {\n{{NESTED_CODE}}\n};"]
178 |
179 | [2,3]
180 | [2,3,8]
181 | []
182 | 4
183 | []
184 | [1]
185 | ["buffer := \"\";"]
186 |
187 | [2,4]
188 | [2,4,8]
189 | []
190 | 3
191 | []
192 | [1]
193 | ["chars := []byte(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\");"]
194 |
195 | [3,4]
196 | [3,4,8]
197 | []
198 | 2
199 | ["math/rand","time"]
200 | [1]
201 | ["rand.Seed(time.Now().UnixNano());"]
202 |
203 | [0]
204 | [0]
205 | [2,3,4,8]
206 | 1
207 | ["math/rand","time"]
208 | []
209 | ["func RandomString(length int) string {\n{{NESTED_CODE}}\n};"]
210 |
211 | [1]
212 | [1]
213 | []
214 | 0
215 | ["errors"]
216 | []
217 | ["func ShuffleSource(codeSets []CodeSet) ([]byte, error) {\n{{NESTED_CODE}}\n};"]
218 |
219 | */
220 |
--------------------------------------------------------------------------------
/core/relay/relay.go:
--------------------------------------------------------------------------------
1 | package relay
2 |
3 | /*
4 |
5 | Relay config handlers.
6 |
7 | */
8 |
9 | import (
10 | "encoding/json"
11 | "errors"
12 | "io/ioutil"
13 | "strings"
14 |
15 | "github.com/buffermet/sewers/core/environment"
16 | "github.com/buffermet/sewers/core/log"
17 | "github.com/buffermet/sewers/core/transport"
18 | )
19 |
20 | type Relay struct {
21 | InterpreterGetTag string
22 | InterpreterPostTag string
23 | RelayAddress string
24 | RelayID string
25 | SewersGetTag string
26 | SewersPostTag string
27 | Sessions []string
28 | }
29 |
30 | func Get(relay_id string) string {
31 | encoded_json, err := ioutil.ReadFile(environment.PATH_RELAYS + "/" + relay_id + "/" + relay_id + ".json")
32 | if err != nil {
33 | log.Error("could not read relay config " + log.BOLD + environment.PATH_RELAYS + "/" + relay_id + "/" + relay_id + ".json" + log.RESET)
34 | }
35 |
36 | return string(encoded_json)
37 | }
38 |
39 | func GetAddress(relay_id string) (string, error) {
40 | relay_path := environment.PATH_RELAYS + "/" + relay_id + "/" + relay_id + ".json"
41 | encoded, err := ioutil.ReadFile(relay_path)
42 | if err != nil {
43 | return "", errors.New("could not read relay config: " + relay_path)
44 | }
45 |
46 | var decoded map[string]interface{}
47 | err = json.Unmarshal(encoded, &decoded)
48 | if err != nil {
49 | return "", errors.New("could not decode relay config: " + relay_path)
50 | }
51 |
52 | return decoded["relay_address"].(string), nil
53 | }
54 |
55 | func GetAllConfigs() string {
56 | relays := []Relay{}
57 |
58 | // Read relay configs.
59 | var relay_configs []string
60 | config_list, err := ioutil.ReadDir(environment.PATH_RELAYS)
61 | if err != nil {
62 | log.Error(err.Error())
63 | return "{}"
64 | }
65 | for _, file := range config_list {
66 | relay_configs = append(relay_configs, file.Name())
67 | }
68 |
69 | // Parse relay data
70 | if len(relay_configs) == 0 {
71 | log.Info("no relays found")
72 | return "{}"
73 | } else {
74 | for i := 0; i < len(relay_configs); i++ {
75 | relay_path := environment.PATH_RELAYS + "/" + relay_configs[i] + "/" + relay_configs[i] + ".json"
76 | json_encoded, err := ioutil.ReadFile(relay_path)
77 | if err != nil {
78 | log.Error(err.Error())
79 | }
80 |
81 | var json_decoded map[string]interface{}
82 | if err := json.Unmarshal([]byte(json_encoded), &json_decoded); err != nil {
83 | log.Error("invalid JSON file: " + log.BOLD + relay_path + log.RESET + "\n[" + log.BOLD_RED + "STACK TRACE" + log.RESET + "]\n" + err.Error())
84 | }
85 |
86 | if json_decoded["relay_address"] != nil && json_decoded["sewers_post_tag"] != nil && json_decoded["sewers_get_tag"] != nil {
87 | relay := Relay{}
88 | relay.RelayID = strings.Replace(relay_configs[i], ".json", "", 1)
89 | relay.RelayAddress = json_decoded["relay_address"].(string)
90 | relays = append(relays, relay)
91 | } else {
92 | log.Error(log.BOLD + relay_path + log.RESET + " is missing one of the following parameters: 'relay_address', 'sewers_post_tag' or 'sewers_get_tag'" + "\n[" + log.BOLD_RED + "STACK TRACE" + log.RESET + "]\n" + err.Error())
93 | }
94 | }
95 | }
96 |
97 | indented, _ := json.MarshalIndent(relays, "", "\t")
98 |
99 | return string(indented)
100 | }
101 |
102 | func FetchSessions(relay string) (string, error) {
103 | json_encoded, err := ioutil.ReadFile(environment.PATH_RELAYS + "/" + relay + "/" + relay + ".json")
104 | if err != nil {
105 | return "", errors.New("cannot read relay config: " + log.BOLD + relay + ".json" + log.RESET + "\n[" + log.BOLD_RED + "STACK TRACE" + log.RESET + "]\n" + err.Error())
106 | }
107 |
108 | var json_decoded map[string]interface{}
109 | if err := json.Unmarshal([]byte(json_encoded), &json_decoded); err != nil {
110 | log.Error("invalid JSON file: " + log.BOLD + environment.PATH_RELAYS + "/" + relay + "/" + relay + ".json" + log.RESET + "\n[" + log.BOLD_RED + "STACK TRACE" + log.RESET + "]\n" + err.Error())
111 | }
112 |
113 | sessions := ""
114 |
115 | // Send HTTP request
116 | if json_decoded["relay_address"] != nil && json_decoded["sewers_get_tag"] != nil {
117 | relay_address := json_decoded["relay_address"].(string)
118 | get_tag := json_decoded["sewers_get_tag"].(string)
119 | user_agent := json_decoded["user_agent"].(string)
120 |
121 | response := transport.SendHTTPRequest(
122 | relay_address,
123 | get_tag,
124 | user_agent,
125 | "",
126 | "")
127 | body, err := ioutil.ReadAll(response.Body)
128 | if err != nil {
129 | return "", errors.New("could not read response body (" + err.Error() + ")")
130 | }
131 | defer response.Body.Close()
132 | sessions = string(body)
133 | } else {
134 | return "", errors.New("relay " + log.BOLD + relay + log.RESET + " is missing a \"relay_address\" and/or \"sewers_get_tag\" property.")
135 | }
136 |
137 | return sessions, nil
138 | }
139 |
140 | func New() *Relay {
141 | return &Relay{}
142 | }
143 |
144 | func NewPayload(payload_type string) ([]byte, error) {
145 | payload_path := environment.PATH_RELAYS + "/" + payload_type + "/raw." + payload_type
146 | payload, err := ioutil.ReadFile(environment.PATH_RELAYS + "/" + payload_type + "/raw." + payload_type)
147 | if err != nil {
148 | return []byte(""), errors.New("could not read relay payload, filetype is removed or doesn't exist: " + payload_path)
149 | }
150 |
151 | return payload, nil
152 | }
153 |
--------------------------------------------------------------------------------
/core/session/session.go:
--------------------------------------------------------------------------------
1 | package session
2 |
3 | /*
4 |
5 | Session config handlers.
6 |
7 | */
8 |
9 | import (
10 | "errors"
11 | "encoding/json"
12 | "io/ioutil"
13 |
14 | "github.com/buffermet/sewers/core/environment"
15 | )
16 |
17 | type Session struct {
18 | SessionID string
19 | OS string
20 | Device string
21 | Hostname string
22 | EncryptKey string
23 | RelayAddress string
24 | InterpreterGetTag string
25 | InterpreterPostTag string
26 | SewersGetTag string
27 | SewersPostTag string
28 | FetchRate string
29 | FetchRateTag string
30 | TerminalSize string
31 | FetchSchedule []string
32 | PauseTerminal bool
33 | }
34 |
35 | func Encode(s *Session) (*[]byte, error) {
36 | var encoded map[string]interface{}
37 | encoded["session_id"] = s.SessionID
38 | encoded["os"] = s.OS
39 | encoded["device"] = s.Device
40 | encoded["hostname"] = s.Hostname
41 | encoded["encryption_key"] = s.EncryptKey
42 | encoded["relay_address"] = s.RelayAddress
43 | encoded["interpreter_get_tag"] = s.InterpreterGetTag
44 | encoded["interpreter_post_tag"] = s.InterpreterPostTag
45 | encoded["sewers_get_tag"] = s.SewersGetTag
46 | encoded["sewers_post_tag"] = s.SewersPostTag
47 | encoded["fetch_rate"] = s.FetchRate
48 | encoded["fetch_rate_tag"] = s.FetchRateTag
49 | encoded["terminal_size"] = s.TerminalSize
50 | encoded["fetch_schedule"] = s.FetchSchedule
51 | encoded["pause_terminal"] = s.PauseTerminal
52 |
53 | b, err := json.Marshal(encoded)
54 | if err != nil {
55 | return nil, errors.New("could not JSON encode session config with session ID " + encoded["session_id"].(string))
56 | }
57 |
58 | return &b, nil
59 | }
60 |
61 | func Get(relay_id, session_id string) (*Session, error) {
62 | encoded, err := GetEncoded(relay_id, session_id)
63 | if err != nil {
64 | return nil, err
65 | }
66 |
67 | s := New()
68 | err = json.Unmarshal(encoded, &s)
69 | if err != nil {
70 | session_path := environment.PATH_RELAYS + "/" + relay_id + "/sessions/" + session_id + ".json"
71 | return nil, errors.New("could not decode JSON file: " + session_path)
72 | }
73 |
74 | return s, nil
75 | }
76 |
77 | func GetEncoded(relay_id, session_id string) ([]byte, error) {
78 | session_path := environment.PATH_RELAYS + "/" + relay_id + "/sessions/" + session_id + ".json"
79 | encoded, e := ioutil.ReadFile(session_path)
80 | if e != nil {
81 | return nil, errors.New("could not read session config: " + session_id)
82 | }
83 |
84 | return encoded, nil
85 | }
86 |
87 | func New() *Session {
88 | return &Session{}
89 | }
90 |
91 | func Set(relay_id, session_id, encoded string) error {
92 | filepath := environment.PATH_RELAYS + "/" + relay_id + "/sessions/" + session_id + ".json"
93 | err := ioutil.WriteFile(environment.PATH_RELAYS + "/" + relay_id + "/sessions/" + session_id + ".json", []byte(encoded), 600)
94 | if err != nil {
95 | return errors.New("could not write file: " + filepath + "\n" + err.Error())
96 | }
97 |
98 | return nil
99 | }
100 |
--------------------------------------------------------------------------------
/core/shell/shell.go:
--------------------------------------------------------------------------------
1 | package shell
2 |
3 | import (
4 | "os/exec"
5 | "runtime"
6 | )
7 |
8 | func Output(command string) ([]byte, error) {
9 | var err error
10 | var b []byte
11 | if runtime.GOOS == "android" {
12 | b, err = exec.Command("/system/bin/sh", "-c", command).Output()
13 | } else if runtime.GOOS == "windows" {
14 | b, err = exec.Command("cmd", "/C", command).Output()
15 | } else {
16 | b, err = exec.Command("/usr/bin/env", "sh", "-c", command).Output()
17 | }
18 | return b, err
19 | }
--------------------------------------------------------------------------------
/core/transport/transport.go:
--------------------------------------------------------------------------------
1 | package transport
2 |
3 | /*
4 |
5 | Handles HTTP transport.
6 |
7 | */
8 |
9 | import (
10 | "net/http"
11 | "strings"
12 |
13 | "github.com/buffermet/sewers/core/log"
14 | )
15 |
16 | func SendHTTPRequest(relay_address, request_type, user_agent, session_id, payload string) *http.Response {
17 | body := request_type + "\n" + session_id + "\n" + payload
18 | reader := strings.NewReader(body)
19 |
20 | req, err := http.NewRequest(
21 | "POST",
22 | relay_address,
23 | reader)
24 | if err != nil {
25 | log.Error(err.Error())
26 | }
27 |
28 | if user_agent != "" {
29 | req.Header.Set("User-Agent", user_agent)
30 | }
31 |
32 | client := &http.Client{}
33 | res, err := client.Do(req)
34 | if err != nil {
35 | log.Error(err.Error())
36 | }
37 |
38 | return res
39 | }
40 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import(
4 | "github.com/buffermet/sewers/core/environment"
5 | "github.com/buffermet/sewers/core/ui"
6 | )
7 |
8 | func main() {
9 | environment.Init()
10 | ui.Start()
11 | }
12 |
--------------------------------------------------------------------------------
/modules/plugins/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/modules/plugins/.gitkeep
--------------------------------------------------------------------------------
/modules/relays/go/android/raw.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "ioutil"
5 | "net/http"
6 | )
7 |
8 |
9 |
--------------------------------------------------------------------------------
/modules/relays/go/compat/raw.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "io/ioutil"
5 | "net/http"
6 | "time"
7 | )
8 |
9 | const (
10 | obf_const_InterpreterGetTag = "obf_tag_interpreter_get_tag"
11 | obf_const_InterpreterPostTag = "obf_tag_interpreter_post_tag"
12 | obf_const_InterpreterStreamTag = "obf_tag_interpreter_stream_tag"
13 | obf_const_Port = "8008"
14 | obf_const_RequestDir = "obf_tag_request_dir"
15 | obf_const_ResponseDir = "obf_tag_response_dir"
16 | obf_const_SewersGetTag = "obf_tag_sewers_get_tag"
17 | obf_const_SewersPostTag = "obf_tag_sewers_get_tag"
18 | obf_const_SewersStreamTag = "obf_tag_sewers_stream_tag"
19 | obf_const_StreamDir = "obf_tag_stream_dir"
20 | )
21 |
22 | func obf_func_serve(res http.ResponseWriter, req *http.Request) {
23 | defer req.Body.Close()
24 | obf_var_body, _ := ioutil.ReadAll(req.Body)
25 | println(string(obf_var_body))
26 | }
27 |
28 | func main() {
29 | obf_var_server := &http.Server {
30 | Addr: ":" + obf_const_Port,
31 | Handler: http.HandlerFunc(obf_func_serve),
32 | ReadTimeout: 10 * time.Second,
33 | ReadHeaderTimeout: 10 * time.Second,
34 | WriteTimeout: 5 * time.Second,
35 | }
36 | println(obf_var_server.ListenAndServe().Error())
37 | }
38 |
--------------------------------------------------------------------------------
/modules/relays/go/ios/raw.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "ioutil"
5 | "net/http"
6 | )
7 |
8 |
9 |
--------------------------------------------------------------------------------
/modules/relays/go/linux/raw.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "ioutil"
5 | "net/http"
6 | )
7 |
8 |
9 |
--------------------------------------------------------------------------------
/modules/relays/go/macos/raw.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "ioutil"
5 | "net/http"
6 | )
7 |
8 |
9 |
--------------------------------------------------------------------------------
/modules/relays/go/windows/raw.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "ioutil"
5 | "net/http"
6 | )
7 |
8 |
9 |
--------------------------------------------------------------------------------
/modules/stagers/android/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/modules/stagers/ios/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/modules/stagers/macos/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/modules/stagers/windows/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ui/assets/audio/bell.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/audio/bell.mp3
--------------------------------------------------------------------------------
/ui/assets/css/animations-terminal.css:
--------------------------------------------------------------------------------
1 | @keyframes blinking {
2 | from {
3 | background: red;
4 | }
5 | to {
6 | background: #222;
7 | }
8 | }
9 | @-webkit-keyframes blinking {
10 | from {
11 | background: red;
12 | }
13 | to {
14 | background: #222;
15 | }
16 | }
17 | @keyframes onlineblinking {
18 | from {
19 | background: rgba(100,255,100,.4);
20 | box-shadow: none;
21 | border-color: transparent;
22 | }
23 | to {
24 | background: rgba(0,255,0,1);
25 | box-shadow: 0 0 5px 1px green;
26 | border-color: rgba(0,255,0,.1);
27 | }
28 | }
29 | @-webkit-keyframes onlineblinking {
30 | from {
31 | background: rgba(100,255,100,.4);
32 | box-shadow: none;
33 | border-color: transparent;
34 | }
35 | to {
36 | background: rgba(0,255,0,1);
37 | box-shadow: 0 0 5px 1px green;
38 | border-color: rgba(0,255,0,.1);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ui/assets/css/colors.css:
--------------------------------------------------------------------------------
1 | span.red{
2 | color: red;
3 | }
4 | span.green{
5 | color: green;
6 | }
7 | span.lightgreen{
8 | color: rgb(122, 255, 0);
9 | }
10 | span.blue{
11 | color: blue;
12 | }
13 | span.cyan{
14 | color: rgb(0,142,255);
15 | }
16 | span.yellow{
17 | color: yellow;
18 | }
19 | span.tan,
20 | span.orange{
21 | color: orange;
22 | }
23 | span.purple{
24 | color: purple;
25 | }
26 | span.pink{
27 | color: pink;
28 | }
29 | span.maroon{
30 | color: maroon;
31 | }
32 | span.grey,
33 | span.gray{
34 | color: #444;
35 | }
36 | span.black{
37 | color: #000;
38 | }
39 | span.whitebg{
40 | background-color: white;
41 | }
42 | span.bold{
43 | font-weight: bold;
44 | }
45 | span.noshadow{
46 | text-shadow: none;
47 | }
--------------------------------------------------------------------------------
/ui/assets/css/fonts.css:
--------------------------------------------------------------------------------
1 | @font-face{
2 | font-family: "Consolas";
3 | src: url("../fonts/Consolas.ttf");
4 | }
5 | @font-face{
6 | font-family: "OpenSans-Bold";
7 | src: url("../fonts/OpenSans-Bold.ttf");
8 | }
9 | @font-face{
10 | font-family: "OpenSans-BoldItalic";
11 | src: url("../fonts/OpenSans-BoldItalic.ttf");
12 | }
13 | @font-face{
14 | font-family: "OpenSans-ExtraBold";
15 | src: url("../fonts/OpenSans-ExtraBold.ttf");
16 | }
17 | @font-face{
18 | font-family: "OpenSans-ExtraBoldItalic";
19 | src: url("../fonts/OpenSans-ExtraBoldItalic.ttf");
20 | }
21 | @font-face{
22 | font-family: "OpenSans-Italic";
23 | src: url("../fonts/OpenSans-Italic.ttf");
24 | }
25 | @font-face{
26 | font-family: "OpenSans-Light";
27 | src: url("../fonts/OpenSans-Light.ttf");
28 | }
29 | @font-face{
30 | font-family: "OpenSans-LightItalic";
31 | src: url("../fonts/OpenSans-LightItalic.ttf");
32 | }
33 | @font-face{
34 | font-family: "OpenSans-Regular";
35 | src: url("../fonts/OpenSans-Regular.ttf");
36 | }
37 | @font-face{
38 | font-family: "OpenSans-Semibold";
39 | src: url("../fonts/OpenSans-Semibold.ttf");
40 | }
41 | @font-face{
42 | font-family: "OpenSans-SemiboldItalic";
43 | src: url("../fonts/OpenSans-SemiboldItalic.ttf");
44 | }
--------------------------------------------------------------------------------
/ui/assets/css/mediaplayer.css:
--------------------------------------------------------------------------------
1 | html,
2 | html body{
3 | width: 100%;
4 | height: 100%;
5 | margin: 0;
6 | padding: 0;
7 | background: #222;
8 | }
9 | html body div.container{
10 | position: relative;
11 | height: 100%;
12 | width: 100%;
13 | }
14 | html body div.container audio,
15 | html body div.container video{
16 | width: 100%;
17 | height: 100%;
18 | margin: 0;
19 | padding: 0;
20 | background-size: 80px auto !important;
21 | background-position: center 50px !important;
22 | background-repeat: no-repeat !important;
23 | }
24 | html body div.container audio{
25 | background: url(./assets/images/stream-mic.svg);
26 | }
27 |
--------------------------------------------------------------------------------
/ui/assets/css/shadow.css:
--------------------------------------------------------------------------------
1 | /* Shadow 1dp */
2 | .shadow-1dp {
3 | box-shadow: 0 1px 1px 0 rgba(0,0,0,0.14), 0 2px 1px -1px rgba(0,0,0,0.12), 0 1px 3px 0 rgba(0,0,0,0.20);
4 | }
5 |
6 | /* Shadow 2dp */
7 | .shadow-2dp {
8 | box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.20);
9 | }
10 |
11 | /* Shadow 3dp */
12 | .shadow-3dp {
13 | box-shadow: 0 3px 4px 0 rgba(0,0,0,0.14), 0 3px 3px -2px rgba(0,0,0,0.12), 0 1px 8px 0 rgba(0,0,0,0.20);
14 | }
15 |
16 | /* Shadow 4dp */
17 | .shadow-4dp {
18 | box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.20);
19 | }
20 |
21 | /* Shadow 6dp */
22 | .shadow-6dp {
23 | box-shadow: 0 6px 10px 0 rgba(0,0,0,0.14), 0 1px 18px 0 rgba(0,0,0,0.12), 0 3px 5px -1px rgba(0,0,0,0.20);
24 | }
25 |
26 | /* Shadw 8dp */
27 | .shadow-8dp {
28 | box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.20);
29 | }
30 |
31 | /* Shadow 9dp */
32 | .shadow-9dp {
33 | box-shadow: 0 9px 12px 1px rgba(0,0,0,0.14), 0 3px 16px 2px rgba(0,0,0,0.12), 0 5px 6px -3px rgba(0,0,0,0.20);
34 | }
35 |
36 | /* Shadow 12dp */
37 | .shadow-12dp {
38 | box-shadow: 0 12px 17px 2px rgba(0,0,0,0.14), 0 5px 22px 4px rgba(0,0,0,0.12), 0 7px 8px -4px rgba(0,0,0,0.20);
39 | }
40 |
41 | /* Shadow 16dp */
42 | .shadow-16dp {
43 | box-shadow: 0 16px 24px 2px rgba(0,0,0,0.14), 0 6px 30px 5px rgba(0,0,0,0.12), 0 8px 10px -5px rgba(0,0,0,0.20);
44 | }
45 |
46 | /* Shadow 24dp */
47 | .shadow-24dp {
48 | box-shadow: 0 24px 38px 3px rgba(0,0,0,0.14), 0 9px 46px 8px rgba(0,0,0,0.12), 0 11px 15px -7px rgba(0,0,0,0.20);
49 | }
50 |
--------------------------------------------------------------------------------
/ui/assets/css/terminal.css:
--------------------------------------------------------------------------------
1 | * {
2 | -webkit-appearance: none !important;
3 | -moz-appearance: none !important;
4 | -ms-appearance: none !important;
5 | -o-appearance: none !important;
6 | }
7 | *::selection {
8 | background: white;
9 | color: #000;
10 | text-shadow: none;
11 | }
12 | *::-moz-selection {
13 | background: white;
14 | color: #000;
15 | text-shadow: none;
16 | }
17 | ::-webkit-scrollbar {
18 | display: none;
19 | }
20 | input {
21 | outline: none;
22 | }
23 | html {
24 | background-color: #090A0D;
25 | }
26 | html,
27 | html body {
28 | width: 100%;
29 | height: 100%;
30 | max-width: 100%;
31 | max-height: 100%;
32 | margin: 0;
33 | overflow: hidden;
34 | font-weight: 100;
35 | }
36 | html body div.scrollBox {
37 | position: absolute;
38 | top: 0;
39 | width: 100%;
40 | height: auto;
41 | max-height: calc(100% - 26px - 12px);
42 | overflow-x: hidden;
43 | overflow-y: auto;
44 | }
45 | html body div.scrollBox div.background {
46 | position: fixed;
47 | top: 0;
48 | height: 100%;
49 | width: 100%;
50 | opacity: .1;
51 | background-size: auto 220px;
52 | background-repeat: no-repeat;
53 | background-position: top right;
54 | pointer-events: none;
55 | }
56 | html body div.scrollBox div.terminal {
57 | padding: 29px 3px 3px 3px;
58 | color: #FFF;
59 | font-family: monospace;
60 | font-size: 1em;
61 | text-shadow: 0 -1px 0px rgba(0,0,0,0.333);
62 | word-break: break-all;
63 | user-select: initial;
64 | -webkit-user-select: initial;
65 | -moz-user-select: initial;
66 | -ms-user-select: initial;
67 | -o-user-select: initial;
68 | }
69 | html body div.scrollBox div.terminal a {
70 | color: white;
71 | text-decoration: underline;
72 | cursor: pointer;
73 | user-select: text !important;
74 | -webkit-user-select: text !important;
75 | -moz-user-select: text !important;
76 | -ms-user-select: text !important;
77 | -o-user-select: text !important;
78 | }
79 | html body div.scrollBox div.terminal a:hover {
80 | text-decoration: none;
81 | }
82 | html body div.scrollBox div.terminal img {
83 | max-width: 100%;
84 | vertical-align: baseline;
85 | }
86 | html body div.scrollBox div.terminal img.icon {
87 | display: inline-block;
88 | position: relative;
89 | width: 12px;
90 | height: 12px;
91 | top: 1px;
92 | margin: 0 3px 0 1px;
93 | }
94 | html body div.scrollBox div.terminal img.icon.link {
95 | margin: 0;
96 | }
97 | html body div.scrollBox div.terminal hr {
98 | display: block;
99 | width: calc(100% - 12px);
100 | height: 1px;
101 | background: rgba(255,255,255,0.05);
102 | margin: 6px;
103 | border: none;
104 | padding: 0px;
105 | }
106 | html body form {
107 | position: absolute;
108 | bottom: 0;
109 | width: 100%;
110 | }
111 | html body form div.loadline {
112 | position: absolute;
113 | right: 0;
114 | width: 0%;
115 | height: 1px;
116 | background-color: white;
117 | opacity: 1;
118 | }
119 | html body form div.loadline.stop {
120 | opacity: 0;
121 | width: 100%;
122 | transition: none !important;
123 | -webkit-transition: none !important;
124 | -moz-transition: none !important;
125 | -ms-transition: none !important;
126 | -o-transition: none !important;
127 | }
128 | html body form textarea {
129 | margin: 0;
130 | padding: 0;
131 | outline: none;
132 | width: 100%;
133 | height: calc(100% - 8px);
134 | border: none;
135 | border-top: 1px solid rgba(255,255,255,0.05);
136 | text-shadow: 0 -1px 0px black;
137 | font-size: 1em;
138 | padding: 3px;
139 | background: transparent;
140 | resize: none;
141 | color: #FFF;
142 | }
143 | html body form input[type=button]:hover {
144 | background: rgba(80,80,80,0.4);
145 | }
146 | .displaynone {
147 | display: none;
148 | }
149 | html body preload {
150 | position: absolute;
151 | display: block;
152 | overflow: hidden;
153 | width: 0px;
154 | height: 0px;
155 | }
156 |
--------------------------------------------------------------------------------
/ui/assets/fonts/Consolas.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/Consolas.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-Bold.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-BoldItalic.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-ExtraBold.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-Italic.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-Light.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-LightItalic.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-Semibold.ttf
--------------------------------------------------------------------------------
/ui/assets/fonts/OpenSans-SemiboldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/fonts/OpenSans-SemiboldItalic.ttf
--------------------------------------------------------------------------------
/ui/assets/images/appearance.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
63 |
--------------------------------------------------------------------------------
/ui/assets/images/back.svg:
--------------------------------------------------------------------------------
1 |
2 |
63 |
--------------------------------------------------------------------------------
/ui/assets/images/box.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
64 |
--------------------------------------------------------------------------------
/ui/assets/images/cards.svg:
--------------------------------------------------------------------------------
1 |
2 |
44 |
--------------------------------------------------------------------------------
/ui/assets/images/clear.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/close.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/controls.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ui/assets/images/expresser.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/eye.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
67 |
--------------------------------------------------------------------------------
/ui/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/images/favicon.png
--------------------------------------------------------------------------------
/ui/assets/images/fetch.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/fingerprint.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/home.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
60 |
--------------------------------------------------------------------------------
/ui/assets/images/io.svg:
--------------------------------------------------------------------------------
1 |
2 |
61 |
--------------------------------------------------------------------------------
/ui/assets/images/javascript.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
72 |
--------------------------------------------------------------------------------
/ui/assets/images/key.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
59 |
--------------------------------------------------------------------------------
/ui/assets/images/link-unsafe.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/loader.svg:
--------------------------------------------------------------------------------
1 |
2 |
134 |
--------------------------------------------------------------------------------
/ui/assets/images/loadline.svg:
--------------------------------------------------------------------------------
1 |
2 |
62 |
--------------------------------------------------------------------------------
/ui/assets/images/lock.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/message-corner.svg:
--------------------------------------------------------------------------------
1 |
2 |
37 |
--------------------------------------------------------------------------------
/ui/assets/images/newwindow.svg:
--------------------------------------------------------------------------------
1 |
2 |
85 |
--------------------------------------------------------------------------------
/ui/assets/images/os_apple.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/os_windows.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/padlock.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/pause.svg:
--------------------------------------------------------------------------------
1 |
2 |
71 |
--------------------------------------------------------------------------------
/ui/assets/images/plug.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
60 |
--------------------------------------------------------------------------------
/ui/assets/images/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
73 |
--------------------------------------------------------------------------------
/ui/assets/images/quit.svg:
--------------------------------------------------------------------------------
1 |
2 |
48 |
--------------------------------------------------------------------------------
/ui/assets/images/route.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/script.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/selectall.svg:
--------------------------------------------------------------------------------
1 |
2 |
58 |
--------------------------------------------------------------------------------
/ui/assets/images/session.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
64 |
--------------------------------------------------------------------------------
/ui/assets/images/settings.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/snapmon.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/stop.svg:
--------------------------------------------------------------------------------
1 |
2 |
39 |
--------------------------------------------------------------------------------
/ui/assets/images/streammic.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/streammon.svg:
--------------------------------------------------------------------------------
1 |
2 |
32 |
--------------------------------------------------------------------------------
/ui/assets/images/tablet.svg:
--------------------------------------------------------------------------------
1 |
2 |
136 |
--------------------------------------------------------------------------------
/ui/assets/images/toggle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
63 |
--------------------------------------------------------------------------------
/ui/assets/images/tor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/images/tor.png
--------------------------------------------------------------------------------
/ui/assets/images/tplink.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/tplink_black.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/tplink_white.svg:
--------------------------------------------------------------------------------
1 |
2 |
36 |
--------------------------------------------------------------------------------
/ui/assets/images/unknown.svg:
--------------------------------------------------------------------------------
1 |
2 |
41 |
--------------------------------------------------------------------------------
/ui/assets/images/wand.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
64 |
--------------------------------------------------------------------------------
/ui/assets/js/http.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI HTTP package
5 | *
6 | */
7 |
8 | app.http.Request = async (method, url, headers, body) => {
9 | return new Promise(async(resolve, reject)=>{
10 | let req = new XMLHttpRequest();
11 |
12 | try {
13 | req.open(method, url);
14 |
15 | try {
16 | for (let i = 0; i < headers.length; i++) {
17 | const header_name = headers[i][0],
18 | header_value = headers[i][1];
19 |
20 | req.setRequestHeader(header_name, header_value);
21 | }
22 | } catch(err) {
23 | console.error(err);
24 | }
25 |
26 | req.onreadystatechange = async () => {
27 | if (req.readyState == 4) {
28 | resolve(req);
29 | }
30 | }
31 | } catch(err) {
32 | reject(err);
33 | }
34 |
35 | req.send(body);
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/ui/assets/js/index.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI index package
5 | *
6 | */
7 |
8 | self.addEventListener("load", async()=>{
9 | await app.functions.whoAmI();
10 | await app.functions.getSewersConfig();
11 | await app.functions.updateCSS();
12 | await app.functions.showRelays();
13 |
14 | app.functions.fetchLog();
15 | setInterval(app.functions.fetchLog, 400); // make websocket
16 |
17 | setInterval(app.functions.cycleNews, 4000);
18 | setTimeout(async()=>{ app.environment.container.classList.remove("hide") }, 720);
19 | })
20 |
--------------------------------------------------------------------------------
/ui/assets/js/index/environment.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI index environment package
5 | *
6 | */
7 |
8 | // App
9 | const app = {}
10 |
11 | // Modules
12 | app.commands = {}
13 | app.events = {}
14 | app.functions = {}
15 | app.http = {}
16 | app.environment = {
17 | whoami: "",
18 | timezone: "",
19 | lastIP: "",
20 | currentRelay: "",
21 | relayUserAgent: "",
22 | relayConfig: {},
23 | sewersConfig: {},
24 | resizingConsole: false,
25 | scrollOnOutput: false,
26 | warnOnRequest: true,
27 | webConsole: document.querySelector("html body div.console"),
28 | consoleContainer: document.querySelector("html body div.console div.consolecontainer"),
29 | consoleClear: document.querySelector("html body div.console div.clear"),
30 | consoleResizeBar: document.querySelector("html body div.console div.resizebar"),
31 | popupBackground: document.querySelector("html body div.popup"),
32 | upstreamIndicator: document.querySelector("html body div.menu div.item div.upstream-indicator"),
33 | backbutton: document.querySelector("html body div.menu div.item[name=backbutton]"),
34 | scrollContainer: document.querySelector("html body div.scrollcontainer"),
35 | container: document.querySelector("html body div.scrollcontainer div.container"),
36 | relayList: document.querySelector("html body div.scrollcontainer div.container div.relaylist"),
37 | relays: document.querySelectorAll("html body div.scrollcontainer div.container div.relaylist div.relay"),
38 | sessions: document.querySelectorAll("html body div.scrollcontainer div.container div.sessionlist div.session"),
39 | newsMessage: document.querySelector("html body div.scrollcontainer div.container div div.header span.newsmessage"),
40 | newsMessageRelays: document.querySelectorAll("html body div.scrollcontainer div.container div.relaylist div.header span.newsmessage"),
41 | newsMessageSessions: document.querySelector("html body div.scrollcontainer div.container div.sessionlist div.header span.newsmessage"),
42 | newsRelays: {},
43 | newsSessions: {},
44 | currentRelaysNews: 0,
45 | currentSessionsNews: 0,
46 | }
47 |
--------------------------------------------------------------------------------
/ui/assets/js/index/events.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI index events package
5 | *
6 | */
7 |
8 | // Quit button
9 | /*
10 | document.querySelector("html body div.menu div[name=quit]").addEventListener("click", async()=>{
11 | //
12 | });
13 | */
14 |
15 | // Preferences button
16 | document.querySelector("html body div.menu div.item[name=settings]").addEventListener("click", async()=>{
17 | app.functions.showPreferences();
18 | });
19 |
20 | // Back button
21 | app.environment.backbutton.addEventListener("click", async(event)=>{
22 | app.environment.backbutton.setAttribute("data-state", "off");
23 |
24 | app.functions.showRelays();
25 | });
26 |
27 | // Console clear button
28 | app.environment.consoleClear.addEventListener("click", async()=>{
29 | app.http.Request("GET", "/clear_console_log", [[]], "").then(async(res)=>{
30 | if (res.status == 200) {
31 | app.environment.consoleContainer.innerHTML = "";
32 | app.functions.fetchLog();
33 | }
34 | });
35 | });
36 |
37 | // Start resizing console with cursor
38 | app.environment.consoleResizeBar.addEventListener("mousedown", async(event)=>{
39 | app.environment.resizingConsole = true;
40 | });
41 |
42 | // Start resizing console with touchscreen
43 | app.environment.consoleResizeBar.addEventListener("touchstart", async(event)=>{
44 | app.environment.resizingConsole = true;
45 | });
46 |
47 | // Resizing of console with cursor
48 | self.addEventListener("mousemove", async function startResizing(event){
49 | if (app.environment.resizingConsole) {
50 | app.functions.resizeConsole(event.clientY);
51 | }
52 | });
53 |
54 | // Resizing of console with touchscreen
55 | self.addEventListener("touchmove", async function resize(event){
56 | if (app.environment.resizingConsole) {
57 | app.functions.resizeConsole(event.touches[0].clientY);
58 | }
59 | });
60 |
61 | // Stop resizing console with cursor
62 | self.addEventListener("mouseup", async function stopResizing(event){
63 | if (app.environment.resizingConsole) {
64 | app.environment.resizingConsole = false;
65 | app.http.Request( "POST", "/config/sewers", [["Content-Type", "application/x-www-form-urlencoded"]], "console_height=" + app.environment.webConsole.getBoundingClientRect().height );
66 | }
67 | });
68 |
69 | // Stop resizing console with touchscreen
70 | self.addEventListener("touchend", async function stopResizing(event){
71 | if (app.environment.resizingConsole) {
72 | app.environment.resizingConsole = false;
73 | app.http.Request( "POST", "/config/sewers", [["Content-Type", "application/x-www-form-urlencoded"]], "console_height=" + app.environment.webConsole.getBoundingClientRect().height );
74 | }
75 | });
76 |
77 | // Prevent console from being hidden when resizing window.
78 | self.addEventListener("resize", async()=>{
79 | if ( app.environment.webConsole.getBoundingClientRect().height >= ( self.innerHeight - 75 ) && app.environment.webConsole.getBoundingClientRect().height > 51 ) {
80 | app.environment.webConsole.style.height = ( self.innerHeight - 75 ) + "px";
81 | app.environment.consoleResizeBar.style.bottom = ( self.innerHeight - 75 - 1 ) + "px";
82 | app.environment.scrollContainer.style.height = "calc(100% - " + ( self.innerHeight - 75 ) + "px)";
83 |
84 | let console_height = app.environment.webConsole.getBoundingClientRect().height;
85 |
86 | app.http.Request("POST", "/config/sewers", [["Content-Type", "application/x-www-form-urlencoded"]], "console_height=" + console_height);
87 | }
88 | });
89 |
--------------------------------------------------------------------------------
/ui/assets/js/index/sockets.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI index websockets package
5 | *
6 | */
7 |
8 | const socket_address = "ws://" + location.host + "/stream"
9 |
--------------------------------------------------------------------------------
/ui/assets/js/mediaplayer.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI mediaplayer package
5 | *
6 | */
7 |
8 | // Parse URL
9 | const queryLine = window.location.href.replace(/.*\?/g, "");
10 | const queries = queryLine.split("&");
11 | const streamType = queries[0],
12 | streamID = queries[1],
13 | streamFile = queries[2];
14 |
15 | // Define elements
16 | const container = document.querySelector("html body div.container");
17 |
18 | // Set title
19 | document.title = streamType.toUpperCase() + " " + streamID;
20 |
21 | // Load media
22 | if (streamType == "mic") {
23 | container.append("");
24 | } else if (streamType == "mon") {
25 | container.append("");
26 | } else if (streamType == "cam") {
27 | container.append("");
28 | } else {
29 | container.append("No stream type specified
");
30 | }
31 |
--------------------------------------------------------------------------------
/ui/assets/js/mediaplayer/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/assets/js/mediaplayer/.gitkeep
--------------------------------------------------------------------------------
/ui/assets/js/menu.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI menu package
5 | *
6 | */
7 |
8 | // Reveal submenus on desktop and mobile
9 | document.querySelectorAll("html body div.menu div.item").forEach(async(item)=>{
10 | if (
11 | item.getAttribute("name") !== "xssbutton"
12 | && item.getAttribute("name") !== "backbutton"
13 | ) {
14 | item.addEventListener("mouseenter", async(event)=>{
15 | event.target.setAttribute("data-state", "on");
16 | });
17 |
18 | item.addEventListener("mouseleave", async(event)=>{
19 | event.target.setAttribute("data-state", "off");
20 | });
21 | }
22 | });
23 |
--------------------------------------------------------------------------------
/ui/assets/js/popup.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI popup package
5 | *
6 | */
7 |
8 | app.functions.showPopup = async html => {
9 | app.environment.popupContent.innerHTML = html;
10 |
11 | app.environment.popup.setAttribute("data-state", "on");
12 | }
13 |
14 | app.functions.closePopup = async () => {
15 | app.environment.popup.setAttribute("data-state", "off");
16 |
17 | app.environment.popupContent.innerHTML = "";
18 | }
19 |
--------------------------------------------------------------------------------
/ui/assets/js/terminal.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI terminal package
5 | *
6 | */
7 |
8 | self.addEventListener("load", async()=>{
9 | app.functions.shrinkInputField().then(async()=>{
10 | app.functions.resetClearBreaks();
11 | });
12 |
13 | await app.functions.getSessionConfig( app.environment.relay, location.pathname.replace(/.*\//, "") );
14 | await app.functions.getRelayConfig(app.environment.relay);
15 | await app.functions.parseUserAgent();
16 |
17 | app.functions.printInstructions();
18 |
19 | Object.keys(app.commands.builtin).forEach(async(command)=>{
20 | app.commands.builtin[command].load();
21 | });
22 | Object.keys(app.commands.pluggedin).forEach(async(command)=>{
23 | app.commands.pluggedin[command].load();
24 | });
25 |
26 | document.title = app.environment.sessionConfig.session_id + ' - ' + app.environment.sessionConfig.hostname;
27 |
28 | app.environment.textarea.focus();
29 | });
30 |
--------------------------------------------------------------------------------
/ui/assets/js/terminal/environment.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | *
4 | * Sewers UI terminal environment package
5 | *
6 | */
7 |
8 | // App
9 | const app = {};
10 |
11 | // Modules
12 | app.environment = {
13 | form: document.querySelector("html body form"),
14 | textarea: document.querySelector("html body form textarea"),
15 | scrollBox: document.querySelector("html body div.scrollBox"),
16 | terminal: document.querySelector("html body div.scrollBox div.terminal"),
17 | xssButton: document.querySelector("html body div.menu div.item[name=xssbutton]"),
18 | xssField: document.querySelector("html body div.menu div.item[name=xssbutton] input"),
19 | upstreamIndicator: document.querySelector("html body div.menu div.item div.upstream-indicator"),
20 | ctrlKey: false,
21 | sessionConfig: {},
22 | relayConfig: {},
23 | autoFetch: async () => {},
24 | autoFetchTimeout: null,
25 | fetchDelay: 1000,
26 | autoFetching: false,
27 | loadLine: document.querySelector("html body form div.loadline"),
28 | relay: location.href.replace(/.*\/terminal\//g, "").replace(/\/.*/g, ""),
29 | requestTag: "sewers \xBB ",
30 | responseTag: "interpreter \xBB ",
31 | request: null,
32 | onResponse: async () => {},
33 | streamingMicrophone: false,
34 | streamingMonitor: false,
35 | streamingShell: false,
36 | streamingWebcam: false,
37 | allowedCharacters: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz".split(""),
38 | cmdHistory: new Array(),
39 | cmdHistoryIndex: 0,
40 | cmdCurrent: "",
41 | clearBreaks: parseInt( document.querySelector("html body div.scrollBox").getBoundingClientRect().height / 12 ),
42 | micBitrate: "16000",
43 | monBitrate: "512000",
44 | monResolution: "1280x800",
45 | camBitrate: "512000",
46 | camResolution: "1280x800",
47 | fetchOnAutoFetchStart: true,
48 | warnOnReset: false,
49 | scrollOnInput: true,
50 | scrollOnOutput: false,
51 | scrollOnJsInput: false,
52 | playSoundOnStdout: false,
53 | warnOnRequest: true,
54 | warnOnClose: true,
55 | };
56 | app.http = {};
57 | app.functions = {};
58 | app.functions.prototypes = {};
59 | app.events = {};
60 | app.commands = {};
61 | app.commands.prototypes = {};
62 | app.streams = {};
63 | app.streams.active = {};
64 | app.streams.current = "";
65 |
--------------------------------------------------------------------------------
/ui/console_log.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buffermet/sewers/34e61b90919d627fea5129e14c387cb999221879/ui/console_log.html
--------------------------------------------------------------------------------
/ui/help.html:
--------------------------------------------------------------------------------
1 |
2 | Terminal commands
3 |
4 |
5 | clear Clear terminal window with linebreaks.
6 |
7 | exit Exit the terminal (pop-up window only).
8 |
9 | fetch Fetch responses from interpreter.
10 |
11 | help, h, ? Show this menu.
12 |
13 | telemetry Show telemetry data of current session.
14 |
15 | reset Reset terminal window.
16 |
17 | startautofetching Set automatic fetch rate of this terminal.
18 |
19 | <MIN SECONDS> <MAX SECONDS>
20 |
21 | stopautofetching Stop automatically fetching new packets.
22 |
23 | xss <CODE> Execute JavaScript in this terminal.
24 |
25 |
26 | Sewers commands
27 |
28 |
29 | Interpreter commands
30 |
31 |
32 |
36 |
38 |
40 |
44 |
46 |
48 |
52 | shell, sh <COMMAND> Execute shell command.
53 |
54 |
56 |
58 |
62 |
64 |
68 | fetchrate Set automatic fetch rate of interpreter.
69 |
70 | <MIN SECONDS> <MAX SECONDS>
71 |
72 |
74 |
75 | Module commands
76 |
77 |
--------------------------------------------------------------------------------
/ui/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Relays
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
26 |
27 |
28 |
29 |
New relay
30 |
New interpreter
31 |
32 |
33 |
40 |
41 |
42 |
1
43 |
44 |
45 |
46 |
127.0.0.1
47 |
Active 54 seconds ago.
48 |
49 |
50 |
51 |
52 |
58 |
59 |
67 |
70 |
73 |
74 |
77 |
78 |
CLEAR
79 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/ui/mediaplayer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ui/terminal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
81 |
85 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------