Products: chat command filter, request signing, saved state

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-29 02:49:10 -07:00
1 parent 2190230f81
commit 0c4f6caec1
4 files changed
+313

No files matched your search

+68
View File
@@ -0,0 +1,68 @@
package products
import (
"crypto/md5"
"encoding/hex"
"net/http"
"regexp"
"sync"
)
// IMVU signs the client's requests: X-imvu-auth is md5(user ID + session security key + body), with the query
// string added for some calls. The proxy re-signs requests it changes (taking community products out), with the key
// from the login response. The key never leaves this machine.
func sign(user, key string, body []byte, query string, withQuery bool) string {
h := md5.New()
h.Write([]byte(user + key))
h.Write(body)
if withQuery {
h.Write([]byte(query))
}
return hex.EncodeToString(h.Sum(nil))
}
// keys holds each signed-in user's security key.
type keys struct {
mu sync.Mutex
byID map[string]string
}
var securityKeyPattern = regexp.MustCompile(`<name>securityKey</name>\s*<value>(?:<string>)?([0-9A-Za-z]+)`)
var userIDPattern = regexp.MustCompile(`<name>userId</name>\s*<value>(?:<int>|<i4>|<string>)?([0-9]+)`)
// learn takes the user's key from a login response (test.avatarInfoForLogin2).
func (k *keys) learn(body []byte) {
key, user := securityKeyPattern.FindSubmatch(body), userIDPattern.FindSubmatch(body)
if key == nil || user == nil {
return
}
k.mu.Lock()
defer k.mu.Unlock()
if k.byID == nil {
k.byID = map[string]string{}
}
k.byID[string(user[1])] = string(key[1])
}
// resign recomputes X-imvu-auth for a request whose body or query changed, in the scheme the original used. It
// reports false if it couldn't (no key, or the original signature didn't match either scheme).
func (k *keys) resign(h http.Header, oldBody []byte, oldQuery string, newBody []byte, newQuery string) bool {
auth, user := h.Get("X-imvu-auth"), h.Get("X-imvu-userid")
if auth == "" {
return true // not signed
}
k.mu.Lock()
key, ok := k.byID[user]
k.mu.Unlock()
if !ok {
return false
}
for _, withQuery := range []bool{false, true} {
if sign(user, key, oldBody, oldQuery, withQuery) == auth {
h.Set("X-imvu-auth", sign(user, key, newBody, newQuery, withQuery))
return true
}
}
return false
}