aboutsummaryrefslogtreecommitdiff
path: root/db/verification.go
diff options
context:
space:
mode:
Diffstat (limited to 'db/verification.go')
-rw-r--r--db/verification.go342
1 files changed, 13 insertions, 329 deletions
diff --git a/db/verification.go b/db/verification.go
index b976908..8be2ffe 100644
--- a/db/verification.go
+++ b/db/verification.go
@@ -1,13 +1,6 @@
package db
import (
- "crypto"
- "crypto/rsa"
- "crypto/sha256"
- "crypto/x509"
- "encoding/base64"
- "encoding/pem"
- "errors"
"fmt"
"math/rand"
"net/smtp"
@@ -15,14 +8,9 @@ import (
"os/exec"
"time"
- "github.com/FChannel0/FChannel-Server/activitypub"
+ "github.com/FChannel0/FChannel-Server/config"
+ "github.com/FChannel0/FChannel-Server/util"
_ "github.com/lib/pq"
-
- crand "crypto/rand"
- "io/ioutil"
- "net/http"
- "regexp"
- "strings"
)
type Verify struct {
@@ -97,7 +85,7 @@ func GetBoardMod(identifier string) (Verify, error) {
}
func CreateBoardMod(verify Verify) error {
- pass := CreateKey(50)
+ pass := util.CreateKey(50)
query := `select code from verification where identifier=$1 and type=$2`
@@ -307,8 +295,8 @@ func VerficationCooldownRemove() error {
func SendVerification(verify Verify) error {
fmt.Println("sending email")
- from := SiteEmail
- pass := SiteEmailPassword
+ from := config.SiteEmail
+ pass := config.SiteEmailPassword
to := verify.Identifier
body := fmt.Sprintf("You can use either\r\nEmail: %s \r\n Verfication Code: %s\r\n for the board %s", verify.Identifier, verify.Code, verify.Board)
@@ -317,23 +305,13 @@ func SendVerification(verify Verify) error {
"Subject: Image Board Verification\n\n" +
body
- return smtp.SendMail(SiteEmailServer+":"+SiteEmailPort,
- smtp.PlainAuth("", from, pass, SiteEmailServer),
+ return smtp.SendMail(config.SiteEmailServer+":"+config.SiteEmailPort,
+ smtp.PlainAuth("", from, pass, config.SiteEmailServer),
from, []string{to}, []byte(msg))
}
func IsEmailSetup() bool {
- if SiteEmail == "" {
- return false
- } else if SiteEmailPassword == "" {
- return false
- } else if SiteEmailServer == "" {
- return false
- } else if SiteEmailPort == "" {
- return false
- }
-
- return true
+ return config.SiteEmail != "" || config.SiteEmailPassword != "" || config.SiteEmailServer != "" || config.SiteEmailPort != ""
}
func HasAuth(code string, board string) (bool, error) {
@@ -342,8 +320,10 @@ func HasAuth(code string, board string) (bool, error) {
return false, err
}
- if verify.Board == Domain || (HasBoardAccess(db, verify) && verify.Board == board) {
+ if res, err := HasBoardAccess(verify); err != nil && (verify.Board == config.Domain || (res && verify.Board == board)) {
return true, nil
+ } else {
+ return false, err
}
return false, nil
@@ -377,12 +357,12 @@ func GetVerify(access string) (Verify, error) {
}
func CreateNewCaptcha() error {
- id := RandomID(8)
+ id := util.RandomID(8)
file := "public/" + id + ".png"
for true {
if _, err := os.Stat("./" + file); err == nil {
- id = RandomID(8)
+ id = util.RandomID(8)
file = "public/" + id + ".png"
} else {
break
@@ -506,299 +486,3 @@ func Captcha() string {
return newID
}
-
-func CreatePem(actor Actor) error {
- privatekey, err := rsa.GenerateKey(crand.Reader, 2048)
- if err != nil {
- return err
- }
-
- privateKeyBytes := x509.MarshalPKCS1PrivateKey(privatekey)
-
- privateKeyBlock := &pem.Block{
- Type: "RSA PRIVATE KEY",
- Bytes: privateKeyBytes,
- }
-
- privatePem, err := os.Create("./pem/board/" + actor.Name + "-private.pem")
- if err != nil {
- return err
- }
-
- if err := pem.Encode(privatePem, privateKeyBlock); err != nil {
- return err
- }
-
- publickey := &privatekey.PublicKey
- publicKeyBytes, err := x509.MarshalPKIXPublicKey(publickey)
- if err != nil {
- return err
- }
-
- publicKeyBlock := &pem.Block{
- Type: "PUBLIC KEY",
- Bytes: publicKeyBytes,
- }
-
- publicPem, err := os.Create("./pem/board/" + actor.Name + "-public.pem")
- if err != nil {
- return err
- }
-
- if err := pem.Encode(publicPem, publicKeyBlock); err != nil {
- return err
- }
-
- _, err = os.Stat("./pem/board/" + actor.Name + "-public.pem")
- if os.IsNotExist(err) {
- return err
- } else {
- return StorePemToDB(actor)
- }
-
- fmt.Println(`Created PEM keypair for the "` + actor.Name + `" board. Please keep in mind that
-the PEM key is crucial in identifying yourself as the legitimate owner of the board,
-so DO NOT LOSE IT!!! If you lose it, YOU WILL LOSE ACCESS TO YOUR BOARD!`)
-
- return nil
-}
-
-func CreatePublicKeyFromPrivate(actor *activitypub.Actor, publicKeyPem string) error {
- publicFilename, err := GetActorPemFileFromDB(publicKeyPem)
- if err != nil {
- return err
- }
-
- privateFilename := strings.ReplaceAll(publicFilename, "public.pem", "private.pem")
- if _, err := os.Stat(privateFilename); err == nil {
- // Not a lost cause
- priv, err := ioutil.ReadFile(privateFilename)
- if err != nil {
- return err
- }
-
- block, _ := pem.Decode([]byte(priv))
- if block == nil || block.Type != "RSA PRIVATE KEY" {
- return errors.New("failed to decode PEM block containing public key")
- }
-
- key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return err
- }
-
- publicKeyDer, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
- if err != nil {
- return err
- }
-
- pubKeyBlock := pem.Block{
- Type: "PUBLIC KEY",
- Headers: nil,
- Bytes: publicKeyDer,
- }
-
- publicFileWriter, err := os.Create(publicFilename)
- if err != nil {
- return err
- }
-
- if err := pem.Encode(publicFileWriter, &pubKeyBlock); err != nil {
- return err
- }
- } else {
- fmt.Println(`\nUnable to locate private key from public key generation. Now,
-this means that you are now missing the proof that you are the
-owner of the "` + actor.Name + `" board. If you are the developer,
-then your job is just as easy as generating a new keypair, but
-if this board is live, then you'll also have to convince the other
-owners to switch their public keys for you so that they will start
-accepting your posts from your board from this site. Good luck ;)`)
- return errors.New("unable to locate private key")
- }
- return nil
-}
-
-func StorePemToDB(actor activitypub.Actor) error {
- query := "select publicKeyPem from actor where id=$1"
- rows, err := db.Query(query, actor.Id)
- if err != nil {
- return err
- }
-
- defer rows.Close()
-
- var result string
- rows.Next()
- rows.Scan(&result)
-
- if result != "" {
- return errors.New("already storing public key for actor")
- }
-
- publicKeyPem := actor.Id + "#main-key"
- query = "update actor set publicKeyPem=$1 where id=$2"
- if _, err := db.Exec(query, publicKeyPem, actor.Id); err != nil {
- return err
- }
-
- file := "./pem/board/" + actor.Name + "-public.pem"
- query = "insert into publicKeyPem (id, owner, file) values($1, $2, $3)"
- _, err = db.Exec(query, publicKeyPem, actor.Id, file)
- return err
-}
-
-func ActivitySign(actor activitypub.Actor, signature string) (string, error) {
- query := `select file from publicKeyPem where id=$1 `
-
- rows, err := db.Query(query, actor.PublicKey.Id)
- if err != nil {
- return "", err
- }
-
- defer rows.Close()
-
- var file string
- rows.Next()
- rows.Scan(&file)
-
- file = strings.ReplaceAll(file, "public.pem", "private.pem")
- _, err = os.Stat(file)
- if err != nil {
- fmt.Println(`\n Unable to locate private key. Now,
-this means that you are now missing the proof that you are the
-owner of the "` + actor.Name + `" board. If you are the developer,
-then your job is just as easy as generating a new keypair, but
-if this board is live, then you'll also have to convince the other
-owners to switch their public keys for you so that they will start
-accepting your posts from your board from this site. Good luck ;)`)
- return "", errors.New("unable to locate private key")
- }
-
- publickey, err := ioutil.ReadFile(file)
- if err != nil {
- return "", err
- }
-
- block, _ := pem.Decode(publickey)
-
- pub, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
- rng := crand.Reader
- hashed := sha256.New()
- hashed.Write([]byte(signature))
- cipher, _ := rsa.SignPKCS1v15(rng, pub, crypto.SHA256, hashed.Sum(nil))
-
- return base64.StdEncoding.EncodeToString(cipher), nil
-}
-
-func ActivityVerify(actor activitypub.Actor, signature string, verify string) error {
- sig, _ := base64.StdEncoding.DecodeString(signature)
-
- if actor.PublicKey.PublicKeyPem == "" {
- actor = FingerActor(actor.Id)
- }
-
- block, _ := pem.Decode([]byte(actor.PublicKey.PublicKeyPem))
- pub, _ := x509.ParsePKIXPublicKey(block.Bytes)
-
- hashed := sha256.New()
- hashed.Write([]byte(verify))
-
- return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA256, hashed.Sum(nil), sig)
-}
-
-func VerifyHeaderSignature(r *http.Request, actor activitypub.Actor) bool {
- s := ParseHeaderSignature(r.Header.Get("Signature"))
-
- var method string
- var path string
- var host string
- var date string
- var digest string
- var contentLength string
-
- var sig string
- for i, e := range s.Headers {
- var nl string
- if i < len(s.Headers)-1 {
- nl = "\n"
- }
-
- switch e {
- case "(request-target)":
- method = strings.ToLower(r.Method)
- path = r.URL.Path
- sig += "(request-target): " + method + " " + path + "" + nl
- break
- case "host":
- host = r.Host
- sig += "host: " + host + "" + nl
- break
- case "date":
- date = r.Header.Get("date")
- sig += "date: " + date + "" + nl
- break
- case "digest":
- digest = r.Header.Get("digest")
- sig += "digest: " + digest + "" + nl
- break
- case "content-length":
- contentLength = r.Header.Get("content-length")
- sig += "content-length: " + contentLength + "" + nl
- break
- }
- }
-
- if s.KeyId != actor.PublicKey.Id {
- return false
- }
-
- t, _ := time.Parse(time.RFC1123, date)
-
- if time.Now().UTC().Sub(t).Seconds() > 75 {
- return false
- }
-
- if ActivityVerify(actor, s.Signature, sig) != nil {
- return false
- }
-
- return true
-}
-
-func ParseHeaderSignature(signature string) Signature {
- var nsig Signature
-
- keyId := regexp.MustCompile(`keyId=`)
- headers := regexp.MustCompile(`headers=`)
- sig := regexp.MustCompile(`signature=`)
- algo := regexp.MustCompile(`algorithm=`)
-
- signature = strings.ReplaceAll(signature, "\"", "")
- parts := strings.Split(signature, ",")
-
- for _, e := range parts {
- if keyId.MatchString(e) {
- nsig.KeyId = keyId.ReplaceAllString(e, "")
- continue
- }
-
- if headers.MatchString(e) {
- header := headers.ReplaceAllString(e, "")
- nsig.Headers = strings.Split(header, " ")
- continue
- }
-
- if sig.MatchString(e) {
- nsig.Signature = sig.ReplaceAllString(e, "")
- continue
- }
-
- if algo.MatchString(e) {
- nsig.Algorithm = algo.ReplaceAllString(e, "")
- continue
- }
- }
-
- return nsig
-}