taldir

Directory service to resolve wallet mailboxes by messenger addresses
Log | Files | Refs | Submodules | README | LICENSE

commit 3d4923ec4c606cda8343c8bd3b30777f3a3d9a3c
parent 64f068eba9a61370dc30935193aec15a3458ac56
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Sun, 17 Jul 2022 07:18:49 +0200

add gnunet-go dependency replacing local copies

Diffstat:
Mcmd/taldir-cli/main.go | 3++-
Mcmd/taldir-server/main_test.go | 3++-
Mgo.mod | 4++++
Mpkg/rest/taldir.go | 34+++++++++++++++++++---------------
Dpkg/util/base32.go | 127-------------------------------------------------------------------------------
Mpkg/util/helper.go | 7++++---
6 files changed, 31 insertions(+), 147 deletions(-)

diff --git a/cmd/taldir-cli/main.go b/cmd/taldir-cli/main.go @@ -25,6 +25,7 @@ import ( "flag" "taler.net/taldir/pkg/rest" "taler.net/taldir/pkg/util" + gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util" "crypto/sha512" ) @@ -32,7 +33,7 @@ import ( func generateLink(host string, addr string, challenge string) string { h := sha512.New() h.Write([]byte(addr)) - h_addr := util.EncodeBinaryToString(h.Sum(nil)) + h_addr := gnunetutil.EncodeBinaryToString(h.Sum(nil)) return host + "/register/" + h_addr + "/" + challenge } diff --git a/cmd/taldir-server/main_test.go b/cmd/taldir-server/main_test.go @@ -30,6 +30,7 @@ import ( "io/ioutil" "taler.net/taldir/pkg/rest" _ "taler.net/taldir/cmd/taldir-server" + gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util" "github.com/jarcoal/httpmock" "taler.net/taldir/pkg/util" ) @@ -82,7 +83,7 @@ func TestMain(m *testing.M) { func getHAddress(addr string) string { h := sha512.New() h.Write([]byte(addr)) - return util.EncodeBinaryToString(h.Sum(nil)) + return gnunetutil.EncodeBinaryToString(h.Sum(nil)) } func TestNoEntry(s *testing.T) { diff --git a/go.mod b/go.mod @@ -3,9 +3,13 @@ module taler.net/taldir go 1.16 require ( + git.gnunet.org/gnunet-go.git v0.1.28-0.20220717050634-369422be2512 + github.com/bfix/gospel v1.2.15 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/gorilla/mux v1.8.0 github.com/jarcoal/httpmock v1.2.0 github.com/jinzhu/now v1.1.5 // indirect + github.com/mattn/go-sqlite3 v1.14.14 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect golang.org/x/text v0.3.7 diff --git a/pkg/rest/taldir.go b/pkg/rest/taldir.go @@ -51,6 +51,7 @@ import ( "gopkg.in/ini.v1" "strings" "github.com/skip2/go-qrcode" + gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util" "golang.org/x/text/language" ) @@ -313,7 +314,7 @@ func saltHAddress(hAddress string, salt string) string { h := sha512.New() h.Write([]byte(hAddress)) h.Write([]byte(salt)) - return util.EncodeBinaryToString(h.Sum(nil)) + return gnunetutil.EncodeBinaryToString(h.Sum(nil)) } // Called by the registrant to validate the registration request. The reference ID was @@ -390,6 +391,7 @@ func (t *Taldir) isRateLimited(hAddress string) (bool, error) { // NOTE: Check rate limit if err == nil { // Limit re-initiation attempts + // FIXME: Do not limit tries. Very unlikely. validationMetadata.InitiationCount++ if time.Now().Before(validationMetadata.TimeframeStart.Add(t.ValidationTimeframe)) { if validationMetadata.InitiationCount > t.ValidationInitiationMax { @@ -420,6 +422,16 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ var validation validation var entry entry var order Order + // Check if this validation method is supported or not. + if !t.Validators[vars["method"]] { + errDetail.Code = gana.TALDIR_METHOD_NOT_SUPPORTED + errDetail.Hint = "Unsupported method" + errDetail.Detail = "Given method: " + vars["method"] + resp, _ := json.Marshal(errDetail) + w.WriteHeader(http.StatusNotFound) + w.Write(resp) + return + } if r.Body == nil { http.Error(w, "No request body", 400) return @@ -435,21 +447,11 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ } json.NewDecoder(r.Body).Decode(&order) - // Check if this validation method is supported or not. - if !t.Validators[vars["method"]] { - errDetail.Code = gana.TALDIR_METHOD_NOT_SUPPORTED - errDetail.Hint = "Unsupported method" - errDetail.Detail = "Given method: " + vars["method"] - resp, _ := json.Marshal(errDetail) - w.WriteHeader(http.StatusNotFound) - w.Write(resp) - return - } // Setup validation object. Retrieve object from DB if it already // exists. h := sha512.New() h.Write([]byte(req.Address)) - hAddress := util.EncodeBinaryToString(h.Sum(nil)) + hAddress := gnunetutil.EncodeBinaryToString(h.Sum(nil)) validation.HAddress = hAddress hsAddress := saltHAddress(validation.HAddress, t.Salt) err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error @@ -487,6 +489,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ t.Db.Delete(&validation) return } + // FIXME try to avoid validationMetadata err = t.Db.First(&validation, "h_address = ? AND public_key = ? AND inbox = ? AND duration = ?", hAddress, req.PublicKey, req.Inbox, reqDuration).Error validationExists := (nil == err) @@ -500,6 +503,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ validation.Duration = reqDuration.Microseconds() } + // FIXME: integer arithmetic fixedCost := t.Cfg.Section("taldir-" + vars["method"]).Key("challenge_fee").MustString("KUDOS:0") sliceDuration := time.Duration(validation.Duration * 1000) cost, currency, err := util.CalculateCost(t.MonthlyFee, @@ -514,8 +518,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ if cost > 0 { if validationExists { if order.ID != validation.OrderID { - log.Fatalf("Order ID is not validation ID what to do?") - w.WriteHeader(http.StatusInternalServerError) + w.WriteHeader(http.StatusConflict) return } } @@ -531,6 +534,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ // FIXME what if provided order ID and validation order ID differ??? // Check if order paid. FIXME: How to check if this the a correct order?? + // FIXME: Remember that it was activated and paid payto, paytoErr := t.Merchant.IsOrderPaid(validation.OrderID) if paytoErr != nil { w.WriteHeader(http.StatusInternalServerError) @@ -540,7 +544,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){ if len(payto) != 0 { t.Db.Save(&validation) w.WriteHeader(http.StatusPaymentRequired) - w.Header().Set("Location", payto) // FIXME no idea what to do with this. + w.Header().Set("Taler", payto) // FIXME no idea what to do with this. return } // In this case, this order was paid diff --git a/pkg/util/base32.go b/pkg/util/base32.go @@ -1,127 +0,0 @@ -// This file is part of gnunet-go, a GNUnet-implementation in Golang. -// Copyright (C) 2019-2022 Bernd Fix >Y< -// -// gnunet-go is free software: you can redistribute it and/or modify it -// under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// gnunet-go is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// SPDX-License-Identifier: AGPL3.0-or-later - -package util - -import ( - "errors" - "strings" -) - -//------------------------------------------------------------------------ -// Base32 conversion between binary data and string representation -//------------------------------------------------------------------------ -// -// A binary array of size m is viewed as a consecutive stream of bits -// from left to right. Bytes are ordered with ascending address, while -// bits (in a byte) are ordered MSB to LSB. - -// For encoding the stream is partitioned into 5-bit chunks; the last chunk -// is right-padded with 0's if 8*m is not divisible by 5. Each chunk (value -// between 0 and 31) is encoded into a character; the mapping for encoding -// is the same as in [https://www.crockford.com/wrmg/base32.html]. -// -// For decoding each character is converted to a 5-bit chunk based on the -// encoder mapping (with one addition: the character 'U' maps to the value -// 27). The chunks are concatenated to produce the bit stream to be stored -// in the output array. - -// character set used for encoding/decoding -const xlate = "0123456789ABCDEFGHJKMNPQRSTVWXYZ" - -var ( - // ErrInvalidEncoding signals an invalid encoding - ErrInvalidEncoding = errors.New("Invalid encoding") - // ErrBufferTooSmall signalsa too small buffer for decoding - ErrBufferTooSmall = errors.New("Buffer to small") -) - -// EncodeBinaryToString encodes a byte array into a string. -func EncodeBinaryToString(data []byte) string { - size, pos, bits, n := len(data), 0, 0, 0 - out := "" - for { - if n < 5 { - if pos < size { - bits = (bits << 8) | (int(data[pos]) & 0xFF) - pos++ - n += 8 - } else if n > 0 { - bits <<= uint(5 - n) - n = 5 - } else { - break - } - } - out += string(xlate[(bits>>uint(n-5))&0x1F]) - n -= 5 - } - return out -} - -// DecodeStringToBinary decodes a string into a byte array. -// The function expects the size of the output buffer to be sepcified as an -// argument ('num'); the function returns an error if the buffer is overrun -// or if an invalid character is found in the encoded string. If the decoded -// bit stream is smaller than the output buffer, it is padded with 0's. -func DecodeStringToBinary(s string, num int) ([]byte, error) { - size := len(s) - out := make([]byte, num) - rpos, wpos, n, bits := 0, 0, 0, 0 - for { - if n < 8 { - if rpos < size { - c := rune(s[rpos]) - rpos++ - v := strings.IndexRune(xlate, c) - if v == -1 { - switch c { - case 'O': - v = 0 - case 'I', 'L': - v = 1 - case 'U': - v = 27 - default: - return nil, ErrInvalidEncoding - } - } - bits = (bits << 5) | (v & 0x1F) - n += 5 - } else { - if wpos < num { - out[wpos] = byte(bits & ((1 << uint(n+1)) - 1)) - wpos++ - for i := wpos; i < num; i++ { - out[i] = 0 - } - } - break - } - } else { - if wpos < num { - out[wpos] = byte((bits >> uint(n-8)) & 0xFF) - wpos++ - n -= 8 - } else { - return nil, ErrBufferTooSmall - } - } - } - return out, nil -} diff --git a/pkg/util/helper.go b/pkg/util/helper.go @@ -27,12 +27,13 @@ import ( "strings" "strconv" "time" + gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util" ) // Generates a solution from a challenge and pubkey func GenerateSolution(pubkeyEncoded string, challenge string) string { - pubkey, err := DecodeStringToBinary(pubkeyEncoded, 36) + pubkey, err := gnunetutil.DecodeStringToBinary(pubkeyEncoded, 36) if err != nil { fmt.Println("error decoding pubkey:", err) return "" @@ -40,7 +41,7 @@ func GenerateSolution(pubkeyEncoded string, challenge string) string { h := sha512.New() h.Write([]byte(challenge)) h.Write(pubkey) - return EncodeBinaryToString(h.Sum(nil)) + return gnunetutil.EncodeBinaryToString(h.Sum(nil)) } // Generates random reference token used in the validation flow. @@ -50,7 +51,7 @@ func GenerateChallenge(bytes int) string { if err != nil { panic(err) } - return EncodeBinaryToString(randBytes) + return gnunetutil.EncodeBinaryToString(randBytes) } // Check if this is a non-zero, positive amount