Overhaul.
This commit is contained in:
parent
44aede482b
commit
235e9bb643
12
common.go
12
common.go
|
@ -5,6 +5,8 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"git.tcp.direct/tcp.direct/tcp.ac/config"
|
||||
)
|
||||
|
||||
type EntryType uint8
|
||||
|
@ -75,7 +77,7 @@ func (p *Post) Log(l zerolog.Logger) *zerolog.Logger {
|
|||
|
||||
func validateKey(rKey string) bool {
|
||||
// if it doesn't match the key size or it isn't alphanumeric - throw it out
|
||||
if len(rKey) != keySize || !valid.IsAlphanumeric(rKey) {
|
||||
if len(rKey) != config.DeleteKeySize || !valid.IsAlphanumeric(rKey) {
|
||||
log.Warn().Str("rKey", rKey).
|
||||
Msg("delete request failed sanity check!")
|
||||
return false
|
||||
|
@ -85,9 +87,9 @@ func validateKey(rKey string) bool {
|
|||
|
||||
func (p *Post) URLString() string {
|
||||
var keyurl string = ""
|
||||
url := baseURL + p.TypeCode() + "/" + string(p.UID())
|
||||
url := config.BaseURL + p.TypeCode() + "/" + string(p.UID())
|
||||
if p.DelKey() != "" {
|
||||
keyurl = baseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
|
||||
keyurl = config.BaseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
|
||||
}
|
||||
|
||||
p.Log(log.Logger).Info().Msg("success")
|
||||
|
@ -100,9 +102,9 @@ func (p *Post) URLString() string {
|
|||
|
||||
func (p *Post) Serve(c *gin.Context) {
|
||||
var keyurl string = ""
|
||||
url := baseURL + p.TypeCode() + "/" + string(p.UID())
|
||||
url := config.BaseURL + p.TypeCode() + "/" + string(p.UID())
|
||||
if p.DelKey() != "" {
|
||||
keyurl = baseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
|
||||
keyurl = config.BaseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
|
||||
}
|
||||
|
||||
log.Info().
|
||||
|
|
74
config.go
74
config.go
|
@ -1,74 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// //////////// global declarations
|
||||
var (
|
||||
// config directives
|
||||
debugBool bool
|
||||
baseURL string
|
||||
webPort string
|
||||
webIP string
|
||||
dbDir string
|
||||
logDir string
|
||||
uidSize int
|
||||
keySize int
|
||||
txtPort string
|
||||
maxSize int
|
||||
|
||||
// utilitarian globals
|
||||
err error
|
||||
fn string
|
||||
s string
|
||||
i int
|
||||
f *os.File
|
||||
)
|
||||
|
||||
func configRead() {
|
||||
// name of the file
|
||||
// and the extension
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("toml")
|
||||
|
||||
// potential config paths
|
||||
viper.AddConfigPath("/etc/tcpac/")
|
||||
viper.AddConfigPath("../")
|
||||
viper.AddConfigPath("./")
|
||||
|
||||
// this should be replaced with more intelligent handling
|
||||
err = viper.ReadInConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Fatal error reading config file: %s \n", err))
|
||||
}
|
||||
|
||||
// read config
|
||||
debugBool = viper.GetBool("global.debug") // we need to load the debug boolean first
|
||||
if debugBool {
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
log.Debug().Msg("Debug mode enabled")
|
||||
} else {
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
}
|
||||
|
||||
baseURL = viper.GetString("http.baseurl")
|
||||
|
||||
i := viper.GetInt("http.port")
|
||||
webPort = strconv.Itoa(i)
|
||||
|
||||
webIP = viper.GetString("http.bindip")
|
||||
dbDir = viper.GetString("files.data")
|
||||
logDir = viper.GetString("files.logs")
|
||||
uidSize = viper.GetInt("global.uidsize")
|
||||
keySize = viper.GetInt("global.delkeysize")
|
||||
txtPort = viper.GetString("txt.port")
|
||||
maxSize = viper.GetInt("files.maxuploadsize")
|
||||
//
|
||||
}
|
36
config.toml
36
config.toml
|
@ -1,20 +1,24 @@
|
|||
title = "tcp.ac config"
|
||||
|
||||
[global]
|
||||
debug = true
|
||||
uidsize = 5
|
||||
delkeysize = 12
|
||||
[data]
|
||||
directory = '.data'
|
||||
max_key_size_mb = 10
|
||||
max_value_size_mb = 20
|
||||
|
||||
[http]
|
||||
baseurl = "http://127.0.0.1:8080/"
|
||||
bindip = "127.0.0.1"
|
||||
port = 8080
|
||||
bind_addr = '127.0.0.1'
|
||||
bind_port = '8080'
|
||||
unix_socket_path = '/var/run/tcp.ac'
|
||||
unix_socket_permissions = 420
|
||||
use_unix_socket = false
|
||||
|
||||
[txt]
|
||||
# string: port to listen on for termbin clone
|
||||
port = "9988"
|
||||
[logger]
|
||||
debug = true
|
||||
directory = '.logs'
|
||||
nocolor = false
|
||||
trace = false
|
||||
use_date_filename = true
|
||||
|
||||
[other]
|
||||
delete_key_size = 12
|
||||
termbin_listen = '127.0.0.1:9999'
|
||||
uid_size = 5
|
||||
|
||||
[files]
|
||||
data = "./data/"
|
||||
logs = "./logs/"
|
||||
sizelimit = 48
|
||||
|
|
111
config/config.go
111
config/config.go
|
@ -7,7 +7,6 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -20,20 +19,24 @@ const (
|
|||
|
||||
var (
|
||||
// Version roughly represents the applications current version.
|
||||
Version = runtime.
|
||||
Version = "asdf"
|
||||
)
|
||||
|
||||
var (
|
||||
BaseURL, WebPort, WebIP, DBDir, LogDir, TxtPort string
|
||||
UIDSize, KeySize, MaxSize int
|
||||
BaseURL, HTTPPort, HTTPBind, DBDir, LogDir,
|
||||
TermbinListen, UnixSocketPath string
|
||||
UIDSize, DeleteKeySize, KVMaxKeySizeMB,
|
||||
KVMaxValueSizeMB int
|
||||
UnixSocketPermissions uint32
|
||||
UseUnixSocket bool
|
||||
)
|
||||
|
||||
var usage = []string{
|
||||
"\n" + Title + " v" + Version + " Usage\n",
|
||||
"-c <config.toml> - Specify config file",
|
||||
"-c <toml> - Specify config file",
|
||||
"--nocolor - disable color and banner ",
|
||||
"--banner - show banner + version and exit",
|
||||
"--genconfig - write default config to 'config.toml' then exit",
|
||||
"--genconfig - write default config to 'toml' then exit",
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
|
@ -42,8 +45,14 @@ func printUsage() {
|
|||
}
|
||||
|
||||
var (
|
||||
forceDebug = false
|
||||
forceTrace = false
|
||||
forceDebug = false
|
||||
forceTrace = false
|
||||
genConfig = false
|
||||
noColorForce = false
|
||||
customconfig = false
|
||||
home string
|
||||
prefConfigLocation string
|
||||
snek *viper.Viper
|
||||
)
|
||||
|
||||
// TODO: should probably just make a proper CLI with flags or something
|
||||
|
@ -53,35 +62,23 @@ func argParse() {
|
|||
case "-h":
|
||||
printUsage()
|
||||
case "--genconfig":
|
||||
GenConfig = true
|
||||
genConfig = true
|
||||
case "--debug", "-v":
|
||||
forceDebug = true
|
||||
case "--trace", "-vv":
|
||||
forceTrace = true
|
||||
case "--nocolor":
|
||||
noColorForce = true
|
||||
case "--banner":
|
||||
BannerOnly = true
|
||||
case "-c", "--config":
|
||||
if len(os.Args) <= i-1 {
|
||||
panic("syntax error! expected file after -c")
|
||||
}
|
||||
loadCustomConfig(os.Args[i+1])
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generic vars
|
||||
var (
|
||||
noColorForce = false
|
||||
customconfig = false
|
||||
home string
|
||||
prefConfigLocation string
|
||||
snek *viper.Viper
|
||||
)
|
||||
|
||||
// exported generic vars
|
||||
var (
|
||||
// Trace is the value of our trace (extra verbose) on/off toggle as per the current configuration.
|
||||
|
@ -92,11 +89,6 @@ var (
|
|||
Filename string
|
||||
)
|
||||
|
||||
func init() {
|
||||
prefConfigLocation = home + "/.config/" + Title
|
||||
snek = viper.New()
|
||||
}
|
||||
|
||||
func writeConfig() {
|
||||
var err error
|
||||
//goland:noinspection GoBoolExpressions
|
||||
|
@ -119,7 +111,7 @@ func writeConfig() {
|
|||
}
|
||||
}
|
||||
|
||||
newconfig := prefConfigLocation + "/" + "config.toml"
|
||||
newconfig := prefConfigLocation + "/" + "toml"
|
||||
if err = snek.SafeWriteConfigAs(newconfig); err != nil {
|
||||
fmt.Println("Failed to write new configuration file: " + err.Error())
|
||||
os.Exit(1)
|
||||
|
@ -130,11 +122,19 @@ func writeConfig() {
|
|||
|
||||
// Init will initialize our toml configuration engine and define our default configuration values which can be written to a new configuration file if desired
|
||||
func Init() {
|
||||
argParse()
|
||||
prefConfigLocation = home + "/.config/" + Title
|
||||
snek = viper.New()
|
||||
|
||||
if genConfig {
|
||||
setDefaults()
|
||||
println("config file generated at: " + Filename)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
snek.SetConfigType("toml")
|
||||
snek.SetConfigName("config")
|
||||
|
||||
argParse()
|
||||
|
||||
if customconfig {
|
||||
associateExportedVariables()
|
||||
return
|
||||
|
@ -146,7 +146,7 @@ func Init() {
|
|||
snek.AddConfigPath(loc)
|
||||
}
|
||||
|
||||
if err = snek.MergeInConfig(); err != nil {
|
||||
if err := snek.MergeInConfig(); err != nil {
|
||||
println("Error reading configuration file: " + err.Error())
|
||||
println("Writing new configuration file...")
|
||||
writeConfig()
|
||||
|
@ -171,7 +171,8 @@ func getConfigPaths() (paths []string) {
|
|||
|
||||
func loadCustomConfig(path string) {
|
||||
/* #nosec */
|
||||
if f, err = os.Open(path); err != nil {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
println("Error opening specified config file: " + path)
|
||||
println(err.Error())
|
||||
os.Exit(1)
|
||||
|
@ -212,59 +213,47 @@ func processOpts() {
|
|||
stringOpt := map[string]*string{
|
||||
"http.bind_addr": &HTTPBind,
|
||||
"http.bind_port": &HTTPPort,
|
||||
"http.unix_socket_path": &UnixSocketPath,
|
||||
"logger.directory": &LogDir,
|
||||
"deception.server_name": &FakeServerName,
|
||||
}
|
||||
// string slice options and their exported variables
|
||||
strSliceOpt := map[string]*[]string{
|
||||
"http.router.paths": &Paths,
|
||||
"other.termbin_listen": &TermbinListen,
|
||||
}
|
||||
|
||||
// bool options and their exported variables
|
||||
boolOpt := map[string]*bool{
|
||||
"performance.restrict_concurrency": &RestrictConcurrency,
|
||||
"http.use_unix_socket": &UseUnixSocket,
|
||||
"logger.debug": &Debug,
|
||||
"logger.trace": &Trace,
|
||||
"logger.nocolor": &NoColor,
|
||||
"http.router.makerobots": &MakeRobots,
|
||||
"http.router.catchall": &CatchAll,
|
||||
"http.use_unix_socket": &UseUnixSocket,
|
||||
"logger.debug": &Debug,
|
||||
"logger.trace": &Trace,
|
||||
"logger.nocolor": &noColorForce,
|
||||
}
|
||||
|
||||
// integer options and their exported variables
|
||||
intOpt := map[string]*int{
|
||||
"performance.max_workers": &MaxWorkers,
|
||||
"data.max_key_size": &KVMaxKeySizeMB,
|
||||
"data.max_value_size": &KVMaxValueSizeMB,
|
||||
"other.uid_size": &UIDSize,
|
||||
}
|
||||
|
||||
uint32Opt := map[string]*uint32{
|
||||
"http.unix_socket_permissions": &UnixSocketPermissions,
|
||||
}
|
||||
|
||||
for key, opt := range stringOpt {
|
||||
*opt = snek.GetString(key)
|
||||
}
|
||||
for key, opt := range strSliceOpt {
|
||||
*opt = snek.GetStringSlice(key)
|
||||
}
|
||||
for key, opt := range boolOpt {
|
||||
*opt = snek.GetBool(key)
|
||||
}
|
||||
for key, opt := range intOpt {
|
||||
*opt = snek.GetInt(key)
|
||||
}
|
||||
for key, opt := range uint32Opt {
|
||||
*opt = snek.GetUint32(key)
|
||||
}
|
||||
}
|
||||
|
||||
func associateExportedVariables() {
|
||||
processOpts()
|
||||
|
||||
if noColorForce {
|
||||
NoColor = true
|
||||
}
|
||||
|
||||
if UseUnixSocket {
|
||||
UnixSocketPath = snek.GetString("http.unix_socket_path")
|
||||
parsedPermissions, err := strconv.ParseUint(snek.GetString("http.unix_socket_permissions"), 8, 32)
|
||||
if err == nil {
|
||||
UnixSocketPermissions = uint32(parsedPermissions)
|
||||
}
|
||||
}
|
||||
|
||||
// We set exported variables here so that it tracks when accessed from other packages.
|
||||
|
||||
if Debug || forceDebug {
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
Debug = true
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
configSections = []string{"logger", "http", "data", "other"}
|
||||
defNoColor = false
|
||||
)
|
||||
|
||||
var defOpts = map[string]map[string]interface{}{
|
||||
"logger": {
|
||||
"directory": ".logs",
|
||||
"debug": true,
|
||||
"trace": false,
|
||||
"nocolor": defNoColor,
|
||||
"use_date_filename": true,
|
||||
},
|
||||
"http": {
|
||||
"use_unix_socket": false,
|
||||
"unix_socket_path": "/var/run/tcp.ac",
|
||||
"unix_socket_permissions": uint32(0644),
|
||||
"bind_addr": "127.0.0.1",
|
||||
"bind_port": "8080",
|
||||
},
|
||||
"data": {
|
||||
"directory": ".data",
|
||||
"max_key_size_mb": 10,
|
||||
"max_value_size_mb": 20,
|
||||
},
|
||||
"other": {
|
||||
"uid_size": 5,
|
||||
"delete_key_size": 12,
|
||||
"termbin_listen": "127.0.0.1:9999",
|
||||
},
|
||||
}
|
||||
|
||||
func setDefaults() {
|
||||
//goland:noinspection GoBoolExpressions
|
||||
if runtime.GOOS == "windows" {
|
||||
snek.SetDefault("logger.directory", "./logs/")
|
||||
defNoColor = true
|
||||
}
|
||||
|
||||
for _, def := range configSections {
|
||||
snek.SetDefault(def, defOpts[def])
|
||||
}
|
||||
|
||||
if genConfig {
|
||||
if err := snek.SafeWriteConfigAs("./config.toml"); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
}
|
14
db.go
14
db.go
|
@ -1,8 +1,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
prologic "git.tcp.direct/Mirrors/bitcask-mirror"
|
||||
"git.tcp.direct/tcp.direct/database/bitcask"
|
||||
|
||||
"git.tcp.direct/tcp.direct/tcp.ac/config"
|
||||
)
|
||||
|
||||
var stores = []string{"hsh", "key", "img", "txt", "url"}
|
||||
|
@ -10,11 +11,16 @@ var megabyte = float64(1024 * 1024)
|
|||
|
||||
var db *bitcask.DB
|
||||
|
||||
func init() {
|
||||
bitcask.SetDefaultBitcaskOptions(
|
||||
bitcask.WithMaxKeySize(uint32(config.KVMaxKeySizeMB*int(megabyte))),
|
||||
bitcask.WithMaxValueSize(uint64(config.KVMaxValueSizeMB*int(megabyte))),
|
||||
)
|
||||
}
|
||||
func dbInit() error {
|
||||
db = bitcask.OpenDB(dbDir)
|
||||
var bitcaskopts = []prologic.Option{prologic.WithMaxValueSize(uint64(maxSize) * uint64(megabyte))}
|
||||
db = bitcask.OpenDB(config.DBDir)
|
||||
for _, st := range stores {
|
||||
if err := db.Init(st, bitcaskopts...); err != nil {
|
||||
if err := db.Init(st); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,6 @@ module git.tcp.direct/tcp.direct/tcp.ac
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34
|
||||
git.tcp.direct/kayos/putxt v0.0.0-20220707194005-5bc828145cc4
|
||||
git.tcp.direct/tcp.direct/database v0.0.0-20220610180603-058d36edd7f0
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
|
@ -19,6 +18,7 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34 // indirect
|
||||
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 // indirect
|
||||
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f // indirect
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20190422055009-d6f9ba25cf48 // indirect
|
||||
|
|
12
img.go
12
img.go
|
@ -17,6 +17,8 @@ import (
|
|||
exifremove "github.com/scottleedavis/go-exif-remove"
|
||||
"github.com/twharmon/gouid"
|
||||
"golang.org/x/crypto/blake2b"
|
||||
|
||||
"git.tcp.direct/tcp.direct/tcp.ac/config"
|
||||
)
|
||||
|
||||
var fExt string
|
||||
|
@ -89,7 +91,7 @@ func imgView(c *gin.Context) {
|
|||
}
|
||||
|
||||
// if it doesn't match the key size or it isn't alphanumeric - throw it out
|
||||
if !valid.IsAlphanumeric(rUid) || len(rUid) != uidSize {
|
||||
if !valid.IsAlphanumeric(rUid) || len(rUid) != config.UIDSize {
|
||||
slog.Warn().
|
||||
Str("remoteaddr", c.ClientIP()).
|
||||
Msg("request discarded as invalid")
|
||||
|
@ -135,17 +137,17 @@ func imgView(c *gin.Context) {
|
|||
func newUIDandKey() (uid string, key string) {
|
||||
slog := log.With().Str("caller", "newUIDandKey").Logger()
|
||||
// generate new uid and delete key
|
||||
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
|
||||
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
|
||||
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
|
||||
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
|
||||
|
||||
// lets make sure that we don't clash even though its highly unlikely
|
||||
for db.With("img").Has([]byte(uid)) {
|
||||
slog.Warn().Msg(" uid already exists! generating new...")
|
||||
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
|
||||
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
|
||||
}
|
||||
for db.With("key").Has([]byte(key)) {
|
||||
slog.Warn().Msg(" delete key already exists! generating new...")
|
||||
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
|
||||
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
94
main.go
94
main.go
|
@ -6,64 +6,40 @@ import (
|
|||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/muesli/termenv"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"git.tcp.direct/tcp.direct/tcp.ac/config"
|
||||
)
|
||||
|
||||
var Banner string = "CiAgLGQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogIDg4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKTU04OE1NTSAsYWRQUFliYSwgOGIsZFBQWWJhLCAgICAgICxhZFBQWVliYSwgICxhZFBQWWJhLCAgCiAgODggICBhOCIgICAgICIiIDg4UCcgICAgIjhhICAgICAiIiAgICAgYFk4IGE4IiAgICAgIiIgIAogIDg4ICAgOGIgICAgICAgICA4OCAgICAgICBkOCAgICAgLGFkUFBQUFA4OCA4YiAgICAgICAgICAKICA4OCwgICI4YSwgICAsYWEgODhiLCAgICxhOCIgODg4IDg4LCAgICAsODggIjhhLCAgICxhYSAgCiAgIlk4ODggYCJZYmJkOCInIDg4YFliYmRQIicgIDg4OCBgIjhiYmRQIlk4ICBgIlliYmQ4IicgIAogICAgICAgICAgICAgICAgICA4OCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgODggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCg=="
|
||||
|
||||
func init() {
|
||||
func makeDirectories() {
|
||||
log.Trace().Msgf("establishing log directory presence at %s...", config.LogDir)
|
||||
err := os.MkdirAll(config.LogDir, 0o644)
|
||||
if err != nil {
|
||||
log.Fatal().
|
||||
Str("directory", config.LogDir).
|
||||
Err(err).Msg("failed to open log directory")
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace().Msgf("establishing data directory presence at %s...", config.DBDir)
|
||||
err = os.MkdirAll(config.DBDir, 0o644)
|
||||
if err != nil {
|
||||
log.Fatal().
|
||||
Str("directory", config.DBDir).
|
||||
Err(err).Msg("failed to open directory")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func printBanner() {
|
||||
out := termenv.String(b64d(Banner))
|
||||
p := termenv.ColorProfile()
|
||||
out = out.Foreground(p.Color("#948DB8"))
|
||||
|
||||
fmt.Println(out)
|
||||
|
||||
// initialize the logger before the config: that way we can output debug lines
|
||||
// pertaining to the parsing of the configuration init
|
||||
|
||||
// ////////// init logging ////////////
|
||||
|
||||
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||
consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
log.Info().Msg("Initializing...")
|
||||
|
||||
// see config.go
|
||||
configRead()
|
||||
|
||||
if !debugBool {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
// now that we know where to put the log file, we can start output (replace logger)
|
||||
|
||||
err := os.MkdirAll(logDir, 0o755)
|
||||
if err != nil {
|
||||
log.Fatal().Str("directory", logDir).Str("intent", "logDir").Err(err).Msg("failed to open directory")
|
||||
return
|
||||
}
|
||||
|
||||
err = os.MkdirAll(dbDir, 0o755)
|
||||
if err != nil {
|
||||
log.Fatal().Str("directory", dbDir).Str("intent", "dbDir").Err(err).Msg("failed to open directory")
|
||||
return
|
||||
}
|
||||
|
||||
lf, err := os.OpenFile(logDir+"tcpac.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
|
||||
if err != nil {
|
||||
log.Fatal().Str("logDir", logDir).Err(err).Msg("Error opening log file!")
|
||||
}
|
||||
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
multi := zerolog.MultiLevelWriter(consoleWriter, lf)
|
||||
log.Logger = zerolog.New(multi).With().Timestamp().Logger()
|
||||
err = dbInit()
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("bitcask failure")
|
||||
}
|
||||
}
|
||||
|
||||
func catchSignal() {
|
||||
|
@ -83,9 +59,27 @@ func catchSignal() {
|
|||
}
|
||||
|
||||
func main() {
|
||||
printBanner()
|
||||
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||
consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}
|
||||
log.Logger = log.Output(consoleWriter).With().Timestamp().Logger()
|
||||
log.Info().Msg("Initializing...")
|
||||
config.Init()
|
||||
makeDirectories()
|
||||
log.Debug().Msg("debug enabled")
|
||||
log.Trace().Msg("trace enabled")
|
||||
lf, err := os.OpenFile(config.LogDir+"tcpac.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
|
||||
if err != nil {
|
||||
log.Fatal().Str("config.LogDir", config.LogDir).Err(err).Msg("Error opening log file!")
|
||||
}
|
||||
multi := zerolog.MultiLevelWriter(consoleWriter, lf)
|
||||
log.Logger = zerolog.New(multi).With().Timestamp().Logger()
|
||||
err = dbInit()
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("bitcask failure")
|
||||
}
|
||||
defer db.SyncAndCloseAll()
|
||||
go catchSignal()
|
||||
go serveTermbin()
|
||||
// see router.go
|
||||
httpRouter()
|
||||
go httpRouter()
|
||||
catchSignal()
|
||||
}
|
||||
|
|
10
router.go
10
router.go
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"git.tcp.direct/tcp.direct/tcp.ac/config"
|
||||
)
|
||||
|
||||
var favicon string = "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"
|
||||
|
@ -30,7 +32,7 @@ func urlPost(c *gin.Context) {
|
|||
}
|
||||
|
||||
func httpRouter() {
|
||||
if !debugBool {
|
||||
if !config.Debug {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
|
@ -79,6 +81,8 @@ func httpRouter() {
|
|||
delR.GET("/i/:key", imgDel)
|
||||
delR.GET("/t/:key", txtDel)
|
||||
|
||||
log.Info().Str("webIP", webIP).Str("webPort", webPort).Msg("done; tcp.ac is live.")
|
||||
router.Run(webIP + ":" + webPort)
|
||||
log.Info().Str("Host", config.HTTPBind).
|
||||
Str("Port", config.HTTPPort).
|
||||
Msg("done; tcp.ac is live.")
|
||||
router.Run(config.HTTPBind + ":" + config.HTTPPort)
|
||||
}
|
||||
|
|
27
txt.go
27
txt.go
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
valid "github.com/asaskevich/govalidator"
|
||||
|
@ -11,6 +12,8 @@ import (
|
|||
"golang.org/x/crypto/blake2b"
|
||||
|
||||
termbin "git.tcp.direct/kayos/putxt"
|
||||
|
||||
"git.tcp.direct/tcp.direct/tcp.ac/config"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -19,7 +22,6 @@ func init() {
|
|||
|
||||
func incoming() {
|
||||
var msg termbin.Message
|
||||
|
||||
select {
|
||||
case msg = <-termbin.Msg:
|
||||
switch msg.Type {
|
||||
|
@ -74,31 +76,31 @@ func termPost(b []byte) {
|
|||
}
|
||||
|
||||
// generate new uid and delete key
|
||||
uid := gouid.String(uidSize, gouid.MixedCaseAlphaNum)
|
||||
key := gouid.String(keySize, gouid.MixedCaseAlphaNum)
|
||||
uid := gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
|
||||
key := gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
|
||||
|
||||
// lets make sure that we don't clash even though its highly unlikely
|
||||
for uidRef, _ := db.With("txt").Get([]byte(uid)); uidRef != nil; {
|
||||
slog.Info().Msg(" uid already exists! generating new...")
|
||||
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
|
||||
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
|
||||
}
|
||||
for keyRef, _ := db.With("key").Get([]byte(key)); keyRef != nil; {
|
||||
slog.Info().Msg(" delete key already exists! generating new...")
|
||||
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
|
||||
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
|
||||
}
|
||||
|
||||
db.With("hsh").Put(hash, []byte(uid))
|
||||
|
||||
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
|
||||
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
|
||||
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
|
||||
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
|
||||
|
||||
for uidRef, _ := db.With("txt").Get([]byte(uid)); uidRef != nil; {
|
||||
slog.Info().Msg(" uid already exists! generating new...")
|
||||
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
|
||||
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
|
||||
}
|
||||
for keyRef, _ := db.With("key").Get([]byte(key)); keyRef != nil; {
|
||||
slog.Info().Msg(" delete key already exists! generating new...")
|
||||
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
|
||||
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
|
||||
}
|
||||
|
||||
db.With("hsh").Put([]byte(hash), []byte(uid))
|
||||
|
@ -129,7 +131,7 @@ func termPost(b []byte) {
|
|||
}
|
||||
|
||||
func txtView(c *gin.Context) {
|
||||
raddr, _ := c.RemoteIP()
|
||||
raddr := net.ParseIP(c.RemoteIP())
|
||||
if termbin.Rater.Check(&termbin.Identity{Actual: raddr}) {
|
||||
errThrow(c, 429, errors.New("ratelimitted"), "too many requests")
|
||||
return
|
||||
|
@ -148,7 +150,7 @@ func txtView(c *gin.Context) {
|
|||
}
|
||||
|
||||
// if it doesn't match the key size or it isn't alphanumeric - throw it out
|
||||
if !valid.IsAlphanumeric(rUid) || len(rUid) != uidSize {
|
||||
if !valid.IsAlphanumeric(rUid) || len(rUid) != config.UIDSize {
|
||||
errThrow(c, 400, errors.New("request discarded as invalid"), "400")
|
||||
return
|
||||
}
|
||||
|
@ -218,7 +220,8 @@ func serveTermbin() {
|
|||
incoming()
|
||||
}
|
||||
}()
|
||||
err := termbin.Listen("", txtPort)
|
||||
split := strings.Split(config.TermbinListen, ":")
|
||||
err := termbin.Listen(split[0], split[1])
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue