aboutsummaryrefslogtreecommitdiff
path: root/post/tripcode.go
blob: 3b7e48b5adb76a4dc6dd905e19009e53d605bde3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package post

import (
	"bytes"
	"regexp"
	"strings"

	"github.com/FChannel0/FChannel-Server/config"
	"github.com/gofiber/fiber/v2"
	_ "github.com/lib/pq"
	"github.com/simia-tech/crypt"
	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
)

const SaltTable = "" +
	"................................" +
	".............../0123456789ABCDEF" +
	"GABCDEFGHIJKLMNOPQRSTUVWXYZabcde" +
	"fabcdefghijklmnopqrstuvwxyz....." +
	"................................" +
	"................................" +
	"................................" +
	"................................"

func TripCode(pass string) (string, error) {
	pass = TripCodeConvert(pass)

	var salt [2]rune

	s := []rune(pass + "H..")[1:3]

	for i, r := range s {
		salt[i] = rune(SaltTable[r%256])
	}

	enc, err := crypt.Crypt(pass, "$1$"+string(salt[:]))
	if err != nil {
		return "", err
	}

	// normally i would just return error here but if the encrypt fails, this operation may fail and as a result cause a panic
	return enc[len(enc)-10 : len(enc)], nil
}

func TripCodeSecure(pass string) (string, error) {
	pass = TripCodeConvert(pass)

	enc, err := crypt.Crypt(pass, "$1$"+config.Salt)
	if err != nil {
		return "", err
	}

	return enc[len(enc)-10 : len(enc)], nil
}

func TripCodeConvert(str string) string {
	var s bytes.Buffer

	transform.NewWriter(&s, japanese.ShiftJIS.NewEncoder()).Write([]byte(str))

	re := strings.NewReplacer(
		"&", "&",
		"\"", """,
		"<", "&lt;",
		">", "&gt;",
	)

	return re.Replace(s.String())
}

func CreateNameTripCode(ctx *fiber.Ctx) (string, string, error) {
	// TODO: to allow this to compile, this will fail for the case of the admin
	// this can be easily fixed when the rest of the code gets converted to fiber

	input := ctx.FormValue("name")

	tripSecure := regexp.MustCompile("##(.+)?")

	if tripSecure.MatchString(input) {
		chunck := tripSecure.FindString(input)
		chunck = strings.Replace(chunck, "##", "", 1)

		//ce := regexp.MustCompile(`(?i)Admin`)
		//admin := ce.MatchString(chunck)

		//board, modcred := GetPasswordFromSession(r)

		//if admin && HasAuth(modcred, board) {
		//	return tripSecure.ReplaceAllString(input, ""), "#Admin"
		//}

		hash, err := TripCodeSecure(chunck)
		return tripSecure.ReplaceAllString(input, ""), "!!" + hash, err
	}

	trip := regexp.MustCompile("#(.+)?")

	if trip.MatchString(input) {
		chunck := trip.FindString(input)
		chunck = strings.Replace(chunck, "#", "", 1)

		//ce := regexp.MustCompile(`(?i)Admin`)
		//admin := ce.MatchString(chunck)
		//board, modcred := GetPasswordFromSession(r)

		//if admin && HasAuth(db, modcred, board) {
		//	return trip.ReplaceAllString(input, ""), "#Admin"
		//}

		hash, err := TripCode(chunck)
		return trip.ReplaceAllString(input, ""), "!" + hash, err
	}

	return input, "", nil
}