This commit is contained in:
Athena Funderburg
2026-05-25 07:05:17 +00:00
commit 4b463a3432
682 changed files with 47796 additions and 0 deletions
View File
+1
View File
@@ -0,0 +1 @@
from .entry import register
+67
View File
@@ -0,0 +1,67 @@
from typing import Any, Dict, List
from aiohttp import web
import json, util.misc
from core.backend import Backend
from core.http import render
TMPL_DIR = 'front/api/tmpl'
def register(app: web.Application) -> None:
util.misc.add_to_jinja_env(app, 'api', TMPL_DIR)
# Actual APIs
app.router.add_get('/api/ircChats', handle_ircchats)
app.router.add_get('/api/stats/{service}', handle_stats_api)
# API tests
app.router.add_route('*', '/api/chats-test', handle_chat_list)
async def handle_ircchats(req: web.Request) -> web.Response:
backend = req.app['backend'] # type: Backend
result = [] # type: List[Dict[str, Any]]
for chat in backend.get_chats_by_scope('irc'):
nicks = [cs.user.email for cs in chat.get_roster_single()]
result.append({
'channel': chat.ids['irc'],
'users': nicks,
})
return web.Response(status = 200, body = json.dumps(result))
async def handle_stats_api(req: web.Request) -> web.Response:
backend = req.app['backend'] # type: Backend
service = req.match_info['service']
result = {} # type: Dict[str, Any]
if service == 'usersActive':
result['users_active'] = str(backend._stats.logged_in)
return web.Response(status = 200, body = json.dumps(result))
if service == 'messages':
# TODO: Support message count by client ID
messages_received = 0
messages_sent = 0
for stats_raw in backend._stats.by_client.values():
from core.stats import _stats_to_json as stats_json
stats = stats_json(stats_raw) # type: Dict[str, Any]
if 'messages_received' in stats:
messages_received += int(stats['messages_received'])
if 'messages_sent' in stats:
messages_sent += int(stats['messages_sent'])
result['messages_received'] = str(messages_received)
result['messages_sent'] = str(messages_sent)
return web.Response(status = 200, body = json.dumps(result))
return web.Response(status = 400)
async def handle_chat_list(req: web.Request) -> web.Response:
return render(req, 'api:chats-test.html')
+36
View File
@@ -0,0 +1,36 @@
<html>
<body>
<h1>IRC Chats</h1>
<div id="chats">
</div>
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/ircChats', true);
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
chats_div = document.getElementById('chats');
innerHtml = '';
response = JSON.parse(this.responseText);
for (i in response) {
channel = response[i]
users = channel['users'];
innerHtml += '<h3>' + channel['channel'] + '</h3>';
innerHtml += '<br/>';
innerHtml += 'Total users: ' + users.length.toString();
innerHtml += '<br/><br/>';
innerHtml += 'Users:';
innerHtml += '<ul>';
for (j in users) {
innerHtml += '<li>' + users[j] + '</li>';
}
innerHtml += '</ul>';
}
chats_div.innerHTML = innerHtml;
}
}
xhr.send();
</script>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
from .entry import register
+177
View File
@@ -0,0 +1,177 @@
from typing import Optional, Dict, Any
import asyncio, random
from core.client import Client
from core.models import (
Substatus, ContactList, Contact, User, Circle, CircleRole, TextWithData,
MessageData, MessageType, LoginOption, OIM,
)
from core.backend import Backend, BackendSession, Chat, ChatSession
from core import event
from util.misc import MultiDict
CLIENT = Client('ct-bot', 'testing', 'direct')
BOT_EMAIL = 'bot1@crosstalk.im'
def register(loop: asyncio.AbstractEventLoop, backend: Backend) -> None:
uuid = backend.util_get_uuid_from_email(BOT_EMAIL)
assert uuid is not None
bs = backend.login(uuid, CLIENT, BackendEventHandler(loop), option = LoginOption.BootOthers)
assert bs is not None
class BackendEventHandler(event.BackendEventHandler):
__slots__ = ('loop', 'bs')
loop: asyncio.AbstractEventLoop
bs: BackendSession
def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
self.loop = loop
def on_open(self) -> None:
bs = self.bs
bs.me_update({ 'substatus': Substatus.Online })
print(f"[Bot] {bs.user.status.name} is now online!")
detail = bs.user.detail
assert detail is not None
def on_maintenance_boot(self) -> None:
pass
def on_presence_notification(
self, ctc: Contact, on_contact_add: bool, old_substatus: Substatus, *,
trid: Optional[str] = None, update_status: bool = True, update_info_other: bool = True,
send_status_on_bl: bool = False, sess_id: Optional[int] = None, updated_phone_info: Optional[Dict[str, Any]] = None,
) -> None:
pass
def on_presence_self_notification(
self, old_substatus: Substatus, *, update_status: bool = True, update_info: bool = True,
) -> None:
pass
def on_circle_created(self, circle: Circle) -> None:
pass
def on_circle_updated(self, circle: Circle) -> None:
pass
def on_left_circle(self, circle: Circle) -> None:
pass
def on_accepted_circle_invite(self, circle: Circle) -> None:
pass
def on_circle_invite_revoked(self, chat_id: str) -> None:
pass
def on_circle_role_updated(self, chat_id: str, role: CircleRole) -> None:
pass
def on_chat_invite(
self, chat: Chat, inviter: User, *, circle: bool = False, inviter_id: Optional[str] = None, invite_msg: str = '',
) -> None:
cs = chat.join('ct-bot', self.bs, ChatEventHandler(self.loop, self.bs))
chat.send_participant_joined(cs)
def on_declined_chat_invite(self, chat: Chat, circle: bool = False) -> None:
pass
def on_added_me(self, user: User, *, adder_id: Optional[str] = None, message: Optional[TextWithData] = None) -> None:
# Auto-remove people from pending list
bs = self.bs
detail = bs.user.detail
assert detail is not None
ctc = detail.contacts.get(user.uuid)
if ctc is not None:
bs.me_contact_remove(ctc.head.uuid, ContactList.PL)
def on_removed_me(self, user: User) -> None:
pass
def on_contact_request_denied(self, user_added: User, message: Optional[str], *, contact_id: Optional[str] = None) -> None:
pass
def on_oim_sent(self, oim: 'OIM') -> None:
pass
def ymsg_on_p2p_msg_request(self, sess_id: int, yahoo_data: MultiDict[bytes, bytes]) -> None:
pass
def ymsg_on_xfer_init(self, sess_id: int, yahoo_data: MultiDict[bytes, bytes]) -> None:
pass
def ymsg_on_sent_ft_http(self, yahoo_id_sender: str, url_path: str, upload_time: float, message: str) -> None:
pass
def on_login_elsewhere(self, option: LoginOption) -> None:
pass
class ChatEventHandler(event.ChatEventHandler):
__slots__ = ('loop', 'bs', 'cs', '_sending')
loop: asyncio.AbstractEventLoop
bs: BackendSession
cs: ChatSession
_sending: bool
def __init__(self, loop: asyncio.AbstractEventLoop, bs: BackendSession) -> None:
self.loop = loop
self.bs = bs
self._sending = False
def on_open(self) -> None:
self.cs.send_message_to_everyone(MessageData(
sender = self.cs.user,
type = MessageType.Chat,
text = "Hello, world!",
))
def on_participant_joined(self, cs_other: ChatSession, first_pop: bool, initial_join: bool) -> None:
pass
def on_participant_left(self, cs_other: ChatSession, last_pop: bool) -> None:
pass
def on_chat_invite_declined(
self, chat: Chat, invitee: User, *, invitee_id: Optional[str] = None, message: Optional[str] = None, circle: bool = False,
) -> None:
pass
def on_chat_updated(self) -> None:
pass
def on_chat_roster_updated(self) -> None:
pass
def on_participant_status_updated(self, cs_other: ChatSession, first_pop: bool, initial: bool, old_substatus: Substatus) -> None:
pass
def on_invite_declined(self, invited_user: User, *, invited_id: Optional[str] = None, message: str = '') -> None:
pass
def on_message(self, message: MessageData) -> None:
if self._sending:
return
if message.sender.email.endswith('@crosstalk.im'):
return
me = self.cs.user
self._sending = True
typing_message = MessageData(sender = me, type = MessageType.Typing)
self.cs.send_message_to_everyone(typing_message)
self.loop.create_task(self._send_delayed(random.uniform(0.5, 1), MessageData(
sender = me, type = MessageType.Chat,
text = "You, {}, insist that \"{}\".".format(message.sender.status.name, message.text),
)))
async def _send_delayed(self, delay: float, message: MessageData) -> None:
await asyncio.sleep(delay, loop = self.loop)
self.cs.send_message_to_everyone(message)
self._sending = False
+1
View File
@@ -0,0 +1 @@
from .entry import register
+170
View File
@@ -0,0 +1,170 @@
from typing import Optional, Dict, Any
import asyncio, random
from core.client import Client
from core.models import (
Substatus, ContactList, Contact, Circle, CircleRole, User,
TextWithData, MessageData, MessageType, LoginOption, OIM,
)
from core.backend import Backend, BackendSession, Chat, ChatSession
from core import event
from util.misc import MultiDict
CLIENT = Client('ct-bot', '0.1', 'direct')
def register(loop: asyncio.AbstractEventLoop, backend: Backend) -> None:
for i in range(5):
uuid = backend.util_get_uuid_from_email('bot{}@crosstalk.im'.format(i))
assert uuid is not None
bs = backend.login(uuid, CLIENT, BackendEventHandler(loop), option = LoginOption.BootOthers)
assert bs is not None
class BackendEventHandler(event.BackendEventHandler):
__slots__ = ('loop', 'bs')
loop: asyncio.AbstractEventLoop
bs: BackendSession
def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
self.loop = loop
def on_open(self) -> None:
self.bs.me_update({ 'substatus': Substatus.Online })
print("Bot active:", self.bs.user.status.name)
def on_presence_notification(
self, ctc: Contact, on_contact_add: bool, old_substatus: Substatus, *,
trid: Optional[str] = None, update_status: bool = True, update_info_other: bool = True,
send_status_on_bl: bool = False, sess_id: Optional[int] = None, updated_phone_info: Optional[Dict[str, Any]] = None,
) -> None:
pass
def on_presence_self_notification(
self, old_substatus: Substatus, *, update_status: bool = True, update_info: bool = True,
) -> None:
pass
def on_circle_created(self, circle: Circle) -> None:
pass
def on_circle_updated(self, circle: Circle) -> None:
pass
def on_left_circle(self, circle: Circle) -> None:
pass
def on_accepted_circle_invite(self, circle: Circle) -> None:
pass
def on_circle_invite_revoked(self, chat_id: str) -> None:
pass
def on_circle_role_updated(self, chat_id: str, role: CircleRole) -> None:
pass
def on_chat_invite(
self, chat: Chat, inviter: User, *, circle: bool = False, inviter_id: Optional[str] = None, invite_msg: Optional[str] = None,
) -> None:
cs = chat.join('ct-bot', self.bs, ChatEventHandler(self.loop, self.bs))
chat.send_participant_joined(cs)
def on_declined_chat_invite(self, chat: Chat, circle: bool = False) -> None:
pass
def on_added_me(self, user: User, *, adder_id: Optional[str] = None, message: Optional[TextWithData] = None) -> None:
# Auto-remove people from pending list
bs = self.bs
detail = bs.user.detail
assert detail is not None
ctc = detail.contacts.get(user.uuid)
if ctc is not None:
bs.me_contact_remove(ctc.head.uuid, ContactList.PL)
def on_removed_me(self, user: User) -> None:
pass
def on_contact_request_denied(self, user_added: User, message: Optional[str], *, contact_id: Optional[str] = None) -> None:
pass
def on_oim_sent(self, oim: 'OIM') -> None:
pass
def on_login_elsewhere(self, option: LoginOption) -> None:
pass
def ymsg_on_p2p_msg_request(self, sess_id: int, yahoo_data: MultiDict[bytes, bytes]) -> None:
pass
def ymsg_on_xfer_init(self, sess_id: int, yahoo_data: MultiDict[bytes, bytes]) -> None:
pass
def ymsg_on_sent_ft_http(self, yahoo_id_sender: str, url_path: str, upload_time: float, message: str) -> None:
pass
class ChatEventHandler(event.ChatEventHandler):
__slots__ = ('loop', 'bs', 'cs', '_sending')
loop: asyncio.AbstractEventLoop
bs: BackendSession
cs: ChatSession
_sending: bool
def __init__(self, loop: asyncio.AbstractEventLoop, bs: BackendSession) -> None:
self.loop = loop
self.bs = bs
self._sending = False
def on_open(self) -> None:
pass
def on_participant_joined(self, cs_other: ChatSession, first_pop: bool, initial_join: bool) -> None:
pass
def on_participant_left(self, cs_other: ChatSession, last_pop: bool) -> None:
pass
def on_chat_invite_declined(
self, chat: Chat, invitee: User, *, invitee_id: Optional[str] = None, message: Optional[str] = None, circle: bool = False,
) -> None:
pass
def on_chat_updated(self) -> None:
pass
def on_chat_roster_updated(self) -> None:
pass
def on_participant_status_updated(self, cs_other: ChatSession, first_pop: bool, initial: bool, old_substatus: Substatus) -> None:
pass
def on_message(self, message: MessageData) -> None:
if message.type not in (MessageType.Chat,MessageType.Nudge):
return
if self._sending:
return
if message.sender.email.endswith('@bot.log1p.gay'):
return
me = self.cs.user
self._sending = True
typing_message = MessageData(sender = me, type = MessageType.Typing)
self.cs.send_message_to_everyone(typing_message)
if message.type is MessageType.Chat:
self.loop.create_task(self._send_delayed(random.uniform(0.5, 1), MessageData(
sender = me, type = MessageType.Chat,
text = "lol :p",
)))
elif message.type is MessageType.Nudge:
self.loop.create_task(self._send_delayed(random.uniform(0.5, 1), MessageData(
sender = me, type = MessageType.Nudge,
)))
async def _send_delayed(self, delay: float, message: MessageData) -> None:
await asyncio.sleep(delay, loop = self.loop)
self.cs.send_message_to_everyone(message)
self._sending = False
+1
View File
@@ -0,0 +1 @@
from .entry import register
+463
View File
@@ -0,0 +1,463 @@
from typing import Tuple, Optional, Iterable, List, Any, Callable, Dict
import io, asyncio, settings
from datetime import datetime
from enum import IntEnum
from util.misc import Logger
from core import event
from core.models import (
Contact, Substatus, User, Circle, CircleRole, TextWithData,
MessageData, MessageType, LoginOption, OIM,
)
from core.backend import Backend, BackendSession, Chat, ChatSession
from core.client import Client
class IRCCtrl:
__slots__ = (
'logger', 'reader', 'writer', 'peername', 'close_callback', 'closed', 'transport',
'backend', 'bs', 'client',
'password', 'username', 'chat_sessions'
)
logger: Logger
reader: 'IRCReader'
writer: 'IRCWriter'
peername: Tuple[str, int]
close_callback: Optional[Callable[[], None]]
closed: bool
transport: Optional[asyncio.WriteTransport]
backend: Backend
bs: Optional[BackendSession]
client: Client
password: Optional[str]
username: Optional[str]
chat_sessions: Dict[Chat, ChatSession]
def __init__(self, logger: Logger, via: str, backend: Backend) -> None:
self.logger = logger
self.reader = IRCReader(logger)
self.writer = IRCWriter(logger)
self.peername = ('0.0.0.0', 6667)
self.close_callback = None
self.closed = False
self.transport = None
self.backend = backend
self.bs = None
self.client = Client('irc', '?', via)
self.password = None
self.username = None
self.chat_sessions = {}
def _m_pass(self, pwd: str) -> None:
self.password = pwd
def _m_user(self, email: str, junk1: str, junk2: str, realname: str) -> None:
password = self.password
self.password = None
assert password is not None
uuid = self.backend.user_service.login(email, password)
if uuid is not None:
bs = self.backend.login(uuid, self.client, BackendEventHandler(self), option = LoginOption.BootOthers)
else:
bs = None
if bs is None:
self.send_numeric(Err.PasswdMismatch, ':Wrong email/password')
return
self.bs = bs
user = bs.user
if user.suspended:
self.send_numeric(Err.YoureBannedCreep, ':Your CrossTalk account has been suspended. You may not connect to the service.')
self.close()
return
self.bs.me_update({ 'substatus': Substatus.Online })
self.send_numeric(RPL.Welcome, email, ':Log on successful.')
self._m_motd()
def _m_ping(self, *servers: str) -> None:
self.send_reply('PONG', *servers)
def _m_join(self, channel: str, keys: Optional[str] = None) -> None:
assert self.bs is not None
email = self.bs.user.email
chat = self._channel_to_chat(channel)
if chat is None:
chat = self.backend.chat_create()
chat.add_id('irc', channel)
cs = self._channel_to_chatsession(channel)
if cs is None:
cs = chat.join('irc', self.bs, ChatEventHandler(self))
chat.send_participant_joined(cs)
self.chat_sessions[chat] = cs
self.send_numeric(RPL.NamReply, email, '=', channel, ':' + ' '.join(
cs.user.email for cs in chat.get_roster_single()
))
# TODO: Chats created in other frontends are usually secret+private.
#self.send_numeric(Err.InviteOnlyChan, email, channel, ":Cannot join channel")
def _m_invite(self, user_email: str, channel: str) -> None:
assert self.bs is not None
cs = self._channel_to_chatsession(channel)
assert cs is not None
uuid = self.backend.util_get_uuid_from_email(user_email)
assert uuid is not None
user = self.backend.user_service.get(uuid)
assert user is not None
cs.invite(user)
self.send_numeric(RPL.Inviting, self.bs.user.email, user_email, channel)
def _m_list(self, arg1: Optional[str] = None, arg2: Optional[str] = None) -> None:
assert self.bs is not None
email = self.bs.user.email
for chat in self.backend.get_chats_by_scope('irc'):
self.send_numeric(RPL.List, email, chat.ids['irc'], str(len(list(chat.get_roster_single()))))
self.send_numeric(RPL.ListEnd, email, ":End of /LIST")
def _m_mode(self, channel: str) -> None:
#self.send_numeric(RPL.ChannelModeIs, self.bs.user.email, channel, '+tnl', 200)
pass
def _m_nick(self, nickname: str) -> None:
self.bs.me_update({ 'name': nickname })
def _m_userhost(self, email: str) -> None:
self._reply_unsupported('USERHOST')
def _m_who(self, channel: str) -> None:
assert self.bs is not None
cs = self._channel_to_chatsession(channel)
assert cs is not None
for cs_other in cs.chat.get_roster():
email = cs_other.user.email
name = cs_other.user.status.name or email
self.send_numeric(RPL.WhoReply, self.bs.user.email, channel, email, 'host', 'server', email, 'H', ':0 0PNE ' + name)
def _m_part(self, channel: str, message: Optional[str] = None) -> None:
assert self.bs is not None
cs = self._channel_to_chatsession(channel)
assert cs is not None
cs.close()
self.send_reply('PART', channel, source = self.bs.user.email)
def _m_privmsg(self, dest: str, message: str) -> None:
assert self.bs is not None
cs = self._channel_to_chatsession(dest)
assert cs is not None
cs.send_message_to_everyone(MessageData(sender = self.bs.user, type = MessageType.Chat, text = message))
def _m_away(self, message: Optional[str]) -> None:
assert self.bs is not None
if self.bs.user.status.substatus == Substatus.Online:
awaymsg = None
if len(message) > 0:
awaymsg = message
self.bs.me_update({ 'substatus': Substatus.Away, message: awaymsg })
self.send_numeric(RPL.NowAway, ':You are now away.')
else:
self.bs.me_update({ 'substatus': Substatus.Online, 'message': None })
self.send_numeric(RPL.UnAway, ':You are no longer away.')
def _m_motd(self) -> None:
self.send_numeric(RPL.MOTDStart, ": ----- CrossTalk (BETA) -----")
self.send_numeric(RPL.MOTD, ": - Welcome to CrossTalk! This frontend is undergoing a massive overhaul, so expect things to be iffy for now.")
self.send_numeric(RPL.MOTD, ": - We support MSNP, YMSG, and OSCAR as well.")
self.send_numeric(RPL.MOTD, ": - Development is going at a faster pace, so this won't stay the case for long. Stay tuned!")
self.send_numeric(RPL.MOTDEnd, ": - End of the MOTD.")
def _m_version(self) -> None:
self.send_numeric(RPL.Version, ": - AZUL (BETA) - IRC")
def _m_quit(self, reason: Optional[str]) -> None:
self.close()
def _m_cap(self, subcommand: str, capabilities: Optional[str] = None) -> None:
self._reply_unsupported('CAP')
def _m_time(self) -> None:
self.send_numeric(RPL.Time, ': - {}'.format(datetime.now()))
def _reply_unsupported(self, cmd: str) -> None:
self.send_numeric(Err.UnknownCommand, cmd, ":Not supported")
def _channel_to_chatsession(self, channel: str) -> Optional[ChatSession]:
chat = self._channel_to_chat(channel)
assert chat is not None
return self.chat_sessions.get(chat)
def _channel_to_chat(self, channel: str) -> Optional[Chat]:
return self.backend.chat_get('irc', channel)
def data_received(self, data: bytes, *, transport: Optional[asyncio.BaseTransport] = None) -> None:
if transport is None:
transport = self.transport
assert transport is not None
self.peername = transport.get_extra_info('peername')
for m in self.reader.data_received(data):
try:
f = getattr(self, '_m_{}'.format(m[0].lower()))
f(*m[1:])
except Exception as ex:
self.logger.error(ex)
def send_numeric(self, n: int, *m: str, source: Optional[str] = None) -> None:
self.send_reply('{:03}'.format(n), *m, source = source)
def send_reply(self, *m: str, source: Optional[str] = None) -> None:
if source is None:
source = 'localhost'
self.writer.write((':' + source,) + m)
transport = self.transport
if transport is not None:
transport.write(self.flush())
def flush(self) -> bytes:
return self.writer.flush()
def close(self) -> None:
if self.closed: return
self.closed = True
for cs in list(self.chat_sessions.values()):
cs.close()
if self.close_callback:
self.close_callback()
if self.bs:
self.bs.close()
class BackendEventHandler(event.BackendEventHandler):
__slots__ = ('ctrl', 'bs')
ctrl: IRCCtrl
bs: BackendSession
def __init__(self, ctrl: IRCCtrl) -> None:
self.ctrl = ctrl
def on_client_alert(self, icon_url: Optional[str], url: Optional[str], message: str = '') -> None:
self.ctrl.send_reply('PRIVMSG', '$*', ':' + message, source = "System")
def on_maintenance_message(self, *args: Any, **kwargs: Any) -> None:
if args[1] is not None:
self.ctrl.send_reply(
'NOTICE', '$*', ':CrossTalk is going to go down for maintenance in {} minutes. Now is a good time to wrap up any conversations.'.format(str(args[1])), source = 'System',
)
def on_maintenance_boot(self) -> None:
msg = ':CrossTalk is now in maintenance mode. Try connecting to the service later..'
self.ctrl.send_reply(
'KILL', '$*', msg, source = 'System'
)
self.ctrl.close()
def on_presence_notification(
self, ctc: Contact, on_contact_add: bool, old_substatus: Substatus, *,
trid: Optional[str] = None, update_status: bool = True, update_info_other: bool = True,
send_status_on_bl: bool = False, sess_id: Optional[int] = None, updated_phone_info: Optional[Dict[str, Any]] = None,
) -> None:
if update_status:
self.ctrl.send_reply('NOTICE', ":{} is now {}".format(ctc.head.email, ctc.status.substatus))
def on_presence_self_notification(self, old_substatus: Substatus, *, update_status: bool = True, update_info: bool = True) -> None:
pass
def on_circle_created(self, circle: Circle) -> None:
pass
def on_circle_updated(self, circle: Circle) -> None:
pass
def on_left_circle(self, circle: Circle) -> None:
pass
def on_accepted_circle_invite(self, circle: Circle) -> None:
pass
def on_circle_invite_revoked(self, chat_id: str) -> None:
pass
def on_circle_role_updated(self, chat_id: str, role: CircleRole) -> None:
pass
def on_chat_invite(
self, chat: Chat, inviter: User, *, circle: bool = False, inviter_id: Optional[str] = None, invite_msg: str = '',
) -> None:
if circle: return
self.ctrl.send_reply('INVITE', self.bs.user.email, chat.ids['main'], source = inviter.email)
def on_declined_chat_invite(self, chat: Chat, circle: bool = False) -> None:
pass
def on_added_me(self, user: User, *, adder_id: Optional[str] = None, message: Optional[TextWithData] = None) -> None:
self.ctrl.send_reply('NOTICE', ":{} has added you to their friends list".format(user.email), source = user.email)
if message:
self.ctrl.send_reply('NOTICE', ":\"{}\"".format(message.text), source = user.email)
def on_removed_me(self, user: User) -> None:
pass
def on_contact_request_denied(self, user_added: User, message: Optional[str], *, contact_id: Optional[str] = None) -> None:
self.ctrl.send_reply('NOTICE', ":{} has declined your friend request".format(user_added.email), source = user_added.email)
if message:
self.ctrl.send_reply('NOTICE', ":\"{}\"".format(message), source = user_added.email)
def on_oim_sent(self, oim: 'OIM') -> None:
pass
def on_login_elsewhere(self, option: LoginOption) -> None:
if option is LoginOption.BootOthers:
self.ctrl.send_reply('NOTICE', ":You are being booted because you are logging in from another location.")
else:
self.ctrl.send_reply('NOTICE', ":You are now logged in from multiple locations.")
def on_close(self) -> None:
self.ctrl.close()
class ChatEventHandler(event.ChatEventHandler):
__slots__ = ('ctrl', 'cs')
ctrl: IRCCtrl
cs: ChatSession
def __init__(self, ctrl: IRCCtrl) -> None:
self.ctrl = ctrl
def on_close(self) -> None:
self.ctrl.chat_sessions.pop(self.cs.chat, None)
def on_participant_joined(self, cs_other: ChatSession, first_pop: bool, initial_join: bool) -> None:
if first_pop:
self.ctrl.send_reply('JOIN', self.cs.chat.ids['irc'], source = cs_other.user.email)
def on_participant_left(self, cs_other: ChatSession, last_pop: bool) -> None:
if last_pop:
self.ctrl.send_reply('PART', self.cs.chat.ids['irc'], source = cs_other.user.email)
def on_chat_invite_declined(
self, chat: Chat, invitee: User, *, invitee_id: Optional[str] = None, message: Optional[str] = None, circle: bool = False,
) -> None:
if circle: return
self.ctrl.send_reply('NOTICE', ":{} declined the invitation".format(invitee.email), source = invitee.email)
if message:
self.ctrl.send_reply('NOTICE', ":\"{}\"".format(message), source = invitee.email)
def on_chat_updated(self) -> None:
pass
def on_chat_roster_updated(self) -> None:
pass
def on_participant_status_updated(self, cs_other: ChatSession, first_pop: bool, initial: bool, old_substatus: Substatus) -> None:
pass
def on_message(self, data: MessageData) -> None:
if data.type is not MessageType.Chat:
return
if data.text is None:
return
self.ctrl.send_reply('PRIVMSG', self.cs.chat.ids['irc'], ':' + data.text, source = data.sender.email)
class IRCReader:
__slots__ = ('_logger', '_data')
_logger: Logger
_data: bytes
def __init__(self, logger: Logger) -> None:
self._logger = logger
self._data = b''
def data_received(self, data: bytes) -> Iterable[List[str]]:
if self._data:
self._data += data
else:
self._data = data
while self._data:
m = self._read()
if m is None: break
self._logger.debug('[Client]', *m)
yield m
def _read(self) -> Optional[List[str]]:
try:
i = self._data.index(b'\r\n')
except IndexError:
return None
except ValueError:
return None
chunk = self._data[:i].decode('utf-8')
self._data = self._data[i+2:]
# TODO: Support @foo :bar prefixes
toks = []
while True:
chunk = chunk.lstrip(' ')
if chunk[:1] == ':':
toks.append(chunk[1:])
break
k = chunk.find(' ')
if k < 0:
tok = chunk
else:
tok = chunk[:k]
chunk = chunk[k:]
if tok:
toks.append(tok)
if k < 0:
break
return toks
class IRCWriter:
__slots__ = ('_logger', '_buf')
_logger: Logger
_buf: io.BytesIO
def __init__(self, logger: Logger) -> None:
self._logger = logger
self._buf = io.BytesIO()
def write(self, m: Iterable[Any]) -> None:
self._logger.debug('[Server]', *m)
self._buf.write(' '.join(map(str, m)).encode('utf-8'))
self._buf.write(b'\r\n')
def flush(self) -> bytes:
data = self._buf.getvalue()
if data:
self._buf = io.BytesIO()
return data
class Err(IntEnum):
UnknownError = 400
UnknownCommand = 421
NoNicknameGiven = 431
NicknameInUse = 433
PasswdMismatch = 464
YoureBannedCreep = 465
InviteOnlyChan = 473
class RPL(IntEnum):
Welcome = 1
List = 322
ListEnd = 323
NamReply = 353
ChannelModeIs = 324
Inviting = 341
WhoReply = 352
MOTDStart = 375
MOTD = 372
MOTDEnd = 376
UnAway = 305
NowAway = 306
Away = 301
Version = 351
Time = 391
+61
View File
@@ -0,0 +1,61 @@
from typing import Optional, Callable
import asyncio, settings
from core.backend import Backend
from util.misc import Logger
from .ctrl import IRCCtrl
def register(loop: asyncio.AbstractEventLoop, backend: Backend, *, devmode: bool = False) -> None:
from util.misc import ProtocolRunner
backend.add_runner(ProtocolRunner('0.0.0.0', 6667, ListenerIRC, args = ['IRC', backend, IRCCtrl], service = 'IRC'))
if settings.ENABLE_FRONT_IRC_SSL:
if devmode:
from brutus import Brutus
ssl_context = Brutus('CrossTalk').create_ssl_context()
else:
from core.tls import TLSContext
ssl_context = TLSContext(settings.CERT_ROOT, settings.CERT_DIR).create_ssl_context()
backend.add_runner(ProtocolRunner('0.0.0.0', 6697, ListenerIRC, args = ['IRC + TLS', backend, IRCCtrl], ssl_context = ssl_context, service = 'IRC/TLS'))
class ListenerIRC(asyncio.Protocol):
logger: Logger
backend: Backend
controller: IRCCtrl
transport: Optional[asyncio.WriteTransport]
def __init__(self, logger_prefix: str, backend: Backend, controller_factory: Callable[[Logger, str, Backend], IRCCtrl]) -> None:
super().__init__()
self.logger = Logger(logger_prefix, self)
self.backend = backend
self.controller = controller_factory(self.logger, 'direct', backend)
self.controller.close_callback = self._on_close
self.transport = None
def connection_made(self, transport: asyncio.BaseTransport) -> None:
assert isinstance(transport, asyncio.WriteTransport)
self.transport = transport
self.logger.log_connect()
def connection_lost(self, exc: Optional[Exception]) -> None:
self.controller.close()
self.logger.log_disconnect()
self.transport = None
def data_received(self, data: bytes) -> None:
transport = self.transport
assert transport is not None
if self.backend.maintenance_mode:
transport.close()
return
self.controller.transport = None
if self.controller.transport is None:
self.controller.transport = self.transport
self.controller.data_received(data)
transport.write(self.controller.flush())
self.controller.transport = transport
def _on_close(self) -> None:
if self.transport is None: return
self.transport.close()
+4
View File
@@ -0,0 +1,4 @@
https://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands
https://tools.ietf.org/html/rfc1459
https://modern.ircdocs.horse
https://www.alien.net.au/irc/irc2numerics.html
+1
View File
@@ -0,0 +1 @@
from .entry import register
+614
View File
@@ -0,0 +1,614 @@
import asyncio
import base64
import io
import random
import secrets
import hashlib
from core import event
from core.backend import Backend, BackendSession, Chat
from core.client import Client
from core.models import LoginOption, Contact, Substatus, User, TextWithData, OIM, Circle, CircleRole, List
from settings import TARGET_HOST
from util.misc import Logger
from typing import Optional, Callable, Dict, Iterable, Any
from arc4 import ARC4
from .misc import get_grouped_contacts, unmarshal_msim_dict, CommandBitFlag, get_contact_groups
last_sesskey = 0
class MSIMCtrl:
__slots__ = (
'logger',
'reader',
'writer',
'close_callback',
'closed',
'transport',
'backend',
'bs',
'client',
'nonce',
'sesskey',
'keep_alive_task'
)
# Escargot-specific
logger: Logger
reader: 'MSIMReader'
writer: 'MSIMWriter'
close_callback: Optional[Callable[[], None]]
closed: bool
transport: Optional[asyncio.WriteTransport]
backend: Backend
bs: Optional[BackendSession]
client: Client
# Frontend-specific
nonce: bytes
sesskey: int
keep_alive_task: Optional[asyncio.Task]
def __init__(self, logger: Logger, via: str, backend: Backend) -> None:
self.logger = logger
self.reader = MSIMReader(logger)
self.writer = MSIMWriter(logger)
self.close_callback = None
self.closed = False
self.transport = None
self.backend = backend
self.bs = None
self.client = Client('msim', '?', via)
global last_sesskey
last_sesskey += 1
self.nonce = secrets.token_bytes(64)
self.sesskey = last_sesskey
self.keep_alive_task = None
def _m_login2(self, data_pairs: Dict[str, str]) -> None:
email = data_pairs['username']
response = base64.b64decode(data_pairs['response'])
clientver = data_pairs['clientver']
valid = False
# get nc1 & nc2 (first/last 0x20 bytes respectively)
nc1, nc2 = self.nonce[:32], self.nonce[32:]
# log what we got
self.logger.info('Packet email:', email)
self.logger.info('Packet response:', response)
self.logger.info('Packet clientver:', clientver)
if (uuid := self.backend.util_get_uuid_from_email(email)) is None:
self.logger.info('E-mail not found!')
else:
# get our hashed password
hashed_pwd = self.backend.user_service.msim_get_sha1_password(email)
if hashed_pwd is None:
self.logger.info('MySpaceIM frontend-specific password not found!')
else:
final_hash = hashlib.sha1(b''.join([hashed_pwd, nc2])).digest()
rc4_key = final_hash[:16] # we only need the first 128 bits of the result
self.logger.info('Hashed password:', hashed_pwd.hex(' '))
self.logger.info('Full hash:', final_hash.hex(' '))
self.logger.info('RC4 key:', rc4_key.hex(' '))
arc4 = ARC4(rc4_key)
blob = arc4.decrypt(response)
self.logger.info('RC4 blob data:', blob)
seperator = blob.find(bytes(4))
if seperator != -1:
blob_nc1 = blob[:32]
blob_email = blob[32:seperator]
self.logger.info('nc1 (context):', nc1)
self.logger.info('nc1 (request):', blob_nc1)
self.logger.info('E-mail (blob):', blob_email)
if nc1 == blob_nc1 and email == blob_email.decode():
valid = True
# allow user in if valid flag was set
if valid:
# set client to use `clientver`
self.client = Client('msim', f'1.0.{clientver}.0', self.client.via)
# set BackendSession
self.bs = self.backend.login(uuid, self.client, BackendEventHandler(self), option=LoginOption.BootOthers)
# log that they successfully signed in and send reply giving sesskey / user id / username / etc
self.logger.info(email, "successfully signed-in!")
self.send_reply({
'lc': 2,
'sesskey': self.sesskey,
'proof': random.randint(0x00000, 0xFFFFF),
'userid': self.bs.user.id,
'profileid': self.bs.user.id,
'uniquenick': self.bs.user.username,
'id': 1
})
# start 180-second timer to send keep-alives periodically
self.keep_alive_task = asyncio.create_task(self.send_keep_alive_periodically())
else:
self.send_reply({
'error': True,
'errmsg': 'The password provided is incorrect.',
'err': 260,
'fatal': True
})
self.close()
def _m_persist(self, data_pairs: Dict[str, str]) -> None:
bs = self.bs
user = bs.user
detail = user.detail
# get cmd, dsn, lid (command type/family/subcode respectively)
cmd = int(data_pairs['cmd']) # i.e. 1 - Get, 2 - Action, 3 - Delete
dsn = int(data_pairs['dsn'])
lid = int(data_pairs['lid'])
# get request/response ID
rid = int(data_pairs['rid'])
# get body
body = data_pairs['body']
def get_user_by_id(id: int) -> Optional[User]:
if (uuid := self.backend.util_get_uuid_from_user_id(id)) is None:
self.logger.info('User ID', id, 'not found!')
self.send_persist_error(cmd, dsn, lid, rid, f'User ID {id} not found')
return None
found_user = self.backend._load_user_record(uuid)
if found_user is None:
self.logger.info('Unable to find uuid')
self.send_persist_error(cmd, dsn, lid, rid, 'Unable to find uuid')
return None
return found_user
match (cmd, dsn, lid):
# 1;0;1 - list all contacts
case (1, 0, 1):
msim_contacts = []
grouped_contacts = get_grouped_contacts(self.bs)
pos = 0
for group, contacts in grouped_contacts.items():
for contact in contacts:
head = contact.head
pos += 1
# For some reason, the MySpaceIM devs made it UNIX time in nano-seconds.
# *Ahem* Kill me.
last_login = int(head.date_login.timestamp() * 1e9)
msim_contacts.append({
'ContactID': head.id,
'Headline': '?', # Status
'Position': pos,
'GroupName': group,
'Visibility': 1,
'AvatarUrl': '',
'ShowAvatar': False, # No avatar yet xd
'LastLogin': last_login,
'IMName': head.username,
'NickName': head.username,
'NameSelect': 0, # 0 = nickname, 1 = email, 2 = email address
'OfflineMsg': '',
'SkyStatus': 0
})
self.send_persist_reply(cmd, dsn, lid, rid, msim_contacts)
# 1;2;6 - list all contact groups
case (1, 2, 6):
msim_groups = []
id = 0
for group in get_contact_groups(bs):
id += 1
msim_groups.append({
'GroupID': id,
'GroupName': group,
'Position': id,
'GroupFlag': 131073 # unclear what GroupFlag does, TODO(subpurple): figure it out
})
# self.send_persist_reply(cmd, dsn, lid, rid, msim_groups)
# 1;1;4 or 1;1;7 - look-up MySpaceIM-specific user info about yourself or by user ID
#
# 1;1;4 - should lookup self
# 1;1;7 - should lookup by given user ID
# - contains `UserID` field that 1;1;7 does not
case (1, 1, 4) | (1, 1, 7):
# default to our user id unless we are given a 1;1;4 persist message
user_id = self.bs.user.id
if lid == 7:
body_dict = unmarshal_msim_dict(body)
user_id = body_dict['UserID']
if (user := get_user_by_id(user_id)) is None:
pass
self.send_persist_reply(cmd, dsn, lid, rid, {
'UserID': user.id,
'Sound': True,
'!PrivacyMode': 0, # 0 = Anyone, 1 = Only people on my Contact List
'!ShowOnlyToList': False, # False = Anyone, True = Only people on my Contact List.
'!OfflineMessageMode': 0, # 0 = Everyone, 1 = Only people on my Contact List, 2 = No one.
'Headline': '',
'Avatarurl': '',
'Alert': '',
'!ShowAvatar': False,
'IMName': '', # No real way to get this right now so default
'!ClientVersion': 0, # No real way to get this right now so default
'!AllowBrowse': True,
'IMLang': 'English',
'LangID': 8192
})
# 1;4;3 or 1;4;5 - look-up MySpace user info by user ID
#
# 1;4;3 - should lookup by given user ID
# 1;4;5 - should lookup self
case (1, 4, 3) | (1, 4, 5):
body_dict = unmarshal_msim_dict(body)
user_id = body_dict['UserID']
if (user := get_user_by_id(user_id)) is None:
pass
# Since CrossTalk doesn't have a social media platform unlike the original MySpaceIM platform, we simply
# give default values to some of the keys here (e.g. BandName, SongName, Age, Gender, and Location).
self.send_persist_reply(cmd, dsn, lid, rid, {
'UserName': user.username,
'Email': user.email,
'UserID': user.id,
'ImageURL': '',
'DisplayName': user.username,
'BandName': '',
'SongName': '',
'Age': 0,
'Gender': 'M',
'Location': '',
'!TotalFriends': len(user.detail.contacts)
})
# 1;7;18 - query for social media (MySpace) notifications
case (1, 7, 18):
self.send_persist_reply(cmd, dsn, lid, rid, {
# 'Mail': 'On',
# 'BlogComment': 'Off',
# 'ProfileComment': 'Off',
# 'FriendRequest': 'Off',
# 'PictureComment': 'Off'
})
# 1;6;11 - network hyperlink request
case (1, 6, 11):
# e.g. Target=now.FriendID=1
#
# i'm not certain what the appropriate URLs to `Target` would be, but for now we send
# `TARGET_HOST`
body_dict = unmarshal_msim_dict(body)
target = body_dict['Target']
self.logger.info('Target:', target)
self.send_persist_reply(cmd, dsn, lid, rid, {
'WebTicket': TARGET_HOST
})
# 514;0;9 (2^512;0;9) - update contact info
case (514, 0, 9):
self.logger.info('Update contact info')
# 2;1;16 - undocumented
#
# however, based off of the command type (2 - reply), and client packet logs, it appears to be
# update group info
case (2, 2, 16):
self.send_persist_reply(cmd, dsn, lid, rid, '')
case _:
self.logger.info(f'Unknown persist command: {cmd};{dsn};{lid}')
def on_connect(self) -> None:
self.send_reply({
'lc': 1,
'nc': self.nonce,
'id': 1
})
def on_data_recieved(self, data: bytes, *, transport: Optional[asyncio.BaseTransport] = None) -> None:
if transport is None:
transport = self.transport
assert transport is not None
for m in self.reader.data_recieved(data):
# get command, which is always the first key
command = next(iter(m))
# run `_m_xxx` where xxx is the command if found in class, otherwise log that we didn't find it
try:
f = getattr(self, f'_m_{command}')
f(m)
except AttributeError:
self.logger.info('Invalid command:', command)
def send_reply(self, data_pairs: Dict[str, int | str | bytes | bool]) -> None:
self.writer.write(data_pairs)
transport = self.transport
if transport is not None:
transport.write(self.flush())
def send_persist_reply(self, cmd: int, dsn: int, lid: int, rid: int, body: Any) -> None:
self.send_reply({
'persistr': True,
'uid': self.bs.user.id,
'cmd': cmd ^ CommandBitFlag.CallbackReply,
'dsn': dsn,
'lid': lid,
'rid': rid,
'body': body
})
def send_persist_error(self, cmd: int, dsn: int, lid: int, rid: int, error_msg: str) -> None:
self.send_reply({
'persistr': True,
'cmd': cmd ^ CommandBitFlag.CallbackError,
'dsn': dsn,
'uid': self.bs.user.id,
'lid': lid,
'rid': rid,
'ErrorMessage': error_msg
})
async def send_keep_alive_periodically(self):
while True:
await asyncio.sleep(180)
self.send_reply({
'ka': True
})
def flush(self) -> bytes:
return self.writer.flush()
def close(self) -> None:
if self.closed:
return
self.closed = True
if self.close_callback:
self.close_callback()
if self.bs:
self.bs.close()
class BackendEventHandler(event.BackendEventHandler):
__slots__ = ('ctrl', 'bs')
ctrl: MSIMCtrl
def __init__(self, ctrl: MSIMCtrl) -> None:
self.ctrl = ctrl
def on_maintenance_message(self, *args: Any, **kwargs: Any) -> None:
self.ctrl.logger.info('on_maintenance message')
pass
def on_maintenance_boot(self) -> None:
self.ctrl.logger.info('on_maintenance_boot')
pass
def on_presence_notification(
self, ctc: Contact, on_contact_add: bool, old_substatus: Substatus, *,
trid: Optional[str] = None, update_status: bool = True, update_info_other: bool = True,
send_status_on_bl: bool = False, sess_id: Optional[int] = None,
updated_phone_info: Optional[Dict[str, Any]] = None,
) -> None:
self.ctrl.logger.info('on_presence_notification')
pass
def on_presence_self_notification(self, old_substatus: Substatus, *, update_status: bool = True,
update_info: bool = True) -> None:
self.ctrl.logger.info('on_presence_self_notification')
pass
def on_chat_invite(
self, chat: Chat, inviter: User, *, circle: bool = False, inviter_id: Optional[str] = None,
invite_msg: str = '',
) -> None:
self.ctrl.logger.info('on_chat_invite')
pass
def on_declined_chat_invite(self, chat: Chat, circle: bool = False) -> None:
self.ctrl.logger.info('on_declined_chat_invite')
pass
def on_added_me(self, user: User, *, adder_id: Optional[str] = None,
message: Optional[TextWithData] = None) -> None:
self.ctrl.logger.info('on_added_me')
pass
def on_removed_me(self, user: User) -> None:
self.ctrl.logger.info('on_removed_me')
pass
def on_contact_request_denied(self, user_added: User, message: Optional[str], *,
contact_id: Optional[str] = None) -> None:
self.ctrl.logger.info('on_contact_request_denied')
pass
def on_oim_sent(self, oim: OIM) -> None:
self.ctrl.logger.info('on_oim_sent')
pass
def on_login_elsewhere(self, option: LoginOption) -> None:
self.ctrl.logger.info('on_login_elsewhere')
pass
def on_circle_invite_revoked(self, chat_id: str) -> None:
self.ctrl.logger.info('on_circle_invite_revoked')
pass
def on_accepted_circle_invite(self, circle: Circle) -> None:
self.ctrl.logger.info('on_accepted_circle_invite')
pass
def on_circle_updated(self, circle: Circle) -> None:
self.ctrl.logger.info('on_circle_updated')
pass
def on_left_circle(self, circle: Circle) -> None:
self.ctrl.logger.info('on_left_circle')
pass
def on_circle_role_updated(self, chat_id: str, role: CircleRole) -> None:
self.ctrl.logger.info('on_circle_role_updated')
pass
def on_circle_created(self, circle: Circle) -> None:
self.ctrl.logger.info('on_circle_created')
pass
def on_close(self) -> None:
self.ctrl.close()
class MSIMReader:
__slots__ = ('_logger', '_buf')
_logger: Logger
_buf: bytes
def __init__(self, logger: Logger) -> None:
self._logger = logger
self._buf = b''
def data_recieved(self, data: bytes) -> Iterable[Dict[str, str]]:
self._buf += data
while self._buf:
m = self._read()
if m is None:
break
yield m
def _read(self) -> Optional[Dict[str, str]]:
# e.g.
# >>> \lc\1\nc\b'YFKltYx6p9Ve2YE+jX9aJjLxynwgzkdi+nOZqZZufXE='\id\1\final\
# <<< \login2\196610\username\toxidation@msn.com\response\bFKdo4E01WHpwimji5wdSgnjifhV7zv1mGg+ZzHSKqaO4bjV0uq9MzMU9Nk0UmzTFN+nI/u2KUf7fuM=\clientver\673\reconn\0\status\100\id\1\final\
#
# each message is terminated with \final\
try:
i = self._buf.index(b'\\final\\')
except (IndexError, ValueError):
return None
# extract message up to \final\`
data = self._buf[:i + len(b'\\final\\')].decode('utf-8')
# advance buffer to exclude `data`
self._buf = self._buf[i + len(b'\\final\\'):]
# log what we got
self._logger.debug('[Client]', data)
# split string by `\` and skip first member due to leading backslash
parts = data.split('\\')[1:]
# convert `parts` into dict by treating first member as key, second member as value, and so on
data_pairs = {}
for i in range(0, len(parts), 2):
key = parts[i]
value = parts[i + 1] if i + 1 < len(parts) else ""
data_pairs[key] = value
return data_pairs
class MSIMWriter:
__slots__ = ('_logger', '_buf')
_logger: Logger
_buf: io.BytesIO
def __init__(self, logger: Logger) -> None:
self._logger = logger
self._buf = io.BytesIO()
def write(self, data_pairs: Dict[str, Any]) -> None:
m = ''
for key, value in data_pairs.items():
m += f'\\{key}'
# skip over if value is bool and it isn't True
if isinstance(value, bool):
if not value:
continue
# otherwise, add \1 as the value pair
m += '\\1'
continue
# MySpaceIM dictionaries are e.g.
# k1=v2\x1ck2=v3
#
# which then deserialize to:
# k1: v2
# k2: v3
if isinstance(value, list):
m += '\\'
for d in value:
if isinstance(d, dict):
m += '\x1c'.join(f'{key}={value}' for key, value in d.items())
elif isinstance(value, dict):
m += '\\'
m += '\x1c'.join(f'{key}={value}' for key, value in value.items())
# encode `value` in base64 and add that as its value
elif isinstance(value, bytes):
b = base64.b64encode(value)
m += f'\\{b.decode('ascii')}'
# treat any other type (e.g. int or str) not seen above as a string
else:
m += f'\\{value}'
m += '\\final\\'
self._logger.debug('[Server]', m)
self._buf.write(m.encode('utf-8'))
def flush(self) -> bytes:
data = self._buf.getvalue()
if data:
self._buf = io.BytesIO()
return data
+64
View File
@@ -0,0 +1,64 @@
import asyncio
import settings
from aiohttp import web
from core.backend import Backend
from typing import Optional, Callable
from util.misc import Logger, ProtocolRunner
from . import http
from .ctrl import MSIMCtrl
def register(loop: asyncio.AbstractEventLoop, backend: Backend, http_app: web.Application) -> None:
# Port 6660 is used here due to being symbolic with the 2nd port it tries, however in practice it always
# connects to port 1863 first. Set the key "HKEY_CURRENT_USER\Software\MySpace\IM\LastConnectedPort" to 6660
# in order to prevent this. If it doesn't exist, add it as a DWORD.
backend.add_runner(ProtocolRunner('0.0.0.0', 6660, ListenerMSIM, args=['MySpaceIM', backend, MSIMCtrl], service="MSIM"))
# Register HTTP routes for e.g. advertisements
http.register(http_app)
class ListenerMSIM(asyncio.Protocol):
logger: Logger
backend: Backend
controller: MSIMCtrl
transport: Optional[asyncio.WriteTransport]
def __init__(self, logger_prefix: str, backend: Backend, controller_factory: Callable[[Logger, str, Backend], MSIMCtrl]) -> None:
super().__init__()
self.logger = Logger(logger_prefix, self)
self.backend = backend
self.controller = controller_factory(self.logger, 'direct', backend)
self.controller.close_callback = self._on_close
self.transport = None
def connection_made(self, transport: asyncio.BaseTransport) -> None:
assert isinstance(transport, asyncio.WriteTransport)
self.transport = transport
self.controller.transport = transport
self.logger.log_connect()
self.controller.on_connect()
def connection_lost(self, exc: Optional[Exception]) -> None:
self.controller.close()
self.logger.log_disconnect()
self.transport = None
def data_received(self, data: bytes) -> None:
transport = self.transport
assert transport is not None
if self.backend.maintenance_mode:
self.transport.close()
return
self.controller.on_data_recieved(data)
transport.write(self.controller.flush())
def _on_close(self) -> None:
if self.transport is not None:
self.transport.close()
+11
View File
@@ -0,0 +1,11 @@
import settings
from aiohttp import web
def register(app: web.Application) -> None:
# http://myspace.com/html.ng/site=myspace&page=30000001&position=imbut&rand=9879
app.router.add_get('/html.ng/{tail:.*}', handle_client_advert)
async def handle_client_advert(request: web.Request) -> web.Response:
return web.HTTPFound(f'http://{settings.AD_HOST}y/ads/banner-sq')
+66
View File
@@ -0,0 +1,66 @@
from enum import IntEnum
from typing import Dict
from core.backend import BackendSession
from core.models import ContactList, Contact
class CommandBitFlag(IntEnum):
CallbackReply = 256,
CallbackAction = 512,
CallbackError = 1024
def get_grouped_contacts(bs: BackendSession) -> Dict[str, list[Contact]]:
user = bs.user
detail = user.detail
contacts = list({
*detail.get_contacts_by_list(ContactList.AL),
*detail.get_contacts_by_list(ContactList.FL)
})
grouped_contacts = {}
# loop through every contact group
for group in detail._groups_by_id.values():
grouped_contacts[group.name] = []
# loop through every contact in this group
for contact in contacts:
for grp in contact._groups:
if grp.id == group.id:
grouped_contacts[group.name].append(contact)
# handle any contacts that might not be apart of any group
if ungrouped_contacts := [contact for contact in contacts if not contact._groups]:
grouped_contacts['(No Group)'] = []
for contact in ungrouped_contacts:
grouped_contacts['(No Group)'].append(contact)
return grouped_contacts
def get_contact_groups(bs: BackendSession) -> list[str]:
groups = []
user = bs.user
detail = user.detail
contacts = list({
*detail.get_contacts_by_list(ContactList.AL),
*detail.get_contacts_by_list(ContactList.FL)
})
for group in detail._groups_by_id.values():
groups.append(group.name)
# add a fake `(No Group)` group if there is any contacts not apart of any group
if any(not contact._groups for contact in contacts):
groups.append('(No Group)')
return groups
def unmarshal_msim_dict(data: str) -> Dict:
return dict(pair.split('=', 1) for pair in data.split('\x1c'))
+1
View File
@@ -0,0 +1 @@
from .entry import register
+62
View File
@@ -0,0 +1,62 @@
from typing import Optional, Callable
import asyncio, settings
from aiohttp import web
from core.backend import Backend
from util.misc import Logger
from .msnp import MSNPCtrl
def register(loop: asyncio.AbstractEventLoop, backend: Backend, http_app: web.Application) -> None:
from util.misc import ProtocolRunner
from . import msnp_dp, msnp_ns, msnp_sb
from .http import appdirectory, abservice, gateway, other
backend.add_runner(ProtocolRunner('0.0.0.0', 1863, ListenerMSNP, args = ['MSNP Dispatch', backend, msnp_dp.MSNPCtrlDP], service = 'MSNP Dispatch'))
backend.add_runner(ProtocolRunner('0.0.0.0', 1864, ListenerMSNP, args = ['MSNP Notification', backend, msnp_ns.MSNPCtrlNS], service = 'MSNP Notification'))
backend.add_runner(ProtocolRunner('0.0.0.0', 1865, ListenerMSNP, args = ['MSNP Switchboard', backend, msnp_sb.MSNPCtrlSB], service = "MSNP Switchboard"))
appdirectory.register(http_app)
other.register(http_app)
abservice.register(http_app)
gateway.register(loop, http_app)
class ListenerMSNP(asyncio.Protocol):
logger: Logger
backend: Backend
controller: MSNPCtrl
transport: Optional[asyncio.WriteTransport]
def __init__(self, logger_prefix: str, backend: Backend, controller_factory: Callable[[Logger, str, Backend], MSNPCtrl]) -> None:
super().__init__()
self.logger = Logger(logger_prefix, self)
self.backend = backend
self.controller = controller_factory(self.logger, 'direct', backend)
self.controller.close_callback = self._on_close
self.transport = None
def connection_made(self, transport: asyncio.BaseTransport) -> None:
assert isinstance(transport, asyncio.WriteTransport)
self.transport = transport
self.logger.log_connect()
self.controller.on_connect()
def connection_lost(self, exc: Optional[Exception]) -> None:
self.controller.close()
self.logger.log_disconnect()
self.transport = None
def data_received(self, data: bytes) -> None:
transport = self.transport
assert transport is not None
# Setting `transport` to None so all data is held until the flush
self.controller.transport = None
if self.controller.transport is None:
self.controller.transport = self.transport
self.controller.data_received(data)
transport.write(self.controller.flush())
self.controller.transport = transport
def _on_close(self) -> None:
if self.transport is None: return
self.transport.close()
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
from .impl import DB
@@ -0,0 +1,28 @@
{
"id": 10351359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Nine Men's Morris",
"description": "A 9 pieces Tic-Tac-Toe spin-off. Originally developed by Doron for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/morris/index.en-us.html",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/morris/imgs/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 10361359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Nine Men's Morris",
"description": "A 9 pieces Tic-Tac-Toe spin-off (Hebrew). Originally developed by Doron for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/morris/index.he-il.html",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/morris/imgs/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 20701359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Backgammon",
"description": "The game of luck and skill. Originally developed by Koen for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/backgammon/backgammon.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/backgammon/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 10311359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Battleships",
"description": "Sink your opponent's fleet. Originally developed by Koen for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/battleships/battleships.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/battleships/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 10321359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Chess",
"description": "The king's game. Originally developed by Koen for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/chess/chess.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/chess/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 10531359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Connect 4",
"description": "Four in a row. Originally developed by Koen for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/connect4/connect4.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/connect4/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 10601359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Memory",
"description": "Find the matching pairs. Originally developed by Koen for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/memory/memory.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/memory/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 10291359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Reversi",
"description": "Also known as Othello. Originally developed by Koen for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/reversi/reversi.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/reversi/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 20601359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Tetris",
"description": "The simple, highly addictive, real-time puzzle game. Originally developed by Koen for games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/tetris/tetris.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/tetris/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": true,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 10301359,
"kids": true,
"page": 1,
"category_id": 102,
"name": "Yahtzee",
"description": "The famous dice game. Originally developed by Koen of games.mess.be",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/yahtzee/yahtzee.htm",
"icon_url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/messbe/yahtzee/images/icon.png",
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": true,
"max_packet_rate": 120,
"user_properties": false,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
@@ -0,0 +1,28 @@
{
"id": 101,
"kids": true,
"page": 1,
"category_id": 101,
"name": "Tic Tac Toe",
"description": "Play against your friends in a game of Tic Tac Toe. Originally developed by Microsoft.",
"url": "http://mactivities.msgrsvcs.ctsrv.gay/static/app-data/tic-tac-toe/tictactoe.htm",
"icon_url": null,
"type": "dir",
"height": 500,
"width": 500,
"location": "side",
"min_users": 2,
"max_users": 2,
"enable_ip": false,
"activex": false,
"send_file": false,
"send_im": false,
"receive_im": false,
"replace_im": false,
"windows": false,
"max_packet_rate": 120,
"user_properties": false,
"minimum_client_version": null,
"app_type": 0,
"hidden": false
}
+20
View File
@@ -0,0 +1,20 @@
[
{
"id": 100,
"app_type": 1,
"name": "CrossTalk",
"description": null
},
{
"id": 101,
"app_type": 0,
"name": "Microsoft",
"description": null
},
{
"id": 102,
"app_type": 0,
"name": "Mess.be Games",
"description": null
}
]
+30
View File
@@ -0,0 +1,30 @@
from typing import Dict, Any
import json
from pathlib import Path
class DB:
def __init__(self):
dir_path = Path(__file__).parent # Change 'dir' to 'dir_path'
self.categories = [
Category(c)
for c in json.loads((dir_path / 'category.json').read_text())
]
app_dir = dir_path / 'app' # Change 'dir' to 'dir_path'
self.apps = {
locale.name: [
App(json.loads(f.read_text()), locale.name)
for f in (app_dir / locale).glob('*.json')
] for locale in (app_dir).iterdir() if locale.is_dir()
}
class Base:
def __init__(self, json: Dict[str, Any]) -> None:
self.__dict__.update(json)
class Category(Base): pass
class App(Base):
def __init__(self, json: Dict[str, Any], locale: str) -> None:
super().__init__(json)
self.locale = (None if locale == 'none' else locale)
+260
View File
@@ -0,0 +1,260 @@
from aiohttp import web
import lxml, jinja2, secrets, util.misc
from markupsafe import Markup
from .util import render, preprocess_soap
from .appdirdb import DB
TMPL_DIR = 'front/msn/http/tmpl/appdir'
def register(app: web.Application) -> None:
util.misc.add_to_jinja_env(app, 'appdir', TMPL_DIR, globals = {
'bool_to_str': _bool_to_str,
})
# Version cacche
app.router.add_get('/AppDirectory/GetAppdirVersion.aspx', handle_getappdirversion)
# AppDirctory SOAP service
app.router.add_get('/AppDirectory/AppDirectory.asmx', handle_appdirectory)
app.router.add_post('/AppDirectory/AppDirectory.asmx', handle_appdirectory)
app.router.add_get(r'/~Live.ConfigServer/{junk:.*}/~op-GetFilteredDataSet2/', handle_appdirectory)
app.router.add_get(r'/~Live.ConfigServer/{junk:.*}/~op-GetFilteredDataSet2/{tail:.*}', handle_appdirectory)
# Activities page
app.router.add_get('/AppDirectory/Directory.aspx', page_directory)
async def handle_getappdirversion(req):
return render(req, 'appdir:GetAppdirVersion.html', {
'version': secrets.token_urlsafe(128),
})
async def handle_appdirectory(req):
action = None
action_str = None
ver = ''
seg_args = {}
if req.method == 'POST':
action = await _preprocess_soap(req)
if action is None:
return web.Response(status=500, text='')
action_str = _get_tag_localname(action)
elif req.method == 'GET':
if 'op' in req.query:
action_str = req.query.get('op')
ver = req.query.get('ver', '')
elif req.match_info.get('tail') is not None:
action_str = 'GetFilteredDataSet2'
parts = [p for p in req.match_info['tail'].split('/') if p]
for seg in parts:
if not seg.startswith('~') or '-' not in seg:
continue
key, val = seg[1:].split('-', 1)
seg_args[key.lower()] = val
ver = seg_args.get('ts', '')
seg_args['locale'] = seg_args.get('locale')
try:
seg_args['page'] = int(seg_args.get('page', 0))
seg_args['kids'] = int(seg_args.get('kids', -1))
seg_args['app_type'] = int(seg_args.get('apptype', 0))
except ValueError:
return web.Response(status=500, text='')
else:
return web.Response(status=500, text='')
else:
return web.Response(status=405, text='')
if action_str == 'GetFullDataSet':
results = []
db = DB()
for apps_locale in db.apps.values():
results.extend([_create_entry_container(req, i, entry) for i, entry in enumerate(apps_locale)])
results.extend([_create_category(req, 'en-US', category, i) for i, category in enumerate(db.categories)])
if req.method == 'POST':
diffgram = _create_diffgram(req, Markup(''.join(results)))
return render(req, 'appdir:GetFullDataSetResponse.xml', {'diffgram': Markup(diffgram)})
else:
return render(req, 'appdir:AppDir.xml', {'v': ver, 'results': Markup(''.join(results))})
elif action_str == 'GetFilteredDataSet2':
if req.method == 'POST':
locale = _get_action_argument(req, action, 'locale')
if locale is not None:
locale = str(locale)
try:
page = int(_get_action_argument(req, action, 'Page'))
kids = int(_get_action_argument(req, action, 'Kids'))
app_type = int(_get_action_argument(req, action, 'AppType'))
except:
return web.Response(status=500, text='')
else:
locale = req.query.get('Locale') or seg_args.get('locale')
page = seg_args.get('page') or int(req.query.get('Page', 0))
kids = seg_args.get('kids') or int(req.query.get('Kids', -1))
app_type = seg_args.get('app_type') or int(req.query.get('AppType', 0))
results = []
db = DB()
entries = [app for app in db.apps['none'] if app.page == page and app.app_type == app_type]
if locale and locale in db.apps:
entries.extend([app for app in db.apps[locale] if app.page == page and app.app_type == app_type])
if kids >= 0:
entries = [app for app in entries if app.kids == (kids == 1)]
categories_filtered = []
for category in db.categories:
if category.app_type != app_type:
continue
for entry in entries:
if entry.category_id == category.id:
categories_filtered.append(category)
break
results.extend([_create_entry_container(req, i, entry) for i, entry in enumerate(entries)])
results.extend([_create_category(req, locale, category, i) for i, category in enumerate(categories_filtered)])
if req.method == 'POST':
diffgram = _create_diffgram(req, Markup(''.join(results)))
return render(req, 'appdir:GetFilteredDataSet2Response.xml', {'diffgram': Markup(diffgram)})
else:
return render(req, 'appdir:AppDir.xml', {'v': ver, 'results': Markup(''.join(results))})
elif action_str == 'GetAppEntry':
try:
id = int(_get_action_argument(req, action, 'ID'))
except:
return web.Response(status=500, text='')
entry = None
db = DB()
for apps_locale in db.apps.values():
for app in apps_locale:
if app.id == id:
entry = app
break
if entry is not None:
break
if req.method == 'POST':
entry_markup = None
if entry:
entry_markup = Markup(_create_entry(req, 0, entry))
return render(req, 'appdir:GetAppEntryResponse.xml', {'entry': entry_markup})
else:
if entry:
return web.Response(status=200, content_type='text/xml', text=_create_entry_container(req, 0, entry, extra=f' code="2" v="{ver}"'))
return web.Response(status=200, content_type='text/xml', text='')
else:
return web.Response(status=500, text='')
async def page_directory(req):
app_entries_js = []
results = []
locale = req.query.get('L') or 'en-US'
db = DB()
categories = db.categories
entries = db.apps
category_tmpl = req.app['jinja_env'].get_template('appdir:Directory/Directory.category.html')
entry_tmpl = req.app['jinja_env'].get_template('appdir:Directory/Directory.entry.html')
category_end_tmpl = req.app['jinja_env'].get_template('appdir:Directory/Directory.category.end.html')
for category in categories:
filtered_entries = [
app for app in entries['none']
if app.category_id == category.id
]
if locale and locale in entries:
filtered_entries.extend([
app for app in entries[locale]
if app.category_id == category.id
])
if not filtered_entries:
continue
results.append(category_tmpl.render(
cat_id = category.id,
cat_name = category.name,
))
for entry in filtered_entries:
results.append(entry_tmpl.render(
app_id = entry.id,
description = entry.description,
name = entry.name,
))
app_entries_js.append(APP_ENTRY_JS.format(
entry.id, (1 if entry.kids else 0), entry.min_users, entry.max_users,
))
results.append(category_end_tmpl.render(
cat_id = category.id,
))
return render(req, 'appdir:Directory/Directory.html', {
'app_entries_js': Markup(''.join(app_entries_js)),
'results': Markup(''.join(results)),
})
# TODO: remove and replace with util.preprocess_soap
async def _preprocess_soap(req):
from lxml.objectify import fromstring as parse_xml
body = await req.read()
root = parse_xml(body)
action = _find_element(root, 'Body/*[1]')
return action
def _get_action_argument(req, action, name):
result = None
if req.method == 'POST':
result = _find_element(action, name)
elif req.method == 'GET':
result = req.query.get(name)
return result
def _create_entry_container(req, i, entry, *, extra = None):
entry_container_tmpl = req.app['jinja_env'].get_template('appdir:Entry_container.xml')
if req.method == 'POST':
extra = Markup(' diffgr:id="Entry{}" msdata:rowOrder="{}" diffgr:hasChanges="inserted"'.format(i + 1, i))
elif extra is not None and req.method != 'POST':
extra = Markup(extra)
return entry_container_tmpl.render(
extra = extra,
entry = Markup(_create_entry(req, i, entry)),
)
def _create_entry(req, i, entry):
entry_tmpl = req.app['jinja_env'].get_template('appdir:Entry.xml')
return entry_tmpl.render(entry = entry, i = i)
def _create_category(req, locale, category, i):
category_tmpl = req.app['jinja_env'].get_template('appdir:Category.xml')
extra = None
if req.method == 'POST':
extra = Markup(' diffgr:id="Category{}" msdata:rowOrder="{}" diffgr:hasChanges="inserted"'.format(i + 1, i))
return category_tmpl.render(
extra = extra,
locale = locale,
category = category,
)
def _create_diffgram(req, results):
diffgram_tmpl = req.app['jinja_env'].get_template('appdir:diffgram.xml')
return diffgram_tmpl.render(
results = results,
)
def _get_tag_localname(elm):
return lxml.etree.QName(elm.tag).localname
def _bool_to_str(b):
return 'True' if b else 'False'
def _find_element(xml, query):
thing = xml.find('.//{*}' + query.replace('/', '/{*}'))
if isinstance(thing, lxml.objectify.StringElement):
thing = str(thing)
elif isinstance(thing, lxml.objectify.BoolElement):
thing = bool(thing)
elif isinstance(thing, lxml.objectify.IntElement):
thing = int(thing)
return thing
APP_ENTRY_JS = ''' [{}, [{}, {}, {}, ""]],
'''
+102
View File
@@ -0,0 +1,102 @@
from typing import Dict
import time, asyncio, settings
from aiohttp import web
from util.misc import Logger, gen_uuid
from front.msn.msnp import MSNPCtrl
def register(loop: asyncio.AbstractEventLoop, app: web.Application) -> None:
gateway_sessions = {} # type: Dict[str, GatewaySession]
app['gateway_sessions'] = gateway_sessions
app.router.add_route('OPTIONS', '/gateway/gateway.dll', handle_http_gateway_options)
app.router.add_post('/gateway/gateway.dll', handle_http_gateway)
loop.create_task(_clean_gateway_sessions(gateway_sessions))
async def _clean_gateway_sessions(gateway_sessions: Dict[str, 'GatewaySession']) -> None:
while True:
await asyncio.sleep(10)
now = time.time()
closed = []
for session_id, gwsess in gateway_sessions.items():
if gwsess.time_last_connect + gwsess.timeout <= now:
gwsess.controller.close()
closed.append(session_id)
for session_id in closed:
del gateway_sessions[session_id]
class GatewaySession:
__slots__ = ('logger', 'hostname', 'controller', 'timeout', 'time_last_connect')
logger: Logger
hostname: str
controller: MSNPCtrl
timeout: float
time_last_connect: float
def __init__(self, logger: Logger, hostname: str, controller: MSNPCtrl, now: float) -> None:
self.logger = logger
self.hostname = hostname
self.controller = controller
self.timeout = 60
self.time_last_connect = now
def _on_close(self) -> None:
self.time_last_connect = 0
async def handle_http_gateway_options(req: web.Request) -> web.Response:
return web.HTTPOk(headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Expose-Headers': 'X-MSN-Messenger',
'Access-Control-Max-Age': '86400',
})
async def handle_http_gateway(req: web.Request) -> web.Response:
query = req.query
session_id = query.get('SessionID')
action = query.get('Action')
backend = req.app['backend']
gateway_sessions = req.app['gateway_sessions'] # type: Dict[str, GatewaySession]
now = time.time()
if not session_id:
from front.msn.msnp_ns import MSNPCtrlNS
from front.msn.msnp_sb import MSNPCtrlSB
# Create new GatewaySession
server_type = query.get('Server')
server_ip = query.get('IP') or ''
session_id = gen_uuid()
logger = Logger('MSN {} via HTTP Gateway'.format(server_type), session_id)
if server_type == 'NS':
controller = MSNPCtrlNS(logger, 'gw', backend) # type: MSNPCtrl
else:
controller = MSNPCtrlSB(logger, 'gw', backend)
tmp = GatewaySession(logger, server_ip, controller, now)
controller.close_callback = tmp._on_close
gateway_sessions[session_id] = tmp
gwsess = gateway_sessions.get(session_id)
if gwsess is None:
raise web.HTTPBadRequest()
assert req.transport is not None
if gwsess.time_last_connect != now:
gwsess.time_last_connect = now
if action != 'poll':
gwsess.logger.log_connect()
gwsess.controller.data_received(await req.read(), transport = req.transport)
gwsess.logger.log_disconnect()
body = gwsess.controller.flush()
return web.HTTPOk(headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Expose-Headers': 'X-MSN-Messenger',
'X-MSN-Messenger': 'SessionID={}; GW-IP={}'.format(session_id, settings.TARGET_IP),
'Content-Type': 'application/x-msn-messenger',
}, body = body)
+914
View File
@@ -0,0 +1,914 @@
from typing import Optional, Any, Tuple
from datetime import datetime, timedelta
from io import BytesIO
from email.parser import Parser
from email.header import decode_header
from email.utils import parsedate_to_datetime
from urllib.parse import unquote, parse_qsl
from pathlib import Path
import re, secrets, base64, random, json, mimetypes, uuid, PyRSS2Gen, settings, util.misc
from markupsafe import Markup
from aiohttp import web
from core import models
from core.backend import Backend, BackendSession
from util.avatar import get_img_type, find_avatar_file
from ..misc import gen_mail_data, format_oim, cid_format, puid_format
from .util import find_element, get_tag_localname, render, preprocess_soap, unknown_soap, bool_to_str
LOGIN_PATH = '/login.srf'
TMPL_DIR = 'front/msn/http/tmpl'
ETC_DIR = 'front/msn/etc'
PP = 'Passport1.4'
def register(app: web.Application) -> None:
util.misc.add_to_jinja_env(app, 'msn', TMPL_DIR, globals = {
'date_format': util.misc.date_format,
'cid_format': cid_format,
'puid_format': puid_format,
'bool_to_str': bool_to_str,
'contact_is_favorite': _contact_is_favorite,
'datetime': datetime,
})
# MSN >= 5
app.router.add_get('/nexus-mock', handle_nexus)
app.router.add_get('/rdr/pprdr.asp', handle_nexus)
app.router.add_get(LOGIN_PATH, handle_login)
app.router.add_get('/svcs/mms/tabs.asp', handle_tabs)
app.router.add_get('/svcs/mms/portal.asp', handle_portal)
app.router.add_get('/svcs/mms/ads.asp', handle_msn5ads)
# MSN >= 6
app.router.add_get('/etc/MsgrConfig', handle_msgrconfig)
app.router.add_post('/etc/MsgrConfig', handle_msgrconfig)
# TODO: this is stupid, find a way to make this case-insensitive
app.router.add_get('/Config/MsgrConfig.asmx', handle_msgrconfig)
app.router.add_post('/Config/MsgrConfig.asmx', handle_msgrconfig)
app.router.add_get('/config/MsgrConfig.asmx', handle_msgrconfig)
app.router.add_post('/config/MsgrConfig.asmx', handle_msgrconfig)
app.router.add_get('/start', handle_today)
# MSN >= 7.5
app.router.add_route('OPTIONS', '/NotRST.srf', handle_not_rst)
app.router.add_post('/NotRST.srf', handle_not_rst)
app.router.add_post('/RST.srf', handle_rst)
app.router.add_post('////RST.srf', handle_rst) # libpurple what the FUCK, also this doesn't even work
app.router.add_post('/RST2.srf', lambda req: handle_rst(req, rst2 = True))
# MSN >= 8
app.router.add_post('/storageservice/SchematizedStore.asmx', handle_storageservice)
app.router.add_post('/ppsecure/sha1auth.srf', handle_sha1auth)
app.router.add_post('/rsi/rsi.asmx', handle_rsi)
app.router.add_post('/OimWS/oim.asmx', handle_oim)
app.router.add_get('/svcs/msn-video-feeds/', handle_videofeed)
app.router.add_get('/svcs/feed', lambda req: handle_videofeed(req, get_videos = True))
# MSN >= 14
app.router.add_post('/whatsnew/whatsnewservice.asmx', handle_whatsnew)
app.router.add_get('/svcs/tab={id}', handle_tabs_newer)
# MSN >= 15
app.router.add_post('/sqm/messenger/sqmserver.dll', handle_blankok)
app.router.add_post('/sqm/WindowsLive/sqmserver.dll', handle_blankok)
app.router.add_post('/uploaddata.aspx', handle_blankok)
app.router.add_get('/ppcrlcheck.srf', handle_ppcrlcheck)
app.router.add_post('/profile/profile.asmx', handle_blankok) # TODO: do the thing
app.router.add_get(r'/~Live.ConfigServer/{junk:.*}/~op-GetClientConfig/{tail:.*}', handle_msgrconfig16)
app.router.add_get(r'/~Live.ConfigServer.SuiteUpdate/{tail:.*}', handle_suiteupdate)
app.router.add_get(r'/~Live.ConfigServer.PSA/{tail:.*}', handle_socialint)
app.router.add_get('/svcs/GameBrowser', handle_gamebrowser)
# Misc
app.router.add_get('/{i}meen_{locale}/{id}', handle_msn_redirect)
async def handle_blankok(req: web.Request) -> web.Response:
return web.Response(status = 200)
async def handle_storageservice(req: web.Request) -> web.Response:
backend = req.app['backend']
header, action, bs, token = await preprocess_soap(req)
assert bs is not None
soapaction = (req.headers.get('SOAPAction') or '')
if soapaction.startswith('"') and soapaction.endswith('"'):
soapaction = soapaction[1:-1]
storage_ns = ('w10' if soapaction.startswith('http://www.msn.com/webservices/storage/w10/') else '2008')
action_str = get_tag_localname(action)
now_str = util.misc.date_format(datetime.utcnow())
user = bs.user
cachekey = secrets.token_urlsafe(172)
cid = cid_format(user.uuid)
if action_str == 'GetProfile':
roaming_info = backend.user_service.get_roaming_info(user)
assert roaming_info is not None
# Resolve the active avatar using the md5 stored in users.avatar.
# find_avatar_file returns None if no avatar has been uploaded yet.
avatar_md5 = user.avatar
mime = None
image_size = 0
image_thumb_size = 0
if avatar_md5:
full_file = find_avatar_file(user.uuid, avatar_md5, small=False)
thumb_file = find_avatar_file(user.uuid, avatar_md5, small=True)
if full_file and full_file.is_file():
ext = full_file.suffix.lstrip('.').lower()
mime = ext
image_size = full_file.stat().st_size
if thumb_file and thumb_file.is_file():
image_thumb_size = thumb_file.stat().st_size
return render(req, 'msn:storageservice/GetProfileResponse.xml', {
'storage_ns': storage_ns,
'cachekey': cachekey,
'cid': cid,
'pptoken1': token,
'user': user,
'now': now_str,
'mime': mime,
'size_static': image_size,
'size_small': image_thumb_size,
'roaming_info': roaming_info,
'host': settings.USERSTORAGE_HOST,
})
if action_str == 'FindDocuments':
# TODO: FindDocuments
return render(req, 'msn:storageservice/FindDocumentsResponse.xml', {
'storage_ns': storage_ns,
'cachekey': cachekey,
'cid': cid,
'pptoken1': token,
'user': user,
})
if action_str == 'UpdateProfile':
delete_psm = False
delete_name = False
delete_avatar = False
# TODO: More properties?
# Update to roaming name/message
# ```
# <UpdateProfile xmlns="http://www.msn.com/webservices/storage/w10">
# <profile>
# <ResourceID>862d987eb60b7a63!106</ResourceID>
# <ExpressionProfile>
# <FreeText>Update</FreeText>
# <DisplayName>Society is betrayal</DisplayName>
# <PersonalStatus>Prosperity is the best medicine. :)</PersonalStatus>
# </ExpressionProfile>
# </profile>
# </UpdateProfile>
# ```
# Remove roaming message
# ```
# <UpdateProfile xmlns="http://www.msn.com/webservices/storage/w10">
# <profile>
# <ResourceID>bb4542ce2eacdbde!106</ResourceID>
# <ExpressionProfile>
# <FreeText>Update</FreeText>
# <DisplayName>%walkingphas3r%</DisplayName>
# <Flags>0</Flags>
# </ExpressionProfile>
# </profile>
# <profileAttributesToDelete>
# <ExpressionProfileAttributes>
# <PersonalStatus>true</PersonalStatus>
# </ExpressionProfileAttributes>
# </profileAttributesToDelete>
# </UpdateProfile>
# ```
expression_profile = find_element(action, 'ExpressionProfile')
name = find_element(expression_profile, 'DisplayName')
message = find_element(expression_profile, 'PersonalStatus')
attributes_to_delete = find_element(action, 'profileAttributesToDelete/ExpressionProfileAttributes')
if attributes_to_delete is not None:
# `PersonalStatus` and `DisplayName` is the only known attribute that has the ability to be deleted
delete_psm = find_element(attributes_to_delete, 'PersonalStatus') or False
assert isinstance(delete_psm, bool)
delete_name = find_element(attributes_to_delete, 'DisplayName') or False
assert isinstance(delete_name, bool)
name = find_element(action, 'DisplayName')
message = find_element(action, 'PersonalStatus')
if name:
backend.user_service.save_single_roaming(user, { 'name': name })
if message and not delete_psm:
backend.user_service.save_single_roaming(user, { 'message': message })
if delete_psm:
backend.user_service.save_single_roaming(user, { 'message': '' })
if delete_name:
backend.user_service.save_single_roaming(user, { 'name': '' })
return render(req, 'msn:storageservice/UpdateProfileResponse.xml', {
'storage_ns': storage_ns,
'cachekey': cachekey,
'cid': cid,
'pptoken1': token,
'user': user
})
if action_str == 'DeleteRelationships':
# TODO: DeleteRelationships
return render(req, 'msn:storageservice/DeleteRelationshipsResponse.xml', {
'storage_ns': storage_ns,
'cachekey': cachekey,
'cid': cid,
'pptoken1': token,
'user': user,
})
if action_str in ('CreateDocument', 'UpdateDocument'):
op = 'Update' if action_str == 'UpdateDocument' else 'Create'
return handle_document(req, action, op, storage_ns, user, cid, token, backend)
if action_str == 'CreateRelationships':
# TODO: CreateRelationships
return render(req, 'msn:storageservice/CreateRelationshipsResponse.xml', {
'storage_ns': storage_ns,
'cachekey': cachekey,
'cid': cid,
'pptoken1': token,
'user': user,
})
if action_str in { 'ShareItem' }:
# TODO: ShareItem
return unknown_soap(req, header, action, expected = True)
return unknown_soap(req, header, action)
def handle_document(
req: web.Request,
action: Any,
op_type: str, # 'Create' or 'Update'
storage_ns: str,
user: models.User,
cid: str,
token: str,
backend: Backend,
) -> web.Response:
streamtype = find_element(action, 'DocumentStreamType')
if streamtype == 'UserTileStatic':
raw_b64 = find_element(action, 'Data')
if raw_b64:
try:
data = base64.b64decode(raw_b64)
except Exception:
return web.HTTPInternalServerError(text='')
err = _store_avatar_from_bytes(backend, user, data)
if err is not None:
return err
return render(req, 'msn:storageservice/{}DocumentResponse.xml'.format(op_type), {
'storage_ns': storage_ns,
'cid': cid,
'pptoken1': token,
'user': user,
})
def _store_avatar_from_bytes(
backend: Backend,
user: models.User,
data: bytes,
) -> Optional[web.Response]:
ext = get_img_type(data)
if ext is None:
return web.HTTPInternalServerError(text='AZUL: Unsupported image format')
try:
backend.user_service.save_avatar(user, data, ext)
except Exception:
return web.HTTPInternalServerError(text='')
return None
async def handle_sha1auth(req: web.Request) -> web.Response:
post = await req.post()
token_data = post.get('token')
if token_data is None:
return web.HTTPInternalServerError()
token_fields = dict(parse_qsl(str(token_data)))
if 'ru' not in token_fields:
return web.HTTPInternalServerError()
return web.HTTPFound(token_fields['ru'])
async def handle_ppcrlcheck(req: web.Request) -> web.Response:
response = '<config>\r\n\t<deviceid minversion="16.000.26889.00"/>\r\n\t<mobilecfg minversion="16.000.26208.0"/>\r\n</config>'
return web.HTTPOk(body=response)
async def handle_rsi(req: web.Request) -> web.Response:
_, action, bs, token = await preprocess_soap_rsi(req)
if token is None or bs is None:
return render(req, 'msn:oim/Fault.validation.xml', status = 500)
action_str = get_tag_localname(action)
user = bs.user
backend = req.app['backend']
if action_str == 'GetMetadata':
return render(req, 'msn:oim/GetMetadataResponse.xml', {
'md': gen_mail_data(user, backend, on_ns = False, e_node = False),
})
if action_str == 'GetMessage':
oim_uuid = find_element(action, 'messageId')
oim_markAsRead = find_element(action, 'alsoMarkAsRead')
oim = backend.user_service.get_oim_single(user, oim_uuid, mark_read = oim_markAsRead is True)
return render(req, 'msn:oim/GetMessageResponse.xml', {
'oim_data': format_oim(oim),
})
if action_str == 'DeleteMessages':
messageIds = action.findall('.//{*}messageIds/{*}messageId')
if not messageIds:
return render(req, 'msn:oim/Fault.validation.xml', status = 500)
for messageId in messageIds:
if backend.user_service.get_oim_single(user, str(messageId)) is None:
return render(req, 'msn:oim/Fault.validation.xml', status = 500)
for messageId in messageIds:
backend.user_service.delete_oim(user.uuid, str(messageId))
bs.evt.msn_on_oim_deletion(len(messageIds))
return render(req, 'msn:oim/DeleteMessagesResponse.xml')
return render(req, 'msn:Fault.doesnotexist.xml', { 'action': action_str })
async def handle_oim(req: web.Request) -> web.Response:
header, _, body_content, bs, _ = await preprocess_soap_oimws(req)
soapaction = (req.headers.get('SOAPAction') or '')
if soapaction.startswith('"') and soapaction.endswith('"'):
soapaction = soapaction[1:-1]
owsns = (
'http://messenger.msn.com/ws/2004/09/oim/'
if soapaction.startswith('http://messenger.msn.com/ws/2004/09/oim/')
else 'http://messenger.live.com/ws/2006/09/oim/'
)
lockkey_result = header.find('.//{*}Ticket').get('lockkey')
if bs is None or lockkey_result in (None,''):
return render(req, 'msn:oim/Fault.authfailed.xml', {
'owsns': owsns,
}, status = 500)
backend: Backend = req.app['backend']
user = bs.user
detail = user.detail
assert detail is not None
friendlyname = None
friendlyname_str = None
friendly_charset = None
friendlyname_mime = header.find('.//{*}From').get('friendlyName')
email = header.find('.//{*}From').get('memberName')
recipient = header.find('.//{*}To').get('memberName')
recipient_uuid = backend.util_get_uuid_from_email(recipient)
user_display_email = backend.util_get_display_email(user)
alias_email = '{}@crosstalk.im'.format(user.username).lower()
if email.lower() not in (user.email.lower(), alias_email, user_display_email.lower()) or recipient_uuid is None or not _is_on_al(recipient_uuid, backend, user, detail):
return render(req, 'msn:oim/Fault.unavailable.xml', {
'owsns': owsns,
}, status = 500)
assert req.transport is not None
peername = req.transport.get_extra_info('peername')
if peername:
host = peername[0]
else:
host = '127.0.0.1'
oim_msg_seq = str(find_element(header, 'Sequence/MessageNumber'))
if not oim_msg_seq.isnumeric():
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
if friendlyname_mime is not None:
try:
friendlyname, friendly_charset = decode_header(friendlyname_mime)[0]
except:
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
if friendly_charset is None:
friendly_charset = 'utf-8'
if friendlyname is not None:
friendlyname_str = friendlyname.decode(friendly_charset)
oim_proxy_string = header.find('.//{*}From').get('proxy')
try:
oim_mime = Parser().parsestr(body_content)
except:
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
oim_run_id = str(oim_mime.get('X-OIM-Run-Id'))
if oim_run_id is None:
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
if not re.match(r'^\{?[A-Fa-f0-9]{8,8}-([A-Fa-f0-9]{4,4}-){3,3}[A-Fa-f0-9]{12,12}\}?', oim_run_id):
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
oim_run_id = oim_run_id.replace('{', '').replace('}', '')
if (
'X-Message-Info', 'Received', 'From', 'To', 'Subject', 'X-OIM-originatingSource', 'X-OIMProxy', 'Message-ID',
'X-OriginalArrivalTime', 'Date', 'Return-Path'
) in oim_mime.keys():
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
if str(oim_mime.get('MIME-Version')) != '1.0':
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
if not str(oim_mime.get('Content-Type')).startswith('text/plain'):
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
if str(oim_mime.get('Content-Transfer-Encoding')) != 'base64':
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
if str(oim_mime.get('X-OIM-Message-Type')) != 'OfflineMessage':
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
oim_seq_num = str(oim_mime.get('X-OIM-Sequence-Num'))
if oim_seq_num != oim_msg_seq:
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
oim_headers = {name: str(value) for name, value in oim_mime.items()}
try:
i = body_content.index('\n\n') + 2
oim_body = body_content[i:]
for oim_b64_line in oim_body.split('\n'):
if len(oim_b64_line) > 77:
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
oim_body_normal = oim_body.strip()
oim_body_normal = base64.b64decode(oim_body_normal).decode('utf-8')
backend.user_service.save_oim(
bs, recipient_uuid, oim_run_id, host, oim_body_normal, True, from_friendly = friendlyname_str,
from_friendly_charset = friendly_charset, headers = oim_headers, oim_proxy = oim_proxy_string,
)
except:
return render(req, 'msn:oim/Fault.invalidcontent.xml', {
'owsns': owsns,
}, status = 500)
return render(req, 'msn:oim/StoreResponse.xml', {
'seq': oim_msg_seq,
'owsns': owsns,
})
def _is_on_al(uuid: str, backend: Backend, user: models.User, detail: models.UserDetail) -> bool:
contact = detail.contacts.get(uuid)
if user.settings.get('BLP', 'AL') == 'AL' and (contact is None or not contact.lists & models.ContactList.BL):
return True
if user.settings.get('BLP', 'AL') == 'BL' and contact is not None and not contact.lists & models.ContactList.BL:
return True
if contact is not None:
ctc_detail = backend._load_detail(contact.head)
assert ctc_detail is not None
ctc_me = ctc_detail.contacts.get(user.uuid)
if ctc_me is None and contact.head.settings.get('BLP', 'AL') == 'AL':
return True
if ctc_me is not None and not ctc_me.lists & models.ContactList.BL:
return True
return False
async def preprocess_soap_rsi(req: web.Request) -> Tuple[Any, Any, Optional[BackendSession], str]:
from lxml.objectify import fromstring as parse_xml
body = await req.read()
root = parse_xml(body)
token_tag = root.find('.//{*}PassportCookie/{*}*[1]')
if get_tag_localname(token_tag) != 't':
token = None
token = token_tag.text
if token is not None:
token = token[0:20]
backend: Backend = req.app['backend']
bs = backend.util_get_sess_by_token(token)
header = find_element(root, 'Header')
action = find_element(root, 'Body/*[1]')
#if settings.DEBUG: print('Action: {}'.format(get_tag_localname(action)))
return header, action, bs, token
async def preprocess_soap_oimws(req: web.Request) -> Tuple[Any, str, str, Optional[BackendSession], str]:
from lxml.objectify import fromstring as parse_xml
body = await req.read()
root = parse_xml(body)
token = root.find('.//{*}Ticket').get('passport')
if token[0:2] == 't=':
token = token[2:22]
backend: Backend = req.app['backend']
bs = backend.util_get_sess_by_token(token)
header = find_element(root, 'Header')
body_msgtype = str(find_element(root, 'Body/MessageType'))
body_content = str(find_element(root, 'Body/Content')).replace('\r\n', '\n')
return header, body_msgtype, body_content, bs, token
# TODO: Make this actually accurate
async def handle_whatsnew(req: web.Request) -> web.Response:
whatsnew = ''
with open('config/whatsnew.json', 'rb') as f:
whatsnew_list = json.loads(f.read())
f.close()
if len(whatsnew_list) > 0:
whatsnew_dict = whatsnew_list[0]
with open(TMPL_DIR + '/whatsnew/WhatsNewResponse.xml') as fh:
whatsnew = fh.read()
whatsnew = whatsnew.format(
date=whatsnew_dict['date'],
url=whatsnew_dict['url'],
title=whatsnew_dict['title'],
appName=whatsnew_dict['appName'],
content=whatsnew_dict['content']
)
return web.HTTPOk(content_type = 'text/xml', text = whatsnew)
async def handle_today(req: web.Request) -> web.Response:
return render(req, 'msn:svcs/MSNToday.html', {
'title': "CrossTalk Today",
'msn': req.query.get('msn') or False,
'wlm': req.query.get('wlm') or False,
'windowslive': req.query.get('windowslive') or False
})
async def handle_gamebrowser(req: web.Request) -> web.Response:
return render(req, 'msn:svcs/GameBrowser.html', {
'title': "Game Browser | CrossTalk",
})
async def handle_portal(req: web.Request) -> web.Response:
return web.HTTPFound(f'http://{settings.TODAY_HOSTs}/start/msn')
async def handle_textadredir(req: web.Request) -> web.Response:
return web.HTTPFound(f'http://{settings.AD_HOST}/ads/txt')
async def handle_banneradredir(req: web.Request) -> web.Response:
return web.HTTPFound(f'http://{settings.AD_HOST}/ads/banner')
async def handle_msn_redirect(req: web.Request) -> web.Response:
i = req.match_info['i']
id = req.match_info['id']
if i == '5':
if id == '60':
return web.HTTPFound('/svcs/mms/tabs.asp')
elif id == '153':
return web.HTTPFound('/start')
return web.HTTPFound('http://g.msn.com{}'.format(req.path_qs))
async def handle_msn5ads(req: web.Request) -> web.Response:
response = '<?xml version="1.0"?><msn-data><RefreshLogin>False</RefreshLogin><RefreshInterval>10080</RefreshInterval></msn-data>'
return web.HTTPOk(body=response)
async def handle_suiteupdate(req: web.Request) -> web.Response:
return render(req, 'msn:config/SuiteUpdate.xml')
async def handle_socialint(req: web.Request) -> web.Response:
return render(req, 'msn:config/Config.PSA.xml')
async def handle_tabs(req: web.Request) -> web.Response:
with open('config/tabs.json') as fh:
tabs_data = json.load(fh)
tmpl = req.app['jinja_env'].get_template('msn:svcs/svcs_tabs.xml')
tab_tmpl = tmpl.render(tabs=tabs_data)
return web.HTTPOk(content_type='text/xml', text='<?xml version="1.0"?>\n' + tab_tmpl)
# TODO: Unify the tabs handlers so spaghetti code isn't a problem
async def handle_tabs_newer(req: web.Request) -> web.Response:
id = int(req.match_info['id'])
with open('config/tabs.json') as fh:
tabs_data = json.load(fh)
tab_data = next((tab for tab in tabs_data if tab["id"] == id), None)
if not tab_data:
return web.HTTPNotFound(text="Tab not found")
tmpl = req.app['jinja_env'].get_template('msn:svcs/svcs_tabs_newer.xml')
tab_tmpl = tmpl.render(tab=tab_data)
return web.HTTPOk(content_type='text/xml', text=tab_tmpl)
async def handle_msgrconfig(req: web.Request) -> web.Response:
if req.method == 'POST':
body = await req.read() # type: Optional[bytes]
else:
body = None
msgr_config = _get_msgr_config(req, body)
if msgr_config == 'INVALID_VER':
return web.Response(status = 500)
return web.HTTPOk(content_type = 'text/xml', text = msgr_config)
async def handle_msgrconfig16(req: web.Request) -> web.Response:
body = await req.read()
msgr_config = _get_msgr_config_16(req, body)
return web.HTTPOk(content_type = 'text/xml', text = msgr_config)
def _get_msgr_config(req: web.Request, body: Optional[bytes]) -> str:
query = req.query
result = None # type: Optional[str]
ver = query.get('ver') or ''
if ver:
if re.match(r'[^\d\.]', ver):
return 'INVALID_VER'
config_ver = ver.split('.', 4)
if 8 <= int(config_ver[0]) <= 9:
with open(TMPL_DIR + '/config/MsgrConfig.wlm.8.xml') as fh:
config = fh.read()
with open('config/tabs.json') as fh:
with open(TMPL_DIR + '/svcs/svcs_tabs.xml') as th:
template = th.read()
tabs_data = json.load(fh)
tmpl_before = req.app['jinja_env'].from_string(template)
tab_tmpl = tmpl_before.render(tabs=tabs_data, settings=settings)
result = config.format(tabs = tab_tmpl)
elif int(config_ver[0]) >= 14:
with open(TMPL_DIR + '/config/MsgrConfig.wlm.14.xml') as fh:
template = fh.read()
with open('config/tabs.json') as fh:
tabs_data = json.load(fh)
tmpl_before = req.app['jinja_env'].from_string(template)
tmpl = tmpl_before.render(tabs=tabs_data, settings=settings)
result = tmpl
elif body is not None:
with open(TMPL_DIR + '/config/MsgrConfig.msn.envelope.xml') as fh:
envelope = fh.read()
with open(TMPL_DIR + '/config/MsgrConfig.msn.xml') as fh:
config = fh.read()
with open('config/tabs.json') as fh:
with open(TMPL_DIR + '/svcs/svcs_tabs.xml') as th:
template = th.read()
tabs_data = json.load(fh)
tmpl_before = req.app['jinja_env'].from_string(template)
tab_tmpl = tmpl_before.render(tabs=tabs_data)
result = envelope.format(MsgrConfig = config.format(tabs = tab_tmpl, settings = settings))
return result or ''
def _get_msgr_config_16(req: web.Request, body: Optional[bytes]) -> str:
with open(TMPL_DIR + '/config/MsgrConfig.wlm.16.xml') as fh:
template = fh.read()
with open('config/tabs.json') as fh:
tabs_data = json.load(fh)
tmpl_before = req.app['jinja_env'].from_string(template)
tmpl = tmpl_before.render(tabs=tabs_data, settings=settings)
result = tmpl
return result or ''
PassportURLs = 'PassportURLs'
async def handle_nexus(req: web.Request) -> web.Response:
return web.HTTPOk(headers = {
PassportURLs: 'DALogin=https://{}{}'.format(settings.LOGIN_HOST, LOGIN_PATH),
})
async def handle_login(req: web.Request) -> web.Response:
tmp = _extract_pp_credentials(req.headers.get('Authorization') or '')
if tmp is None:
token = None
else:
email, pwd = tmp
token_tpl = _login(req, email, pwd)
if token_tpl is None:
raise web.HTTPUnauthorized(headers={
'WWW-Authenticate': '{}da-status=failed'.format(PP),
})
token, _, _ = token_tpl
return web.HTTPOk(headers={
'Authentication-Info': '{}da-status=success,from-PP=\'{}\''.format(PP, token),
})
async def handle_not_rst(req: web.Request) -> web.Response:
if req.method == 'OPTIONS':
return web.HTTPOk(headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'X-User, X-Password, Content-Type',
'Access-Control-Expose-Headers': 'X-Token',
'Access-Control-Max-Age': str(86400),
})
email = req.headers.get('X-User') or ''
pwd = req.headers.get('X-Password') or ''
token_tpl = _login(req, email, pwd, lifetime = 86400)
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Expose-Headers': 'X-Token',
}
if token_tpl is not None:
token, _, _ = token_tpl
headers['X-Token'] = token
return web.HTTPOk(headers = headers)
async def handle_rst(req: web.Request, rst2: bool = False) -> web.Response:
from lxml.objectify import fromstring as parse_xml
body = await req.read()
try:
root = parse_xml(body)
except:
return render(req, 'msn:RST/{}.error.xml'.format('RST2' if rst2 else 'RST'))
email = find_element(root, 'Username')
pwd = str(find_element(root, 'Password'))
if email is None or pwd is None:
return render(req, 'msn:RST/{}.error.xml'.format('RST2' if rst2 else 'RST'))
backend: Backend = req.app['backend']
token_tpl = _login(req, email, pwd, binary_secret = True, lifetime = 86400)
uuid = backend.util_get_uuid_from_email(email)
if token_tpl is not None and uuid is not None:
token, expiry, bsecret = token_tpl
day_before_expiry = expiry - timedelta(days = 1)
timez = util.misc.date_format(day_before_expiry)
tomorrowz = util.misc.date_format(expiry)
time_5mz = util.misc.date_format((day_before_expiry + timedelta(minutes = 5)))
# load PUID and CID
cid = cid_format(uuid)
puid = puid_format(uuid)
assert req.transport is not None
peername = req.transport.get_extra_info('peername')
if peername:
host = peername[0]
else:
host = '127.0.0.1'
# get list of requested domains
domains = root.findall('.//{*}Address')
tmpl = req.app['jinja_env'].get_template('msn:RST/{}.token.xml'.format('RST2' if rst2 else 'RST'))
# collect tokens for requested domains, ignore Passport token request
tokenxmls = [tmpl.render(
i = i + 1,
domain = domain,
timez = timez,
tomorrowz = tomorrowz,
pptoken1 = token,
binarysecret = bsecret,
) for i, domain in enumerate(domains) if domain != 'http://Passport.NET/tb']
tmpl = req.app['jinja_env'].get_template('msn:RST/{}.xml'.format('RST2' if rst2 else 'RST'))
return web.HTTPOk(
content_type = 'text/xml',
text = (tmpl.render(
puidhex = puid,
time_5mz = time_5mz,
timez = timez,
tomorrowz = tomorrowz,
cid = cid,
email = email,
firstname = "John",
lastname = "Doe",
ip = req.headers.get('X-Forwarded-For', req.remote),
pptoken1 = token,
tokenxml = Markup(''.join(tokenxmls)),
) if rst2 else tmpl.render(
puidhex = puid,
timez = timez,
tomorrowz = tomorrowz,
cid = cid,
email = email,
firstname = "John",
lastname = "Doe",
ip = req.headers.get('X-Forwarded-For', req.remote),
pptoken1 = token,
tokenxml = Markup(''.join(tokenxmls)),
)),
)
return render(req, 'msn:RST/{}.authfailed.xml'.format('RST2' if rst2 else 'RST'), {
'timez': util.misc.date_format(datetime.utcnow()),
})
async def handle_videofeed(req: web.Request, get_videos: bool = False) -> web.Response:
if not get_videos:
return render(req, 'msn:svcs/videofeedroot.xml')
else:
with open('config/videos.json', 'rb') as f:
vid_data = json.load(f)
rss_items = []
for video in vid_data:
try:
pub_date = parsedate_to_datetime(video['publish_date'])
except Exception:
pub_date = datetime.now()
item = PyRSS2Gen.RSSItem(
title=video['title'],
link=video['link'],
description=video['description'],
guid=PyRSS2Gen.Guid(video['link'], isPermaLink=True),
pubDate=pub_date,
enclosure=PyRSS2Gen.Enclosure(
url=video['thumbnail'],
length="1",
type="image/jpeg"
)
)
rss_items.append(item)
rss_feed = PyRSS2Gen.RSS2(
title="CrossTalk",
link="http://crosstalk.im",
description="CrossTalk Videos",
language="en-us",
lastBuildDate=datetime.now(),
ttl=10,
copyright="&copy; 2023 - 2025 the undergr0und",
image=PyRSS2Gen.Image(
url="http://hiden.cc/static/icon/misc/hidnet.png",
title="CrossTalk Video - InDev",
link="http://crosstalk.im"
),
items=rss_items
)
rss_xml = rss_feed.to_xml(encoding="utf-8")
return web.HTTPOk(content_type="text/xml", text=rss_xml)
def _extract_pp_credentials(auth_str: str) -> Optional[Tuple[str, str]]:
if not auth_str:
return None
assert auth_str.startswith(PP)
auth = {}
for part in auth_str[len(PP):].split(','):
parts = part.split('=', 1)
if len(parts) == 2:
auth[unquote(parts[0])] = unquote(parts[1])
email = auth['sign-in']
pwd = auth['pwd']
return email, pwd
def _login(req: web.Request, email: str, pwd: str, binary_secret: bool = False, lifetime: int = 30) -> Optional[Tuple[str, datetime, Optional[str]]]:
backend: Backend = req.app['backend']
uuid = backend.user_service.login(email, pwd)
if uuid is None and email.lower().endswith('@crosstalk.im'):
username = email.lower()[:-len('@crosstalk.im')]
uuid = backend.user_service.login_with_username(username, pwd)
if uuid is None: return None
bsecret = None
if binary_secret:
bsecret = base64.b64encode(secrets.token_bytes(24)).decode('ascii')
return (*backend.login_auth_service.create_token('ns/login', [uuid, bsecret], lifetime = lifetime), bsecret)
def _contact_is_favorite(user_detail: models.UserDetail, ctc: models.Contact) -> bool:
groups = user_detail._groups_by_uuid
for group in ctc._groups.copy():
if group.id not in groups: continue
if groups[group.id].is_favorite: return True
return False
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Function '{{action}}' doesn't exist</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Generic SOAP fault</faultstring>
<notAValidSoapTag>{{ exception }}</notAValidSoapTag>
</soap:Fault>
</soap:Body>
</soap:Envelope>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>API {{ action }} no longer supported</faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ action }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">Forbidden</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">API {{ action }} no longer supported</errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">DM2CDP1011931</machineName>
<additionalDetails>
<originalExceptionErrorMessage>API {{ action }} no longer supported</originalExceptionErrorMessage>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<S:Header>
<psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<psf:serverVersion>1</psf:serverVersion>
<psf:authstate>0x80048800</psf:authstate>
<psf:reqstatus>0x80048823</psf:reqstatus>
<psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="{{ timez }}">XYZPPLOGN1A23 2017.09.28.12.44.07</psf:serverInfo>
<psf:cookies/>
<psf:response/>
</psf:pp>
</S:Header>
<S:Fault>
<faultcode>wsse:FailedAuthentication</faultcode>
<faultstring>Authentication Failure</faultstring>
</S:Fault>
</S:Envelope>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<S:Fault>
<faultcode>S:Client</faultcode>
<faultstring>Invalid Request</faultstring>
</S:Fault>
</S:Envelope>
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust">
<Header>
<ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo">
<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>
<ps:BinaryVersion>4</ps:BinaryVersion>
<ps:UIVersion>1</ps:UIVersion>
<ps:Cookies/>
<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMx</ps:RequestParams>
</ps:AuthInfo>
<wsse:Security>
<wsse:UsernameToken Id="user">
<wsse:Username>bob1@hotmail.com</wsse:Username>
<wsse:Password>foopass</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</Header>
<Body>
<ps:RequestMultipleSecurityTokens xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="RSTS">
<wst:RequestSecurityToken Id="RST0">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>http://Passport.NET/tb</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
</wst:RequestSecurityToken>
<wst:RequestSecurityToken Id="RST1">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>messengerclear.live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsse:PolicyReference URI="MBI_KEY_OLD"/>
</wst:RequestSecurityToken>
<wst:RequestSecurityToken Id="RST2">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>messenger.msn.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsse:PolicyReference URI="?id=507"/>
</wst:RequestSecurityToken>
<wst:RequestSecurityToken Id="RST3">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>contacts.msn.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsse:PolicyReference URI="MBI"/>
</wst:RequestSecurityToken>
<wst:RequestSecurityToken Id="RST4">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>messengersecure.live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsse:PolicyReference URI="MBI_SSL"/>
</wst:RequestSecurityToken>
<wst:RequestSecurityToken Id="RST5">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>spaces.live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsse:PolicyReference URI="MBI"/>
</wst:RequestSecurityToken>
<wst:RequestSecurityToken Id="RST6">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>storage.msn.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsse:PolicyReference URI="MBI_SSL"/>
</wst:RequestSecurityToken>
</ps:RequestMultipleSecurityTokens>
</Body>
</Envelope>
@@ -0,0 +1,198 @@
<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<psf:serverVersion>1</psf:serverVersion>
<psf:PUID>0003BFFDB7D5F624</psf:PUID>
<psf:configVersion>16.000.26889.00</psf:configVersion>
<psf:uiVersion>3.100.2179.0</psf:uiVersion>
<psf:mobileConfigVersion>16.000.26208.0</psf:mobileConfigVersion>
<psf:authstate>0x48803</psf:authstate>
<psf:reqstatus>0x0</psf:reqstatus>
<psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="{{ timez }}">XYZPPLOGN1A23 2017.10.03.19.00.04</psf:serverInfo>
<psf:cookies/>
<psf:browserCookies>
<psf:browserCookie Name="MH" URL="http://www.msn.com">MSFT; path=/; domain=.msn.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.msn.com">; path=/; domain=.msn.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MH" URL="http://www.live.com">MSFT; path=/; domain=.live.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.live.com">; path=/; domain=.live.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
</psf:browserCookies>
<psf:credProperties>
<psf:credProperty Name="MainBrandID">MSFT</psf:credProperty>
<psf:credProperty Name="BrandIDList"></psf:credProperty>
<psf:credProperty Name="IsWinLiveUser">true</psf:credProperty>
<psf:credProperty Name="CID">{{ cid }}</psf:credProperty>
<psf:credProperty Name="AuthMembername">{{ email }}</psf:credProperty>
<psf:credProperty Name="Country">US</psf:credProperty>
<psf:credProperty Name="Language">1031</psf:credProperty>
<psf:credProperty Name="FirstName">{{ firstname }}</psf:credProperty>
<psf:credProperty Name="LastName">{{ lastname }}</psf:credProperty>
<psf:credProperty Name="ChildFlags">00000001</psf:credProperty>
<psf:credProperty Name="Flags">40100643</psf:credProperty>
<psf:credProperty Name="FlagsV2">00000000</psf:credProperty>
<psf:credProperty Name="IP">{{ ip }}</psf:credProperty>
<psf:credProperty Name="FamilyID">0000000000000000</psf:credProperty>
<psf:credProperty Name="AssociatedForStrongAuth">0</psf:credProperty>
</psf:credProperties>
<psf:extProperties>
<psf:extProperty Name="ANON" Expiry="Wed, 30-Dec-2037 16:00:00 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">A=2AD1B6380CC38C61A2E95994FFFFFFFF&amp;E=1456&amp;W=1</psf:extProperty>
<psf:extProperty Name="NAP" Expiry="Wed, 30-Dec-2037 16:00:00 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">V=1.9&amp;E=13fc&amp;C=tq1sGI5NyECr4nbob0bsqOGQx85gOAzYs8FuhJP5L22WfJl-67MNNQ&amp;W=1</psf:extProperty>
<psf:extProperty Name="LastUsedCredType">1</psf:extProperty>
<psf:extProperty Name="WebCredType">1</psf:extProperty>
<psf:extProperty Name="CID">{{ cid }}</psf:extProperty>
</psf:extProperties>
<psf:response/>
</psf:pp>
</S:Header>
<S:Body>
<wst:RequestSecurityTokenResponseCollection xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:legacy</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>http://Passport.NET/tb</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Id="BinaryDAToken0" Type="http://www.w3.org/2001/04/xmlenc#Element">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>http://Passport.NET/STS</ds:KeyName>
</ds:KeyInfo>
<CipherData>
<CipherValue>Cap26AQZrSyMm2SwwTyJKyqLR9/S+vQWQsaBc5Mv7PwtQDMzup/udOOMMvSu99R284pmiD3IepBXrEMLK5rLrXAf2A6vrP6vYuGA45GCqQdoxusHZcjt9P2B8WyCTVT2cM8jtGqGIfRlU/4WzOLxNrDJwDfOsmilduGAGZfvRPW7/jyXXrnGK7/PWkymX4YDD+ygJfMrPAfvAprvw/HVE6tutKVc9cViTVYy8oHjosQlb8MKn3vKDW1O2ZWQUc47JPl7DkjQaanfNBGe6CL7K1nr6Z/jy7Ay7MjV+KQehmvphSEmCzLrpB4WWn2PdpdTrOcDj+aJfWHeGL4sIPwEKgrKnTQg9QD8CCsm5wew9P/br39OuIfsC6/PFBEHmVThqj0aMxYLRD4K2GoRay6Ab7NftoIP5dnFnclfRxETAoNpTPE2F5Q669QySrdXxBpBSk8GLmdCDMlhiyzSiByrhFQaZRcH8n9i+i289otYuJQ7xPyP19KwT4CRyOiIlh3DSdlBfurMwihQGxN2spU7P4MwckrDKeOyYQhvNm/XWId/oXBqpHbo2yRPiOwL9p1J4AxA4RaJuh77vyhn2lFQaxPDqZd5A8RJjpb2NE2N3UncKLW7GAangdoLbRDMqt51VMZ0la+b/moL61fKvFXinKRHc7PybrG3MWzgXxO/VMKAuXOsB9XnOgl2A524cgiwyg==</CipherValue>
</CipherData>
</EncryptedData>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport"/>
<wsse:Reference URI="#BinaryDAToken0"/>
</wst:RequestedTokenReference>
<wst:RequestedProofToken>
<wst:BinarySecret>tgoPVK67sU36fQKlGLMgWgTXp7oiaQgE</wst:BinarySecret>
</wst:RequestedProofToken>
</wst:RequestSecurityTokenResponse>
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>messengerclear.live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact1">t={{ pptoken1 }}Y6+H31sTUOFkqjNTDYqAAFLr5Ote7BMrMnUIzpg860jh084QMgs5djRQLLQP0TVOFkKdWDwAJdEWcfsI9YL8otN9kSfhTaPHR1njHmG0H98O2NE/Ck6zrog3UJFmYlCnHidZk1g3AzUNVXmjZoyMSyVvoHLjQSzoGRpgHg3hHdi7zrFhcYKWD8XeNYdoz9wfA2YAAAgZIgF9kFvsy2AC0Fl/ezc/fSo6YgB9TwmXyoK0wm0F9nz5EfhHQLu2xxgsvMOiXUSFSpN1cZaNzEk/KGVa3Z33Mcu0qJqvXoLyv2VjQyI0VLH6YlW5E+GMwWcQurXB9hT/DnddM5Ggzk3nX8uMSV4kV+AgF1EWpiCdLViRI6DmwwYDtUJU6W6wQXsfyTm6CNMv0eE0wFXmZvoKaL24fggkp99dX+m1vgMQJ39JblVH9cmnnkBQcKkV8lnQJ003fd6iIFzGpgPBW5Z3T1Bp7uzSGMWnHmrEw8eOpKC5ny4x8uoViXDmA2UId23xYSoJ/GQrMjqB+NslqnuVsOBE1oWpNrmfSKhGU1X0kR4Eves56t5i5n3XU+7ne0MkcUzlrMi89n2j8aouf0zeuD7o+ngqvfRCsOqjaU71XWtuD4ogu2X7/Ajtwkxg/UJDFGAnCxFTTd4dqrrEpKyMK8eWBMaartFxwwrH39HMpx1T9JgknJ1hFWELzG8b302sKy64nCseOTGaZrdH63pjGkT7vzyIxVH/b+yJwDRmy/PlLz7fmUj6zpTBNmCtl1EGFOEFdtI2R04EprIkLXbtpoIPA7m0TPZURpnWufCSsDtD91ChxR8j/FnQ/gOOyKg/EJrTcHvM1e50PMRmoRZGlltBRRwBV+ArPO64On6zygr5zud5o/aADF1laBjkuYkjvUVsXwgnaIKbTLN2+sr/WjogxT1Yins79jPa1+3dDenxZtE/rHA/6qsdJmo5BJZqNYQUFrnpkU428LryMnBaNp2BW51JRsWXPAA7yCi0wDlHzEDxpqaOnhI4Ol87ra+VAg==&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport:compact"/>
<wsse:Reference URI="#Compact1"/>
</wst:RequestedTokenReference>
<wst:RequestedProofToken>
<wst:BinarySecret>Z1OQ3mCLbrkCGvfRX0V8Ly/nSsbmv4La</wst:BinarySecret>
</wst:RequestedProofToken>
</wst:RequestSecurityTokenResponse>
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>messenger.msn.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact2">t={{ pptoken1 }}rjQ2AdbE08y5Wsm6cgyAAE0YhoO69q4VxqEKEavgL8WJ6gWmdATT7Cz2b6mwE1a7BuNl8H5KwR91KGU8H4vz7xCj5oHh4tnbM92jLWqkQ9Gh07jRpmJasADE4WcY8tDB1JPLfYf/1DE/Y1vwR5enhko97EdAODtnAEb7KRm7DKbZrrqJadYuJRMLbsu+meKcA2YAAAh3qRWjdFREsNABe/PbWQmW7mRbXnkPZ1cWp07lrzAQmHm/zR3yTriSigZPtXMTa0AbEsd943NTrZYdo6DNEdC0y+zypbu0gZgTKHTSntAUbtogmUMWHquFitG0P+oKn2ud6z9eLjGk+Hm2w7s8Vf2UkEqidydi+U3O9Q4lqUJtcLcDa2NciXyffkA8sbS+Wpysj+TZpXVy3sae3EpdncnF678X918n2u/JLUDXL8uyg+eGIuDwO0xmBH1LMg15wzTdq++CZpO3mUIpRBMViqsihMLw8l7TMLvOIupsAJtXhqtfaJaMnSAp/LM7CrAdzpNGv51wJYKqIBJ506QAhhe/VWyBnAyAWiMledzIkafn8L6mgIRq50zvKBX4QRHJoJhHhrN6APnZI+zoHRB/NdJbJULwuz9V3X+ou4PZERl1H/VFR/dtTQd1FY2m0JKYlAG5gdUMTgGRcyD/vRK30ZoEUzoLkGXg1YGlzp1aQnxyD92QZ1nCiZjv2iNIqbtiXSLAAtGsN3Ykftaud0WjWo9rKaibgU1WMZOxU0fWJ+Wczo6uqBQWTlXxDipRceX2eSj1bs3SDEyvmZ9XX11Qh408MJ4/7a7AhbKZitkJW5Q0FrnEk+cq4qqQ0H4VAg==&amp;p=AFww</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport:compact"/>
<wsse:Reference URI="#Compact2"/>
</wst:RequestedTokenReference>
</wst:RequestSecurityTokenResponse>
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>contacts.msn.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact3">t={{ pptoken1 }}tZi9ugdf902M4Br/7wKAAPMX58N8xadYh1AbLntVYhaPZ95S943IE+sYAAsx3KQdGcdN2ad2oHflAbAmiFHWA8Xy29Y/fr9EZbsqpNRjrs6+hRqGKv6KF0bYtYTd9I7YK3qEH8GdiUsxj/H6B4brK+LZtKz5cqYeTX9TYwSQLGqEBvRr2nvO6lT4SfhdvSxdA2YAAAh9hpKyxIHT3NABKHcV1vw1SoIszOpXEazh4QAC8wsqF7uqsP8fOvUF1CyOsouCiG9pueBqL6yc9w22z+esp+QMWAALJhlHdGfHHGtI5ezq0vwvEoDVbo3AAVWOHnJWV1WswJa+0rQAScWb8Iw5LZ60Gls7P24tux8iQ9gaxsnZ29ELGdJek7xnAYtEtFkL1PjXB0Thgpty2LmdqBzJq2F33ueEpoLFL3JW0dWHzL9p1gOGHGDXgIucMwXJ78DhmFPRQRxcHCj8UujBcfO3cRUme8alB3RrkLC/3HCavxCldGK/SmBCDhnjSUl1gm5CUqPcPPe0Wb975lH4IIrsSzjkXb3T3QnYGX5t00kQQ8p7PJ1UFnbGj4GA3Smg6/qAyZJTaSOAuuHjrvd03MlT1JxDRiKZXZhTXT25KW8+NTjt0oGGkYsVxEv7h8ho6Udtf6ymOIv3PNnlwYMwJp2myqcDToqnC0JhN54BmrdSnQoUNYoIKk4eqWK3V2lLnpMVfTxO0Mszjpaz51UP70VlJLjrSXTHO733/k5z9kwDIAmkGyYZCyiTOURA9OcpdydivkJKll6y5xwgbqnjx9Ce/6I2h+5xmHLex5qmn6EaghbP+MsGeJgq30x0wLQGAg==&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport:compact"/>
<wsse:Reference URI="#Compact3"/>
</wst:RequestedTokenReference>
</wst:RequestSecurityTokenResponse>
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>messengersecure.live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact4">t={{ pptoken1 }}2oHItBdtfopLtOddVL6AAMdC+gI2waErOBMJCMqZitiSapE6unig1eU9NNgQZOO3QdgIHELplGTchaqH0MtKxPiGdiHNUNvuZuH+fGx1ij2d1ktZDGKi70eDkVg9dbtGECqhNCsFbFynNwVDebPtFNPXtPv1bNZ9J0Dzshoh6qvS2CU1l3PMrDa+Y3P4zeGVA2YAAAgGg5rOAqHhj9gB9rRZmHJ3ivzxKI/hfRcMWQQegC7gaXs8UcSXmF1GqUJ264kfELpQ0UAVkETFj35qgA21ZfM+L+gQV+UbQ1Tfil4sPNGD5vsrZBKecL0ZJ6TAT/NDjcGe54/vUIaPmi3A2L6QBaC8gbGiQQb+054R+0PU/Hkkn887HEnTIhTRtqqAjI5P/pF1mcC82DVnPlGV8TLzMb3or2KaPjkgDs5MjnXbedubO6uN0Egev+9/hacX/21i6ZQwIVZD0szg6Q6grI6jNGDm4ct3JJHux6534kDB/jdskMtOG97hp2Ed+Ks4vmWYJPetdTd/ARmZkjQcT2CLHKcHEbzK3Hf+Muzqotn3D7L8fbCGZH3xtRNqM3A0VyKLTxdEd+/fBXaWZ1u4CFseoPtSLM3Z6dNnYTHJK27OSjlXtzaSQJZxUgNIlOvtPmoYVnOV2PkymjlvDhcYaIQ1qDQe0Kh/zo0ymOlpvMlqcAa+MVS5UM6375qmD0ebOCu/cx1aCBq30zTxOYCOuUlU4OdTtSgGri3y2IZi3Ti+aQB7fT5h7N/wqCkaZZy07tNs+ALFELX2RkF5R16BA5G9g19QnSrUECaRa7o0pwoDrVRR3aSuaNW1nnSf9jL8blEOcHK6MxUC&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport:compact"/>
<wsse:Reference URI="#Compact4"/>
</wst:RequestedTokenReference>
</wst:RequestSecurityTokenResponse>
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>spaces.live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact5">t={{ pptoken1 }}keHxhjSHsGxIm+YQ/BQAAfpdWf+k17Sun3Krcs/4LzzSsq2MgSfhOeEDNIPUfRT9Jxc/EqHh99Rqb4Irvcn2V7N8RkHW6On9gyYoDFWYt1o2YN03YV/NZzVKVbW/pdDxgs+++FELegQCXzs0V1nhH8IIyl5giiPl87OT7GOIe4rrNJ8BKzAAbcuibR8QZft1A9HqnBkdoq76lnmXvMinQTDTD/PRdx91pB+GiSSXWT9X9fQgVK212vNJtuJBJ4AQOwRUhl46F89W/KhGWIMtuVe4y8UlY/tuZv1PDZ6bIczHejXRuddkIPQ9oM9FbOWHcWLtx/uSO4+zhwphucR+dyaydugESasluP5H1GopoRwDZgAACMzE5rF9T18N0AHPV+yFTi0tV4xpUh1q4ZPn22L56LR0yEr/UG6xHBJ0zhIOYbIB6KOTvpwEdcUYO2BY2799B831TmPqF6lkmA3hMK9NGPTmgY625GFe4EZp+BPgV1Th02g+XC4yMMUhgrYB1U95a2h7bt5bTE+6subNzTbgDC71rLtNe2es/b5qcb+/Rpn5jnCbfkrez6AbDOY9JAHfLx/cjfSdnqRVw62HncSWyqFV9S4asjYW5qmCiqByStDnHtUtZmVEWOTC3O2PFl9xvdvtzrMnNQwgfTLf02hwtNIszC8Y12wJEdYmdGuzOVPnRFEyy58HNZFAMw7i2ifU/UKvjVlUZh4PGy8SQZ0ciTTnW0kdCrKiE2jnF7+GztmXtSc5dv6Cx36IfFuhTVX/XnY5MEEn9TOQ608lXLX+AZ9gotel9bGeMQVrUV1tvNBbcnAfbq3B5k4BHIBr7F8tm6ecoTGqGg39x3yaoLUjkCyMY7wtoU6Uc9oJWV5Vu0ZpmPEF4PZEAB9EWKH+4qED50SuEXOgMncu6Eh92lU5kTrACEd/9SSiK2PpV8BHV/xnHr2QEBbho23NsqUaQY+tB/K9PgyPN2p0YPwTiGF9XdbuUtozXCgZnHIMThUC&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport:compact"/>
<wsse:Reference URI="#Compact5"/>
</wst:RequestedTokenReference>
</wst:RequestSecurityTokenResponse>
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>storage.msn.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact6">t={{ pptoken1 }}Rg6HvEdmXr19KcNgO+7mAAGz0IdAs+sT7TRsKonUJEvPOUrqSyqirOIB6GjVs8PBKT20j5ceFKQeX28m1O6xHODR+vi3zwMUDySaMy1G2rmpccBwpeFJJBBKXdE10b6nAONSLwMD38gMT253/aofIAEm5XxDGzRJkBPHWGTXzEXx/DxNVskTL3YUIwId2Eh44A2YAAAiDtG///iWnZNABjCsiZgVJfU8F3jDylPAvSZHpeXltbIKMUzh5Ja/55AGwfWI4uJZgX4HYu0TYvhlXoxVrHiQY31lYBH0Lof2Nv5/LLCPGziw3tx2wTM3EplJ2SJ2SPNfbVZNX01UNdF+GMsZWI0xglh+lPHaar6i56UFfjjRL+lWX6F7io4QHMIm7wqsP5r28sHsMO9pFp1kIgJBXCqNf5eOrozUjaq7cfA6mnnxw2uj6jDtXuk9xiTBV18gmEHXIw2Wqp2Ca+c4TaadZCup5mTYyi5m02hWdgg3DahiMtEW953gOWyl/+JRYbzQaGQFfbym68qi3j0p4zJ373j9eXlrf4fJUvTYeC5HGjbcrkWnxjhGg0ryUVjDjxKaUO7zhslVnvX6oLxW8fqNiU0H481wu6+OF/gajQp7Ie9ZrVyRpW1KWtXBrVA69gszTdUrWY8clNZ60kgGFw68Pfv1f6gtGo35Oa3U4Wm9nihV81hRtck58WbYCSOzXJVcH6MR0TlUjKGgwaNQpkc+LtSoyRi8oavoIzN1Giz67qXANYtPUHMPEek8K2p57clCiW99Y6M8C/JdBCkLDB4J4aIIBZ7jx/LhVv06P+AoZIJ660v/tRFDu8PDGij8VAg==&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport:compact"/>
<wsse:Reference URI="#Compact6"/>
</wst:RequestedTokenReference>
</wst:RequestSecurityTokenResponse>
</wst:RequestSecurityTokenResponseCollection>
</S:Body>
</S:Envelope>
+24
View File
@@ -0,0 +1,24 @@
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>{{ domain }}</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact{{ i }}">t={{ pptoken1 }}Y6+H31sTUOFkqjNTDYqAAFLr5Ote7BMrMnUIzpg860jh084QMgs5djRQLLQP0TVOFkKdWDwAJdEWcfsI9YL8otN9kSfhTaPHR1njHmG0H98O2NE/Ck6zrog3UJFmYlCnHidZk1g3AzUNVXmjZoyMSyVvoHLjQSzoGRpgHg3hHdi7zrFhcYKWD8XeNYdoz9wfA2YAAAgZIgF9kFvsy2AC0Fl/ezc/fSo6YgB9TwmXyoK0wm0F9nz5EfhHQLu2xxgsvMOiXUSFSpN1cZaNzEk/KGVa3Z33Mcu0qJqvXoLyv2VjQyI0VLH6YlW5E+GMwWcQurXB9hT/DnddM5Ggzk3nX8uMSV4kV+AgF1EWpiCdLViRI6DmwwYDtUJU6W6wQXsfyTm6CNMv0eE0wFXmZvoKaL24fggkp99dX+m1vgMQJ39JblVH9cmnnkBQcKkV8lnQJ003fd6iIFzGpgPBW5Z3T1Bp7uzSGMWnHmrEw8eOpKC5ny4x8uoViXDmA2UId23xYSoJ/GQrMjqB+NslqnuVsOBE1oWpNrmfSKhGU1X0kR4Eves56t5i5n3XU+7ne0MkcUzlrMi89n2j8aouf0zeuD7o+ngqvfRCsOqjaU71XWtuD4ogu2X7/Ajtwkxg/UJDFGAnCxFTTd4dqrrEpKyMK8eWBMaartFxwwrH39HMpx1T9JgknJ1hFWELzG8b302sKy64nCseOTGaZrdH63pjGkT7vzyIxVH/b+yJwDRmy/PlLz7fmUj6zpTBNmCtl1EGFOEFdtI2R04EprIkLXbtpoIPA7m0TPZURpnWufCSsDtD91ChxR8j/FnQ/gOOyKg/EJrTcHvM1e50PMRmoRZGlltBRRwBV+ArPO64On6zygr5zud5o/aADF1laBjkuYkjvUVsXwgnaIKbTLN2+sr/WjogxT1Yins79jPa1+3dDenxZtE/rHA/6qsdJmo5BJZqNYQUFrnpkU428LryMnBaNp2BW51JRsWXPAA7yCi0wDlHzEDxpqaOnhI4Ol87ra+VAg==&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport:compact"></wsse:KeyIdentifier>
<wsse:Reference URI="#Compact{{ i }}"></wsse:Reference>
</wst:RequestedTokenReference>
{% if domain == 'messengerclear.live.com' %}
<wst:RequestedProofToken>
<wst:BinarySecret>{{ binarysecret }}</wst:BinarySecret>
</wst:RequestedProofToken>
{% endif %}
</wst:RequestSecurityTokenResponse>
+82
View File
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<psf:serverVersion>1</psf:serverVersion>
<psf:PUID>{{ puidhex }}</psf:PUID>
<psf:configVersion>16.000.26889.00</psf:configVersion>
<psf:uiVersion>3.100.2179.0</psf:uiVersion>
<psf:mobileConfigVersion>16.000.26208.0</psf:mobileConfigVersion>
<psf:authstate>0x48803</psf:authstate>
<psf:reqstatus>0x0</psf:reqstatus>
<psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="{{ timez }}">XYZPPLOGN1A23 2017.10.03.19.00.04</psf:serverInfo>
<psf:cookies/>
<psf:browserCookies>
<psf:browserCookie Name="MH" URL="http://www.msn.com">MSFT; path=/; domain=.msn.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.msn.com">; path=/; domain=.msn.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MH" URL="http://www.live.com">MSFT; path=/; domain=.live.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.live.com">; path=/; domain=.live.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
</psf:browserCookies>
<psf:credProperties>
<psf:credProperty Name="MainBrandID">MSFT</psf:credProperty>
<psf:credProperty Name="BrandIDList"></psf:credProperty>
<psf:credProperty Name="IsWinLiveUser">true</psf:credProperty>
<psf:credProperty Name="CID">{{ cid }}</psf:credProperty>
<psf:credProperty Name="AuthMembername">{{ email }}</psf:credProperty>
<psf:credProperty Name="Country">US</psf:credProperty>
<psf:credProperty Name="Language">1033</psf:credProperty>
<psf:credProperty Name="FirstName">{{ firstname }}</psf:credProperty>
<psf:credProperty Name="LastName">{{ lastname }}</psf:credProperty>
<psf:credProperty Name="ChildFlags">00000001</psf:credProperty>
<psf:credProperty Name="Flags">40100643</psf:credProperty>
<psf:credProperty Name="FlagsV2">00000000</psf:credProperty>
<psf:credProperty Name="IP">{{ ip }}</psf:credProperty>
<psf:credProperty Name="FamilyID">0000000000000000</psf:credProperty>
<psf:credProperty Name="AssociatedForStrongAuth">0</psf:credProperty>
</psf:credProperties>
<psf:extProperties>
<psf:extProperty Name="ANON" Expiry="Wed, 30-Dec-2037 16:00:00 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">A=2AD1B6380CC38C61A2E95994FFFFFFFF&amp;E=1456&amp;W=1</psf:extProperty>
<psf:extProperty Name="NAP" Expiry="Wed, 30-Dec-2037 16:00:00 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">V=1.9&amp;E=13fc&amp;C=tq1sGI5NyECr4nbob0bsqOGQx85gOAzYs8FuhJP5L22WfJl-67MNNQ&amp;W=1</psf:extProperty>
<psf:extProperty Name="LastUsedCredType">1</psf:extProperty>
<psf:extProperty Name="WebCredType">1</psf:extProperty>
<psf:extProperty Name="CID">{{ cid }}</psf:extProperty>
</psf:extProperties>
<psf:response/>
</psf:pp>
</S:Header>
<S:Body>
<wst:RequestSecurityTokenResponseCollection xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:legacy</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>http://Passport.NET/tb</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Id="BinaryDAToken0" Type="http://www.w3.org/2001/04/xmlenc#Element">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"></EncryptionMethod>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>http://Passport.NET/STS</ds:KeyName>
</ds:KeyInfo>
<CipherData>
<CipherValue>Cap26AQZrSyMm2SwwTyJKyqLR9/S+vQWQsaBc5Mv7PwtQDMzup/udOOMMvSu99R284pmiD3IepBXrEMLK5rLrXAf2A6vrP6vYuGA45GCqQdoxusHZcjt9P2B8WyCTVT2cM8jtGqGIfRlU/4WzOLxNrDJwDfOsmilduGAGZfvRPW7/jyXXrnGK7/PWkymX4YDD+ygJfMrPAfvAprvw/HVE6tutKVc9cViTVYy8oHjosQlb8MKn3vKDW1O2ZWQUc47JPl7DkjQaanfNBGe6CL7K1nr6Z/jy7Ay7MjV+KQehmvphSEmCzLrpB4WWn2PdpdTrOcDj+aJfWHeGL4sIPwEKgrKnTQg9QD8CCsm5wew9P/br39OuIfsC6/PFBEHmVThqj0aMxYLRD4K2GoRay6Ab7NftoIP5dnFnclfRxETAoNpTPE2F5Q669QySrdXxBpBSk8GLmdCDMlhiyzSiByrhFQaZRcH8n9i+i289otYuJQ7xPyP19KwT4CRyOiIlh3DSdlBfurMwihQGxN2spU7P4MwckrDKeOyYQhvNm/XWId/oXBqpHbo2yRPiOwL9p1J4AxA4RaJuh77vyhn2lFQaxPDqZd5A8RJjpb2NE2N3UncKLW7GAangdoLbRDMqt51VMZ0la+b/moL61fKvFXinKRHc7PybrG3MWzgXxO/VMKAuXOsB9XnOgl2A524cgiwyg==</CipherValue>
</CipherData>
</EncryptedData>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport"></wsse:KeyIdentifier>
<wsse:Reference URI="#BinaryDAToken0"></wsse:Reference>
</wst:RequestedTokenReference>
<wst:RequestedProofToken>
<wst:BinarySecret>tgoPVK67sU36fQKlGLMgWgTXp7oiaQgE</wst:BinarySecret>
</wst:RequestedProofToken>
</wst:RequestSecurityTokenResponse>
{{ tokenxml }}
</wst:RequestSecurityTokenResponseCollection>
</S:Body>
</S:Envelope>
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<S:Header>
<psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<psf:serverVersion>1</psf:serverVersion>
<psf:authstate>0x80048800</psf:authstate>
<psf:reqstatus>0x80048821</psf:reqstatus>
<psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="{{ timez }}" BuildVersion="16.0.28426.6">XYZPPLOGN1A23 2017.09.28.12.44.07</psf:serverInfo>
<psf:cookies/>
<psf:response/>
</psf:pp>
</S:Header>
<S:Body>
<S:Fault>
<S:Code>
<S:Value>S:Sender</S:Value>
<S:Subcode>
<S:Value>wst:FailedAuthentication</S:Value>
</S:Subcode>
</S:Code>
<S:Reason>
<S:Text xml:lang="en-US">Authentication Failure</S:Text>
</S:Reason>
<S:Detail>
<psf:error>
<psf:value>0x80048821</psf:value>
<psf:internalerror>
<psf:code>0x80041012</psf:code>
<psf:text>The entered and stored passwords do not match.&#x000D;&#x000A;</psf:text>
</psf:internalerror>
</psf:error>
</S:Detail>
</S:Fault>
</S:Body>
</S:Envelope>
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<S:Body>
<S:Fault>
<S:Code>
<S:Value>S:Sender</S:Value>
<S:Subcode>
<S:Value>wst:InvalidRequest</S:Value>
</S:Subcode>
</S:Code>
<S:Reason>
<S:Text xml:lang="en-US">Invalid Request</S:Text>
</S:Reason>
<S:Detail>
<psf:error>
<psf:value>0x80048820</psf:value>
<psf:internalerror>
<psf:code>0x80045c01</psf:code>
<psf:text>Invalid STS request.&#x000D;&#x000A;</psf:text>
</psf:internalerror>
</psf:error>
</S:Detail>
</S:Fault>
</S:Body>
</S:Envelope>
+30
View File
@@ -0,0 +1,30 @@
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:compact</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:EndpointReference>
<wsa:Address>{{ domain }}</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:Lifetime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:Lifetime>
<wst:RequestedSecurityToken>
<wsse:BinarySecurityToken Id="Compact{{ i }}">t={{ pptoken1 }}Y6+H31sTUOFkqjNTDYqAAFLr5Ote7BMrMnUIzpg860jh084QMgs5djRQLLQP0TVOFkKdWDwAJdEWcfsI9YL8otN9kSfhTaPHR1njHmG0H98O2NE/Ck6zrog3UJFmYlCnHidZk1g3AzUNVXmjZoyMSyVvoHLjQSzoGRpgHg3hHdi7zrFhcYKWD8XeNYdoz9wfA2YAAAgZIgF9kFvsy2AC0Fl/ezc/fSo6YgB9TwmXyoK0wm0F9nz5EfhHQLu2xxgsvMOiXUSFSpN1cZaNzEk/KGVa3Z33Mcu0qJqvXoLyv2VjQyI0VLH6YlW5E+GMwWcQurXB9hT/DnddM5Ggzk3nX8uMSV4kV+AgF1EWpiCdLViRI6DmwwYDtUJU6W6wQXsfyTm6CNMv0eE0wFXmZvoKaL24fggkp99dX+m1vgMQJ39JblVH9cmnnkBQcKkV8lnQJ003fd6iIFzGpgPBW5Z3T1Bp7uzSGMWnHmrEw8eOpKC5ny4x8uoViXDmA2UId23xYSoJ/GQrMjqB+NslqnuVsOBE1oWpNrmfSKhGU1X0kR4Eves56t5i5n3XU+7ne0MkcUzlrMi89n2j8aouf0zeuD7o+ngqvfRCsOqjaU71XWtuD4ogu2X7/Ajtwkxg/UJDFGAnCxFTTd4dqrrEpKyMK8eWBMaartFxwwrH39HMpx1T9JgknJ1hFWELzG8b302sKy64nCseOTGaZrdH63pjGkT7vzyIxVH/b+yJwDRmy/PlLz7fmUj6zpTBNmCtl1EGFOEFdtI2R04EprIkLXbtpoIPA7m0TPZURpnWufCSsDtD91ChxR8j/FnQ/gOOyKg/EJrTcHvM1e50PMRmoRZGlltBRRwBV+ArPO64On6zygr5zud5o/aADF1laBjkuYkjvUVsXwgnaIKbTLN2+sr/WjogxT1Yins79jPa1+3dDenxZtE/rHA/6qsdJmo5BJZqNYQUFrnpkU428LryMnBaNp2BW51JRsWXPAA7yCi0wDlHzEDxpqaOnhI4Ol87ra+VAg==&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>
<wst:RequestedAttachedReference>
<wsse:SecurityTokenReference>
<wsse:Reference URI="/DaESnwwMVTTpRTZEoNqUW/Md0k="></wsse:Reference>
</wsse:SecurityTokenReference>
</wst:RequestedAttachedReference>
<wst:RequestedUnattachedReference>
<wsse:SecurityTokenReference>
<wsse:Reference URI="/DaESnwwMVTTpRTZEoNqUW/Md0k="></wsse:Reference>
</wsse:SecurityTokenReference>
</wst:RequestedUnattachedReference>
{% if domain == 'messengerclear.live.com' %}
<wst:RequestedProofToken>
<wst:BinarySecret>{{ binarysecret }}</wst:BinarySecret>
</wst:RequestedProofToken>
{% endif %}
</wst:RequestSecurityTokenResponse>
+96
View File
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<S:Header>
<wsa:Action xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Action" S:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue</wsa:Action>
<wsa:To xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="To" S:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
<wsse:Security S:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="TS">
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ time_5mz }}</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
<psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<psf:serverVersion>1</psf:serverVersion>
<psf:PUID>{{ puidhex }}</psf:PUID>
<psf:configVersion>16.000.26889.00</psf:configVersion>
<psf:uiVersion>3.100.2179.0</psf:uiVersion>
<psf:mobileConfigVersion>16.000.26208.0</psf:mobileConfigVersion>
<psf:appDataVersion>1</psf:appDataVersion>
<psf:authstate>0x48803</psf:authstate>
<psf:reqstatus>0x0</psf:reqstatus>
<psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="{{ timez }}">XYZPPLOGN1A23 2017.09.28.12.44.07</psf:serverInfo>
<psf:cookies/>
<psf:browserCookies>
<psf:browserCookie Name="MH" URL="http://www.msn.com">MSFT; path=/; domain=.msn.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.msn.com">; path=/; domain=.msn.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MH" URL="http://www.live.com">MSFT; path=/; domain=.live.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.live.com">; path=/; domain=.live.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
</psf:browserCookies>
<psf:credProperties>
<psf:credProperty Name="MainBrandID">MSFT</psf:credProperty>
<psf:credProperty Name="BrandIDList"></psf:credProperty>
<psf:credProperty Name="IsWinLiveUser">true</psf:credProperty>
<psf:credProperty Name="CID">{{ cid }}</psf:credProperty>
<psf:credProperty Name="AuthMembername">{{ email }}</psf:credProperty>
<psf:credProperty Name="Country">US</psf:credProperty>
<psf:credProperty Name="Language">1033</psf:credProperty>
<psf:credProperty Name="FirstName">{{ firstname }}</psf:credProperty>
<psf:credProperty Name="LastName">{{ lastname }}</psf:credProperty>
<psf:credProperty Name="ChildFlags">00000001</psf:credProperty>
<psf:credProperty Name="Flags">40100643</psf:credProperty>
<psf:credProperty Name="FlagsV2">00000000</psf:credProperty>
<psf:credProperty Name="IP">{{ ip }}</psf:credProperty>
<psf:credProperty Name="AssociatedForStrongAuth">0</psf:credProperty>
</psf:credProperties>
<psf:extProperties>
<psf:extProperty Name="ANON" Expiry="Wed, 30-Dec-2037 16:00:00 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">A=B97FB2EE7DB4CE0D0D5B8107FFFFFFFF&amp;E=1542&amp;W=1</psf:extProperty>
<psf:extProperty Name="NAP" Expiry="Wed, 30-Dec-2037 16:00:00 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">V=1.9&amp;E=14e8&amp;C=uT838e-8kV7Jbm-HqQel-ETkvE7QSUGh6ywMjZQ9JJyYtNKxtdfCBw&amp;W=1</psf:extProperty>
<psf:extProperty Name="LastUsedCredType">1</psf:extProperty>
<psf:extProperty Name="WebCredType">1</psf:extProperty>
<psf:extProperty Name="CID">{{ cid }}</psf:extProperty>
</psf:extProperties>
<psf:response/>
</psf:pp>
</S:Header>
<S:Body>
<wst:RequestSecurityTokenResponseCollection xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:legacy</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:EndpointReference>
<wsa:Address>http://Passport.NET/tb</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:Lifetime>
<wsu:Created>{{ timez }}</wsu:Created>
<wsu:Expires>{{ tomorrowz }}</wsu:Expires>
</wst:Lifetime>
<wst:RequestedSecurityToken>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Id="BinaryDAToken0" Type="http://www.w3.org/2001/04/xmlenc#Element">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"></EncryptionMethod>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>http://Passport.NET/STS</ds:KeyName>
</ds:KeyInfo>
<CipherData>
<CipherValue>Cap26AQZrSyMm2SwwTyJKyqLR9/S+vQWQsaBc5Mv7PwtQDMzup/udOOMMvSu99R284pmiD3IepBXrEMLK5rLrXAf2A6vrP6vYuGA45GCqQdoxusHZcjt9P2B8WyCTVT2cM8jtGqGIfRlU/4WzOLxNrDJwDfOsmilduGAGZfvRPW7/jyXXrnGK7/PWkymX4YDD+ygJfMrPAfvAprvw/HVE6tutKVc9cViTVYy8oHjosQlb8MKn3vKDW1O2ZWQUc47JPl7DkjQaanfNBGe6CL7K1nr6Z/jy7Ay7MjV+KQehmvphSEmCzLrpB4WWn2PdpdTrOcDj+aJfWHeGL4sIPwEKgrKnTQg9QD8CCsm5wew9P/br39OuIfsC6/PFBEHmVThqj0aMxYLRD4K2GoRay6Ab7NftoIP5dnFnclfRxETAoNpTPE2F5Q669QySrdXxBpBSk8GLmdCDMlhiyzSiByrhFQaZRcH8n9i+i289otYuJQ7xPyP19KwT4CRyOiIlh3DSdlBfurMwihQGxN2spU7P4MwckrDKeOyYQhvNm/XWId/oXBqpHbo2yRPiOwL9p1J4AxA4RaJuh77vyhn2lFQaxPDqZd5A8RJjpb2NE2N3UncKLW7GAangdoLbRDMqt51VMZ0la+b/moL61fKvFXinKRHc7PybrG3MWzgXxO/VMKAuXOsB9XnOgl2A524cgiwyg==</CipherValue>
</CipherData>
</EncryptedData>
</wst:RequestedSecurityToken>
<wst:RequestedAttachedReference>
<wsse:SecurityTokenReference>
<wsse:Reference URI="2jmj7l5rSw0yVb/vlWAYkK/YBwk="></wsse:Reference>
</wsse:SecurityTokenReference>
</wst:RequestedAttachedReference>
<wst:RequestedUnattachedReference>
<wsse:SecurityTokenReference>
<wsse:Reference URI="2jmj7l5rSw0yVb/vlWAYkK/YBwk="></wsse:Reference>
</wsse:SecurityTokenReference>
</wst:RequestedUnattachedReference>
<wst:RequestedProofToken>
<wst:BinarySecret>tgoPVK67sU36fQKlGLMgWgTXp7oiaQgE</wst:BinarySecret>
</wst:RequestedProofToken>
</wst:RequestSecurityTokenResponse>
{{ tokenxml }}
</wst:RequestSecurityTokenResponseCollection>
</S:Body>
</S:Envelope>
+242
View File
@@ -0,0 +1,242 @@
{% macro contact_entry(ab_id, ctc, detail, now) %}
<contactId>{{ ctc.head.uuid }}</contactId>
<contactInfo>
{% if ctc.detail.personal_email or ctc.detail.work_phone or ctc.detail.im_email or ctc.detail.other_email %}
<emails>
{% if ctc.detail.work_email %}
{{ email_entry('ContactEmailBusiness', ctc.detail.work_email) }}
{% endif %}
{% if ctc.detail.im_email %}
{{ email_entry('ContactEmailMessenger', ctc.detail.im_email) }}
{% endif %}
{% if ctc.detail.other_email %}
{{ email_entry('ContactEmailOther', ctc.detail.other_email) }}
{% endif %}
{% if ctc.detail.personal_email %}
{{ email_entry('ContactEmailPersonal', ctc.detail.personal_email) }}
{% endif %}
</emails>
{% endif %}
{% if ctc.detail.home_phone or ctc.detail.work_phone or ctc.detail.fax_phone or ctc.detail.pager_phone or ctc.detail.mobile_phone or ctc.detail.other_phone %}
<phones>
{% if ctc.detail.work_phone %}
{{ phone_entry('ContactPhoneBusiness', contact.work_phone) }}
{% endif %}
{% if ctc.detail.fax_phone %}
{{ phone_entry('ContactPhoneFax', ctc.detail.fax_phone) }}
{% endif %}
{% if ctc.detail.pager_phone %}
{{ phone_entry('ContactPhonePager', ctc.detail.pager_phone) }}
{% endif %}
{% if ctc.detail.mobile_phone %}
{{ phone_entry('ContactPhoneMobile', ctc.detail.mobile_phone) }}
{% endif %}
{% if ctc.detail.other_phone %}
{{ phone_entry('ContactPhoneOther', ctc.detail.other_phone) }}
{% endif %}
{% if ctc.detail.home_phone %}
{{ phone_entry('ContactPhonePersonal', ctc.detail.home_phone) }}
{% endif %}
</phones>
{% endif %}
{% if ctc.detail.locations %}
<locations>
{% for location in ctc.detail.locations.values() %}
{% if location.street or location.city or location.state or location.country or location.zip_code %}
<ContactLocation>
<contactLocationType>{{ location.type }}</contactLocationType>
{% if location.street %}
<street>{{ location.street }}</street>
{% endif %}
{% if location.city %}
<city>{{ location.city }}</city>
{% endif %}
{% if location.state %}
<state>{{ location.state }}</state>
{% endif %}
{% if location.country %}
<country>{{ location.country }}</country>
{% endif %}
{% if location.zip_code %}
<postalCode>{{ location.zip_code }}</postalCode>
{% endif %}
</ContactLocation>
{% endif %}
{% endfor %}
</locations>
{% endif %}
{% if ctc.detail.personal_website or ctc.detail.business_website %}
<webSites>
{% if ctc.detail.business_website %}
{{ website_entry('ContactWebSiteBusiness', ctc.detail.business_website) }}
{% endif %}
{% if ctc.detail.personal_website %}
{{ website_entry('ContactWebSitePersonal', ctc.detail.personal_website) }}
{% endif %}
</webSites>
{% endif %}
{% if ctc.detail.nickname %}
<annotations>
{{ annotation('AB.NickName', ctc.detail.nickname) }}
</annotations>
{% endif %}
<contactType>Regular</contactType>
<quickName>{{ ctc.status.name }}</quickName>
{% if ctc.detail.first_name %}
<firstName>{{ ctc.detail.first_name }}</firstName>
{% endif %}
{% if ctc.detail.middle_name %}
<MiddleName>{{ ctc.detail.middle_name }}</MiddleName>
{% endif %}
{% if ctc.detail.last_name %}
<lastName>{{ ctc.detail.last_name }}</lastName>
{% endif %}
<passportName>{{ ctc.head.email }}</passportName>
<IsPassportNameHidden>false</IsPassportNameHidden>
<displayName>{{ ctc.status.name }}</displayName>
<puid>{{ puid_format(ctc.head.uuid) }}</puid>
{% if ctc._groups %}
<groupIds>
{% for group in ctc._groups.copy() %}
<guid>{{ group.uuid }}</guid>
{% endfor %}
</groupIds>
{% endif %}
<CID>{{ cid_format(ctc.head.uuid, decimal = True) }}</CID>
<IsNotMobileVisible>false</IsNotMobileVisible>
<isMobileIMEnabled>false</isMobileIMEnabled>
<isMessengerUser>{{ bool_to_str(ctc.is_messenger_user) }}</isMessengerUser>
<isFavorite>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}{{ bool_to_str(contact_is_favorite(detail, ctc)) }}{% else %}false{% endif %}</isFavorite>
<isSmtp>false</isSmtp>
<hasSpace>false</hasSpace>
<spotWatchState>NoDevice</spotWatchState>
<birthdate>{% if ctc.detail.birthdate %}{{ date_format(ctc.detail.birthdate) }}{% else %}0001-01-01T00:00:00{% endif %}</birthdate>
{% if ctc.detail.anniversary %}
<Anniversary>{{ ctc.detail.anniversary.strftime('%Y/%m/%d') }}</Anniversary>
{% endif %}
{% if ctc.detail.notes %}
<comment>{{ ctc.detail.notes }}</comment>
{% endif %}
<primaryEmailType>{% if ctc.detail.primary_email_type %}{{ ctc.detail.primary_email_type }}{% else %}ContactEmailPersonal{% endif %}</primaryEmailType>
<PrimaryLocation>ContactLocationPersonal</PrimaryLocation>
<PrimaryPhone>ContactPhonePersonal</PrimaryPhone>
<IsPrivate>false</IsPrivate>
<Gender>Unspecified</Gender>
<TimeZone>None</TimeZone>
</contactInfo>
<propertiesChanged />
<fDeleted>false</fDeleted>
<lastChange>{{ now }}</lastChange>
{% endmacro %}
{% macro phone_entry(type, phone) %}
<ContactPhone>
<contactPhoneType>{{ type }}</contactPhoneType>
<number>{{ phone }}</number>
<isMessengerEnabled>false</isMessengerEnabled>
</ContactPhone>
{% endmacro %}
{% macro email_entry(type, email) %}
<ContactEmail>
<contactEmailType>{{ type }}</contactEmailType>
<email>{{ email }}</email>
<isMessengerEnabled>false</isMessengerEnabled>
<Capability>0</Capability>
<MessengerEnabledExternally>false</MessengerEnabledExternally>
</ContactEmail>
{% endmacro %}
{% macro website_entry(type, url) %}
<ContactWebSite>
<contactWebSiteType>{{ type }}</contactWebSiteType>
<webURL>{{ url }}</webURL>
</ContactWebSite>
{% endmacro %}
{% macro annotation(name, value) %}
<Annotation>
<Name>{{ name }}</Name>
<Value>{{ value }}</Value>
</Annotation>
{% endmacro %}
{% macro generate_me_entry(user, now) %}
<Contact>
<contactId>{{ user.uuid }}</contactId>
<contactInfo>
<annotations>
<Annotation>
<Name>MSN.IM.MBEA</Name>
<Value>0</Value>
</Annotation>
<Annotation>
<Name>MSN.IM.GTC</Name>
<Value>{% if user.settings.get('GTC') == 'A' %}1{% elif user.settings.get('GTC') == 'N' %}2{% else %}0{% endif %}</Value>
</Annotation>
<Annotation>
<Name>MSN.IM.BLP</Name>
<Value>{% if user.settings.get('BLP') == 'AL' %}1{% elif user.settings.get('BLP') == 'BL' %}2{% else %}0{% endif %}</Value>
</Annotation>
{% if user.settings.get('MPOP') %}
<Annotation>
<Name>MSN.IM.MPOP</Name>
<Value>{{ user.settings.get('MPOP') }}</Value>
</Annotation>
{% endif %}
{% if user.settings.get('RLP') %}
<Annotation>
<Name>MSN.IM.RoamLiveProperties</Name>
<Value>{{ user.settings.get('RLP') }}</Value>
</Annotation>
{% endif %}
</annotations>
<contactType>Me</contactType>
<quickName>{{ user.status.name }}</quickName>
<passportName>{{ user.email }}</passportName>
<IsPassportNameHidden>false</IsPassportNameHidden>
<displayName>{{ user.status.name }}</displayName>
<puid>{{ puid_format(user.uuid) }}</puid>
<CID>{{ cid_format(user.uuid, decimal = True) }}</CID>
<IsNotMobileVisible>false</IsNotMobileVisible>
<isMobileIMEnabled>false</isMobileIMEnabled>
<isMessengerUser>false</isMessengerUser>
<isFavorite>false</isFavorite>
<isSmtp>false</isSmtp>
<hasSpace>false</hasSpace>
<spotWatchState>NoDevice</spotWatchState>
<birthdate>0001-01-01T00:00:00</birthdate>
<primaryEmailType>ContactEmailPersonal</primaryEmailType>
<PrimaryLocation>ContactLocationPersonal</PrimaryLocation>
<PrimaryPhone>ContactPhonePersonal</PrimaryPhone>
<IsPrivate>false</IsPrivate>
<Gender>Unspecified</Gender>
<TimeZone>None</TimeZone>
</contactInfo>
<propertiesChanged />
<fDeleted>false</fDeleted>
<lastChange>{{ now }}</lastChange>
</Contact>
{% endmacro %}
{% macro group_entry(group, now) %}
<Group>
<groupId>{{ group.uuid }}</groupId>
<groupInfo>
<annotations>
<Annotation>
<Name>MSN.IM.Display</Name>
<Value>1</Value>
</Annotation>
</annotations>
<groupType>c8529ce2-6ead-434d-881f-341e17db3ff8</groupType>
<name>{{ group.name }}</name>
<IsNotMobileVisible>false</IsNotMobileVisible>
<IsPrivate>false</IsPrivate>
<IsFavorite>{{ bool_to_str(group.is_favorite) }}</IsFavorite>
</groupInfo>
<propertiesChanged />
<fDeleted>false</fDeleted>
<lastChange>{{ now }}</lastChange>
</Group>
{% endmacro %}
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABContactAddResponse xmlns="http://www.msn.com/webservices/AddressBook">
<ABContactAddResult>
<guid>{{ contact_uuid }}</guid>
</ABContactAddResult>
</ABContactAddResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABContactDeleteResponse xmlns="http://www.msn.com/webservices/AddressBook"/>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABContactUpdateResponse xmlns="http://www.msn.com/webservices/AddressBook" />
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,54 @@
{% from 'msn:_funcs.xml' import contact_entry, group_entry, generate_me_entry, ab_properties %}
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABFindAllResponse xmlns="http://www.msn.com/webservices/AddressBook">
<ABFindAllResult>
<groups>
{% for group in detail._groups_by_uuid.values() %}
{{ group_entry(group, now) }}
{% endfor %}
</groups>
<contacts>
{% for ctc in detail.contacts.values() %}
{% if ctc.lists.__and__(ContactList.FL) %}
<Contact>
{{ contact_entry(ab_id, ctc, detail, now) }}
</Contact>
{% endif %}
{% endfor %}
{{ generate_me_entry(user, now) }}
</contacts>
<ab>
<abId>{{ ab_id }}</abId>
<abInfo>
<ownerPuid>0</ownerPuid>
<OwnerCID>{{ cid_format(user.uuid, decimal = True) }}</OwnerCID>
<ownerEmail>{{ user.email }}</ownerEmail>
<fDefault>true</fDefault>
<joinedNamespace>false</joinedNamespace>
<IsBot>false</IsBot>
<IsParentManaged>false</IsParentManaged>
<SubscribeExternalPartner>false</SubscribeExternalPartner>
<NotifyExternalPartner>false</NotifyExternalPartner>
<AddressBookType>Individual</AddressBookType>
</abInfo>
<lastChange>{{ now }}</lastChange>
<DynamicItemLastChanged>0001-01-01T00:00:00</DynamicItemLastChanged>
<createDate>{{ date_format(user.date_created) }}</createDate>
<propertiesChanged />
</ab>
</ABFindAllResult>
</ABFindAllResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,270 @@
{% from 'msn:_funcs.xml' import contact_entry, group_entry, generate_me_entry, ab_properties %}
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABFindContactsPagedResponse xmlns="http://www.msn.com/webservices/AddressBook">
<ABFindContactsPagedResult>
{% if ab_id == '00000000-0000-0000-0000-000000000000' %}
<Groups>
{% for group in detail._groups_by_uuid.values() %}
{{ group_entry(group, now) }}
{% endfor %}
</Groups>
{% endif %}
<Contacts>
{% if ab_id == '00000000-0000-0000-0000-000000000000' %}
{% for ctc in detail.contacts.values() %}
{% if ctc.lists.__and__(ContactList.FL) %}
<Contact>
{{ contact_entry(ab_id, ctc, detail, now) }}
</Contact>
{% endif %}
{% endfor %}
{% for circle in circles %}
<Contact>
<contactId>00000000-0000-0000-0009-{{ circle.chat_id }}</contactId>
<contactInfo>
<contactType>Circle</contactType>
<quickName>circle</quickName>
<passportName>00000000-0000-0000-0009-{{ circle.chat_id.upper() }}@hotmail.com</passportName>
<IsPassportNameHidden>false</IsPassportNameHidden>
<displayName>{% if circle.memberships[user.uuid].role == CircleRole.Admin %}{{ circle.name }}{% else %}00000000-0000-0000-0009-{{ circle.chat_id.upper() }}@hotmail.com{% endif %}</displayName>
<puid>{{ puid_format(user.uuid) }}</puid>
<CID>{{ cid_format('00000000-0000-0000-0009-' + circle.chat_id, decimal = True) }}</CID>
<IsNotMobileVisible>false</IsNotMobileVisible>
<isMobileIMEnabled>false</isMobileIMEnabled>
<isMessengerUser>false</isMessengerUser>
<isFavorite>false</isFavorite>
<isSmtp>false</isSmtp>
<hasSpace>false</hasSpace>
<spotWatchState>NoDevice</spotWatchState>
<birthdate>0001-01-01T00:00:00</birthdate>
<primaryEmailType>ContactEmailPersonal</primaryEmailType>
<PrimaryLocation>ContactLocationPersonal</PrimaryLocation>
<PrimaryPhone>ContactPhonePersonal</PrimaryPhone>
<IsPrivate>false</IsPrivate>
<IsHidden>true</IsHidden>
<Gender>Unspecified</Gender>
<TimeZone>None</TimeZone>
<NetworkInfoList>
<NetworkInfo>
<DomainId>1</DomainId>
<SourceId>WL</SourceId>
{% if circle.memberships[user.uuid].role != CircleRole.Admin %}
<DomainTag>00000000-0000-0000-0009-{{ circle.chat_id.upper() }}</DomainTag>
<DisplayName>00000000-0000-0000-0009-{{ circle.chat_id.upper() }}</DisplayName>
{% endif %}
<RelationshipType>5</RelationshipType>
<RelationshipState>{{ circle.memberships[user.uuid].state.value }}</RelationshipState>
<RelationshipStateDate>{{ now }}</RelationshipStateDate>
<RelationshipRole>{% if circle.memberships[user.uuid].role == CircleRole.StatePendingOutbound %}4{% else %}0{% endif %}</RelationshipRole>
<NDRCount>0</NDRCount>
{% if circle.memberships[user.uuid].invite_message %}
<InviterMessage>{{ circle.memberships[user.uuid].invite_message }}</InviterMessage>
{% endif %}
<InviterCID>{% if user.uuid == circle.owner_uuid %}0{% else %}{{ cid_format(circle.memberships[user.uuid].inviter_uuid, decimal = True) }}{% endif %}</InviterCID>
{% if circle.memberships[user.uuid].inviter_name %}
<InviterName>{{ circle.memberships[user.uuid].inviter_name }}</InviterName>
{% endif %}
{% if circle.memberships[user.uuid].inviter_email %}
<InviterEmail>{{ circle.memberships[user.uuid].inviter_email }}</InviterEmail>
{% endif %}
<CreateDate>{{ now }}</CreateDate>
<LastUpdated>{{ now }}</LastUpdated>
<PropertiesChanged />
</NetworkInfo>
</NetworkInfoList>
<IsAutoUpdateDisabled>false</IsAutoUpdateDisabled>
<IsShellContact>false</IsShellContact>
<TrustLevel>0</TrustLevel>
<PropertiesChanged />
</contactInfo>
<propertiesChanged />
<fDeleted>false</fDeleted>
<CreateDate>{{ now }}</CreateDate>
<lastChange>{{ now }}</lastChange>
<CreatedBy>96</CreatedBy>
</Contact>
{% endfor %}
{% else %}
{% for membership in circle.memberships.values() %}
<Contact>
<contactId>{{ membership.head.uuid }}</contactId>
<contactInfo>
<contactType>{% if membership.state == CircleState.WaitingResponse or membership.state == CircleState.Rejected or (membership.role == CircleRole.Empty and membership.state == CircleState.Empty) %}LivePending{% else %}Live{% endif %}</contactType>
<quickName>{{ membership.head.email }}</quickName>
<passportName>{{ membership.head.email }}</passportName>
<IsPassportNameHidden>false</IsPassportNameHidden>
<displayName>{{ membership.head.email }}</displayName>
<puid>{{ puid_format(user.uuid) }}</puid>
<CID>{{ cid_format(membership.head.uuid, decimal = True) }}</CID>
<IsNotMobileVisible>false</IsNotMobileVisible>
<isMobileIMEnabled>false</isMobileIMEnabled>
<isMessengerUser>false</isMessengerUser>
<isFavorite>false</isFavorite>
<isSmtp>false</isSmtp>
<hasSpace>false</hasSpace>
<spotWatchState>NoDevice</spotWatchState>
<birthdate>0001-01-01T00:00:00</birthdate>
<primaryEmailType>ContactEmailPersonal</primaryEmailType>
<PrimaryLocation>ContactLocationPersonal</PrimaryLocation>
<PrimaryPhone>ContactPhonePersonal</PrimaryPhone>
<IsPrivate>false</IsPrivate>
<IsHidden>false</IsHidden>
<Gender>Unspecified</Gender>
<TimeZone>None</TimeZone>
{% if not (membership.role == CircleRole.Empty or membership.state == CircleState.Empty) %}
<NetworkInfoList>
<NetworkInfo>
<DomainId>1</DomainId>
<SourceId>WL</SourceId>
<RelationshipType>5</RelationshipType>
<RelationshipState>{% if membership.state == CircleState.WaitingResponse %}2{% else %}{{ membership.state.value }}{% endif %}</RelationshipState>
<RelationshipStateDate>{{ now }}</RelationshipStateDate>
<RelationshipRole>{% if membership.role == CircleRole.StatePendingOutbound %}3{% else %}{{ membership.role.value }}{% endif %}</RelationshipRole>
<NDRCount>0</NDRCount>
{% if membership.invite_message %}
<InviterMessage>{{ membership.invite_message }}</InviterMessage>
{% endif %}
<InviterCID>{% if membership.head.uuid == circle.owner_uuid %}0{% else %}{{ cid_format(membership.inviter_uuid, decimal = True) }}{% endif %}</InviterCID>
{% if membership.inviter_name %}
<InviterName>{{ membership.inviter_name }}</InviterName>
{% endif %}
{% if membership.inviter_email %}
<InviterEmail>{{ membership.inviter_email }}</InviterEmail>
{% endif %}
<CreateDate>{{ now }}</CreateDate>
<LastUpdated>{{ now }}</LastUpdated>
<PropertiesChanged />
</NetworkInfo>
</NetworkInfoList>
{% endif %}
<IsAutoUpdateDisabled>false</IsAutoUpdateDisabled>
<IsShellContact>false</IsShellContact>
<TrustLevel>0</TrustLevel>
<PropertiesChanged />
</contactInfo>
<propertiesChanged />
<fDeleted>{% if membership.state == CircleState.Rejected or (membership.state == CircleState.Empty and not membership.role == CircleRole.Empty) %}true{% else %}false{% endif %}</fDeleted>
<CreateDate>{{ now }}</CreateDate>
<lastChange>{{ now }}</lastChange>
<CreatedBy>96</CreatedBy>
</Contact>
{% endfor %}
{% endif %}
{% if ab_id.startswith('00000000-0000-0000-0009-') %}
<Contact>
<contactId>{{ ab_id }}</contactId>
<contactInfo>
<contactType>Me</contactType>
<quickName>{{ ab_id }}</quickName>
<passportName>{{ ab_id }}@live.com</passportName>
<IsPassportNameHidden>false</IsPassportNameHidden>
<displayName>{{ ab_id }}@live.com</displayName>
<puid>{{ puid_format(user.uuid) }}</puid>
<CID>{{ cid_format(ab_id, decimal = True) }}</CID>
<IsNotMobileVisible>false</IsNotMobileVisible>
<isMobileIMEnabled>false</isMobileIMEnabled>
<isMessengerUser>false</isMessengerUser>
<isFavorite>false</isFavorite>
<isSmtp>false</isSmtp>
<hasSpace>false</hasSpace>
<spotWatchState>NoDevice</spotWatchState>
<birthdate>0001-01-01T00:00:00</birthdate>
<primaryEmailType>ContactEmailPersonal</primaryEmailType>
<PrimaryLocation>ContactLocationPersonal</PrimaryLocation>
<PrimaryPhone>ContactPhonePersonal</PrimaryPhone>
<IsPrivate>false</IsPrivate>
<Gender>Unspecified</Gender>
<TimeZone>None</TimeZone>
</contactInfo>
<propertiesChanged />
<fDeleted>false</fDeleted>
<lastChange>{{ now }}</lastChange>
</Contact>
{% else %}
{{ generate_me_entry(user, now) }}
{% endif %}
</Contacts>
{% if ab_id == '00000000-0000-0000-0000-000000000000' %}
<CircleResult>
{% if circles %}
<Circles>
{% for circle in circles %}
{% if circle.memberships[user.uuid].state == CircleState.Accepted or circle.memberships[user.uuid].state == CircleState.WaitingResponse %}
<CircleInverseInfo>
<Content>
<Handle>
<Id>00000000-0000-0000-0009-{{ circle.chat_id }}</Id>
</Handle>
<Info>
<Domain>1</Domain>
<HostedDomain>live.com</HostedDomain>
<Type>2</Type>
<MembershipAccess>{{ circle.membership_access }}</MembershipAccess>
<IsPresenceEnabled>true</IsPresenceEnabled>
<RequestMembershipOption>{{ circle.request_membership_option }}</RequestMembershipOption>
<DisplayName>{{ circle.name }}</DisplayName>
<ProfileLastUpdated>0001-01-01T00:00:00</ProfileLastUpdated>
<Changes />
<CreateDate>0001-01-01T00:00:00</CreateDate>
<LastUpdated>{{ now }}</LastUpdated>
</Info>
</Content>
<PersonalInfo>
<MembershipInfo>
<CirclePersonalMembership>
<Role>{{ circle.memberships[user.uuid].role.name }}</Role>
<State>{{ circle.memberships[user.uuid].state.name }}</State>
</CirclePersonalMembership>
</MembershipInfo>
<Name>{{ circle.name }}</Name>
<IsNotMobileVisible>false</IsNotMobileVisible>
<IsFavorite>false</IsFavorite>
<IsFamily>false</IsFamily>
<Changes />
</PersonalInfo>
<Deleted>false</Deleted>
</CircleInverseInfo>
{% endif %}
{% endfor %}
</Circles>
{% endif %}
<CircleTicket>{{ signedticket }}</CircleTicket>
</CircleResult>
{% endif %}
<Ab>
<abId>{{ ab_id }}</abId>
<abInfo>
<ownerPuid>0</ownerPuid>
<OwnerCID>{% if ab_id.startswith('00000000-0000-0000-0009-') %}{{ cid_format(ab_id, decimal = True) }}{% else %}{{ cid_format(user.uuid, decimal = True) }}{% endif %}</OwnerCID>
<ownerEmail>{% if ab_id.startswith('00000000-0000-0000-0009-') %}{{ ab_id }}@live.com{% else %}{{ user.email }}{% endif %}</ownerEmail>
<fDefault>true</fDefault>
<joinedNamespace>false</joinedNamespace>
<IsBot>false</IsBot>
<IsParentManaged>false</IsParentManaged>
<AccountTierLastChanged>0001-01-01T00:00:00</AccountTierLastChanged>
<ProfileVersion>0</ProfileVersion>
<SubscribeExternalPartner>false</SubscribeExternalPartner>
<NotifyExternalPartner>false</NotifyExternalPartner>
<AddressBookType>{{ ab_type }}</AddressBookType>
</abInfo>
<lastChange>{{ now }}</lastChange>
<DynamicItemLastChanged>0001-01-01T00:00:00</DynamicItemLastChanged>
<createDate>{{ date_format(user.date_created) }}</createDate>
<propertiesChanged />
</Ab>
</ABFindContactsPagedResult>
</ABFindContactsPagedResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABGroupAddResponse xmlns="http://www.msn.com/webservices/AddressBook">
<ABGroupAddResult>
<guid>{{ group_id }}</guid>
</ABGroupAddResult>
</ABGroupAddResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABGroupContactAddResponse xmlns="http://www.msn.com/webservices/AddressBook">
<ABGroupContactAddResult>
<guid>{{ contact_uuid }}</guid>
</ABGroupContactAddResult>
</ABGroupContactAddResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABGroupContactDeleteResponse xmlns="http://www.msn.com/webservices/AddressBook"/>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABGroupDeleteResponse xmlns="http://www.msn.com/webservices/AddressBook"/>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ABGroupUpdateResponse xmlns="http://www.msn.com/webservices/AddressBook"/>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<BreakConnectionResponse xmlns="http://www.msn.com/webservices/AddressBook"/>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<CreateContactResponse xmlns="http://www.msn.com/webservices/AddressBook">
<CreateContactResult>
<contactId>{{ head.uuid }}</contactId>
<contactInfo>
<contactType>LivePending</contactType>
<quickName>{{ head.email }}</quickName>
<passportName>{{ head.email }}</passportName>
<IsPassportNameHidden>false</IsPassportNameHidden>
<displayName>{{ head.email }}</displayName>
<puid>{{ puid_format(user.uuid) }}</puid>
<CID>{{ cid_format(head.uuid, decimal = True) }}</CID>
<IsNotMobileVisible>false</IsNotMobileVisible>
<isMobileIMEnabled>false</isMobileIMEnabled>
<isMessengerUser>false</isMessengerUser>
<isFavorite>false</isFavorite>
<isSmtp>false</isSmtp>
<hasSpace>false</hasSpace>
<spotWatchState>NoDevice</spotWatchState>
<birthdate>0001-01-01T00:00:00</birthdate>
<primaryEmailType>ContactEmailPersonal</primaryEmailType>
<PrimaryLocation>ContactLocationPersonal</PrimaryLocation>
<PrimaryPhone>ContactPhonePersonal</PrimaryPhone>
<IsPrivate>false</IsPrivate>
<IsHidden>false</IsHidden>
<Gender>Unspecified</Gender>
<TimeZone>None</TimeZone>
<IsAutoUpdateDisabled>false</IsAutoUpdateDisabled>
<IsShellContact>false</IsShellContact>
<TrustLevel>0</TrustLevel>
<PropertiesChanged />
</contactInfo>
<propertiesChanged />
<fDeleted>false</fDeleted>
<CreateDate>{{ now }}</CreateDate>
<lastChange>{{ now }}</lastChange>
<CreatedBy>96</CreatedBy>
</CreateContactResult>
</CreateContactResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Can Not Add Yourself </faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ action_str }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">CanNotAddYourself</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Can Not Add Yourself </errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB133</machineName>
<additionalDetails>
<conflictObjectId>79ACA834-005D-4812-8749-DC976F38BC5D</conflictObjectId>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Contact Already Exists </faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ action_str }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">ContactAlreadyExists</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Contact Already Exists </errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB133</machineName>
<additionalDetails>
<conflictObjectId>79ACA834-005D-4812-8749-DC976F38BC5D</conflictObjectId>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Contact Does Not Exist </faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ action_str }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">ContactDoesNotExist</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Contact Does Not Exist </errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB133</machineName>
<additionalDetails>
<conflictObjectId>79ACA834-005D-4812-8749-DC976F38BC5D</conflictObjectId>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Malformed email Argument Email missing '@' character</faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/ABContactAdd</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">BadEmailArgument</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Malformed email Argument Email missing '@' character</errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB136</machineName>
<additionalDetails>
<originalExceptionErrorMessage>Malformed email Argument Email missing '@' character</originalExceptionErrorMessage>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Malformed email Argument Email missing '.' character</faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/ABContactAdd</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">BadEmailArgument</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Malformed email Argument Email missing '.' character</errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB137</machineName>
<additionalDetails>
<originalExceptionErrorMessage>Malformed email Argument Email missing '.' character</originalExceptionErrorMessage>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Full sync required. Details: Delta syncs disabled.</faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ faultactor }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">FullSyncRequired</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Full sync required. Details: Delta syncs disabled.</errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">DM2CDP1012622</machineName>
<additionalDetails>
<originalExceptionErrorMessage>Full sync required. Details: Delta syncs disabled.</originalExceptionErrorMessage>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Group Already Exists </faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ action_str }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">GroupAlreadyExists</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Group Already Exists </errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB131</machineName>
<additionalDetails>
<conflictObjectId>A4D21A8C-AD06-435F-8AB0-64D8B663FB91</conflictObjectId>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Argument Exceeded Allowed Length GroupName exceeded length</faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ action_str }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">BadArgumentLength</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">Argument Exceeded Allowed Length GroupName exceeded length</errorstring>
<parameterFault xmlns="http://www.msn.com/webservices/AddressBook">GroupName</parameterFault>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB143</machineName>
<additionalDetails>
<originalExceptionErrorMessage>Argument Exceeded Allowed Length GroupName exceeded length</originalExceptionErrorMessage>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>The Passport user specified is invalid SignInName: {{ email }}</faultstring>
<faultactor>http://www.msn.com/webservices/AddressBook/{{ action_str }}</faultactor>
<detail>
<errorcode xmlns="http://www.msn.com/webservices/AddressBook">InvalidPassportUser</errorcode>
<errorstring xmlns="http://www.msn.com/webservices/AddressBook">The Passport user specified is invalid SignInName: {{ email }}</errorstring>
<machineName xmlns="http://www.msn.com/webservices/AddressBook">BAYABCHWBB137</machineName>
<additionalDetails>
<originalExceptionErrorMessage>The Passport user specified is invalid SignInName: {{ email }}</originalExceptionErrorMessage>
</additionalDetails>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<ManageWLConnectionResponse xmlns="http://www.msn.com/webservices/AddressBook">
<ManageWLConnectionResult>
{% if error %}
<clientErrorData>
{{ error }}
</clientErrorData>
{% endif %}
{% if not error %}
<clientErrorData />
<contactId>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}00000000-0000-0000-0009-{{ circle.chat_id }}{% else %}{{ head.uuid }}{% endif %}</contactId>
<contactInfo>
<contactType>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}Circle{% else %}{% if circle.memberships[head.uuid].state == CircleState.WaitingResponse or circle.memberships[head.uuid].state == CircleState.Rejected or (circle.memberships[head.uuid].role == CircleRole.Empty or circle.memberships[head.uuid].state == CircleState.Empty) %}LivePending{% else %}Live{% endif %}{% endif %}</contactType>
<quickName>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}circle{% else %}{{ head.email }}{% endif %}</quickName>
<passportName>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}00000000-0000-0000-0009-{{ circle.chat_id.upper() }}@hotmail.com{% else %}{{ head.email }}{% endif %}</passportName>
<IsPassportNameHidden>false</IsPassportNameHidden>
<displayName>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}{{ circle.name }}{% else %}{{ head.email }}{% endif %}</displayName>
<puid>{{ puid_format(user.uuid) }}</puid>
<CID>{{ cid_format('00000000-0000-0000-0009-' + circle.chat_id, decimal = True) }}</CID>
<IsNotMobileVisible>false</IsNotMobileVisible>
<isMobileIMEnabled>false</isMobileIMEnabled>
<isMessengerUser>false</isMessengerUser>
<isFavorite>false</isFavorite>
<isSmtp>false</isSmtp>
<hasSpace>false</hasSpace>
<spotWatchState>NoDevice</spotWatchState>
<birthdate>0001-01-01T00:00:00</birthdate>
<primaryEmailType>ContactEmailPersonal</primaryEmailType>
<PrimaryLocation>ContactLocationPersonal</PrimaryLocation>
<PrimaryPhone>ContactPhonePersonal</PrimaryPhone>
<IsPrivate>false</IsPrivate>
<IsHidden>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}true{% else %}false{% endif %}</IsHidden>
<Gender>Unspecified</Gender>
<TimeZone>None</TimeZone>
{% if (ab_id == '00000000-0000-0000-0000-000000000000' or ab_id.startswith('00000000-0000-0000-0009-')) and not (circle.memberships[head.uuid].role == CircleRole.Empty or circle.memberships[head.uuid].state == CircleState.Empty) %}
<NetworkInfoList>
<NetworkInfo>
<DomainId>1</DomainId>
<SourceId>WL</SourceId>
{% if ab_id == '00000000-0000-0000-0000-000000000000' and circle.memberships[head.uuid].role != CircleRole.Admin %}
<DomainTag>00000000-0000-0000-0009-{{ circle.chat_id.upper() }}</DomainTag>
<DisplayName>00000000-0000-0000-0009-{{ circle.chat_id.upper() }}</DisplayName>
{% endif %}
<RelationshipType>5</RelationshipType>
<RelationshipState>{% if ab_id.startswith('00000000-0000-0000-0009-') and circle.memberships[head.uuid].state == CircleState.WaitingResponse %}2{% else %}{{ circle.memberships[head.uuid].state.value }}{% endif %}</RelationshipState>
<RelationshipStateDate>{{ now }}</RelationshipStateDate>
<RelationshipRole>{% if ab_id == '00000000-0000-0000-0000-000000000000' %}{% if circle.memberships[head.uuid].role == CircleRole.StatePendingOutbound %}4{% else %}0{% endif %}{% else %}{% if circle.memberships[head.uuid].role == CircleRole.StatePendingOutbound %}3{% else %}{{ circle.memberships[head.uuid].role.value }}{% endif %}{% endif %}</RelationshipRole>
<NDRCount>0</NDRCount>
{% if circle.memberships[head.uuid].invite_message %}
<InviterMessage>{{ circle.memberships[head.uuid].invite_message }}</InviterMessage>
{% endif %}
<InviterCID>{% if head.uuid == circle.owner_uuid %}0{% else %}{{ cid_format(circle.memberships[head.uuid].inviter_uuid, decimal = True) }}{% endif %}</InviterCID>
{% if circle.memberships[head.uuid].inviter_name %}
<InviterName>{{ circle.memberships[head.uuid].inviter_name }}</InviterName>
{% endif %}
{% if circle.memberships[head.uuid].inviter_email %}
<InviterEmail>{{ circle.memberships[head.uuid].inviter_email }}</InviterEmail>
{% endif %}
<CreateDate>{{ now }}</CreateDate>
<LastUpdated>{{ now }}</LastUpdated>
<PropertiesChanged />
</NetworkInfo>
</NetworkInfoList>
{% endif %}
<IsAutoUpdateDisabled>false</IsAutoUpdateDisabled>
<IsShellContact>false</IsShellContact>
<TrustLevel>0</TrustLevel>
<PropertiesChanged />
</contactInfo>
<propertiesChanged />
<fDeleted>false</fDeleted>
<CreateDate>{{ now }}</CreateDate>
<lastChange>{{ now }}</lastChange>
<CreatedBy>96</CreatedBy>
{% endif %}
</ManageWLConnectionResult>
</ManageWLConnectionResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ServiceHeader xmlns="http://www.msn.com/webservices/AddressBook">
<Version>15.01.1408.0000</Version>
<CacheKey>12r1:{{ cachekey }}</CacheKey>
<CacheKeyChanged>true</CacheKeyChanged>
<PreferredHostName>{{ host }}</PreferredHostName>
<SessionId>{{ session_id }}</SessionId>
</ServiceHeader>
</soap:Header>
<soap:Body>
<UpdateDynamicItemResponse xmlns="http://www.msn.com/webservices/AddressBook" />
</soap:Body>
</soap:Envelope>
+3
View File
@@ -0,0 +1,3 @@
<AppDir code="2" v="{{ v}}">
{{ results }}
</AppDir>
+15
View File
@@ -0,0 +1,15 @@
<Category{% if extra %}{{ extra }}{% endif %}>
<CategoryID>{{ category.id }}</CategoryID>
<Locale>{{ locale }}</Locale>
{% if category.icon_url %}
<CategoryIconURL>{{ category.icon_url }}</CategoryIconURL>
{% else %}
<CategoryIconURL />
{% endif %}
<CategoryName>{{ category.name }}</CategoryName>
{% if category.description %}
<CategoryDescription>{{ category.description }}</CategoryDescription>
{% else %}
<CategoryDescription />
{% endif %}
</Category>
@@ -0,0 +1,2 @@
<tr id="r{{ cat_id }}e"><td colspan=3 height=1><img src="/static/AppDir/image/spacer.gif"</td></tr>
<tr><td colspan=3 height=16><img src="/static/AppDir/image/spacer.gif"</td></tr>
@@ -0,0 +1,3 @@
<tr id="cid{{ cat_id }}" ><td valign="top" width=2><img src="/static/AppDir/image/spacer.gif" width=2></td><td colspan=2><a href="#" class="t" title="" onClick="ToggleCatShow({{ cat_id }});" width=100%>{{ cat_name }}</a></td></tr>
<tr id="r{{ cat_id }}s" ><td colspan=3 height=4><img src="/static/AppDir/image/spacer.gif"></td></tr>
<tr ><td colspan=3 height=2 background="/static/AppDir/image/line.gif"></td></tr>
@@ -0,0 +1 @@
<tr id="r{{ app_id }}" ><td valign="top" width=2><img src="/static/AppDir/image/spacer.gif" width=2></td><td width=100% colspan=2><a id="a{{ app_id }}" href="javascript:RA('{{ app_id }}', '{{ app_id }}')" title="{{ description }}">{{ name }}</a></td></tr>
@@ -0,0 +1,377 @@
<HTML>
<HEAD>
<title>MSN Messenger Application Directory</title>
<meta name="CODE_LANGUAGE" Content="Python">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
<style type="text/css">
<!--
A.t {
font-family: Tahoma, Verdana, Arial;
font-weight:bold;
font-size:8pt;
color:#5C5C5C;
text-decoration: none;
line-height: 12pt
}
A {
font-family: Tahoma, Verdana, Arial;
font-size:8pt;
color:#2F4A8F;
text-decoration: none;
}
A:hover {
font-family: Tahoma, Verdana, Arial;
font-size:8pt;
color:#2F4A8F;
text-decoration: underline;
}
.disclaimer {
font-family: Tahoma, Verdana, Arial;
font-size:8pt;
color:#2F4A8F;
text-decoration: none;
}
.ns {
font-family: Tahoma, Verdana, Arial;
font-size:8pt;
color: red;
}
BODY { direction: ltr; }-->
</style>
<script language="javascript">
var g_DaysToExpireCookie = 30;// [id, [Kids, MinUsers, MaxUsers]]
var g_AppInfo = new Array(
{{ app_entries_js }} [0, [0]]
);
</script>
<script language="javascript">
function GetCookieValue(name, defVal) {
var c = document.cookie;
var i = c.indexOf(name + "=");
if (i == -1) return defVal;
i = i + name.length + 1;
var end = c.indexOf(";", i);
if (end == -1) end = c.length;
return unescape(c.substring(i, end));
}
function SetCookieValue(name, value) {
var d = new Date();
d.setTime(d.getTime() + 1000 * 60 * 60 * 24 * g_DaysToExpireCookie);
document.cookie = name + "=" + escape(value) + "; expires=" + d.toUTCString();
}
function GetUrlValue(name, defVal) {
var i = document.URL.toLowerCase().indexOf(name.toLowerCase() + "=");
if (i == -1) return defVal;
i = document.URL.indexOf("=", i) + 1;
var end = document.URL.indexOf("&", i);
if (end == -1) end = document.URL.indexOf("#", i);
if (end == -1) end = document.URL.length;
return document.URL.substring(i, end);
}
function ShowHide(elem, fShow) {
if (fShow)
elem.style.display = 'block';
else
elem.style.display = 'none';
}
function ShowHideRowsInRange(idStart, idEnd, fShow) {
var eRow = document.all[idStart];
var iRow = eRow.rowIndex;
var eTable = eRow.parentElement;
while (eTable.tagName != 'TABLE') {
eTable = eTable.parentElement;
}
do {
ShowHide(eRow, fShow);
iRow++;
eRow = eTable.rows[iRow];
} while (eRow != null && eRow.id != idEnd)
ShowHide(eRow, fShow);
}
function ToggleCatShow(CatId) {
var id = "r" + CatId + "s";
var fShow = true;
if (document.all[id].style != null && document.all[id].style.display != "none")
fShow = false;
if (CatId == 0 && fShow)
UpdateFavUI(); // favs don't all show - only the defined ones do.
else
{
ShowHideRowsInRange(id, "r" + CatId + "e", fShow);
// v9 if (CatId != 0) SaveCatShowHideState(CatId, fShow);
}
}
function GetCatCookieName() {
return "C" + GetUrlValue("k", 0);
}
/* save for V9
function SaveCatShowHideState(CatId, fShow) {
var aCatHiddenList;
var cookieName = GetCatCookieName();
if (GetCookieValue(cookieName) == null)
aCatHiddenList = new Array();
else
aCatHiddenList = GetCookieValue(cookieName).split(",");
var fInHiddenList = (aCatHiddenList.join(",").match(CatId) != null);
if (fShow != fInHiddenList) return;
if (fShow)
aCatHiddenList = aCatHiddenList.join(",").replace(CatId + ",", "").replace("," + CatId, "").replace(CatId, "").split(",");
else
aCatHiddenList = aCatHiddenList.concat(CatId);
SetCookieValue(cookieName, aCatHiddenList.join(","));
}
function HideHiddenCats() {
var i;
var aCatHiddenList;
var cookieName = GetCatCookieName();
if (GetCookieValue(cookieName) == null)
aCatHiddenList = new Array();
else
aCatHiddenList = GetCookieValue(cookieName).split(",");
for (i = 0; i < aCatHiddenList.length; i++)
ShowHideRowsInRange("r" + aCatHiddenList[i] + "s", "r" + aCatHiddenList[i] + "e", false);
} */
function SetFavLinkValues(eLink, sCookieValue, rowId) {
var aV = sCookieValue.split(",");
eLink.href = "javascript:RA('" + aV[0] + "', '" + rowId + "');";
eLink.title = unescape(aV[5]);
eLink.innerText = unescape(aV[1]);
if (aV.length > 6) {
// icon URL
eLink.parentElement.parentElement.children[0].children[0].src = unescape(aV[6]);
}
}
function SetLinkFocus(e, cmd) {
for (i = 0; i < document.links.length; i++) {
if (document.links[i] == e) {
break;
}
}
switch (cmd) {
case "next":
i++;
break;
case "prev":
i--;
break;
}
if (i < 0)
i = document.links.length - 1;
else if (i >= document.links.length)
i = 0;
e = document.links[i];
if ((e.style.display != "none") &&
(e.parentElement.style.display != "none") &&
(e.parentElement.parentElement.style.display != "none")) {
e.focus();
}
else {
SetLinkFocus(e, cmd);
}
}
function OnKeyDownHandler() {
var e = window.event;
switch (e.keyCode) {
case 40: // down
SetLinkFocus(e.srcElement, "next");
break;
case 38: // up
SetLinkFocus(e.srcElement, "prev");
break;
case 32: // space
e.srcElement.click();
break;
}
}
function OnLoad() {
for (var i = 0; i < document.links.length; i++) {
document.links[i].onkeydown = OnKeyDownHandler;
}
UpdateFavUI();
// v9 HideHiddenCats();
// preload any images so we don't see layout changes if the images are slow to get
var img = new Image();
img.src = "/static/AppDir/image/line.gif";
img.src = "/static/AppDir/image/spacer.gif";
img.src = "/static/AppDir/image/defentry.png";
img.src = "/static/AppDir/image/icon_star.png";
img.src = "/static/AppDir/image/icon_arrow.png";
try {
window.external.Initialize(); // tell the client we are done loading.
}
catch(e) {
window.status = "Initialize would have been called.";
}
}
function GetFavsCookieNamePrefix() {
return "F" + GetUrlValue("k", 0) + "-" + GetUrlValue("L", "en-US");
}
function UpdateFavUI() {
if (document.all["cid0"] != null) {
var cookieName = GetFavsCookieNamePrefix();
var aC = new Array(
GetCookieValue(cookieName + 1, "0"),
GetCookieValue(cookieName + 2, "0"),
GetCookieValue(cookieName + 3, "0"));
if (aC[0] == 0)
ShowHideRowsInRange("cid0", "r0e", false);
else {
ShowHideRowsInRange("cid0", "r0e", true);
for (var i = 0; i < 3; i++) {
SetFavLinkValues(document.all["a-" + (i+1)], aC[i], -(i+1));
ShowHide(document.all["r-" + (i+1)], aC[i] != 0);
}
}
}
}
function AddIdToFavorites(id, Name, Kids, MinUsers, MaxUsers, Desc, iconUrl) {
var cookieName = GetFavsCookieNamePrefix();
var aFavs = new Array(
GetCookieValue(cookieName + 1, "0").split(","),
GetCookieValue(cookieName + 2, "0").split(","),
GetCookieValue(cookieName + 3, "0").split(",")
);
// if the same id is already a fav, delete it and shift the others up
var i;
for (i=0; i < 2; i++) {
if (aFavs[i][0] == id) {
var j;
for (j=i; j < 2; j++) {
aFavs[j] = aFavs[j+1];
}
aFavs[3] = "0".split(",");
}
}
// now insert the new fav and shift the others down
SetCookieValue(cookieName + 1, new Array(id, escape(Name), Kids, MinUsers, MaxUsers, escape(Desc), escape(iconUrl)).join(","));
SetCookieValue(cookieName + 2, aFavs[0].join(","));
SetCookieValue(cookieName + 3, aFavs[1].join(","));
UpdateFavUI();
}
function RA(id, rowId) {
var appMinUsers;
var appMaxUsers;
var appKids;
var appName;
var appDesc;
var SubscriptionURL;
if (id > 0) {
var i;
for (i = 0; g_AppInfo[i][0] > 0; i++) {
if (id == g_AppInfo[i][0]) {
var aInfo = g_AppInfo[i];
appKids = aInfo[1][0];
appMinUsers = aInfo[1][1];
appMaxUsers = aInfo[1][2];
SubscriptionURL = aInfo[1][3];
break;
}
}
// Layout dependent code! - first cell of row has img
//var iconUrl = "/static/AppDir/image/spacer.gif"; // document.all["r" + rowId].children[0].children[0].src;
var iconUrl = document.all["r" + rowId].children[0].children[0].src;
var eLink = document.all["a" + rowId];
appName = eLink.innerText;
var title = eLink.title;
AddIdToFavorites(id, appName, appKids, appMinUsers, appMaxUsers, title, iconUrl);
} else { // fav id
var aFav = GetCookieValue(GetFavsCookieNamePrefix() + id, "0").split(",");
id = aFav[0];
appName = unescape(aFav[1]);
appKids = aFav[2];
appMinUsers = aFav[3];
appMaxUsers = aFav[4];
}
try {
var Ex = window.external;
if(FindClientVersion() >= 6.1) {
Ex.StartApp2(appName, id, appMaxUsers, appMinUsers, appKids, SubscriptionURL);
}
else {
Ex.StartApp(appName, id, appMaxUsers, appMinUsers, appKids);
}
} catch(e) {
window.status = "RunApp(" + appName + ", " + id + ", " + appMaxUsers + ", " + appMinUsers + ", " + appKids + ")";
}
}
function FindClientVersion() {
var cstrVersion = "Version";
// find the query string (URL string after the '?' char
var query = document.location.search.substring(1);
// search the query string for the "Version" paramenter
var index = query.indexOf(cstrVersion);
// get the string at the end of the version parameter + 1 (skip '=' character)
var value = query.substring(index + cstrVersion.length + 1);
// return what is after the '=' character and before the '&'
var iend = value.indexOf('&');
if(iend <= 0)
return value;
else
return value.substring(0, iend);
}
</script>
</HEAD>
<body oncontextmenu="return false;" onLoad="OnLoad();" scroll="auto" leftmargin="8" topmargin="10">
<table cellspacing="0" cellpadding="0" width="201" height="100%" border="0">
{{ results }}
<noscript class="ns">Your browser's current security settings will not allow you to use Fun & Games. To use Fun & Games, set your browser security to medium or low, and be sure cookies and scripting are enabled.</noscript><tr><td colspan=3 height=16><img src="/static/AppDir/image/spacer.gif"/></td></tr>
<tr id="cid0" style="{display: none}"><td colspan=3><a href="#" class="t" title="Fun &amp; Games activities you have launched recently" onClick="ToggleCatShow(0);" width=100%>Recently Played</a></td></tr>
<tr id="r0s" style="{display: none}"><td colspan=3 height=4><img src="/static/AppDir/image/spacer.gif"></td></tr>
<tr style="{display: none}"><td colspan=3 height=2 background="/static/AppDir/image/line.gif"></td></tr>
<tr id="r-1" style="{display: none}"><td valign="top" width=18 height=12><img src=""></td><td width=100% colspan=2><a id="a-1" href="javascript:RA('-1', '-1')" title=""></a></td></tr>
<tr id="r-2" style="{display: none}"><td valign="top" width=18 height=12><img src=""></td><td width=100% colspan=2><a id="a-2" href="javascript:RA('-2', '-2')" title=""></a></td></tr>
<tr id="r-3" style="{display: none}"><td valign="top" width=18 height=12><img src=""></td><td width=100% colspan=2><a id="a-3" href="javascript:RA('-3', '-3')" title=""></a></td></tr>
<tr id="r0e"><td colspan=3 height=1><img src="/static/AppDir/image/spacer.gif"</td></tr>
<tr><td colspan=3 height=100%><img src="/static/AppDir/image/spacer.gif"</td></tr>
</table>
</body>
</HTML>
+48
View File
@@ -0,0 +1,48 @@
<EntryID>{{ entry.id }}</EntryID>
<SubscriptionURL />
{% if entry.error %}
<Error>{{ entry.error }}</Error>
{% else %}
<Error/>
{% endif %}
<Locale>{{ entry.locale or 'en-US' }}</Locale>
<Kids>{{ 1 if entry.kids else 0 }}</Kids>
<Page>{{ entry.page }}</Page>
<CategoryID>{{ entry.category_id }}</CategoryID>
<Sequence>{{ i }}</Sequence>
<Name>{{ entry.name }}</Name>
<Description>{{ entry.description }}</Description>
<URL>{{ entry.url }}</URL>
{% if entry.icon_url %}
<IconURL>{{ entry.icon_url }}</IconURL>
<AppIconURL>{{ entry.icon_url }}</AppIconURL>
{% else %}
<IconURL/>
<AppIconURL/>
{% endif %}
<PassportSiteID>0</PassportSiteID>
<Type>{{ entry.type }}</Type>
<Height>{{ entry.height }}</Height>
<Width>{{ entry.width }}</Width>
<Location>{{ entry.location }}</Location>
<MinUsers>{{ entry.min_users }}</MinUsers>
<MaxUsers>{{ entry.max_users }}</MaxUsers>
<EnableIP>{{ bool_to_str(entry.enable_ip) }}</EnableIP>
<ActiveX>{{ bool_to_str(entry.activex) }}</ActiveX>
<SendFile>{{ bool_to_str(entry.send_file) }}</SendFile>
<SendIM>{{ bool_to_str(entry.send_im) }}</SendIM>
<ReceiveIM>{{ bool_to_str(entry.receive_im) }}</ReceiveIM>
<ReplaceIM>{{ bool_to_str(entry.replace_im) }}</ReplaceIM>
<Windows>{{ bool_to_str(entry.windows) }}</Windows>
<MaxPacketRate>{{ entry.max_packet_rate }}</MaxPacketRate>
{% if entry.log_url %}
<LogURL>{{ entry.log_url }}</LogURL>
{% else %}
<LogURL/>
{% endif %}
<UserProperties>{{ bool_to_str(entry.user_properties) }}</UserProperties>
{% if entry.minimum_client_version %}
<ClientVersion>{{ entry.minimum_client_version }}</ClientVersion>
{% endif %}
<AppType>{{ entry.app_type }}</AppType>
<Hidden>{{ bool_to_str(entry.hidden) }}</Hidden>
@@ -0,0 +1,3 @@
<Entry{% if extra %}{{ extra }}{% endif %}>
{{ entry }}
</Entry>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
{% if entry %}
<GetAppEntryResponse xmlns="http://www.msn.com/webservices/Messenger/Client">
<GetAppEntryResult>
{{ entry }}
</GetAppEntryResult>
</GetAppEntryResponse>
{% else %}
<GetAppEntryResponse xmlns="http://www.msn.com/webservices/Messenger/Client" />
{% endif %}
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<TITLE>AppDirectory Version Page</TITLE>
</HEAD>
<BODY>{{ version }}</BODY>
</HTML>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetFilteredDataSet2Response xmlns="http://www.msn.com/webservices/Messenger/Client">
<GetFilteredDataSet2Result>
{{ diffgram }}
</GetFilteredDataSet2Result>
</GetFilteredDataSet2Response>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetFullDataSetResponse xmlns="http://www.msn.com/webservices/Messenger/Client">
<GetFullDataSetResult>
{{ diffgram }}
</GetFullDataSetResult>
</GetFullDataSetResponse>
</soap:Body>
</soap:Envelope>
+9
View File
@@ -0,0 +1,9 @@
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
{% if results %}
<NewDataSet>
{{ results }}
</NewDataSet>
{% else %}
<NewDataSet />
{% endif %}
</diffgr:diffgram>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetClientConfigResponse xmlns="http://www.msn.com/webservices/Messenger/Client">
<GetClientConfigResult><![CDATA[{MsgrConfig}]]></GetClientConfigResult>
</GetClientConfigResponse>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,102 @@
<MsgrConfig>
<Simple>
<Config>
<ExpiresInDays>0</ExpiresInDays>
</Config>
<DisablePhoneDialer>1</DisablePhoneDialer>
<MinFlashPlayer BuildNumber="60" MajorVersion="7" MinorVersion="0"></MinFlashPlayer>
<Relay>
<Enabled>0</Enabled>
<MaxCallLength>0</MaxCallLength>
</Relay>
<TrustedDomains>
<domain name="hiden.cc"/>
<domain name="ugnet.gay"/>
<domain name="crosstalk.im"/>
<domain name="ctsrv.gay"/>
</TrustedDomains>
<ErrorResponseTable>
<Feature type="0" name="Login">
<Entry hr="0x80072EE7" action="3"></Entry>
<Entry hr="0x81000306" action="3"></Entry>
<Entry hr="0x80072EFD" action="3"></Entry>
<Entry hr="0x81000362" action="3"></Entry>
<Entry hr="0x8100030E" action="3"></Entry>
<Entry hr="0x80072745" action="3"></Entry>
<Entry hr="0x800701F7" action="3"></Entry>
<Entry hr="0x80072EFF" action="3"></Entry>
<Entry hr="0x81000363" action="3"></Entry>
<Entry hr="0x81000395" action="3"></Entry>
<Entry hr="0x800B0001" action="3"></Entry>
<Entry hr="0x81000323" action="3"></Entry>
<Entry hr="0x80072F19" action="3"></Entry>
<Entry hr="0x800701F8" action="3"></Entry>
<Entry hr="0x80072746" action="3"></Entry>
<Entry hr="0x800701F6" action="3"></Entry>
<Entry hr="0x81000377" action="3"></Entry>
<Entry hr="0x81000314" action="3"></Entry>
<Entry hr="0x81000378" action="3"></Entry>
<Entry hr="0x80072EFF" action="3"></Entry>
<Entry hr="0x80070190" action="3"></Entry>
<Entry hr="0x80070197" action="3"></Entry>
<Entry hr="0x80048820" action="3"></Entry>
<Entry hr="0x80048829" action="3"></Entry>
<Entry hr="0x80048834" action="3"></Entry>
<Entry hr="0x80048852" action="3"></Entry>
<Entry hr="0x8004886a" action="3"></Entry>
<Entry hr="0x8004886b" action="3"></Entry>
</Feature>
<Feature type="2" name="MapFile">
<Entry hr="0x810003F0" action="3"></Entry>
<Entry hr="0x810003F1" action="3"></Entry>
<Entry hr="0x810003F2" action="3"></Entry>
<Entry hr="0x810003F3" action="3"></Entry>
<Entry hr="0x810003F4" action="3"></Entry>
<Entry hr="0x810003F5" action="3"></Entry>
<Entry hr="0x810003F6" action="3"></Entry>
<Entry hr="0x810003F7" action="3"></Entry>
</Feature>
</ErrorResponseTable>
</Simple>
<TabConfig>
{tabs}
</TabConfig>
<AbchCfg>
<abchconfig>
<url>https://{{ settings.ADDRESSBOOK_HOST }}/abservice.asmx</url>
</abchconfig>
</AbchCfg>
<LocalizedConfig Market="en-US">
<AdMainConfig>
<TextAdRefresh>1</TextAdRefresh>
<TextAdServer>http://{{ settings.AD_HOST }}/ads/txt</TextAdServer>
<AdBanner20URL Refresh="300">http://{{ settings.AD_HOST }}/ads/banner</AdBanner20URL>
</AdMainConfig>
<AppDirConfig>
<AppDirPageURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/Directory.aspx?L=en-us</AppDirPageURL>
<AppDirSeviceURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/AppDirectory.asmx</AppDirSeviceURL>
<AppDirVersionURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/GetAppdirVersion.aspx</AppDirVersionURL>
</AppDirConfig>
<MSNSearch>
<DesktopInstallURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</DesktopInstallURL>
<ImagesURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=images</ImagesURL>
<NearMeURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</NearMeURL>
<NewsURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$+news&amp;ia=news</NewsURL>
<SearchKidsURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SearchKidsURL>
<SearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SearchURL>
<SharedSearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL>
<SharedSearchURL2>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL2>
</MSNSearch>
<MsnTodayConfig>
<MsnTodayURL>http://{{ settings.TODAY_HOST }}/start?msn=1</MsnTodayURL>
</MsnTodayConfig>
<MusicIntegration URL="https://www.last.fm/search/tracks?q=$ARTIST$+$TITLE$"/>
<RL>
<ViewProfileURL>https://{{ settings.WEBSITE_HOST }}/account/settings</ViewProfileURL>
</RL>
<TermsOfUse>
<TermsOfUseSID>956</TermsOfUseSID>
<TermsOfUseURL>https://{{ settings.WEBSITE_HOST }}/tos</TermsOfUseURL>
</TermsOfUse>
</LocalizedConfig>
</MsgrConfig>
@@ -0,0 +1,239 @@
<?xml version="1.0" encoding="utf-8"?>
<MsgrConfig>
<Simple>
<Config>
<ExpiresInDays>0</ExpiresInDays>
</Config>
<P2PConfig>
<ObjectStore>
<SendDelay>1</SendDelay>
</ObjectStore>
</P2PConfig>
<DisablePhoneDialer>1</DisablePhoneDialer>
<GetItemVersionForUnknown>false</GetItemVersionForUnknown>
<MinFlashPlayer BuildNumber="28" MajorVersion="9" MinorVersion="0" />
<Relay>
<Enabled>0</Enabled>
<MaxCallLength>0</MaxCallLength>
</Relay>
<Contacts>
<Client ZombieServerDetectDelay="1800" ZombieServerDetectInterval="30" ZombieServerDetectResumeDelay="1800" />
<Server ZombieServerDetectDelay="900" ZombieServerDetectResumeDelay="900" ZombieServerDetectConnectDelay="900" ZombieServerDetectLongDelay="900" />
</Contacts>
<TrustedDomains>
<domain name="hiden.cc"/>
<domain name="ugnet.gay"/>
<domain name="crosstalk.im"/>
<domain name="ctsrv.gay"/>
</TrustedDomains>
<ErrorResponseTable>
<Feature type="0" name="Login">
<Entry hr="0x80004002" action="3"/>
<Entry hr="0x80004004" action="3"/>
<Entry hr="0x80004005" action="3"/>
<Entry hr="0x8000402A" action="3"/>
<Entry hr="0x8000FFFF" action="3"/>
<Entry hr="0x8001012E" action="3"/>
<Entry hr="0x80040200" action="3"/>
<Entry hr="0x80048051" action="3"/>
<Entry hr="0x80048820" action="3"/>
<Entry hr="0x80048823" action="3"/>
<Entry hr="0x80070002" action="3"/>
<Entry hr="0x80070005" action="3"/>
<Entry hr="0x8007000E" action="3"/>
<Entry hr="0x80070057" action="3"/>
<Entry hr="0x8007007E" action="3"/>
<Entry hr="0x800702E4" action="3"/>
<Entry hr="0x800706BA" action="3"/>
<Entry hr="0x800706BE" action="3"/>
<Entry hr="0x80071392" action="3"/>
<Entry hr="0x80072745" action="3"/>
<Entry hr="0x80072746" action="3"/>
<Entry hr="0x80072EE2" action="3"/>
<Entry hr="0x80072EF3" action="3"/>
<Entry hr="0x80072EFD" action="3"/>
<Entry hr="0x80072EFF" action="3"/>
<Entry hr="0x80072F06" action="3"/>
<Entry hr="0x80072F7D" action="3"/>
<Entry hr="0x800C013E" action="3"/>
<Entry hr="0x80191002" action="3"/>
<Entry hr="0x81000306" action="3"/>
<Entry hr="0x8100030D" action="3"/>
<Entry hr="0x81000314" action="3"/>
<Entry hr="0x81000362" action="3"/>
<Entry hr="0x81000378" action="3"/>
<Entry hr="0x81000395" action="3"/>
<Entry hr="0x85AE000B" action="3"/>
<Entry hr="0x85AE000F" action="3"/>
<Entry hr="0x85AE001D" action="3"/>
<Entry hr="0x85AE0022" action="3"/>
<Entry hr="0x85AE0024" action="3"/>
<Entry hr="0x85AE0027" action="3"/>
<Entry hr="0x85AE003C" action="3"/>
<Entry hr="0x85AE0053" action="3"/>
<Entry hr="0x8E5E0152" action="3"/>
<Entry hr="0x8E5E0158" action="3"/>
<Entry hr="0x8E5E0211" action="3"/>
<Entry hr="0x8E5E0220" action="3"/>
<Entry hr="0x8E5E0226" action="3"/>
<Entry hr="0x8E5E03FE" action="3"/>
<Entry hr="0x8E5E0408" action="3"/>
<Entry hr="0x8E5E05F6" action="3"/>
<Entry hr="0x8E5E0710" action="3"/>
<Entry hr="0x8E5E0713" action="3"/>
</Feature>
<Feature type="2" name="MapFile">
<Entry hr="0x810003F1" action="3"/>
<Entry hr="0x810003F6" action="3"/>
</Feature>
<Feature type="3" name="P2P">
<Entry hr="0x82000016" action="3"/>
<Entry hr="0x82000017" action="3"/>
<Entry hr="0x82000019" action="3"/>
<Entry hr="0x8200001b" action="3"/>
<Entry hr="0x8200001d" action="3"/>
<Entry hr="0x8200001e" action="3"/>
<Entry hr="0x82000024" action="3"/>
<Entry hr="0x82000026" action="3"/>
</Feature>
</ErrorResponseTable>
<USBDevices>
<Device VID="0x045e" PID="0x0719"/>
<Device VID="0x045e" PID="0x0722"/>
<Device VID="0x041e" PID="0x4080"/>
</USBDevices>
<CirclesWeb General="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" General-SiteId="73625" Management="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" Management-SiteId="73625" Membership="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" Membership-SiteId="73625" Leave="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" Leave-SiteId="73625" Disc="https://discord.gg/dumJwXTPxX" />
<AnonymousIMSettings>
<SettingsPage URL="http://settings.messenger.live.com/applications/WebSettings.aspx" SiteID="76215" />
</AnonymousIMSettings>
</Simple>
<AbchCfg>
<abchconfig>
<url>https://{{ settings.ADDRESSBOOK_HOST }}/abservice.asmx</url>
</abchconfig>
</AbchCfg>
<LocalizedConfig Market="en-US">
<AdMainConfig>
<TextAdRotation>420</TextAdRotation>
<TextAdRefresh>1</TextAdRefresh>
<TextAdServer>http://{{ settings.AD_HOST }}/ads/txt</TextAdServer>
<AdBanner20URL Refresh="300">http://{{ settings.AD_HOST }}/ads/banner</AdBanner20URL>
<StdAd AdVisible="60" VideoVisible="120" VideoDldIntvl="0">
<VideoFeeds FeedsListURL="http://{{ settings.AD_HOST }}/svcs/msn-video-feeds/"/>
</StdAd>
</AdMainConfig>
<AppDirConfig>
<AppDirPageURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/Directory.aspx?L=en-us</AppDirPageURL>
<AppDirSeviceURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/AppDirectory.asmx</AppDirSeviceURL>
<AppDirVersionURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/GetAppdirVersion.aspx</AppDirVersionURL>
</AppDirConfig>
<Contacts>
<ABPendingRequests>
<SiteId>73625</SiteId>
<height>672</height>
<IncludeSNRequests>true</IncludeSNRequests>
<width>808</width>
<urlcid>http://cid-%1!16.16I64X!.profile.live.com/invites?partner=Messenger</urlcid>
</ABPendingRequests>
<EditMyLiveContactProfile>
<url>http://{{ settings.SOCIAL_HOST }}/profile.aspx?action=edit&amp;mode=activecontacts&amp;mkt=en-us&amp;partner=Messenger</url>
<SiteId>73625</SiteId>
</EditMyLiveContactProfile>
<EditMyProfile>
<url>http://profile.live.com/details</url>
<SiteId>73625</SiteId>
</EditMyProfile>
<Import>
<url>http://cid-%1!16.16I64X!.profile.live.com/connect/?partner=Messenger</url>
<SiteId>73625</SiteId>
</Import>
<MessengerInvite>
<url>http://cid-%1.profile.live.com/connect/send.aspx?email=%2</url>
<urlcid>http://cid-%1.profile.live.com/connect/send.aspx?cid=%2</urlcid>
<SiteId>73625</SiteId>
</MessengerInvite>
<Profile>
<url>http://{{ settings.SOCIAL_HOST }}/Profile.aspx?partner=Messenger&amp;mkt=en-us&amp;mem=%ls</url>
<urlcid>http://{{ settings.SOCIAL_HOST }}/Profile.aspx?partner=Messenger&amp;mkt=en-us&amp;cid=%ls</urlcid>
<urlcid2>http://cid-%1!16.16I64X!.profile.live.com</urlcid2>
<SiteId>73625</SiteId>
</Profile>
<SNInvites>
<url>http://cid-%1.profile.live.com/connect/Messenger.aspx?Email=%2</url>
<urlcid>http://cid-%1.profile.live.com/connect/Messenger.aspx?cid=0x%2</urlcid>
<SiteId>73625</SiteId>
</SNInvites>
<ViewMapEnabled>true</ViewMapEnabled>
</Contacts>
<ContactCard>
<AddToMySpaceSiteId>45930</AddToMySpaceSiteId>
<AddToMySpaceUrl>http://{{ settings.SOCIAL_HOST }}/?addblogentry=true&amp;mkt=nl-nl</AddToMySpaceUrl>
<ContactCardDisabled>false</ContactCardDisabled>
<CreateSpaceSiteId>45930</CreateSpaceSiteId>
<CreateSpaceUrl>http://{{ settings.SOCIAL_HOST }}/signup.aspx?mkt=nl-nl</CreateSpaceUrl>
<GetItemVerUrl>http://ctas.storage.ugnet.gay/storageservice/schematizedstore.asmx</GetItemVerUrl>
<GetXmlFeedUrl>http://{{ settings.SOCIAL_HOST }}/contactcard/contactcardservice.asmx</GetXmlFeedUrl>
<MySpaceSiteId>45930</MySpaceSiteId>
<MySpaceUrl>http://{{ settings.SOCIAL_HOST }}/homepage.aspx</MySpaceUrl>
<SpaceBaseSiteId>45930</SpaceBaseSiteId>
<SpaceBaseUrl>http://{{ settings.SOCIAL_HOST }}</SpaceBaseUrl>
<SpaceIntegrationEnabled>true</SpaceIntegrationEnabled>
</ContactCard>
<FlashUpgradeURL>http://{{ settings.STORAGE_HOST }}/crosstalk-dist/client/all/tools/flashplayer_10_3r183_48_winax.exe</FlashUpgradeURL>
<GLinkMarket v="en_us" />
<LiveFolders UpsellMessageId="1" />
<MessengerBlogURL>https://{{ settings.WEBSITE_HOST }}/blog</MessengerBlogURL>
<MSNSearch>
<DesktopInstallURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</DesktopInstallURL>
<ImagesURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=images</ImagesURL>
<NearMeURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</NearMeURL>
<NewsURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$+news&amp;ia=news</NewsURL>
<PeopleSearchURL>http://home.live.com/search?query=$QUERY$</PeopleSearchURL>
<PeopleSearchSiteID>73625</PeopleSearchSiteID>
<SearchKidsURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SearchKidsURL>
<SearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SearchURL>
<SharedSearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL>
<SharedSearchURL2>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL2>
</MSNSearch>
<MsnTodayConfig>
<MsnTodaySiteID>6528</MsnTodaySiteID>
<MsnTodayURL>http://{{ settings.TODAY_HOST }}/start?wlm=1</MsnTodayURL>
<Flags>2</Flags>
</MsnTodayConfig>
<MusicIntegration URL="https://www.last.fm/search/tracks?q=$ARTIST$+$TITLE$"/>
<OneCare Enabled="0" />
<PE Tracking=""/>
<PremiumAV Visibility="1" />
<PSTNOut Hidden="0" />
<ReportAbuse>
<ReportAbuseSID />
<ReportAbuseURL>https://{{ settings.WEBSITE_HOST }}/report</ReportAbuseURL>
</ReportAbuse>
<RL>
<ViewProfileURL>http://g.msn.com/5meen_us/106?%1&amp;Plcid=%2!hs!&amp;%3&amp;Country=%4!hs!&amp;BrandID=%5&amp;passport=%6</ViewProfileURL>
</RL>
<SDrive Enabled="true" />
<TermsOfUse>
<TermsOfUseSID>956</TermsOfUseSID>
<TermsOfUseURL>https://{{ settings.WEBSITE_HOST }}/tos</TermsOfUseURL>
</TermsOfUse>
<VoiceClip Hidden="0" />
<VoiceVideo>
<DisableSipProxyInviteTest>0</DisableSipProxyInviteTest>
<DisableSipProxyCapability>0</DisableSipProxyCapability>
<DisableSipProxyInvite>0</DisableSipProxyInvite>
<DisableSipProxyCapability2>0</DisableSipProxyCapability2>
<DisableSipProxyInvite2>0</DisableSipProxyInvite2>
</VoiceVideo>
<TabConfig>
<RowNumber>1</RowNumber>
<slots>
{% for tab in tabs %}
<URL id="{{ tab.id }}">
https://{{ settings.AD_HOST }}/svcs/tab={{ tab.id }}
</URL>
{% endfor %}
</slots>
</TabConfig>
</LocalizedConfig>
</MsgrConfig>
@@ -0,0 +1,804 @@
<?xml version="1.0" encoding="utf-8" ?>
<MsgrConfig>
<Brands>
<Client v="def" bv="1.0.1.0">
<b i="FT01" v="1.0.5.0" f="FT01_fr-fr_R4.cab" u="http://g.msn.com/0USWLPIT/9" p="FT01" />
<b i="Q002" v="1.0.0.1" f="Q002_en-us_P10.cab" u="http://g.msn.com/0USWLPIT/5" p="Q001" />
<b i="VZ03" v="1.0" f="VZ03_en-us_VZ03_R7.cab" u="http://g.msn.com/0USWLPIT/11" p="VZ02" />
</Client>
<Client v="2" CDNVER="http://cba.domains.live.com/cdn1" CDNCAB="http://cba.domains.live.com/cdn3" CDNPRV="http://cba.domains.live.com/prvw" />
<Client v="3" CDNVER="http://cba.domains.live.com/cdn1" CDNCAB="http://cba.domains.live.com/cdn3" CDNPRV="http://cba.domains.live.com/prvw" />
</Brands>
<Simple>
<Config>
<ExpiresInDays>2</ExpiresInDays>
</Config>
<P2PConfig>
<ObjectStore>
<SendDelay>1</SendDelay>
</ObjectStore>
</P2PConfig>
<DisablePhoneDialer>1</DisablePhoneDialer>
<GetItemVersionForUnknown>false</GetItemVersionForUnknown>
<Logitech>
<PremiumAVConfigServer>http://mplocate.spotlife.net/locate.sxml</PremiumAVConfigServer>
<PreRollEnabled>1</PreRollEnabled>
<WebcamConfigServer>http://mlocate.spotlife.net/locate.sxml</WebcamConfigServer>
</Logitech>
<MinFlashPlayer BuildNumber="28" MajorVersion="9" MinorVersion="0" />
<RadUrl Tracking="http://global.msads.net/ads/abuimg/%PACKID%.xml">http://rad.msn.com/ADSAdClient31.dll?GetAd?PG=</RadUrl>
<ComScoreUrlFormat>http://b.scorecardresearch.com/p?c1=7&amp;c2=3000001&amp;c3=%1!d!&amp;cj=1</ComScoreUrlFormat>
<Relay>
<Enabled>1</Enabled>
<MaxCallLength>0</MaxCallLength>
<RegistrationDomain>4.68.251.254</RegistrationDomain>
<RelayDNS>avrelay.msn.com</RelayDNS>
<TimeoutToFallback>7000</TimeoutToFallback>
</Relay>
<Contacts>
<Client ZombieServerDetectDelay="1800" ZombieServerDetectInterval="30" ZombieServerDetectResumeDelay="1800" ZombieServerDetectDelayW4="180" ZombieServerDetectIntervalW4="30" ZombieServerDetectResumeDelayW4="180" />
<Server ZombieServerDetectDelay="900" ZombieServerDetectResumeDelay="900" ZombieServerDetectConnectDelay="900" ZombieServerDetectLongDelay="900" ZombieServerDetectDelayW4="45" ZombieServerDetectResumeDelayW4="600" ZombieServerDetectConnectDelayW4="135" ZombieServerDetectLongDelayW4="450" />
</Contacts>
<TrustedDomains>
<domain name="bluemountaincards.co.uk" />
<domain name="bluemountaincards.com.au" />
<domain name="bmamessenger.com" />
<domain name="gmarket.co.kr" />
<domain name="hotmail.com" />
<domain name="imgag.com" />
<domain name="meegos.com" />
<domain name="msn.com" />
<domain name="msads.net" />
<domain name="imagine-msn.com" />
<domain name="imagine-windowslive.com" />
<domain name="kiwee.com" />
<domain name="live.com" />
<domain name="msnplus.co.kr" />
<domain name="wee-mee.com" />
<domain name="mypersonalexpression.com" />
<domain name="mobilemoney.com" />
<domain name="hotmail.co.jp" />
<domain name="hotmail.de" />
<domain name="hotmail.it" />
<domain name="hotmail.fr" />
<domain name="hotmail.co.uk" />
<domain name="hotmail.com.tr" />
<domain name="hotmail.com.ar" />
<domain name="hotmail.co.th" />
<domain name="ninemsn.com" />
<domain name="ninemsn.com.au" />
<domain name="joyinter.net" />
<domain name="messengervibe.com" />
<domain name="messengervibe.net" />
<domain name="messengervibe.org" />
<domain name="meezone.com" />
<domain name="live.jp" />
<domain name="excite.co.jp" />
<domain name="start.com" />
<domain name="msn.com.hk" />
<domain name="msn.co.il" />
<domain name="msn.co.kr" />
<domain name="event-information.jp" />
<domain name="msn.mydrivers.com" />
<domain name="msn.com.br" />
<domain name="im.live.cn" />
<domain name="sc.imp.live.com" />
<domain name="c.imp.live.com" />
<domain name="origindigital.net" />
<domain name="laughabits.com" />
<domain name="laughabits.net" />
<domain name="windowslive.com" />
<domain name="gowindowslive.com" />
<domain name="msn.com.tw" />
<domain name="msn.co.in" />
<domain name="www.mobilemoney.com" />
<domain name="wall-e.msn.co.uk" />
<domain name="walle.msn.co.uk" />
<domain name="wall-e.msn.fr" />
<domain name="walle.msn.fr" />
<domain name="wall-e.msn.be" />
<domain name="walle.msn.be" />
<domain name="wall-e.fr.msn.be" />
<domain name="walle.fr.msn.be" />
<domain name="wall-e.msn.nl" />
<domain name="walle.msn.nl" />
<domain name="wall-e.msn.es" />
<domain name="walle.msn.es" />
<domain name="wall-e.msn.dk" />
<domain name="walle.msn.dk" />
<domain name="wall-e.msn.fi" />
<domain name="walle.msn.fi" />
<domain name="wall-e.msn.no" />
<domain name="walle.msn.no" />
<domain name="wall-e.msn.se" />
<domain name="walle.msn.se" />
<domain name="wall-e.msn.de" />
<domain name="walle.msn.de" />
<domain name="wall-e.msn.it" />
<domain name="walle.msn.it" />
<domain name="msbrandent.vo.llnwd.net" />
<domain name="www.messengerexpressions.com" />
<domain name="www.sunsilkgangofgirls.com" />
<domain name="messenger.live.de" />
<domain name="themepackchooser.windowslivehosting.de" />
<domain name="messengermakeover.com" />
<domain name="microsoft.com" />
<domain name="windowslive.se" />
<domain name="messenger-themes.com" />
<domain name="visualsearch.msn.com" />
<domain name="xbox.com" />
<domain name="quebles.com" />
<domain name="technodesignip.com" />
<domain name="promotion.hk.msn.com" />
<domain name="promotion.msn.com.tw" />
<domain name="18design.com" />
<domain name="egreetings.com" />
<domain name="kiwee.com" />
<domain name="live.mundijuegos.com" />
<domain name="skype.com" />
<domain name="hiden.cc"/>
<domain name="ugnet.gay"/>
<domain name="crosstalk.im"/>
<domain name="ctsrv.gay"/>
</TrustedDomains>
<ErrorResponseTable>
<Feature type="0" name="Login">
<Entry hr="*" action="3" />
<Entry hr="0x81000605" action="3" />
<Entry hr="0x80048849" action="5" />
<Entry hr="0x8004882A" action="5" />
<Entry hr="0x80048800" action="5" />
<Entry hr="0x8004889C" action="5" />
<Entry hr="0x80048831" action="5" />
<Entry hr="0x81000306" action="5" />
<Entry hr="0x80048862" action="5" />
<Entry hr="0x800488EB" action="5" />
<Entry hr="0x80048848" action="5" />
<Entry hr="0x80004002" action="3" />
<Entry hr="0x80004004" action="3" />
<Entry hr="0x80004005" action="3" />
<Entry hr="0x8000402A" action="3" />
<Entry hr="0x8000FFFF" action="3" />
<Entry hr="0x8001012E" action="3" />
<Entry hr="0x80040200" action="3" />
<Entry hr="0x80048051" action="3" />
<Entry hr="0x80048820" action="5" />
<Entry hr="0x80048823" action="3" />
<Entry hr="0x80070002" action="3" />
<Entry hr="0x80070005" action="3" />
<Entry hr="0x8007000E" action="3" />
<Entry hr="0x80070057" action="3" />
<Entry hr="0x8007007E" action="3" />
<Entry hr="0x800702E4" action="3" />
<Entry hr="0x800706BA" action="3" />
<Entry hr="0x800706BE" action="3" />
<Entry hr="0x80071392" action="3" />
<Entry hr="0x80072745" action="3" />
<Entry hr="0x80072746" action="3" />
<Entry hr="0x80072EE2" action="3" />
<Entry hr="0x80072EF3" action="3" />
<Entry hr="0x80072EFD" action="3" />
<Entry hr="0x80072EFF" action="3" />
<Entry hr="0x80072F06" action="3" />
<Entry hr="0x80072F7D" action="3" />
<Entry hr="0x800C013E" action="3" />
<Entry hr="0x80191002" action="3" />
<Entry hr="0x8100030D" action="3" />
<Entry hr="0x81000314" action="3" />
<Entry hr="0x81000362" action="3" />
<Entry hr="0x81000378" action="3" />
<Entry hr="0x81000395" action="3" />
<Entry hr="0x85AE000B" action="3" />
<Entry hr="0x85AE000F" action="3" />
<Entry hr="0x85AE001D" action="3" />
<Entry hr="0x85AE0022" action="3" />
<Entry hr="0x85AE0024" action="3" />
<Entry hr="0x85AE0027" action="3" />
<Entry hr="0x85AE003C" action="3" />
<Entry hr="0x85AE0053" action="3" />
<Entry hr="0x8E5E0152" action="3" />
<Entry hr="0x8E5E0158" action="3" />
<Entry hr="0x8E5E0211" action="3" />
<Entry hr="0x8E5E0220" action="3" />
<Entry hr="0x8E5E0226" action="3" />
<Entry hr="0x8E5E03FE" action="3" />
<Entry hr="0x8E5E0408" action="3" />
<Entry hr="0x8E5E05F6" action="3" />
<Entry hr="0x8E5E0710" action="3" />
<Entry hr="0x8E5E0713" action="3" />
</Feature>
<Feature type="2" name="MapFile">
<Entry hr="0x810003F1" action="3" />
<Entry hr="0x810003F6" action="3" />
</Feature>
<Feature type="3" name="P2P">
<Entry hr="0x82000016" action="3" />
<Entry hr="0x82000017" action="3" />
<Entry hr="0x82000019" action="3" />
<Entry hr="0x8200001b" action="3" />
<Entry hr="0x8200001d" action="3" />
<Entry hr="0x8200001e" action="3" />
<Entry hr="0x82000024" action="3" />
<Entry hr="0x82000026" action="3" />
</Feature>
<Feature type="5" name="VoiceVideo">
<Entry hr="*" action="3" />
</Feature>
</ErrorResponseTable>
<USBDevices>
<Device VID="0x045e" PID="0x0719" />
<Device VID="0x045e" PID="0x070F" />
<Device VID="0x045e" PID="0x0772" />
<Device VID="0x041e" PID="0x4080" />
<Device VID="0x041e" PID="0x4083" />
<Device VID="0x041e" PID="0x4088" />
<Device VID="0x041e" PID="0x4087" />
<Device VID="0x041e" PID="0x4086" />
</USBDevices>
<VoiceVideo>
<Log PeerLogDisable="1" />
</VoiceVideo>
<CirclesWeb General="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" General-SiteId="73625" Management="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" Management-SiteId="73625" Membership="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" Membership-SiteId="73625" Leave="https://{{ settings.WEBSITE_HOST }}/circles/$CIRCLECID$/settings/" Leave-SiteId="73625" Disc="https://discord.gg/dumJwXTPxX" />
<AnonymousIMSettings>
<SettingsPage URL="http://settings.messenger.live.com/applications/WebSettings.aspx" SiteID="76215" />
</AnonymousIMSettings>
<SocialNews>
<ActivityDisplay PageSize="50" MaxItems="100" />
<AlbumDisplay UnderlayImages="2" LeadUnderlayImages="2" />
<IdleRefreshSecs Typing="180" Scrolling="10" />
<Comments MaxDisplayItems="20" MaxInputLen="512" />
<MainWindow>
<AskIfLessThanXContacts>5</AskIfLessThanXContacts>
<MaxSecsToShowSyncHint>10</MaxSecsToShowSyncHint>
</MainWindow>
<ServerSync>
<FetchImagesForActivities Minimized="10" Visible="1000" />
</ServerSync>
<EXP_URL>http://ro-test.exp.glbdns.microsoft.com/</EXP_URL>
</SocialNews>
<SAC SiteID="73625" />
<InlineFlashEnabled>1</InlineFlashEnabled>
<Badgewhitelist>
<Badge hash="9lfw5+i0VZl9Vg7y5Un2OlJmtfs=" />
<Badge hash="37ryp9MdaDZjOiv4goIAeWK0EX8=" />
<Badge hash="bg4dyWk7FEhW5vh3FrGxr7xw+mg=" />
<Badge hash="h8tLlwWUls1wgiFYbjVZBzs5mW0=" />
<Badge hash="4rzC8sYjtzAbzVYZcB4wvxMhbVg=" />
<Badge hash="vVenvAzv1l+nEMf62r5+n6DCIn0=" />
<Badge hash="vjJ3jVT690ORqHHhBgrYsMK5DOw=" />
<Badge hash="Yxv7pB8BkosiGNn0oGsXryPkGwk=" />
<Badge hash="mChdOIxTCBtxBPa+jrB8wwUs5gw=" />
<Badge hash="4Dyw5JiNMjquWPruSAHEFwYq/Gs=" />
<Badge hash="D9vI4Cg6dxswaI8CWe4OyBnLe9I=" />
<Badge hash="ZPa3APVAtDXHZWkXMuqvHJ7d1Oc=" />
<Badge hash="6on/QiZ+oCinkJoZ46kJUUuOJOU=" />
<Badge hash="m1RNenPjuuPi5K9J8URF+s1t1RA=" />
<Badge hash="IOGiVO3tySKcci62UN5cm3HWpu8=" />
<Badge hash="BozySP9KXMkBFD7yhU5dtFk7uhY=" />
<Badge hash="QvaYObfDCYnqJ7PY1xehXK1h7Vg=" />
<Badge hash="ev1TxfBsXT71YaxkwJ1qLWxTvqM=" />
<Badge hash="AVL5/uKTExH58MBBif46FwDeIlI=" />
<Badge hash="zI4RpERkOV8EIPe8GgVuMP/zsAU=" />
<Badge hash="w+OPDFW9zUCophcUHzCD9vJkWPo=" />
<Badge hash="LTSltKJuhiAXwEnYnhdhlGwCeh4=" />
<Badge hash="Q35ITEMaQZoU6HaJ1O0f/B0t9gs=" />
<Badge hash="4MFANR59I364LscZCocBADKMaUU=" />
<Badge hash="XnMhTovzcp1yO7TI5IVKLHJPZno=" />
<Badge hash="qt7d1rBxs8dAOn7iY0HsxITbLXw=" />
<Badge hash="d5Z7ZpzFS2lWJprExnYdZdH0vn4=" />
<Badge hash="UT1nTu3LYZwfa2TFnZCKrn+vaFU=" />
<Badge hash="nJsMh4U2loNkfYmdB7TEMdLieu8=" />
<Badge hash="XA9SbvUp+iqzFEUWtQpqna7PrC8=" />
<Badge hash="BazH3YqwlvzyhcUkjYGCf+qIyKg=" />
<Badge hash="M8xU6J839spw4iyQFJjTTs6WB84=" />
<Badge hash="8CLDN2ByqlbeiGHlwQyaAytHQ58=" />
<Badge hash="0qbNS31d6WpD5MMMzlWqAOnuo2U=" />
<Badge hash="4RvEU8H6/wZVf9EcET7lqDkFtT4=" />
<Badge hash="egsg4TWsu8qDnSCgvr7iugcG0LM=" />
<Badge hash="YpzN8KhlfuhKwFPJ/7EsMmLAbuk=" />
<Badge hash="MgAjD7JMuFyNFfd4NnZ1Ki+o2pU=" />
<Badge hash="uiJWWP/ub6TK98UTEQ5qcDboodo=" />
<Badge hash="WPaadPRXlBRaxt3hOp2NlM6qbMg=" />
<Badge hash="cDbb4pvKRfY4rMrQ5nkYrWzRgGA=" />
<Badge hash="W5oSJU3k59GI5RbJnZl6Qf6pH08=" />
<Badge hash="/PU6/QRwosJ7qr6KmYsrqehvrJ0=" />
<Badge hash="v9sMUux76smDtxJVy1LeUEhLHRc=" />
<Badge hash="OKXA2XP1372wcWRDsIccDfLu4sw=" />
<Badge hash="7EqLZG50DDPN8wrbo5cZRylxbxA=" />
<Badge hash="C7sxFpDuIksjfGHUeJ8VCT0skuk=" />
<Badge hash="ZVsu2eb55OvHBb8vMaqJuTk04bM=" />
<Badge hash="eCdqiMJSKjhAk4DAnyual0GTEao=" />
<Badge hash="br3uGnBy/3iFUXzRXYcV83k0YEo=" />
<Badge hash="LNYcLtJv0uzfOzGqdGeahV6K6M8=" />
<Badge hash="f9T6bHBmsNSDBA6YXUI+Ev1d1a8=" />
<Badge hash="iAwbvV2Fpl2B1atHWSCeqUxBuQ0=" />
<Badge hash="rSWxtjTwQuOGdQ6icpgCygnC3Cw=" />
<Badge hash="vtFONiM9ZzlcBs6vCdFe0MvAbvM=" />
<Badge hash="3Y6LxMK+gDrjna/wbB1YJhjpgSw=" />
<Badge hash="zQsxtCr0XMSO5uR0Sw+qc+bVwmk=" />
<Badge hash="9WqtJjDlJNleDRs5270wA941Sn0=" />
<Badge hash="hib0Cd2LaqUCE2GhKLZSKuK4Vd4=" />
<Badge hash="e6aj74s8QJdxk8j7sVFNGpjISUM=" />
<Badge hash="BsOFlAwMS+33I7XUYZ8GtyAKbpw=" />
<Badge hash="rYUDkUnRKKhT1fYVQ+HYTGSR0f0=" />
<Badge hash="mt/zjgXkxyAAsuysl7dwQJrtCCs=" />
<Badge hash="9QWMRHSWliBE0Nml7izqsmQueuI=" />
<Badge hash="Af4UlxCI9Q4E69cu3gSnT8QM+J0=" />
<Badge hash="vs+XlfnMXk9XW2h36X2h3B6revc=" />
<Badge hash="XyqywanZEWiRA5lm9qkkoVgvQ0E=" />
<Badge hash="QAJsPE15szOII/tSxPpAFrxNk1Y=" />
<Badge hash="STIkOlYxsAG60k6tfzFrKZ0OEZc=" />
<Badge hash="ddNPDt8PhYnlMZ40k9vCY0ykABM=" />
<Badge hash="PeQELvXViAhtZ/zoTsPdAkD+Q4M=" />
<Badge hash="T62weZK79pgV7mlqdbitG/Dy454=" />
<Badge hash="wil7kcephpQDw1uT4vHaeTBWRlc=" />
<Badge hash="xqrldsPAEO0CER+ThpPWeU6yFIw=" />
<Badge hash="XIcOrK2whUy08x/Qv1WI76a6BPA=" />
<Badge hash="rAakWEDEg7wQcYCBGq7/bIjYao8=" />
<Badge hash="B6X7uu8jrk2SBzS+8Q0Ipl4hS3k=" />
<Badge hash="93YzxkXPI9HYwFsbUndZtkMbWe0=" />
<Badge hash="+nApQVaEOLh3BAnltLW3JNaExcw=" />
<Badge hash="qJ6iPKlEjUoZseAbwTxNKlS+DQA=" />
<Badge hash="wdp3RGOgtGQ+5sq1c4hVU1MB1dI=" />
<Badge hash="+TIl/KYEVwr+JF/nNFGXEWvhp9I=" />
<Badge hash="/O6no1Wc+VwDvk1V4tneT1rVN68=" />
<Badge hash="zbfGlhssMmB5IPvhBQMzK7n6PK4=" />
<Badge hash="KQceiyW0oVyLz2x3aw6ccEKHrcQ=" />
<Badge hash="+s2/b8lxTyuJ9fydnis5szl9mmI=" />
<Badge hash="Hu4DE0KpCc/QcWniA7YsZaIbd4E=" />
<Badge hash="PWNqw7+xphOvbi1hPgTgKuGL5Ds=" />
<Badge hash="wQA4IOu5eFhYnrOz/jpZ3mf10Vw=" />
<Badge hash="sU1+y0KfjoeDQq7Ilk2d/Sltoc8=" />
<Badge hash="3pViUUmJ6Qngao9ZBz0iJGW05W8=" />
<Badge hash="P6X4JKOsvzlCdxSuVuZQ+oQjFn8=" />
<Badge hash="rc5FO/sPiH5RrVGhpxTe57Rvf5s=" />
<Badge hash="PdCll4Hu1FBQCfuxTET6WK4YqvU=" />
<Badge hash="aDip/uLZFXFuQUWDL9Ez+js/Xlg=" />
<Badge hash="gBo+51w4rmvpwXMHKeB/9I+5WO8=" />
<Badge hash="spqOkvjnFubFQqSxKGEY6pylOKo=" />
</Badgewhitelist>
<HotmailUrls>
<BaseUrlFormat>http://mail.live.com/?rru=%1</BaseUrlFormat>
<InboxTarget>inbox</InboxTarget>
<SendMailTarget>compose</SendMailTarget>
<SendMailFormat>?to=%1</SendMailFormat>
<ViewMessageTarget>getmsg</ViewMessageTarget>
<ViewMessageFormat>?msg=%1</ViewMessageFormat>
</HotmailUrls>
<HwBlockList Version="9">
<List Application="0" Version="0">
<Entry Flags="1" Options="1" VendorId="8086" DeviceId="8108" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="00FA" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="00FB" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="00FC" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="00FD" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="00FE" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0301" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0302" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0308" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0309" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0311" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0312" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0314" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="031A" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="031B" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="031C" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0320" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0321" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0322" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0323" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0324" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0325" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0326" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0327" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0328" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="032A" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="032B" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="032C" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="032D" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0330" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0331" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0332" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0333" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0334" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0338" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="033F" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0341" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0342" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0343" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0344" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0347" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="0348" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="034C" />
<Entry Flags="1" Options="1" VendorId="10DE" DeviceId="034E" />
<Entry Flags="0" Options="2" VendorId="1002" />
<Entry Flags="1" Options="4" VendorId="8086" DeviceId="2992" />
<Entry Flags="1" Options="8" VendorId="8086" DeviceId="2A42" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="3154" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="3e54" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4147" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="3154" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4147" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="414b" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4154" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4155" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4156" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4157" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4a4d" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4c58" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4c66" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4e47" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4e4b" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4e54" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4e56" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="4e67" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5148" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5464" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5550" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5551" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5552" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5554" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5571" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="564a" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="564b" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5b64" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5b65" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5b74" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5b75" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5d49" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5d50" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5e48" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="5e49" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7103" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7104" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7105" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7106" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7124" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7152" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7153" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7172" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="7173" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="71c4" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="71d2" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="71d4" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="71f2" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="940a" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="940b" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="940f" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="9489" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="9511" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="958c" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="958d" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="9595" />
<Entry Flags="1" Options="1" VendorId="1002" DeviceId="95cc" />
<Entry Flags="2" Options="1" VendorId="8086" Version="8.15.10.1749" />
<Entry Flags="4" Options="1" VendorId="10DE" Version="8.17.12.8026" />
<Entry Flags="10" Options="1" VendorId="8086" Minimum="8.15.10.2104" Version="8.15.10.2142" />
<Entry Flags="1" Options="1" VendorId="1414" DeviceId="008c" />
</List>
<List Application="1" Version="0">
<Entry Flags="0" Options="2" VendorId="1002" />
<Entry Flags="1" Options="1" VendorId="8086" DeviceId="8108" />
<Entry Flags="1" Options="4" VendorId="8086" DeviceId="2992" />
<Entry Flags="3" Options="1" VendorId="8086" DeviceId="0116" Version="8.15.10.2321" />
<Entry Flags="3" Options="1" VendorId="8086" DeviceId="0106" Version="8.15.10.2321" />
<Entry Flags="3" Options="1" VendorId="8086" DeviceId="0102" Version="8.15.10.2321" />
<Entry Flags="3" Options="1" VendorId="8086" DeviceId="0126" Version="8.15.10.2321" />
<Entry Flags="3" Options="1" VendorId="8086" DeviceId="0122" Version="8.15.10.2321" />
<Entry Flags="3" Options="1" VendorId="8086" DeviceId="0112" Version="8.15.10.2321" />
<Entry Flags="3" Options="1" VendorId="8086" DeviceId="010a" Version="8.15.10.2321" />
<Entry Flags="4" Options="1" VendorId="10DE" Version="8.17.12.8562" />
<Entry Flags="10" Options="1" VendorId="8086" Minimum="8.15.10.2104" Version="8.15.10.2142" />
</List>
</HwBlockList>
</Simple>
<AbchCfg>
<abchconfig>
<url>https://{{ settings.ADDRESSBOOK_HOST }}/abservice.asmx</url>
</abchconfig>
</AbchCfg>
<AdMainConfig>
<AdDownloadTimeInMinutes>120</AdDownloadTimeInMinutes>
<AdMainCfg>http://{{ settings.AD_HOST }}/ads/banner</AdMainCfg>
</AdMainConfig>
<AdPhoneConfig>http://{{ settings.AD_HOST }}/ads/banner</AdPhoneConfig>
<LocalizedConfig Market="en-US">
<AdMainConfig>
<AdBanner20URL Refresh="390">http://{{ settings.AD_HOST }}/ads/banner</AdBanner20URL>
<AdBanner300URL Refresh="390" FooterPane="AlwaysShown">http://{{ settings.AD_HOST }}/ads/banner-lg</AdBanner300URL>
<ConvoWinAd AdVisible="420" FooterPane="CollapsibleAndHideable" />
<ConvoWinAdBannerURL>http://{{ settings.AD_HOST }}/ads/banner</ConvoWinAdBannerURL>
<StdAd AdVisible="60" VideoVisible="120" VideoDldIntvl="0">
<VideoFeeds FeedsListURL="http://{{ settings.AD_HOST }}/svcs/msn-video-feeds/"/>
</StdAd>
<TextAdRotation>420</TextAdRotation>
<TextAdRefresh>1</TextAdRefresh>
<TextAdServer>https://{{ settings.AD_HOST }}/ads/txt</TextAdServer>
<Window Size="680" />
</AdMainConfig>
<AppDirConfig>
<AppDirPageURL>https://{{ settings.APPDIR_HOST }}/AppDirectory/Directory.aspx?L=en-us</AppDirPageURL>
<AppDirSeviceURL>https://{{ settings.APPDIR_HOST }}/AppDirectory/AppDirectory.asmx</AppDirSeviceURL>
<AppDirVersionURL>https://{{ settings.APPDIR_HOST }}/AppDirectory/GetAppdirVersion.aspx</AppDirVersionURL>
</AppDirConfig>
<AVPrerollAd FetchTimeout="6900" IntroLength="3000" MinAdLength="7000" URL="http://rad.msn.com/ADSAdClient31.dll?GetAd=&amp;PG=IMUSV1" />
<AVPrerollAd2 FetchTimeout="6900" IntroLength="0" MinAdLength="7000" URL="http://rad.msn.com/ADSAdClient31.dll?GetAd=&amp;PG=IMUVD1" />
<BuyWebcamLink URL="http://www.logitech.com/msn/index.cfm?c=US&amp;l=EN" />
<Contacts>
<ABPendingRequests>
<SiteId>73625</SiteId>
<height>672</height>
<IncludeSNRequests>true</IncludeSNRequests>
<width>808</width>
<urlcid>http://profile.live.com/invites</urlcid>
</ABPendingRequests>
<EditAlertNotificationOptions>
<url>http://alerts.live.com/Alerts/MyAlerts.aspx</url>
</EditAlertNotificationOptions>
<EditMyLiveContactProfile>
<url>http://profile.live.com/details/edit</url>
<SiteId>73625</SiteId>
</EditMyLiveContactProfile>
<EditMyProfile>
<url>http://profile.live.com/details</url>
<SiteId>73625</SiteId>
</EditMyProfile>
<EditMyName>
<url>http://profile.live.com/details/edit/name</url>
<SiteId>73625</SiteId>
</EditMyName>
<EditMyPrivacySettings>
<url>http://profile.live.com/privacy</url>
<SiteId>73625</SiteId>
</EditMyPrivacySettings>
<EditSocialNotificationOptions>
<url>http://cid-%1!16.16I64X!.profile.live.com/options/notifications</url>
<SiteId>73625</SiteId>
</EditSocialNotificationOptions>
<EditWLPersonURL>
<url>http://cid-%1!16.16I64X!.profile.live.com/details/Edit </url>
<SiteId>73625</SiteId>
</EditWLPersonURL>
<EditNonWLPersonURL>
<url>http://cid-%1!16.16I64X!.profile.live.com/details/Edit/?ContactId=%2 </url>
<SiteId>73625</SiteId>
</EditNonWLPersonURL>
<Export>
<url>http://mail.live.com/?rru=options?subsection=26</url>
<SiteId>73625</SiteId>
</Export>
<Import>
<url>http://cid-%1!16.16I64X!.profile.live.com/connect</url>
<SiteId>73625</SiteId>
</Import>
<Marketplace>
<url>http://expo.live.com/BuddyProfile.aspx?cid=</url>
<SiteId>67227</SiteId>
</Marketplace>
<MessengerInvite>
<url>https://profile.live.com/%1/connect/send?email=%2</url>
<urlcid>https://profile.live.com/%1/connect/send?cid=%2</urlcid>
<SiteId>73625</SiteId>
</MessengerInvite>
<MutualFriends>
<url>http://cid-%1!16.16I64X!.profile.live.com/friends/common/</url>
<SiteId>73625</SiteId>
</MutualFriends>
<PeopleSearch>
<url>http://home.live.com/search</url>
<SiteId>73625</SiteId>
</PeopleSearch>
<Profile>
<url>https://profile.live.com/cid-%1!16.16I64X!</url>
<urlcid>https://profile.live.com/cid-%1!16.16I64X!</urlcid>
<urlcid2>http://cid-%1!16.16I64X!.profile.live.com</urlcid2>
<SiteId>73625</SiteId>
</Profile>
<LimitedAccessHelp>
<url>http://explore.live.com/windows-live-privacy-limited-access-ui</url>
<SiteId>73625</SiteId>
</LimitedAccessHelp>
<SNHip>
<url>http://cid-%1!16.16I64X!.profile.live.com/SecurityCheck/?oid=12&amp;usercid=%3&amp;QRCode=SocialNetworkInvites</url>
<SiteId>73625</SiteId>
</SNHip>
<SNInvites>
<url>http://cid-%1.profile.live.com/connect/Messenger.aspx?Email=%2</url>
<urlcid>http://cid-%1.profile.live.com/connect/Messenger.aspx?cid=0x%2</urlcid>
<SiteId>73625</SiteId>
</SNInvites>
<ViewPhotosWLPersonURL>
<url>http://cid-%1!16.16I64X!.photos.live.com </url>
<SiteId>73625</SiteId>
</ViewPhotosWLPersonURL>
<ViewMapEnabled>true</ViewMapEnabled>
</Contacts>
<ContactCard>
<AddToMySpaceSiteId>73625</AddToMySpaceSiteId>
<AddToMySpaceUrl>http://{{ settings.SOCIAL_HOST }}/?addblogentry=true&amp;mkt=en-us</AddToMySpaceUrl>
<ContactCardDisabled>false</ContactCardDisabled>
<CreateSpaceSiteId>73625</CreateSpaceSiteId>
<CreateSpaceUrl>http://{{ settings.SOCIAL_HOST }}</CreateSpaceUrl>
<GetItemVerUrl>http://storage.msn.com/storageservice/schematizedstore.asmx</GetItemVerUrl>
<GetXmlFeedUrl>http://cc.services.{{ settings.SOCIAL_HOST }}/contactcard/contactcardservice.asmx</GetXmlFeedUrl>
<GetXmlFeedRpsUrl>http://cc.services.{{ settings.SOCIAL_HOST }}/contactcard/contactcardservice.asmx</GetXmlFeedRpsUrl>
<GetXmlFeedRpsCidUrl>http://cid-%1!16.16I64X!.cc.services.{{ settings.SOCIAL_HOST }}/contactcard/contactcardservice.asmx</GetXmlFeedRpsCidUrl>
<MySpaceSiteId>73625</MySpaceSiteId>
<MySpaceUrl>http://{{ settings.SOCIAL_HOST }}</MySpaceUrl>
<SpaceBaseSiteId>73625</SpaceBaseSiteId>
<SpaceBaseUrl>http://{{ settings.SOCIAL_HOST }}</SpaceBaseUrl>
<SpaceIntegrationEnabled>true</SpaceIntegrationEnabled>
</ContactCard>
<EditorialConfig>http://www.msn.com/infopane/messenger.armx</EditorialConfig>
<FlashUpgradeURL>http://{{ settings.STORAGE_HOST }}/crosstalk-dist/client/all/tools/flashplayer_10_3r183_48_winax.exe</FlashUpgradeURL>
<FSS>
<SiteID>71659</SiteID>
<AddBuddyURL>https://fss.live.com/krl/AddContact.aspx</AddBuddyURL>
</FSS>
<GLinkMarket v="en_us" />
<Highlight>
<FirstRunURLSet>
<FirstRunURL id="1">
<url id="1">http://c.imp.live.com/content/dam/imp/surfaces/highlights/skype/en/wave3.html</url>
</FirstRunURL>
</FirstRunURLSet>
<MinDaysBtwFirstRunLaunches>1</MinDaysBtwFirstRunLaunches>
<MinDaysBtwFirstRecurringLaunches>7</MinDaysBtwFirstRecurringLaunches>
<RecurringHighlightURL>
<url>http://c.imp.live.com/content/dam/imp/surfaces/highlights/skype/en/wave3.html</url>
</RecurringHighlightURL>
<Wave val="4">
<FirstRunURLSet>
<FirstRunURL id="1">
<url id="1">http://c.imp.live.com/content/dam/imp/surfaces/highlights/skype/en/wave4.html</url>
</FirstRunURL>
</FirstRunURLSet>
<RecurringHighlightURL>
<url>http://c.imp.live.com/content/dam/imp/surfaces/highlights/skype/en/wave4.html</url>
</RecurringHighlightURL>
</Wave>
</Highlight>
<IntroConfig />
<LiveFolders UpsellMessageId="1" />
<Marketplace>
<General URL="http://www.microsoft.com/windowslivedevices/marketplace/default.aspx" />
<Webcam URL="http://www.microsoft.com/windowslivedevices/marketplace/default.aspx" />
</Marketplace>
<MessengerBlogURL>https://{{ settings.WEBSITE_HOST }}/blog</MessengerBlogURL>
<MobileMessaging Mode="RPPNew" CarrierList="" CrossSell="1" CharMax="140" MainWindowButton="true" OperatorPage="http://get.live.com/messenger/mobile" ValidRoutes="US;CA" />
<MSNSearch>
<DesktopInstallURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</DesktopInstallURL>
<ImagesURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=images</ImagesURL>
<NearMeURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</NearMeURL>
<NewsURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$+news&amp;ia=news</NewsURL>
<PeopleSearchURL>http://home.live.com/search?query=$QUERY$</PeopleSearchURL>
<PeopleSearchSiteID>73625</PeopleSearchSiteID>
<SearchKidsURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SearchKidsURL>
<SearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SearchURL>
<SharedSearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL>
<SharedSearchURL2>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL2>
</MSNSearch>
<MsnTodayConfig>
<MsnTodaySiteID>6528</MsnTodaySiteID>
<MsnTodayURL>https://{{ settings.TODAY_HOST }}/start?windowslive=1</MsnTodayURL>
<Flags>2</Flags>
</MsnTodayConfig>
<MusicIntegration URL="https://www.last.fm/search/tracks?q=$ARTIST$+$TITLE$"/>
<PartnerFeeds>
<Feed Name="MSN" URL="https://{{ settings.TODAY_HOST }}/start?windowslive=1" Owner="MSN" />
<Feed Name="GAMES" URL="http://windowsphone.xbox.com/en-US/MessengerGames/TabConfig" Owner="GAMES" />
</PartnerFeeds>
<PartnerFeedsSSL>
<Feed Name="MSN" URL="https://{{ settings.TODAY_HOST }}/start?windowslive=1" Owner="MSN" />
<Feed Name="GAMES" URL="http://windowsphone.xbox.com/en-US/MessengerGames/TabConfig" Owner="GAMES" />
</PartnerFeedsSSL>
<PE Tracking="http://trackingw4.technodesignip.com/?ContentID=$ContentID$&amp;Click=$Click$" />
<PremiumAV Visibility="1" />
<PSTNOut Hidden="0" />
<PublicFederated>
<YahooNetwork Enabled="true" OfflineIM="true" />
</PublicFederated>
<ReportAbuse>
<ReportAbuseSID />
<ReportAbuseURL>http://support.live.com/default.aspx?productkey=wlmessengerabuse</ReportAbuseURL>
<BiciReportAbuseApiUrl>https://home.live.com/handlers/ReportAbuse.mvc</BiciReportAbuseApiUrl>
<BiciReportAbuseApiServiceTarget>{{ settings.SOCIAL_HOST }}</BiciReportAbuseApiServiceTarget>
</ReportAbuse>
<RL>
<ViewProfileURL>http://g.msn.com/5meen_us/106?%1&amp;Plcid=%2!hs!&amp;%3&amp;Country=%4!hs!&amp;BrandID=%5&amp;passport=%6</ViewProfileURL>
</RL>
<SDrive Enabled="true" />
<ServiceAwareness>
<FindMoreUrl>http://cid-%1!16.16I64X!.profile.live.com/Services/</FindMoreUrl>
<FindMoreSiteId>73625</FindMoreSiteId>
<ManageUrl>http://cid-%1!16.16I64X!.profile.live.com/Services/?view=manage</ManageUrl>
<ManageSiteId>73625</ManageSiteId>
<ServicePartnerUrl>http://cid-%1!16.16I64X!.profile.live.com/Services/Add.aspx?appid=%2</ServicePartnerUrl>
<ServicePartnerSiteId>73625</ServicePartnerSiteId>
<WindowsLiveUrl>http://cid-%1!16.16I64X!.profile.live.com/whatsnewsettings</WindowsLiveUrl>
<WindowsLiveSiteId>73625</WindowsLiveSiteId>
</ServiceAwareness>
<SocialNews>
<EventUrl>http://cid-%1!16.16I64X!.events.live.com</EventUrl>
<EventSiteID>73625</EventSiteID>
<GroupUrl>http://cid-%1!16.16I64X!.groups.live.com</GroupUrl>
<GroupSiteID>73625</GroupSiteID>
<MainUrl>http://home.live.com/whatsnew.aspx</MainUrl>
<MainSiteID>73625</MainSiteID>
<OptionsUrl>http://profile.live.com/whatsnewsettings/</OptionsUrl>
<OptionsSiteID>73625</OptionsSiteID>
<HideUserFirstPartyUrl>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?cid=%2&amp;name=%3</HideUserFirstPartyUrl>
<HideUserFirstPartyUrl2>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?cid=%2&amp;name=%3</HideUserFirstPartyUrl2>
<HideUserFirstPartySiteID>73625</HideUserFirstPartySiteID>
<HideUserThirdPartyUrl>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?externalSourceId=%2&amp;externalObjectId=%3&amp;name=%4</HideUserThirdPartyUrl>
<HideUserThirdPartyUrl2>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?externalSourceId=%2&amp;externalObjectId=%3&amp;name=%4</HideUserThirdPartyUrl2>
<HideUserThirdPartySiteID>73625</HideUserThirdPartySiteID>
<HideUserEmailUrl>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?email=%2&amp;name=%3</HideUserEmailUrl>
<HideUserEmailUrl2>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?email=%2&amp;name=%3</HideUserEmailUrl2>
<HideUserEmailSiteID>73625</HideUserEmailSiteID>
<HideServiceUrl>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?appid=%2</HideServiceUrl>
<HideServiceUrl2>http://cid-%1.profile.live.com/WhatsNew/HideUpdates?appid=%2</HideServiceUrl2>
<HideServiceSiteID>73625</HideServiceSiteID>
<UserUrl>http://cid-%1!16.16I64X!.profile.live.com</UserUrl>
<UserSiteID>73625</UserSiteID>
</SocialNews>
<SocialToast>
<SuppressedEmailDomain>windowslivemail.com</SuppressedEmailDomain>
</SocialToast>
<TabConfig>
<RowNumber>1</RowNumber>
<slots>
{% for tab in tabs %}
<URL id="{{ tab.id }}">
https://{{ settings.AD_HOST }}/svcs/tab={{ tab.id }}
</URL>
{% endfor %}
</slots>
</TabConfig>
<TermsOfUse>
<TermsOfUseSID>956</TermsOfUseSID>
<TermsOfUseURL>https://{{ settings.WEBSITE_HOST }}/tos</TermsOfUseURL>
</TermsOfUse>
<UPUX>
<Product id="8" PartnerID="TD" ProductName="Winks" BrandName="Quebles Winks">
<BasePurchaseURL LaunchWindowType="Messenger" SiteID="60025" URL="http://www.mobilemoney.com/partners/msnmessenger/webshop/winks.asp?pos=chatwindow&amp;contentID=$CONTENTID$" />
<BillingHelpURL LaunchWindowType="Messenger" SiteID="60025" URL="http://us.mobilemoney.com/partners/msnmessenger/webshop/winks.asp?account=msnus&amp;pos=billingmenu" />
<BillingURL LaunchWindowType="Messenger" SiteID="60025" URL="http://us.mobilemoney.com/partners/msnmessenger/webshop/winks.asp?account=msnus&amp;pos=billingmenu" />
<ProductShopURL LaunchWindowType="Messenger" SiteID="60025" URL="http://us.mobilemoney.com/partners/msnmessenger/webshop/winks.asp?account=msnus&amp;pos=actionmenu" />
</Product>
<Product id="9" PartnerID="TD" ProductName="Dynamic Display Pictures" BrandName="Quebles Display Pictures" DialogMenuString="Quebles Display Pictures" IntegrationType="deep">
<BillingHelpURL LaunchWindowType="Messenger" SiteID="60025" URL="http://us.mobilemoney.com/partners/msnmessenger/webshop/ddp.asp?account=msnus&amp;pos=billingmenu" />
<BillingURL LaunchWindowType="Messenger" SiteID="60025" URL="http://us.mobilemoney.com/partners/msnmessenger/webshop/ddp.asp?account=msnus&amp;pos=billingmenu" />
<ProductShopURL LaunchWindowType="Messenger" SiteID="60025" URL="http://us.mobilemoney.com/partners/msnmessenger/webshop/ddp.asp?account=msnus&amp;pos=actionmenu" />
</Product>
<Product id="10" PartnerID="SY" ProductName="Dynamic Display Pictures" BrandName="WeeMee" DialogMenuString="Create a Dynamic WeeMee" IntegrationType="medium">
<ProductShopURL LaunchWindowType="IE" SiteID="41170" URL="http://www.wee-mee.com/en-us/ddp/" />
<BillingURL LaunchWindowType="IE" SiteID="41170" URL="http://www.wee-mee.com/en-us/myaccount/" />
<BillingHelpURL LaunchWindowType="IE" SiteID="41170" URL="http://www.wee-mee.com/en-us/help/" />
</Product>
<Product id="11" PartnerID="SY" ProductName="Winks" BrandName="WeeMee Winks">
<ProductShopURL LaunchWindowType="IE" SiteID="41170" URL="http://www.wee-mee.com/en-us/winks/" />
<BillingURL LaunchWindowType="IE" SiteID="41170" URL="http://www.wee-mee.com/en-us/myaccount/" />
<BillingHelpURL LaunchWindowType="IE" SiteID="41170" URL="http://www.wee-mee.com/en-us/help/" />
<BasePurchaseURL LaunchWindowType="IE" SiteID="41170" URL="http://www.wee-mee.com/en-us/content.aspx?id=$CONTENTID$" />
</Product>
<Product id="98" PartnerID="TD" ProductName="Emoticons" BrandName="Quebles Emoticons">
<BasePurchaseURL LaunchWindowType="Messenger" SiteID="60025" URL="http://www.mobilemoney.com/partners/msnmessenger/webshop/emoticons.asp?pos=chatwindow&amp;contentID=$CONTENTID$" />
</Product>
<Product id="99" PartnerID="VML" ProductName="Winks">
<BasePurchaseURL LaunchWindowType="Messenger" SiteID="258666" URL="http://themepackfactory.windowslive.com/default.aspx?tpf.loc=WKGetThis&amp;tpf.cid=$CONTENTID$" />
</Product>
</UPUX>
<VoiceClip Hidden="0" />
<VoiceVideo>
<DisableSipProxyInviteTest>0</DisableSipProxyInviteTest>
<DisableSipProxyCapability>0</DisableSipProxyCapability>
<DisableSipProxyInvite>0</DisableSipProxyInvite>
<DisableSipProxyCapability2>0</DisableSipProxyCapability2>
<DisableSipProxyInvite2>0</DisableSipProxyInvite2>
<VideoMessages>
<Config EnableRecording="1" Length="30" />
</VideoMessages>
</VoiceVideo>
</LocalizedConfig>
</MsgrConfig>
@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8" ?>
<MsgrConfig>
<Simple>
<Config>
<ExpiresInDays>0</ExpiresInDays>
</Config>
<DisablePhoneDialer>0</DisablePhoneDialer>
<GetItemVersionForUnknown>false</GetItemVersionForUnknown>
<MinFlashPlayer BuildNumber="28" MajorVersion="9" MinorVersion="0"/>
<Relay>
<Enabled>0</Enabled>
<MaxCallLength>0</MaxCallLength>
</Relay>
<TrustedDomains>
<domain name="hiden.cc"/>
<domain name="ugnet.gay"/>
<domain name="crosstalk.im"/>
<domain name="ctsrv.gay"/>
</TrustedDomains>
<ErrorResponseTable>
<Feature type="0" name="Login">
<Entry hr="0x80072EE7" action="3"/>
<Entry hr="0x81000306" action="3"/>
<Entry hr="0x80072EFD" action="3"/>
<Entry hr="0x81000362" action="3"/>
<Entry hr="0x8100030E" action="3"/>
<Entry hr="0x80072745" action="3"/>
<Entry hr="0x800701F7" action="3"/>
<Entry hr="0x80072EFF" action="3"/>
<Entry hr="0x81000363" action="3"/>
<Entry hr="0x81000395" action="3"/>
<Entry hr="0x800B0001" action="3"/>
<Entry hr="0x81000323" action="3"/>
<Entry hr="0x80072F19" action="3"/>
<Entry hr="0x800701F8" action="3"/>
<Entry hr="0x80072746" action="3"/>
<Entry hr="0x800701F6" action="3"/>
<Entry hr="0x81000377" action="3"/>
<Entry hr="0x81000314" action="3"/>
<Entry hr="0x81000378" action="3"/>
<Entry hr="0x80072EFF" action="3"/>
<Entry hr="0x80070190" action="3"/>
<Entry hr="0x80070197" action="3"/>
<Entry hr="0x80048820" action="3"/>
<Entry hr="0x80048829" action="3"/>
<Entry hr="0x80048834" action="3"/>
<Entry hr="0x80048852" action="3"/>
<Entry hr="0x8004886a" action="3"/>
<Entry hr="0x8004886b" action="3"/>
</Feature>
<Feature type="2" name="MapFile">
<Entry hr="0x810003F0" action="3"/>
<Entry hr="0x810003F1" action="3"/>
<Entry hr="0x810003F2" action="3"/>
<Entry hr="0x810003F3" action="3"/>
<Entry hr="0x810003F4" action="3"/>
<Entry hr="0x810003F5" action="3"/>
<Entry hr="0x810003F6" action="3"/>
<Entry hr="0x810003F7" action="3"/>
</Feature>
<Feature type="3" name="P2P">
<Entry hr="0x82000012" action="3"/>
<Entry hr="0x82000013" action="3"/>
<Entry hr="0x82000016" action="3"/>
<Entry hr="0x82000017" action="3"/>
<Entry hr="0x82000018" action="3"/>
<Entry hr="0x82000019" action="3"/>
</Feature>
</ErrorResponseTable>
</Simple>
<TabConfig>
{tabs}
</TabConfig>
<AbchCfg>
<abchconfig>
<url>https://{{ settings.ADDRESSBOOK_HOST }}/abservice.asmx</url>
</abchconfig>
</AbchCfg>
<LocalizedConfig Market="en-US">
<AdMainConfig>
<TextAdRefresh>1</TextAdRefresh>
<TextAdServer>http://{{ settings.AD_HOST }}/ads/txt</TextAdServer>
<AdBanner20URL Refresh="300">http://{{ settings.AD_HOST }}/ads/banner</AdBanner20URL>
<StdAd AdVisible="60" VideoVisible="120" VideoDldIntvl="0">
<VideoFeeds FeedsListURL="http://{{ settings.AD_HOST }}/svcs/msn-video-feeds/"/>
</StdAd>
</AdMainConfig>
<AppDirConfig>
<AppDirPageURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/Directory.aspx?L=en-us</AppDirPageURL>
<AppDirSeviceURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/AppDirectory.asmx</AppDirSeviceURL>
<AppDirVersionURL>http://{{ settings.APPDIR_HOST }}/AppDirectory/GetAppdirVersion.aspx</AppDirVersionURL>
</AppDirConfig>
<Contacts>
<ABPendingRequests>
<url>http://{{ settings.SOCIAL_HOST }}/PendingRequests.aspx?mkt=en-us&amp;partner=Messenger</url>
<siteid>73625</siteid>
<height>672</height>
<width>808</width>
</ABPendingRequests>
<BuddysSocialNetwork>
<url>http://{{ settings.SOCIAL_HOST }}/NetworkExplorer.aspx?mkt=en-us&amp;partner=Messenger&amp;cid=%1</url>
<siteid>73625</siteid>
<height>674</height>
<width>808</width>
</BuddysSocialNetwork>
<EditMyLiveContactProfile>
<url>http://{{ settings.SOCIAL_HOST }}/profile.aspx?action=edit&amp;mode=activecontacts&amp;mkt=en-us&amp;partner=Messenger</url>
<siteid>73625</siteid>
</EditMyLiveContactProfile>
<EditMyProfile>
<url>http://{{ settings.SOCIAL_HOST }}/profile.aspx?action=edit&amp;partner=Messenger&amp;mkt=en-us</url>
<siteid>73625</siteid>
</EditMyProfile>
<Profile>
<url>http://{{ settings.SOCIAL_HOST }}/Profile.aspx?partner=Messenger&amp;mkt=en-us&amp;mem=%ls</url>
<urlcid>http://{{ settings.SOCIAL_HOST }}/Profile.aspx?partner=Messenger&amp;mkt=en-us&amp;cid=%ls</urlcid>
<siteid>73625</siteid>
</Profile>
<SocialNetwork>
<url>http://{{ settings.SOCIAL_HOST }}/NetworkSetup.aspx?mkt=en-us&amp;partner=Messenger</url>
<siteid>73625</siteid>
<height>674</height>
<width>808</width>
</SocialNetwork>
<ViewMapEnabled>false</ViewMapEnabled>
</Contacts>
<ContactCard>
<AddToMySpaceSiteId>45930</AddToMySpaceSiteId>
<AddToMySpaceUrl>http://{{ settings.SOCIAL_HOST }}/?addblogentry=true&amp;mkt=nl-nl</AddToMySpaceUrl>
<ContactCardDisabled>false</ContactCardDisabled>
<CreateSpaceSiteId>45930</CreateSpaceSiteId>
<CreateSpaceUrl>http://{{ settings.SOCIAL_HOST }}/signup.aspx?mkt=nl-nl</CreateSpaceUrl>
<GetItemVerUrl>http://storage.msn.com/storageservice/schematizedstore.asmx</GetItemVerUrl>
<GetXmlFeedUrl>http://services.{{ settings.SOCIAL_HOST }}/contactcard/contactcardservice.asmx</GetXmlFeedUrl>
<MySpaceSiteId>45930</MySpaceSiteId>
<MySpaceUrl>http://{{ settings.SOCIAL_HOST }}/homepage.aspx</MySpaceUrl>
<SpaceBaseSiteId>45930</SpaceBaseSiteId>
<SpaceBaseUrl>http://{{ settings.SOCIAL_HOST }}</SpaceBaseUrl>
<SpaceIntegrationEnabled>true</SpaceIntegrationEnabled>
</ContactCard>
<FlashUpgradeURL>http://{{ settings.STORAGE_HOST }}/crosstalk-dist/client/all/tools/flashplayer_10_3r183_48_winax.exe</FlashUpgradeURL>
<GLinkMarket v="en_us"/>
<MessengerBlogURL>https://{{ settings.WEBSITE_HOST }}/blog</MessengerBlogURL>
<MSNSearch>
<ImagesURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=images</ImagesURL>
<NewsURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$+news&amp;ia=news</NewsURL>
<SearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SearchURL>
<SharedSearchURL>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL>
<SharedSearchURL2>https://searx.ugnet.gay/searxng/search?q=$QUERY$&amp;ia=web</SharedSearchURL2>
</MSNSearch>
<MsnTodayConfig>
<MsnTodaySiteID>6528</MsnTodaySiteID>
<MsnTodayURL>http://{{ settings.TODAY_HOST }}/start?wlm=1</MsnTodayURL>
<Flags>2</Flags>
</MsnTodayConfig>
<MusicIntegration URL="https://www.last.fm/search/tracks?q=$ARTIST$+$TITLE$"/>
<OneCare Enabled="0"/>
<PSTNOut Hidden="1"/>
<ReportAbuse>
<ReportAbuseSID/>
<ReportAbuseURL>https://{{ settings.WEBSITE_HOST }}/report</ReportAbuseURL>
</ReportAbuse>
<RL>
<ViewProfileURL>https://{{ settings.WEBSITE_HOST }}/account/settings</ViewProfileURL>
</RL>
<SDrive Enabled="true"/>
<TermsOfUse>
<TermsOfUseSID>956</TermsOfUseSID>
<TermsOfUseURL>https://{{ settings.WEBSITE_HOST }}/tos</TermsOfUseURL>
</TermsOfUse>
<VoiceClip Hidden="0"/>
<VoiceVideo>
<DisableSipProxyInviteTest>0</DisableSipProxyInviteTest>
<DisableSipProxyCapability>0</DisableSipProxyCapability>
<DisableSipProxyInvite>0</DisableSipProxyInvite>
<DisableSipProxyCapability2>0</DisableSipProxyCapability2>
<DisableSipProxyInvite2>0</DisableSipProxyInvite2>
</VoiceVideo>
</LocalizedConfig>
</MsgrConfig>
@@ -0,0 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<catalog version='ship.client.main.w5m4--RR1BLDF038-2014-04-01T05:44:12.5238180Z-16.4.3528.0331'>
<hash><![CDATA[RzxtMCwjtYFypyMdfgLnBKXe4sTQlLkwNGglT2JlC3i2KNTe9o5951InWF+NOvB3l7OqSCeZeMB6ya+sgv+QTg==]]></hash><url><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/catalog-daily.cab]]></url><updatebinary version="16.4.12.0" hash="tqLEnISBlpKDwuPqyngCatvR9SQ=" hash512="C4eX3BXbvaEvOqdeuuiNM2/Mp/dqYkYd/eSjccioKBqT3NJdzTJxDquAWYjctx+aNa8oQpTVAhwmspQH6tpoSw=="><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/wlupdate.dll]]></updatebinary><setupbinary hash="RlB+TMr+j3kQ7aMcATOrqFw5ntwRJEsTVZbT0jXoswScV5K/A8gItinGvp5+us+Ku1WY9bA8z8QTXs7AnOlWKA=="><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/wlsetup-daily.exe]]></setupbinary><setupresources hash="udf7sUELzfq3mkHsv6ieVfG+thuVaa8s8WjNylwCk8AYGWQbUl+tH24XtwOVL+nGz+EpFqTc/eDP3DETZ9Sn/A"><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/en/wlsres.dll.mui]]></setupresources><rule name="IsValidOs" logic="and"><!-- Win7 and above --><os version="win7" condition="greaterthanorequal" /><!-- only for W5, only for less than QFE1 --><msiVersion version="16.4.3528.0331" condition="lessthan" upgradeCode="{9E1469E4-F701-FF47-7DF0-7B079A3E1586}" /><msiVersion version="16.0.0.0" condition="greaterthanorequal" upgradeCode="{9E1469E4-F701-FF47-7DF0-7B079A3E1586}" /></rule><MUDelay>0</MUDelay><Throttle>100</Throttle><RescanTimer>720</RescanTimer>
<update version='ship.client.main.w5m4--RR1BLDF038-2014-04-01T05:44:12.5238180Z-16.4.3528.0331'>
<hash><![CDATA[RzxtMCwjtYFypyMdfgLnBKXe4sTQlLkwNGglT2JlC3i2KNTe9o5951InWF+NOvB3l7OqSCeZeMB6ya+sgv+QTg==]]></hash><url><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/catalog-daily.cab]]></url><updatebinary version="16.4.12.0" hash="tqLEnISBlpKDwuPqyngCatvR9SQ=" hash512="C4eX3BXbvaEvOqdeuuiNM2/Mp/dqYkYd/eSjccioKBqT3NJdzTJxDquAWYjctx+aNa8oQpTVAhwmspQH6tpoSw=="><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/wlupdate.dll]]></updatebinary><setupbinary hash="RlB+TMr+j3kQ7aMcATOrqFw5ntwRJEsTVZbT0jXoswScV5K/A8gItinGvp5+us+Ku1WY9bA8z8QTXs7AnOlWKA=="><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/wlsetup-daily.exe]]></setupbinary><setupresources hash="udf7sUELzfq3mkHsv6ieVfG+thuVaa8s8WjNylwCk8AYGWQbUl+tH24XtwOVL+nGz+EpFqTc/eDP3DETZ9Sn/A"><![CDATA[https://secure.wlxrs.com/~Live.Setup.Catalogship/~16.4.12/~/~/~/~/ship/en/wlsres.dll.mui]]></setupresources><rule name="IsValidOs" logic="and"><!-- Win7 and above --><os version="win7" condition="greaterthanorequal" /><!-- only for W5, only for less than QFE1 --><msiVersion version="16.4.3528.0331" condition="lessthan" upgradeCode="{9E1469E4-F701-FF47-7DF0-7B079A3E1586}" /><msiVersion version="16.0.0.0" condition="greaterthanorequal" upgradeCode="{9E1469E4-F701-FF47-7DF0-7B079A3E1586}" /></rule><MUDelay>0</MUDelay><Throttle>100</Throttle><RescanTimer>720</RescanTimer>
</update>
</catalog>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<DeleteMessagesResponse xmlns="http://www.hotmail.msn.com/ws/2004/09/oim/rsi" />
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode xmlns:q0="{{ owsns }}">q0:AuthenticationFailed</faultcode>
<faultstring>Exception of type System.Web.Services.Protocols.SoapException was thrown.</faultstring>
<faultactor>https://ows.messenger.msn.com/OimWS/oim.asmx</faultactor>
<detail>
<TweenerChallenge xmlns="{{ owsns }}">ct=1,rver=1,wp=FS_40SEC_0_COMPACT,lc=1,id=1</TweenerChallenge>
<LockKeyChallenge xmlns="{{ owsns }}">1850937852</LockKeyChallenge>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<Machine xmlns="{{ owsns }}" name="BAYM-OW15" ver="12.30.1623.0"/>
</soap:Header>
<soap:Body>
<soap:Fault>
<faultcode xmlns:q0="{{ owsns }}">q0:InvalidContent</faultcode>
<faultstring>Exception of type 'System.Web.Services.Protocols.SoapException' was thrown.</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>

Some files were not shown because too many files have changed in this diff Show More