summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Philipp15b/go-steam/auth.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Philipp15b/go-steam/auth.go')
-rw-r--r--vendor/github.com/Philipp15b/go-steam/auth.go178
1 files changed, 178 insertions, 0 deletions
diff --git a/vendor/github.com/Philipp15b/go-steam/auth.go b/vendor/github.com/Philipp15b/go-steam/auth.go
new file mode 100644
index 00000000..b67de335
--- /dev/null
+++ b/vendor/github.com/Philipp15b/go-steam/auth.go
@@ -0,0 +1,178 @@
+package steam
+
+import (
+ "crypto/sha1"
+ . "github.com/Philipp15b/go-steam/protocol"
+ . "github.com/Philipp15b/go-steam/protocol/protobuf"
+ . "github.com/Philipp15b/go-steam/protocol/steamlang"
+ . "github.com/Philipp15b/go-steam/steamid"
+ "github.com/golang/protobuf/proto"
+ "sync/atomic"
+ "time"
+)
+
+type Auth struct {
+ client *Client
+ details *LogOnDetails
+}
+
+type SentryHash []byte
+
+type LogOnDetails struct {
+ Username string
+ Password string
+ AuthCode string
+ TwoFactorCode string
+ SentryFileHash SentryHash
+}
+
+// Log on with the given details. You must always specify username and
+// password. For the first login, don't set an authcode or a hash and you'll receive an error
+// and Steam will send you an authcode. Then you have to login again, this time with the authcode.
+// Shortly after logging in, you'll receive a MachineAuthUpdateEvent with a hash which allows
+// you to login without using an authcode in the future.
+//
+// If you don't use Steam Guard, username and password are enough.
+func (a *Auth) LogOn(details *LogOnDetails) {
+ if len(details.Username) == 0 || len(details.Password) == 0 {
+ panic("Username and password must be set!")
+ }
+
+ logon := new(CMsgClientLogon)
+ logon.AccountName = &details.Username
+ logon.Password = &details.Password
+ if details.AuthCode != "" {
+ logon.AuthCode = proto.String(details.AuthCode)
+ }
+ if details.TwoFactorCode != "" {
+ logon.TwoFactorCode = proto.String(details.TwoFactorCode)
+ }
+ logon.ClientLanguage = proto.String("english")
+ logon.ProtocolVersion = proto.Uint32(MsgClientLogon_CurrentProtocol)
+ logon.ShaSentryfile = details.SentryFileHash
+
+ atomic.StoreUint64(&a.client.steamId, uint64(NewIdAdv(0, 1, int32(EUniverse_Public), int32(EAccountType_Individual))))
+
+ a.client.Write(NewClientMsgProtobuf(EMsg_ClientLogon, logon))
+}
+
+func (a *Auth) HandlePacket(packet *Packet) {
+ switch packet.EMsg {
+ case EMsg_ClientLogOnResponse:
+ a.handleLogOnResponse(packet)
+ case EMsg_ClientNewLoginKey:
+ a.handleLoginKey(packet)
+ case EMsg_ClientSessionToken:
+ case EMsg_ClientLoggedOff:
+ a.handleLoggedOff(packet)
+ case EMsg_ClientUpdateMachineAuth:
+ a.handleUpdateMachineAuth(packet)
+ case EMsg_ClientAccountInfo:
+ a.handleAccountInfo(packet)
+ case EMsg_ClientWalletInfoUpdate:
+ case EMsg_ClientRequestWebAPIAuthenticateUserNonceResponse:
+ case EMsg_ClientMarketingMessageUpdate:
+ }
+}
+
+func (a *Auth) handleLogOnResponse(packet *Packet) {
+ if !packet.IsProto {
+ a.client.Fatalf("Got non-proto logon response!")
+ return
+ }
+
+ body := new(CMsgClientLogonResponse)
+ msg := packet.ReadProtoMsg(body)
+
+ result := EResult(body.GetEresult())
+ if result == EResult_OK {
+ atomic.StoreInt32(&a.client.sessionId, msg.Header.Proto.GetClientSessionid())
+ atomic.StoreUint64(&a.client.steamId, msg.Header.Proto.GetSteamid())
+ a.client.Web.webLoginKey = *body.WebapiAuthenticateUserNonce
+
+ go a.client.heartbeatLoop(time.Duration(body.GetOutOfGameHeartbeatSeconds()))
+
+ a.client.Emit(&LoggedOnEvent{
+ Result: EResult(body.GetEresult()),
+ ExtendedResult: EResult(body.GetEresultExtended()),
+ OutOfGameSecsPerHeartbeat: body.GetOutOfGameHeartbeatSeconds(),
+ InGameSecsPerHeartbeat: body.GetInGameHeartbeatSeconds(),
+ PublicIp: body.GetPublicIp(),
+ ServerTime: body.GetRtime32ServerTime(),
+ AccountFlags: EAccountFlags(body.GetAccountFlags()),
+ ClientSteamId: SteamId(body.GetClientSuppliedSteamid()),
+ EmailDomain: body.GetEmailDomain(),
+ CellId: body.GetCellId(),
+ CellIdPingThreshold: body.GetCellIdPingThreshold(),
+ Steam2Ticket: body.GetSteam2Ticket(),
+ UsePics: body.GetUsePics(),
+ WebApiUserNonce: body.GetWebapiAuthenticateUserNonce(),
+ IpCountryCode: body.GetIpCountryCode(),
+ VanityUrl: body.GetVanityUrl(),
+ NumLoginFailuresToMigrate: body.GetCountLoginfailuresToMigrate(),
+ NumDisconnectsToMigrate: body.GetCountDisconnectsToMigrate(),
+ })
+ } else if result == EResult_Fail || result == EResult_ServiceUnavailable || result == EResult_TryAnotherCM {
+ // some error on Steam's side, we'll get an EOF later
+ } else {
+ a.client.Emit(&LogOnFailedEvent{
+ Result: EResult(body.GetEresult()),
+ })
+ a.client.Disconnect()
+ }
+}
+
+func (a *Auth) handleLoginKey(packet *Packet) {
+ body := new(CMsgClientNewLoginKey)
+ packet.ReadProtoMsg(body)
+ a.client.Write(NewClientMsgProtobuf(EMsg_ClientNewLoginKeyAccepted, &CMsgClientNewLoginKeyAccepted{
+ UniqueId: proto.Uint32(body.GetUniqueId()),
+ }))
+ a.client.Emit(&LoginKeyEvent{
+ UniqueId: body.GetUniqueId(),
+ LoginKey: body.GetLoginKey(),
+ })
+}
+
+func (a *Auth) handleLoggedOff(packet *Packet) {
+ result := EResult_Invalid
+ if packet.IsProto {
+ body := new(CMsgClientLoggedOff)
+ packet.ReadProtoMsg(body)
+ result = EResult(body.GetEresult())
+ } else {
+ body := new(MsgClientLoggedOff)
+ packet.ReadClientMsg(body)
+ result = body.Result
+ }
+ a.client.Emit(&LoggedOffEvent{Result: result})
+}
+
+func (a *Auth) handleUpdateMachineAuth(packet *Packet) {
+ body := new(CMsgClientUpdateMachineAuth)
+ packet.ReadProtoMsg(body)
+ hash := sha1.New()
+ hash.Write(packet.Data)
+ sha := hash.Sum(nil)
+
+ msg := NewClientMsgProtobuf(EMsg_ClientUpdateMachineAuthResponse, &CMsgClientUpdateMachineAuthResponse{
+ ShaFile: sha,
+ })
+ msg.SetTargetJobId(packet.SourceJobId)
+ a.client.Write(msg)
+
+ a.client.Emit(&MachineAuthUpdateEvent{sha})
+}
+
+func (a *Auth) handleAccountInfo(packet *Packet) {
+ body := new(CMsgClientAccountInfo)
+ packet.ReadProtoMsg(body)
+ a.client.Emit(&AccountInfoEvent{
+ PersonaName: body.GetPersonaName(),
+ Country: body.GetIpCountry(),
+ CountAuthedComputers: body.GetCountAuthedComputers(),
+ AccountFlags: EAccountFlags(body.GetAccountFlags()),
+ FacebookId: body.GetFacebookId(),
+ FacebookName: body.GetFacebookName(),
+ })
+}