diff --git a/server/signserver/dsgn_resp.go b/server/signserver/dsgn_resp.go index 7e9305434..ad224f48f 100644 --- a/server/signserver/dsgn_resp.go +++ b/server/signserver/dsgn_resp.go @@ -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 diff --git a/server/signserver/respid.go b/server/signserver/respid.go index 47e7683d4..014daa862 100644 --- a/server/signserver/respid.go +++ b/server/signserver/respid.go @@ -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 diff --git a/server/signserver/session.go b/server/signserver/session.go index 19270fafc..3e35708a6 100644 --- a/server/signserver/session.go +++ b/server/signserver/session.go @@ -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) - s.logger.Info("Deleted character", zap.Int("CharacterID", characterID)) - err := s.cryptConn.SendPacket([]byte{0x01}) // DEL_SUCCESS - if err != nil { - return nil + err := s.server.deleteCharacter(characterID, loginTokenString) + if err == nil { + s.logger.Info("Deleted character", zap.Int("CharacterID", characterID)) + 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 - } - - return nil + err = s.cryptConn.SendPacket(bf.Data()) +} + +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) }