summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Steam/src/steam_login.cpp38
-rw-r--r--protocols/Steam/src/steam_proto.h15
2 files changed, 42 insertions, 11 deletions
diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp
index 669d164351..4ea0e6cf9d 100644
--- a/protocols/Steam/src/steam_login.cpp
+++ b/protocols/Steam/src/steam_login.cpp
@@ -18,6 +18,7 @@ bool CSteamProto::IsOnline()
void CSteamProto::Logout()
{
m_bTerminated = true;
+ m_impl.m_loginPoll.StopSafe();
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, m_iStatus);
@@ -116,29 +117,41 @@ void CSteamProto::OnBeginSession(const CAuthenticationBeginAuthSessionViaCredent
if (reply.has_request_id)
m_requestId.append(reply.request_id.data, reply.request_id.len);
+ bool bHasEmail = false, bHasTotp = false;
for (int i = 0; i < reply.n_allowed_confirmations; i++) {
auto &conf = reply.allowed_confirmations[i];
debugLogA("Confirmation required %d (%s)", conf->confirmation_type, conf->associated_message);
switch (conf->confirmation_type) {
+ case EAUTH_SESSION_GUARD_TYPE__k_EAuthSessionGuardType_DeviceConfirmation:
+ m_impl.m_loginPoll.StartSafe((reply.has_interval ? reply.interval : 5) * 1000);
+ m_iPollStartTime = time(0);
+ __fallthrough;
+
case EAUTH_SESSION_GUARD_TYPE__k_EAuthSessionGuardType_None: // nothing to do
SendPollRequest();
return;
case EAUTH_SESSION_GUARD_TYPE__k_EAuthSessionGuardType_EmailCode: // email confirmation
- CallFunctionSync(EnterEmailCode, this);
- return;
+ bHasEmail = true;
+ break;
case EAUTH_SESSION_GUARD_TYPE__k_EAuthSessionGuardType_DeviceCode: // totp confirmation
- CallFunctionSync(EnterTotpCode, this);
+ bHasTotp = true;
+ break;
+
+ default:
+ debugLogA("Unsupported confirmation code: %i", conf->confirmation_type);
+ Logout();
return;
}
-
- debugLogA("Unsupported confirmation code: %i", conf->confirmation_type);
- Logout();
}
- // no confirmation needed - we've done
- SendPollRequest();
+ if (bHasEmail)
+ CallFunctionSync(EnterEmailCode, this);
+ else if (bHasTotp)
+ CallFunctionSync(EnterTotpCode, this);
+ else // no confirmation needed - we've done
+ SendPollRequest();
}
else {
debugLogA("Something went wrong: %s", reply.extended_error_message);
@@ -214,6 +227,15 @@ void CSteamProto::SendPollRequest()
void CSteamProto::OnPollSession(const CAuthenticationPollAuthSessionStatusResponse &reply, const CMsgProtoBufHeader &)
{
+ if (!reply.refresh_token) {
+ if (m_iPollStartTime && time(0) - m_iPollStartTime > 60)
+ Logout();
+ return;
+ }
+
+ // hurrah, server accepted guard request
+ m_impl.m_loginPoll.StopSafe();
+
if (reply.has_new_client_id)
m_iClientId = reply.new_client_id;
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index f21bcb4869..15af1e7059 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -113,13 +113,18 @@ class CSteamProto : public PROTO<CSteamProto>
friend class CSteamProto;
CSteamProto &m_proto;
- CTimer m_heartBeat, m_deleteMsg;
+ CTimer m_heartBeat, m_deleteMsg, m_loginPoll;
void OnHeartBeat(CTimer *)
{
m_proto.SendHeartBeat();
}
+ void OnLoginPoll(CTimer *)
+ {
+ m_proto.SendPollRequest();
+ }
+
void OnDeleteMsg(CTimer *)
{
m_proto.SendDeleteMessageRequest();
@@ -127,11 +132,13 @@ class CSteamProto : public PROTO<CSteamProto>
CProtoImpl(CSteamProto &pro) :
m_proto(pro),
- m_heartBeat(Miranda_GetSystemWindow(), UINT_PTR(this) + 1),
- m_deleteMsg(Miranda_GetSystemWindow(), UINT_PTR(this) + 2)
+ m_heartBeat(Miranda_GetSystemWindow(), UINT_PTR(&m_heartBeat)),
+ m_deleteMsg(Miranda_GetSystemWindow(), UINT_PTR(&m_deleteMsg)),
+ m_loginPoll(Miranda_GetSystemWindow(), UINT_PTR(&m_loginPoll))
{
m_heartBeat.OnEvent = Callback(this, &CProtoImpl::OnHeartBeat);
m_deleteMsg.OnEvent = Callback(this, &CProtoImpl::OnDeleteMsg);
+ m_loginPoll.OnEvent = Callback(this, &CProtoImpl::OnLoginPoll);
}
}
m_impl;
@@ -189,6 +196,8 @@ class CSteamProto : public PROTO<CSteamProto>
void SendPollRequest();
// login
+ time_t m_iPollStartTime;
+
bool IsOnline();
void Login();