\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7<F<2PFAFZUP_xxnnx\F5\AF\B9\91\C8\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\DB\00CUZZxix‚\EB\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\C0\00\00b\00d\00\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00\001A!Q\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00!1AQ\FF\DA\00\00\00?\00\F6\00\00\00\00\00\00\00\00\00\00\A0\00\00\C5\CF\F8\E7Ó\FCjD~\B9^\AD\%\B3]\D8cs-\BBs,-\A0\00"\80\00%\B83rÏ^K~F\A4ea\00E\00\C6\EE=u\B1\9B\D1\00@\00r\BE8\F9:\FE5#.M\00\E7\CB\C9q\CBq\D6\F2\BE\B7\C7>\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7	\8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh
\00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€
\00$\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95
59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>C///</title>
</head>
#
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
#

"""
classes/utils for Kerberos principal name validation/manipulation
"""
import re
import six

from ipapython.ipautil import escape_seq, unescape_seq

if six.PY3:
    unicode = str

REALM_SPLIT_RE = re.compile(r'(?<!\\)@')
COMPONENT_SPLIT_RE = re.compile(r'(?<!\\)/')


def parse_princ_name_and_realm(principal, realm=None):
    """
    split principal to the <principal_name>, <realm> components

    :param principal: unicode representation of principal
    :param realm: if not None, replace the parsed realm with the specified one

    :returns: tuple containing the principal name and realm
        realm will be `None` if no realm was found in the input string
    """
    realm_and_name = REALM_SPLIT_RE.split(principal)
    if len(realm_and_name) > 2:
        raise ValueError(
            "Principal is not in <name>@<realm> format")

    principal_name = realm_and_name[0]

    try:
        parsed_realm = realm_and_name[1]
    except IndexError:
        parsed_realm = None if realm is None else realm

    return principal_name, parsed_realm


def split_principal_name(principal_name):
    """
    Split principal name (without realm) into the components

    NOTE: operates on the following RFC 1510 types:
        * NT-PRINCIPAL
        * NT-SRV-INST
        * NT-SRV-HST

    Enterprise principals (NT-ENTERPRISE, see RFC 6806) are also handled

    :param principal_name: unicode representation of principal name
    :returns: tuple of individual components (i.e. primary name for
    NT-PRINCIPAL and NT-ENTERPRISE, primary name and instance for others)
    """
    return tuple(COMPONENT_SPLIT_RE.split(principal_name))


@six.python_2_unicode_compatible
class Principal(object):
    """
    Container for the principal name and realm according to RFC 1510
    """
    def __init__(self, components, realm=None):
        if isinstance(components, six.binary_type):
            raise TypeError(
                "Cannot create a principal object from bytes: {!r}".format(
                    components)
            )
        elif isinstance(components, six.string_types):
            # parse principal components from realm
            self.components, self.realm = self._parse_from_text(
                components, realm)

        elif isinstance(components, Principal):
            self.components = components.components
            self.realm = components.realm if realm is None else realm
        else:
            self.components = tuple(components)
            self.realm = realm

    def __eq__(self, other):
        if not isinstance(other, Principal):
            return False

        return (self.components == other.components and
                self.realm == other.realm)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __lt__(self, other):
        return unicode(self) < unicode(other)

    def __le__(self, other):
        return self.__lt__(other) or self.__eq__(other)

    def __gt__(self, other):
        return not self.__le__(other)

    def __ge__(self, other):
        return self.__gt__(other) or self.__eq__(other)

    def __hash__(self):
        return hash(self.components + (self.realm,))

    def _parse_from_text(self, principal, realm=None):
        """
        parse individual principal name components from the string
        representation of the principal. This is done in three steps:
            1.) split the string at the unescaped '@'
            2.) unescape any leftover '\@' sequences
            3.) split the primary at the unescaped '/'
            4.) unescape leftover '\/'
        :param principal: unicode representation of the principal name
        :param realm: if not None, this realm name will be used instead of the
            one parsed from `principal`

        :returns: tuple containing the principal name components and realm
        """
        principal_name, parsed_realm = parse_princ_name_and_realm(
            principal, realm=realm)

        (principal_name,) = unescape_seq(u'@', principal_name)

        if parsed_realm is not None:
            (parsed_realm,) = unescape_seq(u'@', parsed_realm)

        name_components = split_principal_name(principal_name)
        name_components = unescape_seq(u'/', *name_components)

        return name_components, parsed_realm

    @property
    def is_user(self):
        return len(self.components) == 1

    @property
    def is_enterprise(self):
        return self.is_user and u'@' in self.components[0]

    @property
    def is