#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  king_phisher/ua_parser.py
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following disclaimer
#    in the documentation and/or other materials provided with the
#    distribution.
#  * Neither the name of the project nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

import collections
import re

__all__ = ['UserAgent', 'parse_user_agent']
__version__ = '0.1'

USER_AGENT_REGEX_OS = re.compile(r'(android|blackberry|(ipad|iphone)?; cpu (ipad |iphone )?os|linux|mac os x|windows nt) (([\d\._\-]+)(;|\)| ))?', flags=re.IGNORECASE)
USER_AGENT_REGEX_ARCH_X86 = re.compile(r'(x|(i[3456]))86[^-_]', flags=re.IGNORECASE)
USER_AGENT_REGEX_ARCH_X86_64 = re.compile(r'(amd|wow|x(86[-_])?)?64', flags=re.IGNORECASE)

UserAgent = collections.namedtuple('UserAgent', ['os_name', 'os_version', 'os_arch'])

def parse_user_agent(user_agent):
	os_parts = USER_AGENT_REGEX_OS.search(user_agent)
	if not os_parts:
		return None
	# OS Name
	os_name = os_parts.group(1).lower()
	if 'android' in os_name:
		os_name = 'Android'
	elif 'blackberry' in os_name:
		os_name = 'BlackBerry'
	elif 'ipad' in os_name or 'iphone' in os_name:
		os_name = 'iOS'
	elif 'linux' in os_name:
		os_name = 'Linux'
	elif 'os x' in os_name:
		os_name = 'OS X'
	elif 'windows nt' in os_name:
		os_name = 'Windows NT'
	else:
		return None
	# OS Version
	os_version = os_parts.group(5)
	if os_version:
		os_version = re.sub(r'[_-]', r'.', os_version)
	# OS Arch
	os_arch = None
	if USER_AGENT_REGEX_ARCH_X86_64.search(user_agent):
		os_arch = 'x86-64'
	elif USER_AGENT_REGEX_ARCH_X86.search(user_agent):
		os_arch = 'x86'
	return UserAgent(os_name, os_version, os_arch)

@@ -1666,16 +1666,192 @@
  '0.1'%0A%0A
+USER_AGENT_REGEX_ARCH_X86 = re.compile(r'(x%7C(i%5B3456%5D))86%5B%5E-_%5D', flags=re.IGNORECASE)%0AUSER_AGENT_REGEX_ARCH_X86_64 = re.compile(r'(amd%7Cwow%7Cx(86%5B-_%5D)?)?64', flags=re.IGNORECASE)%0A
 USER_AGE
@@ -2023,32 +2023,31 @@
 AGENT_REGEX_
-ARCH_X86
+VERSION
  = re.compil
@@ -2054,141 +2054,39 @@
 e(r'
-(x%7C(i%5B3456%5D))86%5B%5E-_%5D', flags=re.IGNORECASE)%0AUSER_AGENT_REGEX_ARCH_X86_64 = re.compile(r'(amd%7Cwow%7Cx(86%5B-_%5D)?)?64', flags=re.IGNORECASE
+Version/((%5B%5Cd%5C._%5C-%5D+)(;%7C%5C)%7C ))'
 )%0A%0AU
@@ -2272,30 +2272,203 @@
 os_parts:%0A%09%09
-return
+user_agent = re.sub(r'(BB)(%5Cd+)', r'BlackBerry %5C2', user_agent)%0A%09%09os_parts = USER_AGENT_REGEX_OS.search(user_agent)%0A%09%09if not os_parts:%0A%09%09%09return None%0A%09os_arch = None%0A%09os_version =
  None%0A%09# OS 
@@ -2613,16 +2613,131 @@
 kBerry'%0A
+%09%09version_tag = USER_AGENT_REGEX_VERSION.search(user_agent)%0A%09%09if version_tag:%0A%09%09%09os_version = version_tag.group(2)%0A
 %09elif 'i
@@ -2988,16 +2988,31 @@
 ersion =
+ (os_version or
  os_part
@@ -3021,16 +3021,17 @@
 group(5)
+)
 %0A%09if os_

Update user agent parsing for odd blackberry devices