You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
308 lines
8.4 KiB
308 lines
8.4 KiB
package tdesktop |
|
|
|
import ( |
|
"github.com/go-faster/errors" |
|
|
|
"github.com/gotd/td/bin" |
|
"github.com/gotd/td/internal/crypto" |
|
) |
|
|
|
// MTPConfigEnvironment is enum of config environment. |
|
type MTPConfigEnvironment int32 |
|
|
|
func (e MTPConfigEnvironment) valid() bool { |
|
return e == 0 || e == 1 |
|
} |
|
|
|
// String implements fmt.Stringer. |
|
func (e MTPConfigEnvironment) String() string { |
|
switch e { |
|
case 0: |
|
return "production" |
|
case 1: |
|
return "test" |
|
default: |
|
return "unknown" |
|
} |
|
} |
|
|
|
// Test denotes that environment is test. |
|
func (e MTPConfigEnvironment) Test() bool { |
|
return e == 1 |
|
} |
|
|
|
// MTPConfig is a Telegram Desktop storage structure which stores MTProto config info. |
|
// |
|
// See https://github.com/telegramdesktop/tdesktop/blob/v2.9.8/Telegram/SourceFiles/mtproto/mtproto_config.h. |
|
type MTPConfig struct { |
|
Environment MTPConfigEnvironment |
|
DCOptions MTPDCOptions |
|
ChatSizeMax int32 // default: 200 |
|
MegagroupSizeMax int32 // default: 10000 |
|
ForwardedCountMax int32 // default: 100 |
|
OnlineUpdatePeriod int32 // default: 120000 |
|
OfflineBlurTimeout int32 // default: 5000 |
|
OfflineIdleTimeout int32 // default: 30000 |
|
OnlineFocusTimeout int32 // default: 1000 |
|
OnlineCloudTimeout int32 // default: 300000 |
|
NotifyCloudDelay int32 // default: 30000 |
|
NotifyDefaultDelay int32 // default: 1500 |
|
SavedGifsLimit int32 // default: 200 |
|
EditTimeLimit int32 // default: 172800 |
|
RevokeTimeLimit int32 // default: 172800 |
|
RevokePrivateTimeLimit int32 // default: 172800 |
|
RevokePrivateInbox bool // default: false |
|
StickersRecentLimit int32 // default: 30 |
|
StickersFavedLimit int32 // default: 5 |
|
PinnedDialogsCountMax int32 // default: 5 |
|
PinnedDialogsInFolderMax int32 // default: 100 |
|
InternalLinksDomain string // default: "https://t.me/" |
|
ChannelsReadMediaPeriod int32 // default: 86400 * 7 |
|
CallReceiveTimeoutMs int32 // default: 20000 |
|
CallRingTimeoutMs int32 // default: 90000 |
|
CallConnectTimeoutMs int32 // default: 30000 |
|
CallPacketTimeoutMs int32 // default: 10000 |
|
WebFileDCID int32 // default: 4 |
|
TxtDomainString string // default: "" |
|
PhoneCallsEnabled bool // default: true |
|
BlockedMode bool // default: false |
|
CaptionLengthMax int32 // default: 1024 |
|
} |
|
|
|
// See https://github.com/telegramdesktop/tdesktop/blob/v2.9.8/Telegram/SourceFiles/storage/storage_account.cpp#L938. |
|
func readMTPConfig(tgf *tdesktopFile, localKey crypto.Key) (MTPConfig, error) { |
|
encrypted, err := tgf.readArray() |
|
if err != nil { |
|
return MTPConfig{}, errors.Wrap(err, "read encrypted data") |
|
} |
|
|
|
decrypted, err := decryptLocal(encrypted, localKey) |
|
if err != nil { |
|
return MTPConfig{}, errors.Wrap(err, "decrypt data") |
|
} |
|
// Skip decrypted data length (uint32). |
|
decrypted = decrypted[4:] |
|
root := qtReader{buf: bin.Buffer{Buf: decrypted}} |
|
|
|
cfgReader, err := root.subArray() |
|
if err != nil { |
|
return MTPConfig{}, errors.Wrap(err, "read config array") |
|
} |
|
|
|
var m MTPConfig |
|
if err := m.deserialize(&cfgReader); err != nil { |
|
return MTPConfig{}, errors.Wrap(err, "deserialize MTPConfig") |
|
} |
|
return m, err |
|
} |
|
|
|
func (m *MTPConfig) deserialize(r *qtReader) error { |
|
version, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read version") |
|
} |
|
if version != kVersion { |
|
return errors.Errorf("wrong version (expected %d, got %d)", kVersion, version) |
|
} |
|
|
|
environment, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read environment") |
|
} |
|
m.Environment = MTPConfigEnvironment(environment) |
|
if !m.Environment.valid() { |
|
return errors.Errorf("invalid environment %d", environment) |
|
} |
|
|
|
{ |
|
sub, err := r.subArray() |
|
if err != nil { |
|
return err |
|
} |
|
if err := m.DCOptions.deserialize(&sub); err != nil { |
|
return errors.Wrap(err, "read DC options") |
|
} |
|
} |
|
|
|
chatSizeMax, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read chatSizeMax") |
|
} |
|
m.ChatSizeMax = chatSizeMax |
|
|
|
megagroupSizeMax, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read megagroupSizeMax") |
|
} |
|
m.MegagroupSizeMax = megagroupSizeMax |
|
|
|
forwardedCountMax, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read forwardedCountMax") |
|
} |
|
m.ForwardedCountMax = forwardedCountMax |
|
|
|
onlineUpdatePeriod, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read onlineUpdatePeriod") |
|
} |
|
m.OnlineUpdatePeriod = onlineUpdatePeriod |
|
|
|
offlineBlurTimeout, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read offlineBlurTimeout") |
|
} |
|
m.OfflineBlurTimeout = offlineBlurTimeout |
|
|
|
offlineIdleTimeout, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read offlineIdleTimeout") |
|
} |
|
m.OfflineIdleTimeout = offlineIdleTimeout |
|
|
|
onlineFocusTimeout, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read onlineFocusTimeout") |
|
} |
|
m.OnlineFocusTimeout = onlineFocusTimeout |
|
|
|
onlineCloudTimeout, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read onlineCloudTimeout") |
|
} |
|
m.OnlineCloudTimeout = onlineCloudTimeout |
|
|
|
notifyCloudDelay, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read notifyCloudDelay") |
|
} |
|
m.NotifyCloudDelay = notifyCloudDelay |
|
|
|
notifyDefaultDelay, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read notifyDefaultDelay") |
|
} |
|
m.NotifyDefaultDelay = notifyDefaultDelay |
|
|
|
savedGifsLimit, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read savedGifsLimit") |
|
} |
|
m.SavedGifsLimit = savedGifsLimit |
|
|
|
editTimeLimit, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read editTimeLimit") |
|
} |
|
m.EditTimeLimit = editTimeLimit |
|
|
|
revokeTimeLimit, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read revokeTimeLimit") |
|
} |
|
m.RevokeTimeLimit = revokeTimeLimit |
|
|
|
revokePrivateTimeLimit, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read revokePrivateTimeLimit") |
|
} |
|
m.RevokePrivateTimeLimit = revokePrivateTimeLimit |
|
|
|
revokePrivateInbox, err := r.readUint32() |
|
if err != nil { |
|
return errors.Wrap(err, "read revokePrivateInbox") |
|
} |
|
m.RevokePrivateInbox = revokePrivateInbox == 1 |
|
|
|
stickersRecentLimit, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read stickersRecentLimit") |
|
} |
|
m.StickersRecentLimit = stickersRecentLimit |
|
|
|
stickersFavedLimit, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read stickersFavedLimit") |
|
} |
|
m.StickersFavedLimit = stickersFavedLimit |
|
|
|
pinnedDialogsCountMax, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read pinnedDialogsCountMax") |
|
} |
|
m.PinnedDialogsCountMax = pinnedDialogsCountMax |
|
|
|
pinnedDialogsInFolderMax, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read pinnedDialogsInFolderMax") |
|
} |
|
m.PinnedDialogsInFolderMax = pinnedDialogsInFolderMax |
|
|
|
internalLinksDomain, err := r.readString() |
|
if err != nil { |
|
return errors.Wrap(err, "read internalLinksDomain") |
|
} |
|
m.InternalLinksDomain = internalLinksDomain |
|
|
|
channelsReadMediaPeriod, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read channelsReadMediaPeriod") |
|
} |
|
m.ChannelsReadMediaPeriod = channelsReadMediaPeriod |
|
|
|
callReceiveTimeoutMs, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read callReceiveTimeoutMs") |
|
} |
|
m.CallReceiveTimeoutMs = callReceiveTimeoutMs |
|
|
|
callRingTimeoutMs, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read callRingTimeoutMs") |
|
} |
|
m.CallRingTimeoutMs = callRingTimeoutMs |
|
|
|
callConnectTimeoutMs, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read callConnectTimeoutMs") |
|
} |
|
m.CallConnectTimeoutMs = callConnectTimeoutMs |
|
|
|
callPacketTimeoutMs, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read callPacketTimeoutMs") |
|
} |
|
m.CallPacketTimeoutMs = callPacketTimeoutMs |
|
|
|
webFileDCID, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read webFileDCID") |
|
} |
|
m.WebFileDCID = webFileDCID |
|
|
|
txtDomainString, err := r.readString() |
|
if err != nil { |
|
return errors.Wrap(err, "read txtDomainString") |
|
} |
|
m.TxtDomainString = txtDomainString |
|
|
|
phoneCallsEnabled, err := r.readUint32() |
|
if err != nil { |
|
return errors.Wrap(err, "read phoneCallsEnabled") |
|
} |
|
m.PhoneCallsEnabled = phoneCallsEnabled == 1 |
|
|
|
blockedMode, err := r.readUint32() |
|
if err != nil { |
|
return errors.Wrap(err, "read blockedMode") |
|
} |
|
m.BlockedMode = blockedMode == 1 |
|
|
|
captionLengthMax, err := r.readInt32() |
|
if err != nil { |
|
return errors.Wrap(err, "read captionLengthMax") |
|
} |
|
m.CaptionLengthMax = captionLengthMax |
|
|
|
return nil |
|
}
|
|
|