commit ebb1f9a89b279fd6fdf0297c9c52cdf3a08ba1cf
parent ee5c19e9edf7e4e0959becc99e97606d9e6de041
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Tue, 22 Apr 2025 13:27:17 +0200
update
Diffstat:
3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +1 @@
-mailbox-server
+./mailbox-server
diff --git a/cmd/mailbox-server/main.go b/cmd/mailbox-server/main.go
@@ -28,7 +28,7 @@ import (
var m mailbox.Mailbox
-func handleRequests() {
+func handleRequests(m *mailbox.Mailbox) {
log.Fatal(http.ListenAndServe(m.Cfg.Section("mailbox").Key("bind_to").MustString("localhost:11000"), m.Router))
}
@@ -42,5 +42,5 @@ func main() {
}
m := mailbox.Mailbox{}
m.Initialize(cfgfile)
- handleRequests()
+ handleRequests(&m)
}
diff --git a/pkg/rest/mailbox.go b/pkg/rest/mailbox.go
@@ -28,6 +28,7 @@ import (
"log"
"net/http"
"os"
+ "strings"
"time"
gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
@@ -57,9 +58,14 @@ type Mailbox struct {
Merchant merchant.Merchant
}
-type identityMessage struct {
+type IdentityMessage struct {
+ // Internal ID primary key (GORM thingy).
+ // Not returned in JSON
+ ID int64 `json:"-"`
+
// Public DH key used to encrypt the body. Must be fresh
// and only used once (ephemeral).
+ // FIXME: Do we want to use HPKE DHKEM X25519 + ChaChaPoly?
EphemeralKey string `json:"ephemeral_key"`
// Encrypted message. Must be exactly 256-32 bytes long.
@@ -171,6 +177,9 @@ func (m *Mailbox) getMessagesResponse(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
return
}
+ // Add ETag of first message ID
+ etag := entries[0].ID
+ w.Header().Add("ETag", fmt.Sprintf("%d", etag))
for _, entry := range entries {
eph, err := gnunetutil.DecodeStringToBinary(entry.EphemeralKey, 32)
if err != nil {
@@ -182,17 +191,15 @@ func (m *Mailbox) getMessagesResponse(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
return
}
- entry.Read = true
w.Write(eph)
w.Write(body)
}
- m.Db.Save(&entries)
w.WriteHeader(http.StatusOK)
}
func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- var msg identityMessage
+ var msg IdentityMessage
var entry inboxEntry
if r.Body == nil {
http.Error(w, "No request body", 400)
@@ -211,7 +218,7 @@ func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) {
return
}
err = m.Db.First(&entry, "h_mailbox = ? AND ephemeral_key = ? AND body = ?", vars["h_mailbox"], msg.EphemeralKey, msg.Body).Error
- // FIXME
+ // FIXME actual cost
cost, _ := talerutil.ParseAmount("KUDOS:1")
if err != nil {
entry.HMailbox = vars["h_mailbox"]
@@ -261,6 +268,15 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request)
w.WriteHeader(http.StatusInternalServerError)
return
}
+ etag_expected := r.Header.Get("If-Match")
+ if etag_expected == "" {
+ http.Error(w, "If-Match header missing", 400)
+ return
+ }
+ if strings.Contains(etag_expected, ",") {
+ http.Error(w, "If-Match contains multiple values", 400)
+ return
+ }
pkey, err := gnunetutil.DecodeStringToBinary(vars["mailbox"], 32)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
@@ -281,7 +297,7 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request)
size := make([]byte, 4)
binary.BigEndian.PutUint32(size, 64+4+4)
purp := make([]byte, 4)
- binary.BigEndian.PutUint32(purp, 23) // FIXME purpose
+ binary.BigEndian.PutUint32(purp, 23) // FIXME purpose in GANA
signed_msg.Write(size)
signed_msg.Write(purp)
signed_msg.Write(checksum)
@@ -292,7 +308,7 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request)
h := sha512.New()
h.Write(pkey)
h_mailbox := gnunetutil.EncodeBinaryToString(h.Sum(nil))
- err = m.Db.Where("h_mailbox = ? AND read = ? LIMIT ?", h_mailbox, true, msg.Count).Find(&entries).Error
+ err = m.Db.Where("h_mailbox = ? AND ID >= ? LIMIT ?", h_mailbox, etag_expected, msg.Count).Find(&entries).Error
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
@@ -316,7 +332,7 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request)
h_all.Write(eph)
h_all.Write(body)
}
- if 0 != bytes.Compare(h_all.Sum(nil), checksum) {
+ if !bytes.Equal(h_all.Sum(nil), checksum) {
w.WriteHeader(http.StatusNotFound)
return
}