def set_name(self, substitute_name, print_name):
        b_substitute_name = to_bytes(to_text(substitute_name),
                                     encoding='utf-16-le')
        b_print_name = to_bytes(to_text(print_name), encoding='utf-16-le')

        self['substitute_name_offset'] = 0
        self['substitute_name_length'] = len(b_substitute_name)
        self['print_name_offset'] = len(b_substitute_name)
        self['print_name_length'] = len(b_print_name)
        self['buffer'] = b_substitute_name + b_print_name
Ejemplo n.º 2
0
 def _get_packed_size(self):
     text_value = self._get_calculated_value(self.value)
     size = len(to_bytes(text_value, encoding=self.encoding))
     if self.null_terminated:
         char_len = len("\x00".encode(self.encoding))
         size += char_len
     return size
Ejemplo n.º 3
0
    def test_resolve_path_different_host(self):
        b_sub_name = to_bytes(u'\\??\\UNC\\sérver\\sharé2\\foldér', encoding='utf-16-le')
        b_print_name = to_bytes(u'\\\\sérver\\sharé2\\foldér', encoding='utf-16-le')
        resp = SMB2SymbolicLinkErrorResponse()
        resp['unparsed_path_length'] = 0
        resp['substitute_name_offset'] = 0
        resp['substitute_name_length'] = len(b_sub_name)
        resp['print_name_offset'] = len(b_sub_name)
        resp['print_name_length'] = len(b_print_name)
        resp['flags'] = SymbolicLinkErrorFlags.SYMLINK_FLAG_ABSOLUTE
        resp['path_buffer'] = b_sub_name + b_print_name

        link_path = u'\\\\sérver\\sharé\\foldér'
        expected = u"Encountered symlink at '%s' that points to '\\\\sérver\\sharé2\\foldér' which cannot be " \
                   u"redirected: Cannot resolve link targets that point to a different host/share" % link_path
        with pytest.raises(SMBLinkRedirectionError, match=re.escape(to_native(expected))):
            resp.resolve_path(link_path)
Ejemplo n.º 4
0
    def test_resolve_path(self, unparsed_length, sub_name, print_name, flags, link_path, expected):
        b_sub_name = to_bytes(sub_name, encoding='utf-16-le')
        b_print_name = to_bytes(print_name, encoding='utf-16-le')
        resp = SMB2SymbolicLinkErrorResponse()
        resp['unparsed_path_length'] = unparsed_length
        resp['substitute_name_offset'] = 0
        resp['substitute_name_length'] = len(b_sub_name)
        resp['print_name_offset'] = len(b_sub_name)
        resp['print_name_length'] = len(b_print_name)
        resp['flags'] = flags
        resp['path_buffer'] = b_sub_name + b_print_name

        assert resp.get_print_name() == print_name
        assert resp.get_substitute_name() == sub_name

        actual = resp.resolve_path(link_path)
        assert actual == expected
Ejemplo n.º 5
0
    def set_name(self, print_name, substitute_name):
        """
        Set's the path_buffer and print/substitute name length of the message
        with the values passed in. These values should be a string and not a
        byte string as it is encoded in this function.

        :param print_name: The print name string to set
        :param substitute_name: The substitute name string to set
        """
        # Ensure that the to_bytes input is an actual text string for py2 compat with native strings.
        print_bytes = to_bytes(to_text(print_name), encoding='utf-16-le')
        sub_bytes = to_bytes(to_text(substitute_name), encoding='utf-16-le')
        path_buffer = print_bytes + sub_bytes

        self['print_name_offset'].set_value(0)
        self['print_name_length'].set_value(len(print_bytes))
        self['substitute_name_offset'].set_value(len(print_bytes))
        self['substitute_name_length'].set_value(len(sub_bytes))
        self['path_buffer'].set_value(path_buffer)
Ejemplo n.º 6
0
def test_native_to_bytes():
    # Python 3 the default string type is unicode so the expected value will
    # be "abc" in UTF-16 form while Python 2 "abc" is the bytes representation
    # already
    if PY3:
        expected = b"\x61\x00\x62\x00\x63\x00"
    else:
        expected = b"\x61\x62\x63"
    actual = to_bytes("abc", encoding='utf-16-le')
    assert actual == expected
    def test_create_message(self):
        message = SymbolicLinkReparseDataBuffer()
        message['substitute_name_offset'] = 8
        message['substitute_name_length'] = 16
        message['print_name_offset'] = 0
        message['print_name_length'] = 8
        message['flags'] = SymbolicLinkFlags.SYMLINK_FLAG_RELATIVE
        message['buffer'] = to_bytes(u"café\\??\\café", encoding='utf-16-le')

        actual = message.pack()
        assert len(message) == 36
        assert actual == self.DATA
    def test_parse_message(self):
        actual = SymbolicLinkReparseDataBuffer()
        data = actual.unpack(self.DATA)

        assert data == b""
        assert len(actual) == 36
        assert actual['substitute_name_offset'].get_value() == 8
        assert actual['substitute_name_length'].get_value() == 16
        assert actual['print_name_offset'].get_value() == 0
        assert actual['print_name_length'].get_value() == 8
        assert actual['flags'].get_value(
        ) == SymbolicLinkFlags.SYMLINK_FLAG_RELATIVE
        assert actual['buffer'].get_value() == to_bytes(u"café\\??\\café",
                                                        encoding='utf-16-le')
        assert actual.get_substitute_name() == u"\\??\\café"
        assert actual.get_print_name() == u"café"
Ejemplo n.º 9
0
    def resolve_path(self, link_path):
        """
        [MS-SMB2] 2.2.2.2.1.1 Handling the Symbolic Link Error Response
        https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/a8da655c-8b0b-415a-b726-16dc33fa5827

        Attempts to resolve the link target path. Will fail if the link is pointing to a local path or a UNC path
        on another host or share.

        :param link_path: The original path to the symbolic link to resolve relative paths from.
        :return: The resolved link target path.
        """
        substitute_name = self.get_substitute_name()
        print_name = self.get_print_name()
        unparsed_path_length = self['unparsed_path_length'].get_value()

        b_link_path = to_bytes(to_text(link_path), encoding='utf-16-le')
        unparsed_idx = len(b_link_path) - unparsed_path_length
        base_link_path = to_text(b_link_path[:unparsed_idx],
                                 encoding='utf-16-le')
        unparsed_path = to_text(b_link_path[unparsed_idx:],
                                encoding='utf-16-le')

        # Use the common code in SymbolicLinkReparseDataBuffer() to resolve the link target.
        symlink_buffer = SymbolicLinkReparseDataBuffer()
        symlink_buffer['flags'] = self['flags'].get_value()
        symlink_buffer.set_name(substitute_name, print_name)
        target_path = symlink_buffer.resolve_link(
            base_link_path) + unparsed_path

        if not target_path.startswith('\\\\'):
            raise SMBLinkRedirectionError(
                "Cannot resolve link targets that point to a local path",
                link_path, print_name)

        link_share = ntpath.splitdrive(link_path)[0]
        target_share = ntpath.splitdrive(target_path)[0]
        if link_share != target_share:
            raise SMBLinkRedirectionError(
                "Cannot resolve link targets that point to a different host/share",
                link_path, print_name)

        return target_path
Ejemplo n.º 10
0
def test_bytes_to_bytes():
    expected = b"\x01\x02\x03\x04"
    actual = to_bytes(b"\x01\x02\x03\x04")
    assert actual == expected
Ejemplo n.º 11
0
def test_text_to_bytes_diff_encoding():
    expected = b"\x61\x00\x62\x00\x63\x00"
    actual = to_bytes(u"abc", encoding='utf-16-le')
    assert actual == expected
Ejemplo n.º 12
0
def test_text_to_bytes_default():
    expected = b"\x61\x62\x63"
    actual = to_bytes(u"abc")
    assert actual == expected
Ejemplo n.º 13
0
 def _get_packed_size(self):
     text_value = self._get_calculated_value(self.value)
     return len(to_bytes(text_value, encoding=self.encoding))
Ejemplo n.º 14
0
 def _pack_value(self, value):
     return to_bytes(value, encoding=self.encoding)
Ejemplo n.º 15
0
 def _pack_value(self, value):
     if self.null_terminated:
         value += u"\x00"
     return to_bytes(value, encoding=self.encoding)