Philipp15b / go-steam

Steam's protocol in Go to allow automation of different actions on the Steam network without running an actual Steam client. Includes APIs for friends, chatting, trading, trade offers and TF2 crafting.
https://pkg.go.dev/github.com/Philipp15b/go-steam/v3
Other
387 stars 131 forks source link

Sentry file ignored — possible cause #122

Open Delicious-Bacon opened 2 years ago

Delicious-Bacon commented 2 years ago

I use Steam Guard 2FA and I can't solve this one.

Right now, the sentry file is ignored on subsequent login attempts, and I'm always asked for the 2FA. Here are some observations on the code.

An observation on the gsbot's Auth type HandleEvent method:

func (a *Auth) HandleEvent(event interface{}) {
    switch e := event.(type) {
    case *steam.MachineAuthUpdateEvent:
        a.machineAuthHash = e.Hash
        err := ioutil.WriteFile(a.sentryPath, e.Hash, 0666)
        if err != nil {
            panic(err)
        }
    }
}

It never informs Steam servers of accepting the Sentry file.

An observation on SteamKit's MachineAuthUpdateEvent:

        static void OnMachineAuth( SteamUser.UpdateMachineAuthCallback callback )
        {
            Console.WriteLine( "Updating sentryfile..." );

            // write out our sentry file
            // ideally we'd want to write to the filename specified in the callback
            // but then this sample would require more code to find the correct sentry file to read during logon
            // for the sake of simplicity, we'll just use "sentry.bin"

            int fileSize;
            byte[] sentryHash;
            using ( var fs = File.Open( "sentry.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite ) )
            {
                fs.Seek( callback.Offset, SeekOrigin.Begin );
                fs.Write( callback.Data, 0, callback.BytesToWrite );
                fileSize = ( int )fs.Length;

                fs.Seek( 0, SeekOrigin.Begin );
                using ( var sha = SHA1.Create() )
                {
                    sentryHash = sha.ComputeHash( fs );
                }
            }

            // inform the steam servers that we're accepting this sentry file
            steamUser.SendMachineAuthResponse( new SteamUser.MachineAuthDetails
            {
                JobID = callback.JobID,

                FileName = callback.FileName,

                BytesWritten = callback.BytesToWrite,
                FileSize = fileSize,
                Offset = callback.Offset,

                Result = EResult.OK,
                LastError = 0,

                OneTimePassword = callback.OneTimePassword,

                SentryFileHash = sentryHash,
            } );

            Console.WriteLine( "Done!" );
        }

It informs Steam servers of accepting the sentry file. Source: SteamKit SteamGuard example

Philipp15b commented 2 years ago

You're right! It seems that gsbot.go needs to send a response that it accepts the sentry file. I'm happy to accept pull requests for this.

Delicious-Bacon commented 1 year ago

Do you know which fields would correspond to JobID, BytesWritten, EResult.OK to write back to Steam?

I'm also having errors when requesting the sentry file for the first time - the client immediately logs off after writing the request for sentry file:

sc.Write(
    protocol.NewClientMsgProtobuf(
        steamlang.EMsg_ClientUpdateMachineAuth,
        &protobuf.CMsgClientRequestMachineAuth{}, // Tried setting MachineName and FileName
    ),
)