rewrite signserver

This commit is contained in:
wish
2023-04-12 05:37:41 +10:00
parent 23138b2d5b
commit 2ede81925a
3 changed files with 64 additions and 79 deletions

View File

@@ -11,15 +11,7 @@ import (
"strings"
)
func makeSignInFailureResp(respID RespID) []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint8(uint8(respID))
return bf.Data()
}
func (s *Session) makeSignInResp(uid int) []byte {
returnExpiry := s.server.getReturnExpiry(uid)
func (s *Session) makeSignResponse(uid int) []byte {
// Get the characters from the DB.
chars, err := s.server.getCharactersForUser(uid)
if err != nil {
@@ -27,7 +19,7 @@ func (s *Session) makeSignInResp(uid int) []byte {
}
sessToken := token.Generate(16)
s.server.registerToken(uid, sessToken)
_ = s.server.registerToken(uid, sessToken)
bf := byteframe.NewByteFrame()
@@ -116,6 +108,11 @@ func (s *Session) makeSignInResp(uid int) []byte {
bf.WriteUint32(s.server.getLastCID(uid))
bf.WriteUint32(s.server.getUserRights(uid))
ps.Uint16(bf, "", false) // filters
if s.client == VITA {
var psnUser string
s.server.db.QueryRow("SELECT username FROM users WHERE id = $1", uid).Scan(&psnUser)
stringsupport.PaddedString(psnUser, 20, true)
}
bf.WriteUint16(0xCA10)
bf.WriteUint16(0x4E20)
ps.Uint16(bf, "", false) // unk key
@@ -124,7 +121,7 @@ func (s *Session) makeSignInResp(uid int) []byte {
bf.WriteUint16(0x0001)
bf.WriteUint16(0x4E20)
ps.Uint16(bf, "", false) // unk ipv4
bf.WriteUint32(uint32(returnExpiry.Unix()))
bf.WriteUint32(uint32(s.server.getReturnExpiry(uid).Unix()))
bf.WriteUint32(0x00000000)
bf.WriteUint32(0x0A5197DF) // unk id

View File

@@ -1,10 +1,7 @@
package signserver
//revive:disable
type RespID uint8
type RespID uint16
//go:generate stringer -type=RespID
const (
SIGN_UNKNOWN RespID = iota
SIGN_SUCCESS

View File

@@ -13,6 +13,13 @@ import (
"golang.org/x/crypto/bcrypt"
)
type Client int
const (
PC100 Client = iota
VITA
)
// Session holds state for the sign server connection.
type Session struct {
sync.Mutex
@@ -20,6 +27,7 @@ type Session struct {
server *Server
rawConn net.Conn
cryptConn *network.CryptConn
client Client
}
func (s *Session) work() {
@@ -42,91 +50,65 @@ func (s *Session) handlePacket(pkt []byte) error {
bf := byteframe.NewByteFrameFromBytes(pkt)
reqType := string(bf.ReadNullTerminatedBytes())
switch reqType {
case "DLTSKEYSIGN:100":
fallthrough
case "DSGN:100":
err := s.handleDSGNRequest(bf)
if err != nil {
return nil
}
case "DLTSKEYSIGN:100", "DSGN:100":
s.handleDSGN(bf)
case "VITASGN:100":
s.client = VITA
s.handleVITASGN(bf)
case "DELETE:100":
loginTokenString := string(bf.ReadNullTerminatedBytes())
characterID := int(bf.ReadUint32())
_ = int(bf.ReadUint32()) // login_token_number
s.server.deleteCharacter(characterID, loginTokenString)
err := s.server.deleteCharacter(characterID, loginTokenString)
if err == nil {
s.logger.Info("Deleted character", zap.Int("CharacterID", characterID))
err := s.cryptConn.SendPacket([]byte{0x01}) // DEL_SUCCESS
if err != nil {
return nil
s.cryptConn.SendPacket([]byte{0x01}) // DEL_SUCCESS
}
default:
s.logger.Warn("Unknown sign request", zap.String("reqType", reqType))
s.logger.Warn("Unknown request", zap.String("reqType", reqType))
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.LogInboundMessages {
fmt.Printf("\n[Client] -> [Server]\nData [%d bytes]:\n%s\n", len(pkt), hex.Dump(pkt))
}
}
return nil
}
func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
reqUsername := string(bf.ReadNullTerminatedBytes())
reqPassword := string(bf.ReadNullTerminatedBytes())
_ = string(bf.ReadNullTerminatedBytes()) // Unk
func (s *Session) authenticate(username string, password string) {
newCharaReq := false
if reqUsername[len(reqUsername)-1] == 43 { // '+'
reqUsername = reqUsername[:len(reqUsername)-1]
if username[len(username)-1] == 43 { // '+'
username = username[:len(username)-1]
newCharaReq = true
}
var (
id int
password string
)
err := s.server.db.QueryRow("SELECT id, password FROM users WHERE username = $1", reqUsername).Scan(&id, &password)
var serverRespBytes []byte
var id int
var hash string
bf := byteframe.NewByteFrame()
err := s.server.db.QueryRow("SELECT id, password FROM users WHERE username = $1", username).Scan(&id, &hash)
switch {
case err == sql.ErrNoRows:
s.logger.Info("User not found", zap.String("Username", reqUsername))
serverRespBytes = makeSignInFailureResp(SIGN_EAUTH)
s.logger.Info("User not found", zap.String("Username", username))
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.AutoCreateAccount {
s.logger.Info("Creating user", zap.String("Username", reqUsername))
err = s.server.registerDBAccount(reqUsername, reqPassword)
if err != nil {
s.logger.Error("Error registering new user", zap.Error(err))
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
break
s.logger.Info("Creating user", zap.String("Username", username))
err = s.server.registerDBAccount(username, password)
if err == nil {
bf.WriteBytes(s.makeSignResponse(id))
}
} else {
break
bf.WriteUint8(uint8(SIGN_EAUTH))
}
var id int
err = s.server.db.QueryRow("SELECT id FROM users WHERE username = $1", reqUsername).Scan(&id)
if err != nil {
s.logger.Error("Error getting new user ID", zap.Error(err))
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
break
}
serverRespBytes = s.makeSignInResp(id)
break
case err != nil:
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
bf.WriteUint8(uint8(SIGN_EABORT))
s.logger.Error("Error getting user details", zap.Error(err))
break
default:
if bcrypt.CompareHashAndPassword([]byte(password), []byte(reqPassword)) == nil {
if bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil {
s.logger.Debug("Passwords match!")
if newCharaReq {
err = s.server.newUserChara(reqUsername)
err = s.server.newUserChara(username)
if err != nil {
s.logger.Error("Error adding new character to user", zap.Error(err))
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
bf.WriteUint8(uint8(SIGN_EABORT))
break
}
}
@@ -137,22 +119,31 @@ func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
// serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
// break
// }
serverRespBytes = s.makeSignInResp(id)
bf.WriteBytes(s.makeSignResponse(id))
} else {
s.logger.Warn("Incorrect password")
serverRespBytes = makeSignInFailureResp(SIGN_EPASS)
bf.WriteUint8(uint8(SIGN_EPASS))
}
}
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.LogOutboundMessages {
fmt.Printf("\n[Server] -> [Client]\nData [%d bytes]:\n%s\n", len(serverRespBytes), hex.Dump(serverRespBytes))
fmt.Printf("\n[Server] -> [Client]\nData [%d bytes]:\n%s\n", len(bf.Data()), hex.Dump(bf.Data()))
}
err = s.cryptConn.SendPacket(serverRespBytes)
if err != nil {
return err
err = s.cryptConn.SendPacket(bf.Data())
}
return nil
func (s *Session) handleVITASGN(bf *byteframe.ByteFrame) {
_ = bf.ReadNullTerminatedBytes() // 0000000256
_ = bf.ReadNullTerminatedBytes() // 1
_ = bf.ReadBytes(82)
psnUser := string(bf.ReadNullTerminatedBytes())
s.authenticate(psnUser, "")
}
func (s *Session) handleDSGN(bf *byteframe.ByteFrame) {
reqUsername := string(bf.ReadNullTerminatedBytes())
reqPassword := string(bf.ReadNullTerminatedBytes())
_ = string(bf.ReadNullTerminatedBytes()) // Unk
s.authenticate(reqUsername, reqPassword)
}