New checkin of pysmb 1.0.0
Michael Teo
12 years ago
0 | ||
1 | pysmb-1.0.0, 25 Dec 2011 | |
2 | ======================== | |
3 | ||
4 | - Completely rewrites pysmb. API is not compatible with previous pysmb-0.x.x | |
5 | - Supports NTLMv1 and NTLMv2 authentication | |
6 | - Adds in NMB/SMB protocol implementation for use with Twisted framework | |
7 | - Tested with Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x | |
8 | - Requires Python 2.4.4 or later, and pyasn1. Not tested with Python3 | |
9 | ||
10 | pysmb-0.4.5, 22 Jun 2009 | |
11 | ======================== | |
12 | ||
13 | - Prevents pysmb from failing when there are too many files/folders to | |
14 | be returned in a single SMB TRANS2 call. pysmb will "resume" requesting | |
15 | for more files/folders information in subsequent SMB TRANS2 requests. | |
16 | ||
17 | pysmb-0.4.4, 12 Jan 2004 | |
18 | ======================== | |
19 | ||
20 | - Add in support for AMK's Python Cryptography Toolkit which will be used | |
21 | for DES password hashing. If AMK's pycrypto is found, it will be used | |
22 | instead of mxCrypto. | |
23 | ||
24 | pysmb-0.4.3, 22 Feb 2003 | |
25 | ======================== | |
26 | ||
27 | - Fix a bug which fails to close the socket in nmb.py on socket exception | |
28 | - Fix a bug which fails to close the NetBIOSSession in smb.py if the session | |
29 | has not been properly established yet. | |
30 | ||
31 | pysmb-0.4.2, 03 Aug 2002 | |
32 | ======================== | |
33 | ||
34 | - Add new methods to SharedFile instances, get_mtime_epoch, get_atime_epoch | |
35 | and get_ctime_epoch. These methods will return the mtime, atime and ctime in | |
36 | epoch time rather than SMB time. | |
37 | - Remove debugging printout in smb.py which has been released accidentally | |
38 | with the last release. | |
39 | - Fix a bug in smbcp which causes to local to remote copy to fail | |
40 | ||
41 | pysmb-0.4.1, 22 Jun 2002 | |
42 | ======================== | |
43 | ||
44 | - Fix a bug in smb.py which does not return the correct file size for files | |
45 | with their archive bits turned off. This results in these files not being | |
46 | retrieved or sent properly. | |
47 | - Fix some typo error in the documentations | |
48 | ||
49 | pysmb-0.4.0, 17 Apr 2002 | |
50 | ======================== | |
51 | ||
52 | - Use NT LM0.12 dialect. | |
53 | - New smb.SMBMachine class | |
54 | - Add SMB.get_server_domain(), smb.get_server_os(), SMB.get_server_lanman() | |
55 | ||
56 | pysmb-0.3.1, 12 Nov 2001 | |
57 | ======================== | |
58 | ||
59 | - Fix a problem with some Windows server where an UID is required when server is in share mode. | |
60 | Now, pysmb calls login() with empty authentication information when server is in share mode. | |
61 | - Add TYPE_DOMAIN_MASTER constant and description to nmb.py. | |
62 | ||
63 | pysmb-0.3.0, 10 Nov 2001 | |
64 | ======================== | |
65 | ||
66 | - Add support for services in share mode. Minor changes to smb.SMB class API. | |
67 | - Fix a bug in smb.py's __raw_retr_file which has failed to initialize the max_buf_size prior to usage. | |
68 | - Fix a bug in smblistshare which fails to print the correct NMB error message | |
69 | - Modify smb.py not throw AttributeError in the destructor when there is an error while creating a session | |
70 | in the constructor | |
71 | ||
72 | pysmb-0.2.0, 04 Oct 2001 | |
73 | ======================== | |
74 | ||
75 | - Add support for encrypted authentication using DES | |
76 | - Fix a bug(?) which treats all services and filenames as case-sensitive | |
77 | ||
78 | pysmb-0.1.3, 03 Sep 2001 | |
79 | ======================== | |
80 | ||
81 | - Fix a bug in smblistshare and smbdu which fails to catch the nmb.NetBIOSError raised when session | |
82 | setup fails. | |
83 | - Fix a bug in smb.SMB that arises from the change in nmb.NetBIOSSession which sends | |
84 | the session port number as the remote host type. | |
85 | ||
86 | pysmb-0.1.2, 01 Sep 2001 | |
87 | ======================== | |
88 | ||
89 | - Fix a bug in nmb.NetBIOSSession which specifies a TYPE_WORKSTATION for remote host instead of TYPE_SERVER. | |
90 | - Minor change to nmb.NetBIOSSession constructor API. | |
91 | - Fix a bug in smbdu which raises OverflowError when printing long file size values. | |
92 | - Fix a bug in smbcp which does not handle the destination path correctly when | |
93 | the source file is copied to a different filename. | |
94 | ||
95 | pysmb-0.1.1, 25 Aug 2001 | |
96 | ======================== | |
97 | ||
98 | - Change nmb's NetBIOS and NetBIOSSession class such that they raise a NetBIOSError | |
99 | with a tuple of ( err_msg, err_class, err_code ) | |
100 | - Add a function strerror() in both smb and nmb to return human readable messages | |
101 | for error codes. | |
102 | - Fix a bug in smbcp which fails to print an error message and terminate when the | |
103 | remote source path is not found. | |
104 | - Add in another utility, smblistshare. | |
105 | ||
106 | pysmb-0.1.0, 20 Aug 2001 | |
107 | ======================== | |
108 | ||
109 | - First public release |
0 | ||
1 | Copyright (C) 2001-2011 Michael Teo <miketeo (a) miketeo.net> | |
2 | ||
3 | This software is provided 'as-is', without any express or implied warranty. | |
4 | In no event will the author be held liable for any damages arising from the | |
5 | use of this software. | |
6 | ||
7 | Permission is granted to anyone to use this software for any purpose, | |
8 | including commercial applications, and to alter it and redistribute it | |
9 | freely, subject to the following restrictions: | |
10 | ||
11 | 1. The origin of this software must not be misrepresented; you must not | |
12 | claim that you wrote the original software. If you use this software | |
13 | in a product, an acknowledgment in the product documentation would be | |
14 | appreciated but is not required. | |
15 | ||
16 | 2. Altered source versions must be plainly marked as such, and must not be | |
17 | misrepresented as being the original software. | |
18 | ||
19 | 3. This notice cannot be removed or altered from any source distribution. |
0 | # file GENERATED by distutils, do NOT edit | |
1 | CHANGELOG | |
2 | LICENSE | |
3 | README.txt | |
4 | setup.py | |
5 | docs/doctrees/environment.pickle | |
6 | docs/doctrees/extending.doctree | |
7 | docs/doctrees/index.doctree | |
8 | docs/doctrees/api/nmb_NBNSProtocol.doctree | |
9 | docs/doctrees/api/nmb_NetBIOS.doctree | |
10 | docs/doctrees/api/smb_SMBConnection.doctree | |
11 | docs/doctrees/api/smb_SMBProtocolFactory.doctree | |
12 | docs/doctrees/api/smb_SharedDevice.doctree | |
13 | docs/doctrees/api/smb_SharedFile.doctree | |
14 | docs/doctrees/api/smb_exceptions.doctree | |
15 | docs/html/.buildinfo | |
16 | docs/html/extending.html | |
17 | docs/html/genindex.html | |
18 | docs/html/index.html | |
19 | docs/html/objects.inv | |
20 | docs/html/search.html | |
21 | docs/html/searchindex.js | |
22 | docs/html/_modules/index.html | |
23 | docs/html/_modules/nmb/NetBIOS.html | |
24 | docs/html/_modules/nmb/NetBIOSProtocol.html | |
25 | docs/html/_modules/smb/SMBConnection.html | |
26 | docs/html/_modules/smb/SMBProtocol.html | |
27 | docs/html/_modules/smb/base.html | |
28 | docs/html/_modules/smb/smb_structs.html | |
29 | docs/html/_sources/extending.txt | |
30 | docs/html/_sources/index.txt | |
31 | docs/html/_sources/api/nmb_NBNSProtocol.txt | |
32 | docs/html/_sources/api/nmb_NetBIOS.txt | |
33 | docs/html/_sources/api/smb_SMBConnection.txt | |
34 | docs/html/_sources/api/smb_SMBProtocolFactory.txt | |
35 | docs/html/_sources/api/smb_SharedDevice.txt | |
36 | docs/html/_sources/api/smb_SharedFile.txt | |
37 | docs/html/_sources/api/smb_exceptions.txt | |
38 | docs/html/_static/ajax-loader.gif | |
39 | docs/html/_static/basic.css | |
40 | docs/html/_static/comment-bright.png | |
41 | docs/html/_static/comment-close.png | |
42 | docs/html/_static/comment.png | |
43 | docs/html/_static/contents.png | |
44 | docs/html/_static/doctools.js | |
45 | docs/html/_static/down-pressed.png | |
46 | docs/html/_static/down.png | |
47 | docs/html/_static/file.png | |
48 | docs/html/_static/jquery.js | |
49 | docs/html/_static/minus.png | |
50 | docs/html/_static/navigation.png | |
51 | docs/html/_static/plus.png | |
52 | docs/html/_static/pygments.css | |
53 | docs/html/_static/searchtools.js | |
54 | docs/html/_static/sphinxdoc.css | |
55 | docs/html/_static/underscore.js | |
56 | docs/html/_static/up-pressed.png | |
57 | docs/html/_static/up.png | |
58 | docs/html/_static/websupport.js | |
59 | docs/html/api/nmb_NBNSProtocol.html | |
60 | docs/html/api/nmb_NetBIOS.html | |
61 | docs/html/api/smb_SMBConnection.html | |
62 | docs/html/api/smb_SMBProtocolFactory.html | |
63 | docs/html/api/smb_SharedDevice.html | |
64 | docs/html/api/smb_SharedFile.html | |
65 | docs/html/api/smb_exceptions.html | |
66 | nmb/NetBIOS.py | |
67 | nmb/NetBIOSProtocol.py | |
68 | nmb/__init__.py | |
69 | nmb/base.py | |
70 | nmb/nmb_constants.py | |
71 | nmb/nmb_structs.py | |
72 | nmb/utils.py | |
73 | smb/SMBConnection.py | |
74 | smb/SMBProtocol.py | |
75 | smb/__init__.py | |
76 | smb/base.py | |
77 | smb/ntlm.py | |
78 | smb/securityblob.py | |
79 | smb/smb_constants.py | |
80 | smb/smb_structs.py | |
81 | smb/utils/README.txt | |
82 | smb/utils/U32.py | |
83 | smb/utils/__init__.py | |
84 | smb/utils/md4.py | |
85 | smb/utils/pyDes.py | |
86 | sphinx/Makefile | |
87 | sphinx/make.bat | |
88 | sphinx/source/conf.py | |
89 | sphinx/source/extending.rst | |
90 | sphinx/source/index.rst | |
91 | sphinx/source/api/nmb_NBNSProtocol.rst | |
92 | sphinx/source/api/nmb_NetBIOS.rst | |
93 | sphinx/source/api/smb_SMBConnection.rst | |
94 | sphinx/source/api/smb_SMBProtocolFactory.rst | |
95 | sphinx/source/api/smb_SharedDevice.rst | |
96 | sphinx/source/api/smb_SharedFile.rst | |
97 | sphinx/source/api/smb_exceptions.rst | |
98 | tests/README_1st.txt | |
99 | tests/__init__.py | |
100 | tests/connection.ini | |
101 | tests/smbtest.zip | |
102 | tests/test_ntlm.py | |
103 | tests/test_securityblob.py | |
104 | tests/NetBIOSTests/__init__.py | |
105 | tests/NetBIOSTests/test_queryname.py | |
106 | tests/NetBIOSTwistedTests/__init__.py | |
107 | tests/NetBIOSTwistedTests/test_queryname.py | |
108 | tests/SMBConnectionTests/__init__.py | |
109 | tests/SMBConnectionTests/test_auth.py | |
110 | tests/SMBConnectionTests/test_createdeletedirectory.py | |
111 | tests/SMBConnectionTests/test_echo.py | |
112 | tests/SMBConnectionTests/test_listpath.py | |
113 | tests/SMBConnectionTests/test_listshares.py | |
114 | tests/SMBConnectionTests/test_rename.py | |
115 | tests/SMBConnectionTests/test_retrievefile.py | |
116 | tests/SMBConnectionTests/test_storefile.py | |
117 | tests/SMBConnectionTests/util.py | |
118 | tests/SMBTwistedTests/__init__.py | |
119 | tests/SMBTwistedTests/test_auth.py | |
120 | tests/SMBTwistedTests/test_createdeletedirectory.py | |
121 | tests/SMBTwistedTests/test_echo.py | |
122 | tests/SMBTwistedTests/test_listpath.py | |
123 | tests/SMBTwistedTests/test_listshares.py | |
124 | tests/SMBTwistedTests/test_rename.py | |
125 | tests/SMBTwistedTests/test_retrievefile.py | |
126 | tests/SMBTwistedTests/test_storefile.py | |
127 | tests/SMBTwistedTests/util.py | |
128 | tests/SupportFiles/binary.dat |
0 | include LICENSE | |
1 | include CHANGELOG | |
2 | recursive-include nmb * | |
3 | recursive-exclude nmb *.pyc | |
4 | recursive-include smb * | |
5 | recursive-exclude smb *.pyc | |
6 | recursive-include tests * | |
7 | recursive-exclude tests *.pyc | |
8 | recursive-include sphinx * | |
9 | recursive-include docs * |
0 | pysmb is an experimental SMB/CIFS library written in Python. | |
1 | It implements the client-side SMB/CIFS protocol which allows your Python application to access | |
2 | and transfer files to/from SMB/CIFS shared folders like your Windows file sharing and Samba folders. |
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 | # Sphinx build info version 1 | |
1 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. | |
2 | config: c707d5f0c2f3122707ecae391b521805 | |
3 | tags: fbb0d17656682115ca4d033fb2f83ba1 |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>Overview: module code — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | </head> | |
29 | <body> | |
30 | <div class="related"> | |
31 | <h3>Navigation</h3> | |
32 | <ul> | |
33 | <li class="right" style="margin-right: 10px"> | |
34 | <a href="../genindex.html" title="General Index" | |
35 | accesskey="I">index</a></li> | |
36 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
37 | </ul> | |
38 | </div> | |
39 | <div class="sphinxsidebar"> | |
40 | <div class="sphinxsidebarwrapper"> | |
41 | <div id="searchbox" style="display: none"> | |
42 | <h3>Quick search</h3> | |
43 | <form class="search" action="../search.html" method="get"> | |
44 | <input type="text" name="q" /> | |
45 | <input type="submit" value="Go" /> | |
46 | <input type="hidden" name="check_keywords" value="yes" /> | |
47 | <input type="hidden" name="area" value="default" /> | |
48 | </form> | |
49 | <p class="searchtip" style="font-size: 90%"> | |
50 | Enter search terms or a module, class or function name. | |
51 | </p> | |
52 | </div> | |
53 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
54 | </div> | |
55 | </div> | |
56 | ||
57 | <div class="document"> | |
58 | <div class="documentwrapper"> | |
59 | <div class="bodywrapper"> | |
60 | <div class="body"> | |
61 | ||
62 | <h1>All modules for which code is available</h1> | |
63 | <ul><li><a href="nmb/NetBIOS.html">nmb.NetBIOS</a></li> | |
64 | <li><a href="nmb/NetBIOSProtocol.html">nmb.NetBIOSProtocol</a></li> | |
65 | <li><a href="smb/SMBConnection.html">smb.SMBConnection</a></li> | |
66 | <li><a href="smb/SMBProtocol.html">smb.SMBProtocol</a></li> | |
67 | <li><a href="smb/base.html">smb.base</a></li> | |
68 | <li><a href="smb/smb_structs.html">smb.smb_structs</a></li> | |
69 | </ul> | |
70 | ||
71 | </div> | |
72 | </div> | |
73 | </div> | |
74 | <div class="clearer"></div> | |
75 | </div> | |
76 | <div class="related"> | |
77 | <h3>Navigation</h3> | |
78 | <ul> | |
79 | <li class="right" style="margin-right: 10px"> | |
80 | <a href="../genindex.html" title="General Index" | |
81 | >index</a></li> | |
82 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
83 | </ul> | |
84 | </div> | |
85 | <div class="footer"> | |
86 | © Copyright 2011, Michael Teo. | |
87 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
88 | </div> | |
89 | </body> | |
90 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>nmb.NetBIOS — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../../index.html" /> | |
28 | <link rel="up" title="Module code" href="../index.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="../../genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
38 | <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |
39 | </ul> | |
40 | </div> | |
41 | <div class="sphinxsidebar"> | |
42 | <div class="sphinxsidebarwrapper"> | |
43 | <div id="searchbox" style="display: none"> | |
44 | <h3>Quick search</h3> | |
45 | <form class="search" action="../../search.html" method="get"> | |
46 | <input type="text" name="q" /> | |
47 | <input type="submit" value="Go" /> | |
48 | <input type="hidden" name="check_keywords" value="yes" /> | |
49 | <input type="hidden" name="area" value="default" /> | |
50 | </form> | |
51 | <p class="searchtip" style="font-size: 90%"> | |
52 | Enter search terms or a module, class or function name. | |
53 | </p> | |
54 | </div> | |
55 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
56 | </div> | |
57 | </div> | |
58 | ||
59 | <div class="document"> | |
60 | <div class="documentwrapper"> | |
61 | <div class="bodywrapper"> | |
62 | <div class="body"> | |
63 | ||
64 | <h1>Source code for nmb.NetBIOS</h1><div class="highlight"><pre> | |
65 | <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">random</span><span class="o">,</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">time</span><span class="o">,</span> <span class="nn">select</span> | |
66 | <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">NBNS</span> | |
67 | ||
68 | <span class="k">class</span> <span class="nc">NetBIOS</span><span class="p">(</span><span class="n">NBNS</span><span class="p">):</span> | |
69 | <div class="viewcode-block" id="NetBIOS"><a class="viewcode-back" href="../../api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS">[docs]</a> | |
70 | <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'NMB.NetBIOS'</span><span class="p">)</span> | |
71 | ||
72 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">listen_port</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
73 | <div class="viewcode-block" id="NetBIOS.__init__"><a class="viewcode-back" href="../../api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.__init__">[docs]</a> <span class="sd">"""</span> | |
74 | <span class="sd"> Instantiate a NetBIOS instance, and creates a IPv4 UDP socket to listen/send NBNS packets.</span> | |
75 | ||
76 | <span class="sd"> :param boolean broadcast: A boolean flag to indicate if we should setup the listening UDP port in broadcast mode</span> | |
77 | <span class="sd"> :param integer listen_port: Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.</span> | |
78 | <span class="sd"> """</span> | |
79 | <span class="bp">self</span><span class="o">.</span><span class="n">broadcast</span> <span class="o">=</span> <span class="n">broadcast</span> | |
80 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_DGRAM</span><span class="p">)</span> | |
81 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">broadcast</span><span class="p">:</span> | |
82 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_BROADCAST</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> | |
83 | <span class="k">if</span> <span class="n">listen_port</span><span class="p">:</span> | |
84 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span> <span class="s">''</span><span class="p">,</span> <span class="n">listen_port</span> <span class="p">))</span> | |
85 | ||
86 | <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
87 | <div class="viewcode-block" id="NetBIOS.close"><a class="viewcode-back" href="../../api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.close">[docs]</a> <span class="sd">"""</span> | |
88 | <span class="sd"> Close the underlying and free resources.</span> | |
89 | ||
90 | <span class="sd"> The NetBIOS instance should not be used to perform any operations after this method returns.</span> | |
91 | ||
92 | <span class="sd"> :return: None</span> | |
93 | <span class="sd"> """</span> | |
94 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> | |
95 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="bp">None</span> | |
96 | ||
97 | <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">):</span></div> | |
98 | <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">,</span> <span class="s">'Socket is already closed'</span> | |
99 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="p">(</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="p">))</span> | |
100 | ||
101 | <span class="k">def</span> <span class="nf">queryName</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">ip</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">137</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
102 | <div class="viewcode-block" id="NetBIOS.queryName"><a class="viewcode-back" href="../../api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.queryName">[docs]</a> <span class="sd">"""</span> | |
103 | <span class="sd"> Send a query on the network and hopes that if machine matching the *name* will reply with its IP address.</span> | |
104 | ||
105 | <span class="sd"> :param string ip: If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.</span> | |
106 | <span class="sd"> If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</span> | |
107 | <span class="sd"> :param integer port: The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</span> | |
108 | <span class="sd"> :param integer/float timeout: Number of seconds to wait for a reply, after which the method will return None</span> | |
109 | <span class="sd"> :return: A list of IP addresses in dotted notation (aaa.bbb.ccc.ddd). On timeout, returns None.</span> | |
110 | <span class="sd"> """</span> | |
111 | <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">,</span> <span class="s">'Socket is already closed'</span> | |
112 | ||
113 | <span class="n">trn_id</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="p">)</span> | |
114 | <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">prepareNameQuery</span><span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> | |
115 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">broadcast</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">ip</span><span class="p">:</span> | |
116 | <span class="n">ip</span> <span class="o">=</span> <span class="s">'<broadcast>'</span> | |
117 | <span class="k">elif</span> <span class="ow">not</span> <span class="n">ip</span><span class="p">:</span> | |
118 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'queryName: ip parameter is empty. OS might not transmit this query to the network'</span><span class="p">)</span> | |
119 | ||
120 | <span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">)</span> | |
121 | ||
122 | <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span> | |
123 | ||
124 | <span class="c">#</span> | |
125 | <span class="c"># Protected Methods</span> | |
126 | <span class="c">#</span> | |
127 | ||
128 | <span class="k">def</span> <span class="nf">_pollForNetBIOSPacket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wait_trn_id</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span></div> | |
129 | <span class="n">end_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">timeout</span> | |
130 | <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> | |
131 | <span class="k">try</span><span class="p">:</span> | |
132 | <span class="n">_timeout</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">-</span><span class="n">end_time</span> | |
133 | <span class="k">if</span> <span class="n">_timeout</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">:</span> | |
134 | <span class="k">return</span> <span class="bp">None</span> | |
135 | ||
136 | <span class="n">ready</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="n">_timeout</span><span class="p">)</span> | |
137 | <span class="k">if</span> <span class="ow">not</span> <span class="n">ready</span><span class="p">:</span> | |
138 | <span class="k">return</span> <span class="bp">None</span> | |
139 | ||
140 | <span class="n">data</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recvfrom</span><span class="p">(</span><span class="mh">0xFFFF</span><span class="p">)</span> | |
141 | <span class="n">trn_id</span><span class="p">,</span> <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">decodePacket</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |
142 | ||
143 | <span class="k">if</span> <span class="n">trn_id</span> <span class="o">==</span> <span class="n">wait_trn_id</span><span class="p">:</span> | |
144 | <span class="k">return</span> <span class="n">ret</span> | |
145 | <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span> | |
146 | <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span> <span class="ow">is</span> <span class="n">types</span><span class="o">.</span><span class="n">TupleType</span><span class="p">:</span> | |
147 | <span class="k">if</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EINTR</span> <span class="ow">and</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EAGAIN</span><span class="p">:</span> | |
148 | <span class="k">raise</span> <span class="n">ex</span> | |
149 | <span class="k">else</span><span class="p">:</span> | |
150 | <span class="k">raise</span> <span class="n">ex</span> | |
151 | </pre></div></div> | |
152 | ||
153 | </div> | |
154 | </div> | |
155 | </div> | |
156 | <div class="clearer"></div> | |
157 | </div> | |
158 | <div class="related"> | |
159 | <h3>Navigation</h3> | |
160 | <ul> | |
161 | <li class="right" style="margin-right: 10px"> | |
162 | <a href="../../genindex.html" title="General Index" | |
163 | >index</a></li> | |
164 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
165 | <li><a href="../index.html" >Module code</a> »</li> | |
166 | </ul> | |
167 | </div> | |
168 | <div class="footer"> | |
169 | © Copyright 2011, Michael Teo. | |
170 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
171 | </div> | |
172 | </body> | |
173 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>nmb.NetBIOSProtocol — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../../index.html" /> | |
28 | <link rel="up" title="Module code" href="../index.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="../../genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
38 | <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |
39 | </ul> | |
40 | </div> | |
41 | <div class="sphinxsidebar"> | |
42 | <div class="sphinxsidebarwrapper"> | |
43 | <div id="searchbox" style="display: none"> | |
44 | <h3>Quick search</h3> | |
45 | <form class="search" action="../../search.html" method="get"> | |
46 | <input type="text" name="q" /> | |
47 | <input type="submit" value="Go" /> | |
48 | <input type="hidden" name="check_keywords" value="yes" /> | |
49 | <input type="hidden" name="area" value="default" /> | |
50 | </form> | |
51 | <p class="searchtip" style="font-size: 90%"> | |
52 | Enter search terms or a module, class or function name. | |
53 | </p> | |
54 | </div> | |
55 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
56 | </div> | |
57 | </div> | |
58 | ||
59 | <div class="document"> | |
60 | <div class="documentwrapper"> | |
61 | <div class="bodywrapper"> | |
62 | <div class="body"> | |
63 | ||
64 | <h1>Source code for nmb.NetBIOSProtocol</h1><div class="highlight"><pre> | |
65 | <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">random</span><span class="o">,</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">time</span> | |
66 | <span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span><span class="p">,</span> <span class="n">defer</span> | |
67 | <span class="kn">from</span> <span class="nn">twisted.internet.protocol</span> <span class="kn">import</span> <span class="n">DatagramProtocol</span> | |
68 | <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">NBNS</span> | |
69 | ||
70 | <span class="k">class</span> <span class="nc">NetBIOSTimeout</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> | |
71 | <div class="viewcode-block" id="NetBIOSTimeout"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NetBIOSTimeout">[docs]</a> <span class="sd">"""Raised in NBNSProtocol via Deferred.errback method when queryName method has timeout waiting for reply"""</span> | |
72 | <span class="k">pass</span> | |
73 | ||
74 | <span class="k">class</span> <span class="nc">NBNSProtocol</span><span class="p">(</span><span class="n">DatagramProtocol</span><span class="p">,</span> <span class="n">NBNS</span><span class="p">):</span></div> | |
75 | <div class="viewcode-block" id="NBNSProtocol"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol">[docs]</a> | |
76 | <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'NMB.NBNSProtocol'</span><span class="p">)</span> | |
77 | ||
78 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">listen_port</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
79 | <div class="viewcode-block" id="NBNSProtocol.__init__"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.__init__">[docs]</a> <span class="sd">"""</span> | |
80 | <span class="sd"> Instantiate a NBNSProtocol instance.</span> | |
81 | ||
82 | <span class="sd"> This automatically calls reactor.listenUDP method to start listening for incoming packets, so you **must not** call the listenUDP method again.</span> | |
83 | ||
84 | <span class="sd"> :param boolean broadcast: A boolean flag to indicate if we should setup the listening UDP port in broadcast mode</span> | |
85 | <span class="sd"> :param integer listen_port: Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.</span> | |
86 | <span class="sd"> """</span> | |
87 | <span class="bp">self</span><span class="o">.</span><span class="n">broadcast</span> <span class="o">=</span> <span class="n">broadcast</span> | |
88 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span> <span class="o">=</span> <span class="p">{</span> <span class="p">}</span> <span class="c"># TRN ID -> ( expiry_time, name, Deferred instance )</span> | |
89 | <span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">reactor</span><span class="o">.</span><span class="n">listenUDP</span><span class="p">(</span><span class="n">listen_port</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span> | |
90 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">broadcast</span><span class="p">:</span> | |
91 | <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">getHandle</span><span class="p">()</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_BROADCAST</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> | |
92 | <span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleanupPendingTrns</span><span class="p">)</span> | |
93 | ||
94 | <span class="k">def</span> <span class="nf">datagramReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">)):</span></div> | |
95 | <span class="n">trn_id</span><span class="p">,</span> <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">decodePacket</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |
96 | ||
97 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> | |
98 | <span class="k">if</span> <span class="n">d</span><span class="p">:</span> | |
99 | <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span> | |
100 | ||
101 | <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">):</span> | |
102 | <span class="c"># We don't use the transport.write method directly as it keeps raising DeprecationWarning for ip='<broadcast>'</span> | |
103 | <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">getHandle</span><span class="p">()</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="p">(</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="p">))</span> | |
104 | ||
105 | <span class="k">def</span> <span class="nf">queryName</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">ip</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">137</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
106 | <div class="viewcode-block" id="NBNSProtocol.queryName"><a class="viewcode-back" href="../../api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.queryName">[docs]</a> <span class="sd">"""</span> | |
107 | <span class="sd"> Send a query on the network and hopes that if machine matching the *name* will reply with its IP address.</span> | |
108 | ||
109 | <span class="sd"> :param string ip: If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address.</span> | |
110 | <span class="sd"> If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</span> | |
111 | <span class="sd"> :param integer port: The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</span> | |
112 | <span class="sd"> :param integer/float timeout: Number of seconds to wait for a reply, after which the returned Deferred instance will be called with a NetBIOSTimeout exception.</span> | |
113 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of IP addresses in dotted notation (aaa.bbb.ccc.ddd).</span> | |
114 | <span class="sd"> On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception</span> | |
115 | <span class="sd"> """</span> | |
116 | <span class="n">trn_id</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="p">)</span> | |
117 | <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> | |
118 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">trn_id</span><span class="p">):</span> | |
119 | <span class="k">break</span> | |
120 | <span class="k">else</span><span class="p">:</span> | |
121 | <span class="n">trn_id</span> <span class="o">=</span> <span class="p">(</span><span class="n">trn_id</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&</span> <span class="mh">0xFFFF</span> | |
122 | ||
123 | <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">prepareNameQuery</span><span class="p">(</span><span class="n">trn_id</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> | |
124 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">broadcast</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">ip</span><span class="p">:</span> | |
125 | <span class="n">ip</span> <span class="o">=</span> <span class="s">'<broadcast>'</span> | |
126 | <span class="k">elif</span> <span class="ow">not</span> <span class="n">ip</span><span class="p">:</span> | |
127 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'queryName: ip parameter is empty. OS might not transmit this query to the network'</span><span class="p">)</span> | |
128 | ||
129 | <span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">)</span> | |
130 | ||
131 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
132 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="p">[</span><span class="n">trn_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span><span class="o">+</span><span class="n">timeout</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">d</span> <span class="p">)</span> | |
133 | <span class="k">return</span> <span class="n">d</span> | |
134 | ||
135 | <span class="k">def</span> <span class="nf">stopProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
136 | <span class="n">DatagramProtocol</span><span class="o">.</span><span class="n">stopProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |
137 | ||
138 | <span class="k">def</span> <span class="nf">cleanupPendingTrns</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
139 | <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> | |
140 | <span class="k">for</span> <span class="n">trn_id</span><span class="p">,</span> <span class="p">(</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">d</span> <span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> | |
141 | <span class="k">if</span> <span class="n">expiry_time</span> <span class="o"><</span> <span class="n">now</span><span class="p">:</span> | |
142 | <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_trns</span><span class="p">[</span><span class="n">trn_id</span><span class="p">]</span> | |
143 | <span class="k">try</span><span class="p">:</span> | |
144 | <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">(</span><span class="n">NetBIOSTimeout</span><span class="p">(</span><span class="n">name</span><span class="p">))</span> | |
145 | <span class="k">except</span><span class="p">:</span> <span class="k">pass</span> | |
146 | ||
147 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="p">:</span> | |
148 | <span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cleanupPendingTrns</span><span class="p">)</span> | |
149 | </pre></div></div> | |
150 | ||
151 | </div> | |
152 | </div> | |
153 | </div> | |
154 | <div class="clearer"></div> | |
155 | </div> | |
156 | <div class="related"> | |
157 | <h3>Navigation</h3> | |
158 | <ul> | |
159 | <li class="right" style="margin-right: 10px"> | |
160 | <a href="../../genindex.html" title="General Index" | |
161 | >index</a></li> | |
162 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
163 | <li><a href="../index.html" >Module code</a> »</li> | |
164 | </ul> | |
165 | </div> | |
166 | <div class="footer"> | |
167 | © Copyright 2011, Michael Teo. | |
168 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
169 | </div> | |
170 | </body> | |
171 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>smb.SMBConnection — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../../index.html" /> | |
28 | <link rel="up" title="Module code" href="../index.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="../../genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
38 | <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |
39 | </ul> | |
40 | </div> | |
41 | <div class="sphinxsidebar"> | |
42 | <div class="sphinxsidebarwrapper"> | |
43 | <div id="searchbox" style="display: none"> | |
44 | <h3>Quick search</h3> | |
45 | <form class="search" action="../../search.html" method="get"> | |
46 | <input type="text" name="q" /> | |
47 | <input type="submit" value="Go" /> | |
48 | <input type="hidden" name="check_keywords" value="yes" /> | |
49 | <input type="hidden" name="area" value="default" /> | |
50 | </form> | |
51 | <p class="searchtip" style="font-size: 90%"> | |
52 | Enter search terms or a module, class or function name. | |
53 | </p> | |
54 | </div> | |
55 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
56 | </div> | |
57 | </div> | |
58 | ||
59 | <div class="document"> | |
60 | <div class="documentwrapper"> | |
61 | <div class="bodywrapper"> | |
62 | <div class="body"> | |
63 | ||
64 | <h1>Source code for smb.SMBConnection</h1><div class="highlight"><pre> | |
65 | <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">select</span><span class="o">,</span> <span class="nn">socket</span><span class="o">,</span> <span class="nn">types</span><span class="o">,</span> <span class="nn">struct</span> | |
66 | <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span> | |
67 | <span class="kn">from</span> <span class="nn">smb_structs</span> <span class="kn">import</span> <span class="o">*</span> | |
68 | <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">SMB</span><span class="p">,</span> <span class="n">NotConnectedError</span><span class="p">,</span> <span class="n">NotReadyError</span><span class="p">,</span> <span class="n">SMBTimeout</span> | |
69 | ||
70 | ||
71 | <span class="k">class</span> <span class="nc">SMBConnection</span><span class="p">(</span><span class="n">SMB</span><span class="p">):</span> | |
72 | <div class="viewcode-block" id="SMBConnection"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection">[docs]</a> | |
73 | <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'SMB.SMBConnection'</span><span class="p">)</span> | |
74 | ||
75 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">):</span> | |
76 | <div class="viewcode-block" id="SMBConnection.__init__"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.__init__">[docs]</a> <span class="sd">"""</span> | |
77 | <span class="sd"> Create a new SMBConnection instance.</span> | |
78 | ||
79 | <span class="sd"> *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server.</span> | |
80 | <span class="sd"> File operations can only be proceeded after the connection has been authenticated successfully.</span> | |
81 | ||
82 | <span class="sd"> Note that you need to call *connect* method to actually establish the SMB connection to the remote server and perform authentication.</span> | |
83 | ||
84 | <span class="sd"> :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from.</span> | |
85 | <span class="sd"> You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?";|+``</span> | |
86 | <span class="sd"> :param string remote_name: The NetBIOS machine name of the remote server.</span> | |
87 | <span class="sd"> On windows, you can find out the machine name by right-clicking on the "My Computer" and selecting "Properties".</span> | |
88 | <span class="sd"> This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</span> | |
89 | <span class="sd"> :param string domain: The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string.</span> | |
90 | <span class="sd"> :param boolean use_ntlm_v2: Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication.</span> | |
91 | <span class="sd"> The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured.</span> | |
92 | <span class="sd"> Hence, we can only "guess" or try both algorithms.</span> | |
93 | <span class="sd"> On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2.</span> | |
94 | <span class="sd"> """</span> | |
95 | <span class="n">SMB</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span><span class="p">,</span> <span class="n">use_ntlm_v2</span><span class="p">)</span> | |
96 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="bp">None</span> | |
97 | <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">None</span> | |
98 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
99 | ||
100 | <span class="c">#</span> | |
101 | <span class="c"># SMB (and its superclass) Methods</span> | |
102 | <span class="c">#</span> | |
103 | ||
104 | <span class="k">def</span> <span class="nf">onAuthOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
105 | <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">True</span> | |
106 | ||
107 | <span class="k">def</span> <span class="nf">onAuthFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
108 | <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">False</span> | |
109 | ||
110 | <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |
111 | <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> | |
112 | <span class="n">data_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |
113 | <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="n">data_len</span> | |
114 | ||
115 | <span class="c">#</span> | |
116 | <span class="c"># Public Methods</span> | |
117 | <span class="c">#</span> | |
118 | ||
119 | <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">sock_family</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">60</span><span class="p">):</span> | |
120 | <div class="viewcode-block" id="SMBConnection.connect"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.connect">[docs]</a> <span class="sd">"""</span> | |
121 | <span class="sd"> Establish the SMB connection to the remote SMB/CIFS server.</span> | |
122 | ||
123 | <span class="sd"> You must call this method before attempting any of the file operations with the remote server.</span> | |
124 | <span class="sd"> This method will block until the SMB connection has attempted at least one authentication.</span> | |
125 | ||
126 | <span class="sd"> :return: A boolean value indicating the result of the authentication atttempt: True if authentication is successful; False, if otherwise.</span> | |
127 | <span class="sd"> """</span> | |
128 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
129 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> | |
130 | ||
131 | <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="o">=</span> <span class="bp">None</span> | |
132 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">sock_family</span><span class="p">)</span> | |
133 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">connect_ex</span><span class="p">((</span> <span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="p">))</span> | |
134 | ||
135 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
136 | <span class="k">try</span><span class="p">:</span> | |
137 | <span class="bp">self</span><span class="o">.</span><span class="n">requestNMBSession</span><span class="p">()</span> | |
138 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |
139 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
140 | <span class="k">finally</span><span class="p">:</span> | |
141 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
142 | ||
143 | <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">auth_result</span> | |
144 | ||
145 | <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
146 | <div class="viewcode-block" id="SMBConnection.close"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.close">[docs]</a> <span class="sd">"""</span> | |
147 | <span class="sd"> Terminate the SMB connection (if it has been started) and release any sources held by the underlying socket.</span> | |
148 | <span class="sd"> """</span> | |
149 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
150 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> | |
151 | <span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="bp">None</span> | |
152 | ||
153 | <span class="k">def</span> <span class="nf">listShares</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
154 | <div class="viewcode-block" id="SMBConnection.listShares"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listShares">[docs]</a> <span class="sd">"""</span> | |
155 | <span class="sd"> Retrieve a list of shared resources on remote server.</span> | |
156 | ||
157 | <span class="sd"> :return: A list of :doc:`smb.base.SharedDevice<smb_SharedDevice>` instances describing the shared resource</span> | |
158 | <span class="sd"> """</span> | |
159 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
160 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
161 | ||
162 | <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
163 | ||
164 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">entries</span><span class="p">):</span> | |
165 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
166 | <span class="n">results</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">entries</span><span class="p">)</span> | |
167 | ||
168 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
169 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
170 | <span class="k">raise</span> <span class="n">failure</span> | |
171 | ||
172 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
173 | <span class="k">try</span><span class="p">:</span> | |
174 | <span class="bp">self</span><span class="o">.</span><span class="n">_listShares</span><span class="p">(</span><span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span> | |
175 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
176 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
177 | <span class="k">finally</span><span class="p">:</span> | |
178 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
179 | ||
180 | <span class="k">return</span> <span class="n">results</span> | |
181 | ||
182 | <span class="k">def</span> <span class="nf">listPath</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span></div> | |
183 | <div class="viewcode-block" id="SMBConnection.listPath"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listPath">[docs]</a> <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span><span class="p">,</span> | |
184 | <span class="n">pattern</span> <span class="o">=</span> <span class="s">'</span><span class="se">\\</span><span class="s">*'</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
185 | <span class="sd">"""</span> | |
186 | <span class="sd"> Retrieve a directory listing of files/folders at *path*</span> | |
187 | ||
188 | <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span> | |
189 | <span class="sd"> :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.</span> | |
190 | <span class="sd"> :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).</span> | |
191 | <span class="sd"> The default *search* value will query for all read-only, hidden, system, archive files and directories.</span> | |
192 | <span class="sd"> :param string/unicode pattern: the filter to apply to the results before returning to the client.</span> | |
193 | <span class="sd"> :return: A list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances.</span> | |
194 | <span class="sd"> """</span> | |
195 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
196 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
197 | ||
198 | <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
199 | ||
200 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">entries</span><span class="p">):</span> | |
201 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
202 | <span class="n">results</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">entries</span><span class="p">)</span> | |
203 | ||
204 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
205 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
206 | <span class="k">raise</span> <span class="n">failure</span> | |
207 | ||
208 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
209 | <span class="k">try</span><span class="p">:</span> | |
210 | <span class="bp">self</span><span class="o">.</span><span class="n">_listPath</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">search</span> <span class="o">=</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
211 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
212 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
213 | <span class="k">finally</span><span class="p">:</span> | |
214 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
215 | ||
216 | <span class="k">return</span> <span class="n">results</span> | |
217 | ||
218 | <span class="k">def</span> <span class="nf">retrieveFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
219 | <div class="viewcode-block" id="SMBConnection.retrieveFile"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFile">[docs]</a> <span class="sd">"""</span> | |
220 | <span class="sd"> Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*.</span> | |
221 | ||
222 | <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span> | |
223 | <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback.</span> | |
224 | <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service.</span> | |
225 | <span class="sd"> :return: A 2-element tuple of ( file attributes of the file on server, number of bytes retrieved ).</span> | |
226 | <span class="sd"> The file attributes is an integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py)</span> | |
227 | <span class="sd"> """</span> | |
228 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
229 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
230 | ||
231 | <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
232 | ||
233 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span> | |
234 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
235 | <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> | |
236 | ||
237 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
238 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
239 | <span class="k">raise</span> <span class="n">failure</span> | |
240 | ||
241 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
242 | <span class="k">try</span><span class="p">:</span> | |
243 | <span class="bp">self</span><span class="o">.</span><span class="n">_retrieveFile</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
244 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
245 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
246 | <span class="k">finally</span><span class="p">:</span> | |
247 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
248 | ||
249 | <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> | |
250 | ||
251 | <span class="k">def</span> <span class="nf">storeFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
252 | <div class="viewcode-block" id="SMBConnection.storeFile"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFile">[docs]</a> <span class="sd">"""</span> | |
253 | <span class="sd"> Store the contents of the *file_obj* at *path* on the *service_name*.</span> | |
254 | ||
255 | <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span> | |
256 | <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file at *path* does not exist, it will be created. Otherwise, it will be overwritten.</span> | |
257 | <span class="sd"> If the *path* refers to a folder or the file cannot be opened for writing, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback.</span> | |
258 | <span class="sd"> :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF.</span> | |
259 | <span class="sd"> :return: Number of bytes uploaded</span> | |
260 | <span class="sd"> """</span> | |
261 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
262 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
263 | ||
264 | <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
265 | ||
266 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span> | |
267 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
268 | <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> | |
269 | ||
270 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
271 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
272 | <span class="k">raise</span> <span class="n">failure</span> | |
273 | ||
274 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
275 | <span class="k">try</span><span class="p">:</span> | |
276 | <span class="bp">self</span><span class="o">.</span><span class="n">_storeFile</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
277 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
278 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
279 | <span class="k">finally</span><span class="p">:</span> | |
280 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
281 | ||
282 | <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> | |
283 | ||
284 | <span class="k">def</span> <span class="nf">deleteFiles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
285 | <div class="viewcode-block" id="SMBConnection.deleteFiles"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteFiles">[docs]</a> <span class="sd">"""</span> | |
286 | <span class="sd"> Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</span> | |
287 | ||
288 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
289 | <span class="sd"> :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.</span> | |
290 | <span class="sd"> Wildcards may be used in th filename component of the path.</span> | |
291 | <span class="sd"> If your path/filename contains non-English characters, you must pass in an unicode string.</span> | |
292 | <span class="sd"> :return: None</span> | |
293 | <span class="sd"> """</span> | |
294 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
295 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
296 | ||
297 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span> | |
298 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
299 | ||
300 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
301 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
302 | <span class="k">raise</span> <span class="n">failure</span> | |
303 | ||
304 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
305 | <span class="k">try</span><span class="p">:</span> | |
306 | <span class="bp">self</span><span class="o">.</span><span class="n">_deleteFiles</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
307 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
308 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
309 | <span class="k">finally</span><span class="p">:</span> | |
310 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
311 | ||
312 | <span class="k">def</span> <span class="nf">createDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
313 | <div class="viewcode-block" id="SMBConnection.createDirectory"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.createDirectory">[docs]</a> <span class="sd">"""</span> | |
314 | <span class="sd"> Creates a new directory *path* on the *service_name*.</span> | |
315 | ||
316 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
317 | <span class="sd"> :param string/unicode path: The path of the new folder (relative to) the shared folder.</span> | |
318 | <span class="sd"> If the path contains non-English characters, an unicode string must be used to pass in the path.</span> | |
319 | <span class="sd"> :return: None</span> | |
320 | <span class="sd"> """</span> | |
321 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
322 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
323 | ||
324 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span> | |
325 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
326 | ||
327 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
328 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
329 | <span class="k">raise</span> <span class="n">failure</span> | |
330 | ||
331 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
332 | <span class="k">try</span><span class="p">:</span> | |
333 | <span class="bp">self</span><span class="o">.</span><span class="n">_createDirectory</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
334 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
335 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
336 | <span class="k">finally</span><span class="p">:</span> | |
337 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
338 | ||
339 | <span class="k">def</span> <span class="nf">deleteDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
340 | <div class="viewcode-block" id="SMBConnection.deleteDirectory"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteDirectory">[docs]</a> <span class="sd">"""</span> | |
341 | <span class="sd"> Delete the empty folder at *path* on *service_name*</span> | |
342 | ||
343 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
344 | <span class="sd"> :param string/unicode path: The path of the to-be-deleted folder (relative to) the shared folder.</span> | |
345 | <span class="sd"> If the path contains non-English characters, an unicode string must be used to pass in the path.</span> | |
346 | <span class="sd"> :return: None</span> | |
347 | <span class="sd"> """</span> | |
348 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
349 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
350 | ||
351 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span> | |
352 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
353 | ||
354 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
355 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
356 | <span class="k">raise</span> <span class="n">failure</span> | |
357 | ||
358 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
359 | <span class="k">try</span><span class="p">:</span> | |
360 | <span class="bp">self</span><span class="o">.</span><span class="n">_deleteDirectory</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
361 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
362 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
363 | <span class="k">finally</span><span class="p">:</span> | |
364 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
365 | ||
366 | <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
367 | <div class="viewcode-block" id="SMBConnection.rename"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.rename">[docs]</a> <span class="sd">"""</span> | |
368 | <span class="sd"> Rename a file or folder at *old_path* to *new_path* shared at *service_name*. Note that this method cannot be used to rename file/folder across different shared folders</span> | |
369 | ||
370 | <span class="sd"> *old_path* and *new_path* are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder.</span> | |
371 | <span class="sd"> If the path contains non-English characters, an unicode string must be used to pass in the path.</span> | |
372 | ||
373 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
374 | <span class="sd"> :return: None</span> | |
375 | <span class="sd"> """</span> | |
376 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
377 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
378 | ||
379 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span> | |
380 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
381 | ||
382 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
383 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
384 | <span class="k">raise</span> <span class="n">failure</span> | |
385 | ||
386 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
387 | <span class="k">try</span><span class="p">:</span> | |
388 | <span class="bp">self</span><span class="o">.</span><span class="n">_rename</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">)</span> | |
389 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
390 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
391 | <span class="k">finally</span><span class="p">:</span> | |
392 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
393 | ||
394 | <span class="k">def</span> <span class="nf">echo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">10</span><span class="p">):</span></div> | |
395 | <div class="viewcode-block" id="SMBConnection.echo"><a class="viewcode-back" href="../../api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.echo">[docs]</a> <span class="sd">"""</span> | |
396 | <span class="sd"> Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.</span> | |
397 | ||
398 | <span class="sd"> :param string data: Data to send to the remote server.</span> | |
399 | <span class="sd"> :return: The *data* parameter</span> | |
400 | <span class="sd"> """</span> | |
401 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="p">:</span> | |
402 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
403 | ||
404 | <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
405 | ||
406 | <span class="k">def</span> <span class="nf">cb</span><span class="p">(</span><span class="n">r</span><span class="p">):</span> | |
407 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
408 | <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> | |
409 | ||
410 | <span class="k">def</span> <span class="nf">eb</span><span class="p">(</span><span class="n">failure</span><span class="p">):</span> | |
411 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
412 | <span class="k">raise</span> <span class="n">failure</span> | |
413 | ||
414 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">True</span> | |
415 | <span class="k">try</span><span class="p">:</span> | |
416 | <span class="bp">self</span><span class="o">.</span><span class="n">_echo</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">cb</span><span class="p">,</span> <span class="n">eb</span><span class="p">)</span> | |
417 | <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span><span class="p">:</span> | |
418 | <span class="bp">self</span><span class="o">.</span><span class="n">_pollForNetBIOSPacket</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> | |
419 | <span class="k">finally</span><span class="p">:</span> | |
420 | <span class="bp">self</span><span class="o">.</span><span class="n">is_busy</span> <span class="o">=</span> <span class="bp">False</span> | |
421 | ||
422 | <span class="k">return</span> <span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> | |
423 | ||
424 | <span class="c">#</span> | |
425 | <span class="c"># Protected Methods</span> | |
426 | <span class="c">#</span> | |
427 | ||
428 | <span class="k">def</span> <span class="nf">_pollForNetBIOSPacket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span><span class="p">):</span></div> | |
429 | <span class="n">read_len</span> <span class="o">=</span> <span class="mi">4</span> | |
430 | <span class="n">data</span> <span class="o">=</span> <span class="s">''</span> | |
431 | ||
432 | <span class="k">while</span> <span class="n">read_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
433 | <span class="k">try</span><span class="p">:</span> | |
434 | <span class="n">ready</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="n">timeout</span><span class="p">)</span> | |
435 | <span class="k">if</span> <span class="ow">not</span> <span class="n">ready</span><span class="p">:</span> | |
436 | <span class="k">raise</span> <span class="n">SMBTimeout</span> | |
437 | ||
438 | <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="n">read_len</span><span class="p">)</span> | |
439 | <span class="n">data</span> <span class="o">=</span> <span class="n">data</span> <span class="o">+</span> <span class="n">d</span> | |
440 | <span class="n">read_len</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> | |
441 | <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span> | |
442 | <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span> <span class="ow">is</span> <span class="n">types</span><span class="o">.</span><span class="n">TupleType</span><span class="p">:</span> | |
443 | <span class="k">if</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EINTR</span> <span class="ow">and</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EAGAIN</span><span class="p">:</span> | |
444 | <span class="k">raise</span> <span class="n">ex</span> | |
445 | <span class="k">else</span><span class="p">:</span> | |
446 | <span class="k">raise</span> <span class="n">ex</span> | |
447 | ||
448 | <span class="nb">type</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'>BBH'</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> | |
449 | <span class="k">if</span> <span class="n">flags</span> <span class="o">&</span> <span class="mh">0x01</span><span class="p">:</span> | |
450 | <span class="n">length</span> <span class="o">=</span> <span class="n">length</span> <span class="o">|</span> <span class="mh">0x10000</span> | |
451 | ||
452 | <span class="n">read_len</span> <span class="o">=</span> <span class="n">length</span> | |
453 | <span class="k">while</span> <span class="n">read_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
454 | <span class="k">try</span><span class="p">:</span> | |
455 | <span class="n">ready</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">([</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="p">[</span> <span class="p">],</span> <span class="n">timeout</span><span class="p">)</span> | |
456 | <span class="k">if</span> <span class="ow">not</span> <span class="n">ready</span><span class="p">:</span> | |
457 | <span class="k">raise</span> <span class="n">SMBTimeout</span> | |
458 | ||
459 | <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="n">read_len</span><span class="p">)</span> | |
460 | <span class="n">data</span> <span class="o">=</span> <span class="n">data</span> <span class="o">+</span> <span class="n">d</span> | |
461 | <span class="n">read_len</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> | |
462 | <span class="k">except</span> <span class="n">select</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span> | |
463 | <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span> <span class="ow">is</span> <span class="n">types</span><span class="o">.</span><span class="n">TupleType</span><span class="p">:</span> | |
464 | <span class="k">if</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EINTR</span> <span class="ow">and</span> <span class="n">ex</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">errno</span><span class="o">.</span><span class="n">EAGAIN</span><span class="p">:</span> | |
465 | <span class="k">raise</span> <span class="n">ex</span> | |
466 | <span class="k">else</span><span class="p">:</span> | |
467 | <span class="k">raise</span> <span class="n">ex</span> | |
468 | ||
469 | <span class="bp">self</span><span class="o">.</span><span class="n">feedData</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |
470 | </pre></div></div> | |
471 | ||
472 | </div> | |
473 | </div> | |
474 | </div> | |
475 | <div class="clearer"></div> | |
476 | </div> | |
477 | <div class="related"> | |
478 | <h3>Navigation</h3> | |
479 | <ul> | |
480 | <li class="right" style="margin-right: 10px"> | |
481 | <a href="../../genindex.html" title="General Index" | |
482 | >index</a></li> | |
483 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
484 | <li><a href="../index.html" >Module code</a> »</li> | |
485 | </ul> | |
486 | </div> | |
487 | <div class="footer"> | |
488 | © Copyright 2011, Michael Teo. | |
489 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
490 | </div> | |
491 | </body> | |
492 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>smb.SMBProtocol — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../../index.html" /> | |
28 | <link rel="up" title="Module code" href="../index.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="../../genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
38 | <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |
39 | </ul> | |
40 | </div> | |
41 | <div class="sphinxsidebar"> | |
42 | <div class="sphinxsidebarwrapper"> | |
43 | <div id="searchbox" style="display: none"> | |
44 | <h3>Quick search</h3> | |
45 | <form class="search" action="../../search.html" method="get"> | |
46 | <input type="text" name="q" /> | |
47 | <input type="submit" value="Go" /> | |
48 | <input type="hidden" name="check_keywords" value="yes" /> | |
49 | <input type="hidden" name="area" value="default" /> | |
50 | </form> | |
51 | <p class="searchtip" style="font-size: 90%"> | |
52 | Enter search terms or a module, class or function name. | |
53 | </p> | |
54 | </div> | |
55 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
56 | </div> | |
57 | </div> | |
58 | ||
59 | <div class="document"> | |
60 | <div class="documentwrapper"> | |
61 | <div class="bodywrapper"> | |
62 | <div class="body"> | |
63 | ||
64 | <h1>Source code for smb.SMBProtocol</h1><div class="highlight"><pre> | |
65 | <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">time</span> | |
66 | <span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span><span class="p">,</span> <span class="n">defer</span> | |
67 | <span class="kn">from</span> <span class="nn">twisted.internet.protocol</span> <span class="kn">import</span> <span class="n">ClientFactory</span><span class="p">,</span> <span class="n">Protocol</span> | |
68 | <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span> | |
69 | <span class="kn">from</span> <span class="nn">smb_structs</span> <span class="kn">import</span> <span class="o">*</span> | |
70 | <span class="kn">from</span> <span class="nn">base</span> <span class="kn">import</span> <span class="n">SMB</span><span class="p">,</span> <span class="n">NotConnectedError</span><span class="p">,</span> <span class="n">NotReadyError</span><span class="p">,</span> <span class="n">SMBTimeout</span> | |
71 | ||
72 | ||
73 | <span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'SMBProtocolFactory'</span><span class="p">,</span> <span class="s">'NotConnectedError'</span><span class="p">,</span> <span class="s">'NotReadyError'</span> <span class="p">]</span> | |
74 | ||
75 | ||
76 | <span class="k">class</span> <span class="nc">SMBProtocol</span><span class="p">(</span><span class="n">Protocol</span><span class="p">,</span> <span class="n">SMB</span><span class="p">):</span> | |
77 | ||
78 | <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'SMB.SMBProtocol'</span><span class="p">)</span> | |
79 | ||
80 | <span class="c">#</span> | |
81 | <span class="c"># Protocol Methods</span> | |
82 | <span class="c">#</span> | |
83 | ||
84 | <span class="k">def</span> <span class="nf">connectionMade</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
85 | <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="bp">self</span> | |
86 | <span class="bp">self</span><span class="o">.</span><span class="n">requestNMBSession</span><span class="p">()</span> | |
87 | ||
88 | <span class="k">def</span> <span class="nf">connectionLost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span> | |
89 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">instance</span> <span class="o">==</span> <span class="bp">self</span><span class="p">:</span> | |
90 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="bp">None</span> | |
91 | ||
92 | <span class="k">def</span> <span class="nf">dataReceived</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |
93 | <span class="bp">self</span><span class="o">.</span><span class="n">feedData</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |
94 | ||
95 | <span class="c">#</span> | |
96 | <span class="c"># SMB (and its superclass) Methods</span> | |
97 | <span class="c">#</span> | |
98 | ||
99 | <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |
100 | <span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |
101 | ||
102 | <span class="k">def</span> <span class="nf">onAuthOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
103 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">instance</span> <span class="o">==</span> <span class="bp">self</span><span class="p">:</span> | |
104 | <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">onAuthOK</span><span class="p">()</span> | |
105 | <span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cleanupPendingRequests</span><span class="p">)</span> | |
106 | ||
107 | <span class="k">def</span> <span class="nf">onAuthFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
108 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">instance</span> <span class="o">==</span> <span class="bp">self</span><span class="p">:</span> | |
109 | <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span> | |
110 | ||
111 | <span class="k">def</span> <span class="nf">onNMBSessionFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
112 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">'Cannot establish NetBIOS session. You might have provided a wrong remote_name'</span><span class="p">)</span> | |
113 | ||
114 | <span class="c">#</span> | |
115 | <span class="c"># Protected Methods</span> | |
116 | <span class="c">#</span> | |
117 | ||
118 | <span class="k">def</span> <span class="nf">_cleanupPendingRequests</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
119 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">instance</span> <span class="o">==</span> <span class="bp">self</span><span class="p">:</span> | |
120 | <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> | |
121 | <span class="k">for</span> <span class="n">mid</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> | |
122 | <span class="k">if</span> <span class="n">r</span><span class="o">.</span><span class="n">expiry_time</span> <span class="o"><</span> <span class="n">now</span><span class="p">:</span> | |
123 | <span class="k">try</span><span class="p">:</span> | |
124 | <span class="n">r</span><span class="o">.</span><span class="n">errback</span><span class="p">(</span><span class="n">SMBTimeout</span><span class="p">())</span> | |
125 | <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> <span class="k">pass</span> | |
126 | <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">mid</span><span class="p">]</span> | |
127 | ||
128 | <span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cleanupPendingRequests</span><span class="p">)</span> | |
129 | ||
130 | ||
131 | <span class="k">class</span> <span class="nc">SMBProtocolFactory</span><span class="p">(</span><span class="n">ClientFactory</span><span class="p">):</span> | |
132 | <div class="viewcode-block" id="SMBProtocolFactory"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory">[docs]</a> | |
133 | <span class="n">protocol</span> <span class="o">=</span> <span class="n">SMBProtocol</span> | |
134 | <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'SMB.SMBFactory'</span><span class="p">)</span> | |
135 | ||
136 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">):</span> | |
137 | <div class="viewcode-block" id="SMBProtocolFactory.__init__"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.__init__">[docs]</a> <span class="sd">"""</span> | |
138 | <span class="sd"> Create a new SMBProtocolFactory instance.</span> | |
139 | ||
140 | <span class="sd"> *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server.</span> | |
141 | <span class="sd"> File operations can only be proceeded after the connection has been authenticated successfully.</span> | |
142 | ||
143 | <span class="sd"> :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from.</span> | |
144 | <span class="sd"> You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?";|+``</span> | |
145 | <span class="sd"> :param string remote_name: The NetBIOS machine name of the remote server.</span> | |
146 | <span class="sd"> On windows, you can find out the machine name by right-clicking on the "My Computer" and selecting "Properties".</span> | |
147 | <span class="sd"> This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</span> | |
148 | <span class="sd"> :param string domain: The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string.</span> | |
149 | <span class="sd"> :param boolean use_ntlm_v2: Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication.</span> | |
150 | <span class="sd"> The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured.</span> | |
151 | <span class="sd"> Hence, we can only "guess" or try both algorithms.</span> | |
152 | <span class="sd"> On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2.</span> | |
153 | <span class="sd"> """</span> | |
154 | <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span> | |
155 | <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span> | |
156 | <span class="bp">self</span><span class="o">.</span><span class="n">my_name</span> <span class="o">=</span> <span class="n">my_name</span> | |
157 | <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span> <span class="o">=</span> <span class="n">remote_name</span> | |
158 | <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">domain</span> | |
159 | <span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="n">use_ntlm_v2</span> | |
160 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="bp">None</span> <span class="c">#: The single SMBProtocol instance for each SMBProtocolFactory instance. Usually, you should not need to touch this attribute directly.</span> | |
161 | ||
162 | <span class="c">#</span> | |
163 | <span class="c"># Public Property</span> | |
164 | <span class="c">#</span> | |
165 | ||
166 | <span class="nd">@property</span></div> | |
167 | <span class="k">def</span> <span class="nf">isReady</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
168 | <div class="viewcode-block" id="SMBProtocolFactory.isReady"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.isReady">[docs]</a> <span class="sd">"""A convenient property to return True if the underlying SMB connection has connected to remote server, has successfully authenticated itself and is ready for file operations."""</span> | |
169 | <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">)</span> | |
170 | ||
171 | <span class="c">#</span> | |
172 | <span class="c"># Public Methods for Callbacks</span> | |
173 | <span class="c">#</span> | |
174 | ||
175 | <span class="k">def</span> <span class="nf">onAuthOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
176 | <div class="viewcode-block" id="SMBProtocolFactory.onAuthOK"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.onAuthOK">[docs]</a> <span class="sd">"""</span> | |
177 | <span class="sd"> Override this method in your *SMBProtocolFactory* subclass to add in post-authentication handling.</span> | |
178 | <span class="sd"> This method will be called when the server has replied that the SMB connection has been successfully authenticated.</span> | |
179 | <span class="sd"> File operations can proceed when this method has been called.</span> | |
180 | <span class="sd"> """</span> | |
181 | <span class="k">pass</span> | |
182 | ||
183 | <span class="k">def</span> <span class="nf">onAuthFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
184 | <div class="viewcode-block" id="SMBProtocolFactory.onAuthFailed"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.onAuthFailed">[docs]</a> <span class="sd">"""</span> | |
185 | <span class="sd"> Override this method in your *SMBProtocolFactory* subclass to add in post-authentication handling.</span> | |
186 | <span class="sd"> This method will be called when the server has replied that the SMB connection has been successfully authenticated.</span> | |
187 | ||
188 | <span class="sd"> If you want to retry authenticating from this method,</span> | |
189 | <span class="sd"> 1. Disconnect the underlying SMB connection (call ``self.instance.transport.loseConnection()``)</span> | |
190 | <span class="sd"> 2. Create a new SMBProtocolFactory subclass instance with different user credientials or different NTLM algorithm flag.</span> | |
191 | <span class="sd"> 3. Call ``reactor.connectTCP`` with the new instance to re-establish the SMB connection</span> | |
192 | <span class="sd"> """</span> | |
193 | <span class="k">pass</span> | |
194 | ||
195 | <span class="c">#</span> | |
196 | <span class="c"># Public Methods</span> | |
197 | <span class="c">#</span> | |
198 | ||
199 | <span class="k">def</span> <span class="nf">listShares</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
200 | <div class="viewcode-block" id="SMBProtocolFactory.listShares"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listShares">[docs]</a> <span class="sd">"""</span> | |
201 | <span class="sd"> Retrieve a list of shared resources on remote server.</span> | |
202 | ||
203 | <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.</span> | |
204 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of :doc:`smb.base.SharedDevice<smb_SharedDevice>` instances.</span> | |
205 | <span class="sd"> """</span> | |
206 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
207 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
208 | ||
209 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
210 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_listShares</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span> | |
211 | <span class="k">return</span> <span class="n">d</span> | |
212 | ||
213 | <span class="k">def</span> <span class="nf">listPath</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span></div> | |
214 | <div class="viewcode-block" id="SMBProtocolFactory.listPath"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listPath">[docs]</a> <span class="n">search</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_READONLY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_DIRECTORY</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_ARCHIVE</span><span class="p">,</span> | |
215 | <span class="n">pattern</span> <span class="o">=</span> <span class="s">'</span><span class="se">\\</span><span class="s">*'</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
216 | <span class="sd">"""</span> | |
217 | <span class="sd"> Retrieve a directory listing of files/folders at *path*</span> | |
218 | ||
219 | <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span> | |
220 | <span class="sd"> :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders.</span> | |
221 | <span class="sd"> :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py).</span> | |
222 | <span class="sd"> The default *search* value will query for all read-only, hidden, system, archive files and directories.</span> | |
223 | <span class="sd"> :param string/unicode pattern: the filter to apply to the results before returning to the client.</span> | |
224 | <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.</span> | |
225 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances.</span> | |
226 | <span class="sd"> """</span> | |
227 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
228 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
229 | ||
230 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
231 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_listPath</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">search</span> <span class="o">=</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
232 | <span class="k">return</span> <span class="n">d</span> | |
233 | ||
234 | <span class="k">def</span> <span class="nf">retrieveFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
235 | <div class="viewcode-block" id="SMBProtocolFactory.retrieveFile"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.retrieveFile">[docs]</a> <span class="sd">"""</span> | |
236 | <span class="sd"> Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*.</span> | |
237 | ||
238 | <span class="sd"> The meaning of the *timeout* parameter will be different from other file operation methods. As the downloaded file usually exceeeds the maximum size</span> | |
239 | <span class="sd"> of each SMB/CIFS data message, it will be packetized into a series of request messages (each message will request about about 60kBytes).</span> | |
240 | <span class="sd"> The *timeout* parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and downloaded from the remote SMB/CIFS server.</span> | |
241 | ||
242 | <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span> | |
243 | <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback.</span> | |
244 | <span class="sd"> :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service.</span> | |
245 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 3-element tuple of ( *file_obj*, file attributes of the file on server, number of bytes retrieved ).</span> | |
246 | <span class="sd"> The file attributes is an integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py)</span> | |
247 | <span class="sd"> """</span> | |
248 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
249 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
250 | ||
251 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
252 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_retrieveFile</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
253 | <span class="k">return</span> <span class="n">d</span> | |
254 | ||
255 | <span class="k">def</span> <span class="nf">storeFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
256 | <div class="viewcode-block" id="SMBProtocolFactory.storeFile"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.storeFile">[docs]</a> <span class="sd">"""</span> | |
257 | <span class="sd"> Store the contents of the *file_obj* at *path* on the *service_name*.</span> | |
258 | ||
259 | <span class="sd"> The meaning of the *timeout* parameter will be different from other file operation methods. As the uploaded file usually exceeeds the maximum size</span> | |
260 | <span class="sd"> of each SMB/CIFS data message, it will be packetized into a series of messages (usually about 60kBytes).</span> | |
261 | <span class="sd"> The *timeout* parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and acknowledged</span> | |
262 | <span class="sd"> by the remote SMB/CIFS server.</span> | |
263 | ||
264 | <span class="sd"> :param string/unicode service_name: the name of the shared folder for the *path*</span> | |
265 | <span class="sd"> :param string/unicode path: Path of the file on the remote server. If the file at *path* does not exist, it will be created. Otherwise, it will be overwritten.</span> | |
266 | <span class="sd"> If the *path* refers to a folder or the file cannot be opened for writing, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback.</span> | |
267 | <span class="sd"> :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF.</span> | |
268 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 2-element tuple of ( *file_obj*, number of bytes uploaded ).</span> | |
269 | <span class="sd"> """</span> | |
270 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
271 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
272 | ||
273 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
274 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_storeFile</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
275 | <span class="k">return</span> <span class="n">d</span> | |
276 | ||
277 | <span class="k">def</span> <span class="nf">deleteFiles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span></div> | |
278 | <div class="viewcode-block" id="SMBProtocolFactory.deleteFiles"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteFiles">[docs]</a> <span class="sd">"""</span> | |
279 | <span class="sd"> Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</span> | |
280 | ||
281 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
282 | <span class="sd"> :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name.</span> | |
283 | <span class="sd"> Wildcards may be used in th filename component of the path.</span> | |
284 | <span class="sd"> If your path/filename contains non-English characters, you must pass in an unicode string.</span> | |
285 | <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.</span> | |
286 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *path_file_pattern* parameter.</span> | |
287 | <span class="sd"> """</span> | |
288 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
289 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
290 | ||
291 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
292 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_deleteFiles</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span><span class="p">)</span> | |
293 | <span class="k">return</span> <span class="n">d</span> | |
294 | ||
295 | <span class="k">def</span> <span class="nf">createDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span></div> | |
296 | <div class="viewcode-block" id="SMBProtocolFactory.createDirectory"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.createDirectory">[docs]</a> <span class="sd">"""</span> | |
297 | <span class="sd"> Creates a new directory *path* on the *service_name*.</span> | |
298 | ||
299 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
300 | <span class="sd"> :param string/unicode path: The path of the new folder (relative to) the shared folder.</span> | |
301 | <span class="sd"> If the path contains non-English characters, an unicode string must be used to pass in the path.</span> | |
302 | <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.</span> | |
303 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *path* parameter.</span> | |
304 | <span class="sd"> """</span> | |
305 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
306 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
307 | ||
308 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
309 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_createDirectory</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">)</span> | |
310 | <span class="k">return</span> <span class="n">d</span> | |
311 | ||
312 | <span class="k">def</span> <span class="nf">deleteDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span></div> | |
313 | <div class="viewcode-block" id="SMBProtocolFactory.deleteDirectory"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteDirectory">[docs]</a> <span class="sd">"""</span> | |
314 | <span class="sd"> Delete the empty folder at *path* on *service_name*</span> | |
315 | ||
316 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
317 | <span class="sd"> :param string/unicode path: The path of the to-be-deleted folder (relative to) the shared folder.</span> | |
318 | <span class="sd"> If the path contains non-English characters, an unicode string must be used to pass in the path.</span> | |
319 | <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.</span> | |
320 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *path* parameter.</span> | |
321 | <span class="sd"> """</span> | |
322 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
323 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
324 | ||
325 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
326 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_deleteDirectory</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">)</span> | |
327 | <span class="k">return</span> <span class="n">d</span> | |
328 | ||
329 | <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">):</span></div> | |
330 | <div class="viewcode-block" id="SMBProtocolFactory.rename"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.rename">[docs]</a> <span class="sd">"""</span> | |
331 | <span class="sd"> Rename a file or folder at *old_path* to *new_path* shared at *service_name*. Note that this method cannot be used to rename file/folder across different shared folders</span> | |
332 | ||
333 | <span class="sd"> *old_path* and *new_path* are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder.</span> | |
334 | <span class="sd"> If the path contains non-English characters, an unicode string must be used to pass in the path.</span> | |
335 | ||
336 | <span class="sd"> :param string/unicode service_name: Contains the name of the shared folder.</span> | |
337 | <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.</span> | |
338 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 2-element tuple of ( *old_path*, *new_path* ).</span> | |
339 | <span class="sd"> """</span> | |
340 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
341 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
342 | ||
343 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
344 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_rename</span><span class="p">(</span><span class="n">service_name</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">)</span> | |
345 | <span class="k">return</span> <span class="n">d</span> | |
346 | ||
347 | <span class="k">def</span> <span class="nf">echo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">10</span><span class="p">):</span></div> | |
348 | <div class="viewcode-block" id="SMBProtocolFactory.echo"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.echo">[docs]</a> <span class="sd">"""</span> | |
349 | <span class="sd"> Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*.</span> | |
350 | ||
351 | <span class="sd"> :param string data: Data to send to the remote server.</span> | |
352 | <span class="sd"> :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method.</span> | |
353 | <span class="sd"> :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *data* parameter.</span> | |
354 | <span class="sd"> """</span> | |
355 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
356 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
357 | ||
358 | <span class="n">d</span> <span class="o">=</span> <span class="n">defer</span><span class="o">.</span><span class="n">Deferred</span><span class="p">()</span> | |
359 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">_echo</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">callback</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span> | |
360 | <span class="k">return</span> <span class="n">d</span> | |
361 | ||
362 | <span class="k">def</span> <span class="nf">closeConnection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
363 | <div class="viewcode-block" id="SMBProtocolFactory.closeConnection"><a class="viewcode-back" href="../../api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.closeConnection">[docs]</a> <span class="sd">"""</span> | |
364 | <span class="sd"> Disconnect from the remote SMB/CIFS server. The TCP connection will be closed at the earliest opportunity after this method returns.</span> | |
365 | ||
366 | <span class="sd"> :return: None</span> | |
367 | <span class="sd"> """</span> | |
368 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span> | |
369 | <span class="k">raise</span> <span class="n">NotConnectedError</span><span class="p">(</span><span class="s">'Not connected to server'</span><span class="p">)</span> | |
370 | ||
371 | <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">loseConnection</span><span class="p">()</span> | |
372 | ||
373 | <span class="c">#</span> | |
374 | <span class="c"># ClientFactory methods</span> | |
375 | <span class="c"># (Do not touch these unless you know what you are doing)</span> | |
376 | <span class="c">#</span> | |
377 | ||
378 | <span class="k">def</span> <span class="nf">buildProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span></div> | |
379 | <span class="n">p</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">my_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span><span class="p">)</span> | |
380 | <span class="n">p</span><span class="o">.</span><span class="n">factory</span> <span class="o">=</span> <span class="bp">self</span> | |
381 | <span class="k">return</span> <span class="n">p</span> | |
382 | </pre></div></div> | |
383 | ||
384 | </div> | |
385 | </div> | |
386 | </div> | |
387 | <div class="clearer"></div> | |
388 | </div> | |
389 | <div class="related"> | |
390 | <h3>Navigation</h3> | |
391 | <ul> | |
392 | <li class="right" style="margin-right: 10px"> | |
393 | <a href="../../genindex.html" title="General Index" | |
394 | >index</a></li> | |
395 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
396 | <li><a href="../index.html" >Module code</a> »</li> | |
397 | </ul> | |
398 | </div> | |
399 | <div class="footer"> | |
400 | © Copyright 2011, Michael Teo. | |
401 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
402 | </div> | |
403 | </body> | |
404 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>smb.base — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../../index.html" /> | |
28 | <link rel="up" title="Module code" href="../index.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="../../genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
38 | <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |
39 | </ul> | |
40 | </div> | |
41 | <div class="sphinxsidebar"> | |
42 | <div class="sphinxsidebarwrapper"> | |
43 | <div id="searchbox" style="display: none"> | |
44 | <h3>Quick search</h3> | |
45 | <form class="search" action="../../search.html" method="get"> | |
46 | <input type="text" name="q" /> | |
47 | <input type="submit" value="Go" /> | |
48 | <input type="hidden" name="check_keywords" value="yes" /> | |
49 | <input type="hidden" name="area" value="default" /> | |
50 | </form> | |
51 | <p class="searchtip" style="font-size: 90%"> | |
52 | Enter search terms or a module, class or function name. | |
53 | </p> | |
54 | </div> | |
55 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
56 | </div> | |
57 | </div> | |
58 | ||
59 | <div class="document"> | |
60 | <div class="documentwrapper"> | |
61 | <div class="bodywrapper"> | |
62 | <div class="body"> | |
63 | ||
64 | <h1>Source code for smb.base</h1><div class="highlight"><pre> | |
65 | <span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">binascii</span><span class="o">,</span> <span class="nn">time</span> | |
66 | <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span> | |
67 | <span class="kn">from</span> <span class="nn">smb_structs</span> <span class="kn">import</span> <span class="o">*</span> | |
68 | <span class="kn">from</span> <span class="nn">nmb.base</span> <span class="kn">import</span> <span class="n">NMBSession</span> | |
69 | <span class="kn">from</span> <span class="nn">utils</span> <span class="kn">import</span> <span class="n">convertFILETIMEtoEpoch</span> | |
70 | <span class="kn">import</span> <span class="nn">ntlm</span><span class="o">,</span> <span class="nn">securityblob</span> | |
71 | ||
72 | <span class="k">class</span> <span class="nc">NotReadyError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> | |
73 | <div class="viewcode-block" id="NotReadyError"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.base.NotReadyError">[docs]</a> <span class="sd">"""Raised when SMB connection is not ready (i.e. not authenticated or authentication failed)"""</span> | |
74 | <span class="k">pass</span> | |
75 | ||
76 | <span class="k">class</span> <span class="nc">NotConnectedError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span></div> | |
77 | <div class="viewcode-block" id="NotConnectedError"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.base.NotConnectedError">[docs]</a> <span class="sd">"""Raised when underlying SMB connection has been disconnected or not connected yet"""</span> | |
78 | <span class="k">pass</span> | |
79 | ||
80 | <span class="k">class</span> <span class="nc">SMBTimeout</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span></div> | |
81 | <div class="viewcode-block" id="SMBTimeout"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.base.SMBTimeout">[docs]</a> <span class="sd">"""Raised when a timeout has occurred while waiting for a response or for a SMB/CIFS operation to complete."""</span> | |
82 | <span class="k">pass</span> | |
83 | ||
84 | ||
85 | <span class="k">class</span> <span class="nc">SMB</span><span class="p">(</span><span class="n">NMBSession</span><span class="p">):</span></div> | |
86 | <span class="sd">"""</span> | |
87 | <span class="sd"> This class represents a "connection" to the remote SMB/CIFS server.</span> | |
88 | <span class="sd"> It is not meant to be used directly in an application as it does not have any network transport implementations.</span> | |
89 | ||
90 | <span class="sd"> For application use, please refer to</span> | |
91 | <span class="sd"> - L{SMBProtocol.SMBProtocolFactory<smb.SMBProtocol>} if you are using Twisted framework</span> | |
92 | ||
93 | <span class="sd"> In [MS-CIFS], this class will contain attributes of Client, Client.Connection and Client.Session abstract data models.</span> | |
94 | ||
95 | <span class="sd"> References:</span> | |
96 | <span class="sd"> ===========</span> | |
97 | <span class="sd"> - [MS-CIFS]: 3.2.1</span> | |
98 | <span class="sd"> """</span> | |
99 | ||
100 | <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'SMB.SMB'</span><span class="p">)</span> | |
101 | ||
102 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">,</span> <span class="n">domain</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="bp">True</span><span class="p">):</span> | |
103 | <span class="n">NMBSession</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">my_name</span><span class="p">,</span> <span class="n">remote_name</span><span class="p">)</span> | |
104 | <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span> | |
105 | <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span> | |
106 | <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">domain</span> | |
107 | <span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span> <span class="o">=</span> <span class="n">use_ntlm_v2</span> <span class="c">#: Similar to LMAuthenticationPolicy and NTAuthenticationPolicy as described in [MS-CIFS] 3.2.1.1</span> | |
108 | <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">()</span> | |
109 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span> <span class="o">=</span> <span class="p">{</span> <span class="p">}</span> <span class="c">#: MID mapped to _PendingRequest instance</span> | |
110 | <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span> <span class="o">=</span> <span class="p">{</span> <span class="p">}</span> <span class="c">#: Share name mapped to TID</span> | |
111 | <span class="bp">self</span><span class="o">.</span><span class="n">next_rpc_call_id</span> <span class="o">=</span> <span class="mi">0</span> <span class="c">#: Next RPC callID value. Not used directly in SMB message. Usually encapsulated in sub-commands under SMB_COM_TRANSACTION or SMB_COM_TRANSACTION2 messages</span> | |
112 | ||
113 | <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="bp">False</span> | |
114 | <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">False</span> | |
115 | <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="mi">0</span> | |
116 | <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="mi">0</span> | |
117 | ||
118 | <span class="c"># Most of the following attributes will be initialized upon receipt of SMB_COM_NEGOTIATE message from server (via self._updateServerInfo method)</span> | |
119 | <span class="bp">self</span><span class="o">.</span><span class="n">use_plaintext_authentication</span> <span class="o">=</span> <span class="bp">False</span> <span class="c">#: Similar to PlaintextAuthenticationPolicy in in [MS-CIFS] 3.2.1.1</span> | |
120 | <span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span> <span class="o">=</span> <span class="mi">0</span> | |
121 | <span class="bp">self</span><span class="o">.</span><span class="n">max_buffer_size</span> <span class="o">=</span> <span class="mi">0</span> <span class="c">#: Similar to MaxBufferSize as described in [MS-CIFS] 3.2.1.1</span> | |
122 | <span class="bp">self</span><span class="o">.</span><span class="n">max_mpx_count</span> <span class="o">=</span> <span class="mi">0</span> <span class="c">#: Similar to MaxMpxCount as described in [MS-CIFS] 3.2.1.1</span> | |
123 | <span class="bp">self</span><span class="o">.</span><span class="n">capabilities</span> <span class="o">=</span> <span class="mi">0</span> | |
124 | ||
125 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Authetication with remote machine "</span><span class="si">%s</span><span class="s">" for user "</span><span class="si">%s</span><span class="s">" will be using NTLM </span><span class="si">%s</span><span class="s"> authentication (</span><span class="si">%s</span><span class="s"> extended security)'</span><span class="p">,</span> | |
126 | <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> | |
127 | <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span> <span class="ow">and</span> <span class="s">'v2'</span><span class="p">)</span> <span class="ow">or</span> <span class="s">'v1'</span><span class="p">,</span> | |
128 | <span class="p">(</span><span class="n">SUPPORT_EXTENDED_SECURITY</span> <span class="ow">and</span> <span class="s">'with'</span><span class="p">)</span> <span class="ow">or</span> <span class="s">'without'</span><span class="p">)</span> | |
129 | ||
130 | ||
131 | <span class="c">#</span> | |
132 | <span class="c"># NMBSession Methods</span> | |
133 | <span class="c">#</span> | |
134 | ||
135 | <span class="k">def</span> <span class="nf">onNMBSessionOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
136 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComNegotiateRequest</span><span class="p">()))</span> | |
137 | ||
138 | <span class="k">def</span> <span class="nf">onNMBSessionFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
139 | <span class="k">pass</span> | |
140 | ||
141 | <span class="k">def</span> <span class="nf">onNMBSessionMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |
142 | <span class="n">i</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |
143 | <span class="k">if</span> <span class="n">i</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
144 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'Received SMB message "</span><span class="si">%s</span><span class="s">" (command:0x</span><span class="si">%2X</span><span class="s"> flags:0x</span><span class="si">%02X</span><span class="s"> flags2:0x</span><span class="si">%04X</span><span class="s"> TID:</span><span class="si">%d</span><span class="s"> UID:</span><span class="si">%d</span><span class="s">)'</span><span class="p">,</span> | |
145 | <span class="n">SMB_COMMAND_NAMES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="s">'<unknown>'</span><span class="p">),</span> | |
146 | <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">flags2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span> | |
147 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_updateState</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="p">):</span> | |
148 | <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">()</span> | |
149 | ||
150 | <span class="c">#</span> | |
151 | <span class="c"># Public Methods for Overriding in Subclasses</span> | |
152 | <span class="c">#</span> | |
153 | ||
154 | <span class="k">def</span> <span class="nf">onAuthOK</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
155 | <span class="k">pass</span> | |
156 | ||
157 | <span class="k">def</span> <span class="nf">onAuthFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
158 | <span class="k">pass</span> | |
159 | ||
160 | <span class="c">#</span> | |
161 | <span class="c"># Protected Methods</span> | |
162 | <span class="c">#</span> | |
163 | ||
164 | <span class="k">def</span> <span class="nf">_sendSMBMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">smb_message</span><span class="p">):</span> | |
165 | <span class="k">if</span> <span class="n">smb_message</span><span class="o">.</span><span class="n">mid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> | |
166 | <span class="n">smb_message</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getNextMID</span><span class="p">()</span> | |
167 | <span class="n">smb_message</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> | |
168 | <span class="n">smb_message</span><span class="o">.</span><span class="n">raw_data</span> <span class="o">=</span> <span class="n">smb_message</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span> | |
169 | <span class="bp">self</span><span class="o">.</span><span class="n">sendNMBMessage</span><span class="p">(</span><span class="n">smb_message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">)</span> | |
170 | ||
171 | <span class="k">def</span> <span class="nf">_getNextMID</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
172 | <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">+=</span> <span class="mi">1</span> | |
173 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">>=</span> <span class="mh">0xFFFF</span><span class="p">:</span> <span class="c"># MID cannot be 0xFFFF. [MS-CIFS]: 2.2.1.6.2</span> | |
174 | <span class="c"># We don't use MID of 0 as MID can be reused for SMB_COM_TRANSACTION2_SECONDARY messages</span> | |
175 | <span class="c"># where if mid=0, _sendSMBMessage will re-assign new MID values again</span> | |
176 | <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="mi">1</span> | |
177 | <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> | |
178 | ||
179 | <span class="k">def</span> <span class="nf">_getNextRPCCallID</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
180 | <span class="bp">self</span><span class="o">.</span><span class="n">next_rpc_call_id</span> <span class="o">+=</span> <span class="mi">1</span> | |
181 | <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">next_rpc_call_id</span> | |
182 | ||
183 | <span class="k">def</span> <span class="nf">_updateState</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
184 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">isReply</span><span class="p">:</span> | |
185 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_NEGOTIATE</span><span class="p">:</span> | |
186 | <span class="bp">self</span><span class="o">.</span><span class="n">has_negotiated</span> <span class="o">=</span> <span class="bp">True</span> | |
187 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'SMB dialect negotiation successful (ExtendedSecurity:</span><span class="si">%s</span><span class="s">)'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span><span class="p">)</span> | |
188 | <span class="bp">self</span><span class="o">.</span><span class="n">_updateServerInfo</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="p">)</span> | |
189 | <span class="bp">self</span><span class="o">.</span><span class="n">_handleNegotiateResponse</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> | |
190 | <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_SESSION_SETUP_ANDX</span><span class="p">:</span> | |
191 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span><span class="p">:</span> | |
192 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
193 | <span class="k">try</span><span class="p">:</span> | |
194 | <span class="n">result</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">decodeAuthResponseSecurityBlob</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">security_blob</span><span class="p">)</span> | |
195 | <span class="k">if</span> <span class="n">result</span> <span class="o">==</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">RESULT_ACCEPT_COMPLETED</span><span class="p">:</span> | |
196 | <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">True</span> | |
197 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Authentication (with extended security) successful!'</span><span class="p">)</span> | |
198 | <span class="bp">self</span><span class="o">.</span><span class="n">onAuthOK</span><span class="p">()</span> | |
199 | <span class="k">else</span><span class="p">:</span> | |
200 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'SMB_COM_SESSION_SETUP_ANDX status is 0 but security blob negResult value is </span><span class="si">%d</span><span class="s">'</span> <span class="o">%</span> <span class="n">result</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
201 | <span class="k">except</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span> | |
202 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">),</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
203 | <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000016</span><span class="p">:</span> <span class="c"># STATUS_MORE_PROCESSING_REQUIRED</span> | |
204 | <span class="k">try</span><span class="p">:</span> | |
205 | <span class="n">result</span><span class="p">,</span> <span class="n">ntlm_token</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">decodeChallengeSecurityBlob</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">security_blob</span><span class="p">)</span> | |
206 | <span class="k">if</span> <span class="n">result</span> <span class="o">==</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">RESULT_ACCEPT_INCOMPLETE</span><span class="p">:</span> | |
207 | <span class="bp">self</span><span class="o">.</span><span class="n">_handleSessionChallenge</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">ntlm_token</span><span class="p">)</span> | |
208 | <span class="k">except</span> <span class="p">(</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">BadSecurityBlobError</span><span class="p">,</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">UnsupportedSecurityProvider</span> <span class="p">),</span> <span class="n">ex</span><span class="p">:</span> | |
209 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">),</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
210 | <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc000006d</span><span class="p">:</span> <span class="c"># STATUS_LOGON_FAILURE</span> | |
211 | <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">False</span> | |
212 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Authentication (with extended security) failed. Please check username and password. You may need to enable/disable NTLMv2 authentication.'</span><span class="p">)</span> | |
213 | <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span> | |
214 | <span class="k">else</span><span class="p">:</span> | |
215 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Unknown status value (0x</span><span class="si">%08X</span><span class="s">) in SMB_COM_SESSION_SETUP_ANDX (with extended security)'</span> <span class="o">%</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span><span class="p">,</span> | |
216 | <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
217 | <span class="k">else</span><span class="p">:</span> | |
218 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> | |
219 | <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">True</span> | |
220 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Authentication (without extended security) successful!'</span><span class="p">)</span> | |
221 | <span class="bp">self</span><span class="o">.</span><span class="n">onAuthOK</span><span class="p">()</span> | |
222 | <span class="k">else</span><span class="p">:</span> | |
223 | <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span> <span class="o">=</span> <span class="bp">False</span> | |
224 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Authentication (without extended security) failed. Please check username and password'</span><span class="p">)</span> | |
225 | <span class="bp">self</span><span class="o">.</span><span class="n">onAuthFailed</span><span class="p">()</span> | |
226 | <span class="k">elif</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TREE_CONNECT_ANDX</span><span class="p">:</span> | |
227 | <span class="k">try</span><span class="p">:</span> | |
228 | <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">message</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> | |
229 | <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> | |
230 | <span class="k">pass</span> | |
231 | <span class="k">else</span><span class="p">:</span> | |
232 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
233 | <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">req</span><span class="o">.</span><span class="n">kwargs</span><span class="p">[</span><span class="s">'path'</span><span class="p">]]</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">tid</span> | |
234 | ||
235 | <span class="n">req</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> | |
236 | <span class="k">if</span> <span class="n">req</span><span class="p">:</span> | |
237 | <span class="n">req</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">req</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span> | |
238 | <span class="k">return</span> <span class="bp">True</span> | |
239 | ||
240 | ||
241 | <span class="k">def</span> <span class="nf">_updateServerInfo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span><span class="p">):</span> | |
242 | <span class="bp">self</span><span class="o">.</span><span class="n">capabilities</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">capabilities</span> | |
243 | <span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">max_raw_size</span> | |
244 | <span class="bp">self</span><span class="o">.</span><span class="n">max_buffer_size</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">max_buffer_size</span> | |
245 | <span class="bp">self</span><span class="o">.</span><span class="n">max_mpx_count</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">max_mpx_count</span> | |
246 | <span class="bp">self</span><span class="o">.</span><span class="n">use_plaintext_authentication</span> <span class="o">=</span> <span class="ow">not</span> <span class="nb">bool</span><span class="p">(</span><span class="n">payload</span><span class="o">.</span><span class="n">security_mode</span> <span class="o">&</span> <span class="n">NEGOTIATE_ENCRYPT_PASSWORDS</span><span class="p">)</span> | |
247 | ||
248 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">use_plaintext_authentication</span><span class="p">:</span> | |
249 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'Remote server only supports plaintext authentication. Your password can be stolen easily over the network.'</span><span class="p">)</span> | |
250 | ||
251 | <span class="k">if</span> <span class="n">payload</span><span class="o">.</span><span class="n">security_mode</span> <span class="o">&</span> <span class="n">NEGOTIATE_SECURITY_SIGNATURES_REQUIRE</span><span class="p">:</span> | |
252 | <span class="k">raise</span> <span class="n">UnsupportedFeature</span><span class="p">(</span><span class="s">'Remote server requires secure SMB message signing but current version pysmb does not support this yet.'</span><span class="p">)</span> | |
253 | ||
254 | ||
255 | <span class="k">def</span> <span class="nf">_handleSessionChallenge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">ntlm_token</span><span class="p">):</span> | |
256 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span> | |
257 | ||
258 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">:</span> | |
259 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'SMB uid is now </span><span class="si">%d</span><span class="s">'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span> | |
260 | <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span> | |
261 | ||
262 | <span class="n">server_challenge</span><span class="p">,</span> <span class="n">server_flags</span><span class="p">,</span> <span class="n">server_info</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">decodeChallengeMessage</span><span class="p">(</span><span class="n">ntlm_token</span><span class="p">)</span> | |
263 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">use_ntlm_v2</span><span class="p">:</span> | |
264 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Performing NTLMv2 authentication (with extended security) with server challenge "</span><span class="si">%s</span><span class="s">"'</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">server_challenge</span><span class="p">))</span> | |
265 | <span class="n">nt_challenge_response</span><span class="p">,</span> <span class="n">lm_challenge_response</span><span class="p">,</span> <span class="n">session_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV2</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> | |
266 | <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> | |
267 | <span class="n">server_challenge</span><span class="p">,</span> | |
268 | <span class="n">server_info</span><span class="p">,</span> | |
269 | <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">)</span> | |
270 | ||
271 | <span class="k">else</span><span class="p">:</span> | |
272 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Performing NTLMv1 authentication (with extended security) with server challenge "</span><span class="si">%s</span><span class="s">"'</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">server_challenge</span><span class="p">))</span> | |
273 | <span class="n">nt_challenge_response</span><span class="p">,</span> <span class="n">lm_challenge_response</span><span class="p">,</span> <span class="n">session_key</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">server_challenge</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span> | |
274 | ||
275 | <span class="n">ntlm_data</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateAuthenticateMessage</span><span class="p">(</span><span class="n">server_flags</span><span class="p">,</span> | |
276 | <span class="n">nt_challenge_response</span><span class="p">,</span> | |
277 | <span class="n">lm_challenge_response</span><span class="p">,</span> | |
278 | <span class="n">session_key</span><span class="p">,</span> | |
279 | <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span> | |
280 | ||
281 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">):</span> | |
282 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'NT challenge response is "</span><span class="si">%s</span><span class="s">" (</span><span class="si">%d</span><span class="s"> bytes)'</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">nt_challenge_response</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">nt_challenge_response</span><span class="p">))</span> | |
283 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'LM challenge response is "</span><span class="si">%s</span><span class="s">" (</span><span class="si">%d</span><span class="s"> bytes)'</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">lm_challenge_response</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">lm_challenge_response</span><span class="p">))</span> | |
284 | ||
285 | <span class="n">blob</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">generateAuthSecurityBlob</span><span class="p">(</span><span class="n">ntlm_data</span><span class="p">)</span> | |
286 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComSessionSetupAndxRequest__WithSecurityExtension</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">blob</span><span class="p">)))</span> | |
287 | ||
288 | ||
289 | <span class="k">def</span> <span class="nf">_handleNegotiateResponse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
290 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">:</span> | |
291 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'SMB uid is now </span><span class="si">%d</span><span class="s">'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span> | |
292 | <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">uid</span> | |
293 | ||
294 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span><span class="p">:</span> | |
295 | <span class="n">ntlm_data</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateNegotiateMessage</span><span class="p">()</span> | |
296 | <span class="n">blob</span> <span class="o">=</span> <span class="n">securityblob</span><span class="o">.</span><span class="n">generateNegotiateSecurityBlob</span><span class="p">(</span><span class="n">ntlm_data</span><span class="p">)</span> | |
297 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComSessionSetupAndxRequest__WithSecurityExtension</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span> <span class="n">blob</span><span class="p">)))</span> | |
298 | <span class="k">else</span><span class="p">:</span> | |
299 | <span class="n">nt_password</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">ntlm</span><span class="o">.</span><span class="n">generateChallengeResponseV1</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">challenge</span><span class="p">,</span> <span class="bp">False</span><span class="p">)</span> | |
300 | <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">'Performing NTLMv1 authentication (without extended security) with challenge "</span><span class="si">%s</span><span class="s">" and hashed password of "</span><span class="si">%s</span><span class="s">"'</span><span class="p">,</span> | |
301 | <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">challenge</span><span class="p">),</span> | |
302 | <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">nt_password</span><span class="p">))</span> | |
303 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComSessionSetupAndxRequest__NoSecurityExtension</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span> | |
304 | <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> | |
305 | <span class="n">nt_password</span><span class="p">,</span> | |
306 | <span class="bp">True</span><span class="p">,</span> | |
307 | <span class="n">message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">domain</span><span class="p">)))</span> | |
308 | ||
309 | <span class="k">def</span> <span class="nf">_listShares</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
310 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
311 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
312 | ||
313 | <span class="n">expiry_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span> | |
314 | <span class="n">path</span> <span class="o">=</span> <span class="s">'IPC$'</span> | |
315 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
316 | ||
317 | <span class="k">def</span> <span class="nf">connectSrvSvc</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
318 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComNTCreateAndxRequest</span><span class="p">(</span><span class="s">'</span><span class="se">\\</span><span class="s">srvsvc'</span><span class="p">,</span> | |
319 | <span class="n">flags</span> <span class="o">=</span> <span class="n">NT_CREATE_REQUEST_EXTENDED_RESPONSE</span><span class="p">,</span> | |
320 | <span class="n">access_mask</span> <span class="o">=</span> <span class="n">READ_CONTROL</span> <span class="o">|</span> <span class="n">FILE_WRITE_ATTRIBUTES</span> <span class="o">|</span> <span class="n">FILE_READ_ATTRIBUTES</span> <span class="o">|</span> <span class="n">FILE_WRITE_EA</span> <span class="o">|</span> <span class="n">FILE_READ_EA</span> <span class="o">|</span> <span class="n">FILE_APPEND_DATA</span> <span class="o">|</span> <span class="n">FILE_WRITE_DATA</span> <span class="o">|</span> <span class="n">FILE_READ_DATA</span><span class="p">,</span> | |
321 | <span class="n">share_access</span> <span class="o">=</span> <span class="n">FILE_SHARE_READ</span> <span class="o">|</span> <span class="n">FILE_SHARE_WRITE</span><span class="p">,</span> | |
322 | <span class="n">create_disp</span> <span class="o">=</span> <span class="n">FILE_OPEN</span><span class="p">,</span> | |
323 | <span class="n">create_options</span> <span class="o">=</span> <span class="n">FILE_OPEN_NO_RECALL</span> <span class="o">|</span> <span class="n">FILE_NON_DIRECTORY_FILE</span><span class="p">,</span> | |
324 | <span class="n">impersonation</span> <span class="o">=</span> <span class="n">SEC_IMPERSONATE</span><span class="p">,</span> | |
325 | <span class="n">security_flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">))</span> | |
326 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
327 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
328 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectSrvSvcCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
329 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
330 | ||
331 | <span class="k">def</span> <span class="nf">connectSrvSvcCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
332 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span> | |
333 | <span class="k">if</span> <span class="ow">not</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
334 | <span class="n">call_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getNextRPCCallID</span><span class="p">()</span> | |
335 | <span class="c"># See [MS-CIFS]: 2.2.5.6.1 for more information on TRANS_TRANSACT_NMPIPE (0x0026) parameters</span> | |
336 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<HH'</span><span class="p">,</span> <span class="mh">0x0026</span><span class="p">,</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span> | |
337 | <span class="c"># The data_bytes are binding call to Server Service RPC using DCE v1.1 RPC over SMB. See [MS-SRVS] and [C706]</span> | |
338 | <span class="c"># If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream</span> | |
339 | <span class="n">data_bytes</span> <span class="o">=</span> \ | |
340 | <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s">"""05 00 0b 03 10 00 00 00 48 00 00 00"""</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> <span class="o">+</span> \ | |
341 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<I'</span><span class="p">,</span> <span class="n">call_id</span><span class="p">)</span> <span class="o">+</span> \ | |
342 | <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s">"""</span> | |
343 | <span class="s">b8 10 b8 10 00 00 00 00 01 00 00 00 00 00 01 00</span> | |
344 | <span class="s">c8 4f 32 4b 70 16 d3 01 12 78 5a 47 bf 6e e1 88</span> | |
345 | <span class="s">03 00 00 00 04 5d 88 8a eb 1c c9 11 9f e8 08 00</span> | |
346 | <span class="s">2b 10 48 60 02 00 00 00"""</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
347 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransactionRequest</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
348 | <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">4280</span><span class="p">,</span> | |
349 | <span class="n">max_setup_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
350 | <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">,</span> | |
351 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">setup_bytes</span><span class="p">))</span> | |
352 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">tid</span> | |
353 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
354 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">rpcBindCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">create_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">)</span> | |
355 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
356 | <span class="k">else</span><span class="p">:</span> | |
357 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to list shares: Unable to locate Server Service RPC endpoint'</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span> | |
358 | ||
359 | <span class="k">def</span> <span class="nf">rpcBindCB</span><span class="p">(</span><span class="n">trans_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
360 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">trans_message</span><span class="p">)</span> | |
361 | <span class="k">if</span> <span class="ow">not</span> <span class="n">trans_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
362 | <span class="n">call_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getNextRPCCallID</span><span class="p">()</span> | |
363 | ||
364 | <span class="n">padding</span> <span class="o">=</span> <span class="s">''</span> | |
365 | <span class="n">server_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span> | |
366 | <span class="n">server_bytes_len</span> <span class="o">=</span> <span class="n">server_len</span> <span class="o">*</span> <span class="mi">2</span> | |
367 | <span class="k">if</span> <span class="n">server_len</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
368 | <span class="n">padding</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> | |
369 | <span class="n">server_bytes_len</span> <span class="o">+=</span> <span class="mi">2</span> | |
370 | ||
371 | <span class="c"># See [MS-CIFS]: 2.2.5.6.1 for more information on TRANS_TRANSACT_NMPIPE (0x0026) parameters</span> | |
372 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<HH'</span><span class="p">,</span> <span class="mh">0x0026</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
373 | <span class="c"># The data bytes are the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC.</span> | |
374 | <span class="c"># If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream</span> | |
375 | <span class="n">data_bytes</span> <span class="o">=</span> \ | |
376 | <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s">"""05 00 00 03 10 00 00 00"""</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> <span class="o">+</span> \ | |
377 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<HHI'</span><span class="p">,</span> <span class="mi">72</span><span class="o">+</span><span class="n">server_bytes_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">call_id</span><span class="p">)</span> <span class="o">+</span> \ | |
378 | <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s">"""4c 00 00 00 00 00 0f 00 00 00 02 00"""</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> <span class="o">+</span> \ | |
379 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<III'</span><span class="p">,</span> <span class="n">server_len</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">server_len</span><span class="p">)</span> <span class="o">+</span> \ | |
380 | <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="n">padding</span> <span class="o">+</span> \ | |
381 | <span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="s">"""</span> | |
382 | <span class="s">01 00 00 00 01 00 00 00 04 00 02 00 00 00 00 00</span> | |
383 | <span class="s">00 00 00 00 ff ff ff ff 08 00 02 00 00 00 00 00</span> | |
384 | <span class="s">"""</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
385 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransactionRequest</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
386 | <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">4280</span><span class="p">,</span> | |
387 | <span class="n">max_setup_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
388 | <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">,</span> | |
389 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">setup_bytes</span><span class="p">))</span> | |
390 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">trans_message</span><span class="o">.</span><span class="n">tid</span> | |
391 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
392 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">listShareResultsCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
393 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
394 | <span class="k">else</span><span class="p">:</span> | |
395 | <span class="n">closeFid</span><span class="p">(</span><span class="n">trans_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
396 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to list shares: Unable to bind to Server Service RPC endpoint'</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span> | |
397 | ||
398 | <span class="k">def</span> <span class="nf">listShareResultsCB</span><span class="p">(</span><span class="n">result_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
399 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">result_message</span><span class="p">)</span> | |
400 | <span class="k">if</span> <span class="ow">not</span> <span class="n">result_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
401 | <span class="c"># The payload.data_bytes will contain the results of the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC.</span> | |
402 | <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">result_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span> | |
403 | <span class="n">shares_count</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<I'</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="mi">36</span><span class="p">:</span><span class="mi">40</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span> | |
404 | ||
405 | <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> <span class="c"># A list of SharedDevice instances</span> | |
406 | <span class="n">offset</span> <span class="o">=</span> <span class="mi">36</span> <span class="o">+</span> <span class="mi">12</span> <span class="c"># You need to study the byte stream to understand the meaning of these constants</span> | |
407 | <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">shares_count</span><span class="p">):</span> | |
408 | <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedDevice</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<I'</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">4</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">8</span><span class="p">])[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">))</span> | |
409 | <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span> | |
410 | ||
411 | <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">shares_count</span><span class="p">):</span> | |
412 | <span class="n">max_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<III'</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">12</span><span class="p">])</span> | |
413 | <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span> | |
414 | <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="s">'UTF-16LE'</span><span class="p">)</span> | |
415 | ||
416 | <span class="k">if</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
417 | <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> | |
418 | <span class="k">else</span><span class="p">:</span> | |
419 | <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span> | |
420 | ||
421 | <span class="n">max_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<III'</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">12</span><span class="p">])</span> | |
422 | <span class="n">offset</span> <span class="o">+=</span> <span class="mi">12</span> | |
423 | <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">comments</span> <span class="o">=</span> <span class="nb">unicode</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">length</span><span class="o">*</span><span class="mi">2</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="s">'UTF-16LE'</span><span class="p">)</span> | |
424 | ||
425 | <span class="k">if</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
426 | <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> | |
427 | <span class="k">else</span><span class="p">:</span> | |
428 | <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">length</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span> | |
429 | ||
430 | <span class="n">closeFid</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
431 | <span class="n">callback</span><span class="p">(</span><span class="n">results</span><span class="p">)</span> | |
432 | <span class="k">else</span><span class="p">:</span> | |
433 | <span class="n">closeFid</span><span class="p">(</span><span class="n">result_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
434 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to list shares: Unable to retrieve shared device list'</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span> | |
435 | ||
436 | <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">):</span> | |
437 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComCloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span> | |
438 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
439 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
440 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
441 | ||
442 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">path</span><span class="p">):</span> | |
443 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
444 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
445 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
446 | <span class="n">connectSrvSvc</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
447 | <span class="k">else</span><span class="p">:</span> | |
448 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to list shares: Unable to connect to IPC$'</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span> | |
449 | ||
450 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">path</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
451 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
452 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="p">)</span> | |
453 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
454 | <span class="k">else</span><span class="p">:</span> | |
455 | <span class="n">connectSrvSvc</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">path</span><span class="p">])</span> | |
456 | ||
457 | <span class="k">def</span> <span class="nf">_listPath</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">search</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
458 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
459 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
460 | ||
461 | <span class="n">expiry_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">timeout</span> | |
462 | <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
463 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
464 | <span class="n">results</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
465 | ||
466 | <span class="k">def</span> <span class="nf">sendFindFirst</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
467 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="mh">0x0001</span><span class="p">)</span> <span class="c"># TRANS2_FIND_FIRST2 sub-command. See [MS-CIFS]: 2.2.6.2.1</span> | |
468 | <span class="n">params_bytes</span> <span class="o">=</span> \ | |
469 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<HHHHI'</span><span class="p">,</span> | |
470 | <span class="n">search</span><span class="p">,</span> <span class="c"># SearchAttributes</span> | |
471 | <span class="mi">100</span><span class="p">,</span> <span class="c"># SearchCount</span> | |
472 | <span class="mh">0x0006</span><span class="p">,</span> <span class="c"># Flags: SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS</span> | |
473 | <span class="mh">0x0104</span><span class="p">,</span> <span class="c"># InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO</span> | |
474 | <span class="mh">0x0000</span><span class="p">)</span> <span class="c"># SearchStorageType</span> | |
475 | <span class="n">params_bytes</span> <span class="o">+=</span> <span class="n">pattern</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> | |
476 | ||
477 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransaction2Request</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> | |
478 | <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">16644</span><span class="p">,</span> | |
479 | <span class="n">max_setup_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
480 | <span class="n">params_bytes</span> <span class="o">=</span> <span class="n">params_bytes</span><span class="p">,</span> | |
481 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">setup_bytes</span><span class="p">))</span> | |
482 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
483 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
484 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">findFirstCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
485 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
486 | ||
487 | <span class="k">def</span> <span class="nf">decodeFindStruct</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">):</span> | |
488 | <span class="c"># SMB_FIND_FILE_BOTH_DIRECTORY_INFO structure. See [MS-CIFS]: 2.2.8.1.7 and [MS-SMB]: 2.2.8.1.1</span> | |
489 | <span class="n">info_format</span> <span class="o">=</span> <span class="s">'<IIQQQQQQIIIBB24s'</span> | |
490 | <span class="n">info_size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">info_format</span><span class="p">)</span> | |
491 | ||
492 | <span class="n">data_length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span> | |
493 | <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span> | |
494 | <span class="k">while</span> <span class="n">offset</span> <span class="o"><</span> <span class="n">data_length</span><span class="p">:</span> | |
495 | <span class="n">next_offset</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> \ | |
496 | <span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span> \ | |
497 | <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">filename_length</span><span class="p">,</span> <span class="n">ea_size</span><span class="p">,</span> \ | |
498 | <span class="n">short_name_length</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">short_name</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="n">info_format</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="n">info_size</span><span class="p">])</span> | |
499 | ||
500 | <span class="n">offset2</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">+</span> <span class="n">info_size</span> | |
501 | ||
502 | <span class="n">filename</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">[</span><span class="n">offset2</span><span class="p">:</span><span class="n">offset2</span><span class="o">+</span><span class="n">filename_length</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> | |
503 | <span class="n">short_name</span> <span class="o">=</span> <span class="n">short_name</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> | |
504 | <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SharedFile</span><span class="p">(</span><span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span> | |
505 | <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">))</span> | |
506 | ||
507 | <span class="k">if</span> <span class="n">next_offset</span><span class="p">:</span> | |
508 | <span class="n">offset</span> <span class="o">+=</span> <span class="n">next_offset</span> | |
509 | <span class="k">else</span><span class="p">:</span> | |
510 | <span class="k">break</span> | |
511 | ||
512 | <span class="k">def</span> <span class="nf">findFirstCB</span><span class="p">(</span><span class="n">find_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
513 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">find_message</span><span class="p">)</span> | |
514 | <span class="k">if</span> <span class="ow">not</span> <span class="n">find_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
515 | <span class="c"># TRANS2_FIND_FIRST2 response. [MS-CIFS]: 2.2.6.2.2</span> | |
516 | <span class="n">sid</span><span class="p">,</span> <span class="n">search_count</span><span class="p">,</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">last_name_offset</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<HHHHH'</span><span class="p">,</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">[:</span><span class="mi">10</span><span class="p">])</span> | |
517 | <span class="k">if</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">:</span> | |
518 | <span class="n">decodeFindStruct</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span> | |
519 | ||
520 | <span class="k">if</span> <span class="n">end_of_search</span><span class="p">:</span> | |
521 | <span class="n">callback</span><span class="p">(</span><span class="n">results</span><span class="p">)</span> | |
522 | <span class="k">else</span><span class="p">:</span> | |
523 | <span class="n">sendFindNext</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="n">last_name_offset</span><span class="p">)</span> | |
524 | <span class="k">else</span><span class="p">:</span> | |
525 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to list </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to retrieve file list'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
526 | ||
527 | <span class="k">def</span> <span class="nf">sendFindNext</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">sid</span><span class="p">,</span> <span class="n">resume_key</span><span class="p">):</span> | |
528 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="mh">0x0002</span><span class="p">)</span> <span class="c"># TRANS2_FIND_NEXT2 sub-command. See [MS-CIFS]: 2.2.6.3.1</span> | |
529 | <span class="n">params_bytes</span> <span class="o">=</span> \ | |
530 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<HHHIH'</span><span class="p">,</span> | |
531 | <span class="n">sid</span><span class="p">,</span> <span class="c"># SID</span> | |
532 | <span class="mi">100</span><span class="p">,</span> <span class="c"># SearchCount</span> | |
533 | <span class="mh">0x0104</span><span class="p">,</span> <span class="c"># InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO</span> | |
534 | <span class="n">resume_key</span><span class="p">,</span> <span class="c"># ResumeKey</span> | |
535 | <span class="mh">0x000a</span><span class="p">)</span> <span class="c"># Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS</span> | |
536 | <span class="n">params_bytes</span> <span class="o">+=</span> <span class="n">pattern</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> | |
537 | ||
538 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTransaction2Request</span><span class="p">(</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> | |
539 | <span class="n">max_data_count</span> <span class="o">=</span> <span class="mi">16644</span><span class="p">,</span> | |
540 | <span class="n">max_setup_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
541 | <span class="n">params_bytes</span> <span class="o">=</span> <span class="n">params_bytes</span><span class="p">,</span> | |
542 | <span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">setup_bytes</span><span class="p">))</span> | |
543 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
544 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
545 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">findNextCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">sid</span> <span class="o">=</span> <span class="n">sid</span><span class="p">)</span> | |
546 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
547 | ||
548 | <span class="k">def</span> <span class="nf">findNextCB</span><span class="p">(</span><span class="n">find_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
549 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">find_message</span><span class="p">)</span> | |
550 | <span class="k">if</span> <span class="ow">not</span> <span class="n">find_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
551 | <span class="c"># TRANS2_FIND_NEXT2 response. [MS-CIFS]: 2.2.6.3.2</span> | |
552 | <span class="n">search_count</span><span class="p">,</span> <span class="n">end_of_search</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">last_name_offset</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<HHHH'</span><span class="p">,</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">[:</span><span class="mi">8</span><span class="p">])</span> | |
553 | <span class="k">if</span> <span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">:</span> | |
554 | <span class="n">decodeFindStruct</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span> | |
555 | ||
556 | <span class="k">if</span> <span class="n">end_of_search</span><span class="p">:</span> | |
557 | <span class="n">callback</span><span class="p">(</span><span class="n">results</span><span class="p">)</span> | |
558 | <span class="k">else</span><span class="p">:</span> | |
559 | <span class="n">sendFindNext</span><span class="p">(</span><span class="n">find_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'sid'</span><span class="p">],</span> <span class="n">last_name_offset</span><span class="p">)</span> | |
560 | <span class="k">else</span><span class="p">:</span> | |
561 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to list </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to retrieve file list'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
562 | ||
563 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span> | |
564 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
565 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
566 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
567 | <span class="n">sendFindFirst</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
568 | <span class="k">else</span><span class="p">:</span> | |
569 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to list </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to connect to shared device'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
570 | ||
571 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
572 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
573 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span> | |
574 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
575 | <span class="k">else</span><span class="p">:</span> | |
576 | <span class="n">sendFindFirst</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span> | |
577 | ||
578 | <span class="k">def</span> <span class="nf">_retrieveFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
579 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
580 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
581 | ||
582 | <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
583 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
584 | ||
585 | <span class="k">def</span> <span class="nf">sendOpen</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
586 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComOpenAndxRequest</span><span class="p">(</span><span class="n">filename</span> <span class="o">=</span> <span class="n">path</span><span class="p">,</span> | |
587 | <span class="n">access_mode</span> <span class="o">=</span> <span class="mh">0x0040</span><span class="p">,</span> <span class="c"># Sharing mode: Deny nothing to others</span> | |
588 | <span class="n">open_mode</span> <span class="o">=</span> <span class="mh">0x0001</span><span class="p">,</span> <span class="c"># Failed if file does not exist</span> | |
589 | <span class="n">search_attributes</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span><span class="p">,</span> | |
590 | <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">))</span> | |
591 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
592 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
593 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">openCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
594 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
595 | ||
596 | <span class="k">def</span> <span class="nf">openCB</span><span class="p">(</span><span class="n">open_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
597 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">open_message</span><span class="p">)</span> | |
598 | <span class="k">if</span> <span class="ow">not</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
599 | <span class="n">sendRead</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="il">0L</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">)</span> | |
600 | <span class="k">else</span><span class="p">:</span> | |
601 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to retrieve </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to open file'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
602 | ||
603 | <span class="k">def</span> <span class="nf">sendRead</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">):</span> | |
604 | <span class="n">read_count</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span> <span class="o">-</span> <span class="mi">2</span> | |
605 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComReadAndxRequest</span><span class="p">(</span><span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> | |
606 | <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="p">,</span> | |
607 | <span class="n">max_return_bytes_count</span> <span class="o">=</span> <span class="n">read_count</span><span class="p">,</span> | |
608 | <span class="n">min_return_bytes_count</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mh">0xFFFF</span><span class="p">,</span> <span class="n">read_count</span><span class="p">)))</span> | |
609 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
610 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
611 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">readCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="p">,</span> <span class="n">file_attributes</span> <span class="o">=</span> <span class="n">file_attributes</span><span class="p">)</span> | |
612 | ||
613 | <span class="k">def</span> <span class="nf">readCB</span><span class="p">(</span><span class="n">read_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
614 | <span class="c"># To avoid crazy memory usage when retrieving large files, we do not save every read_message in messages_history.</span> | |
615 | <span class="k">if</span> <span class="ow">not</span> <span class="n">read_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
616 | <span class="n">file_obj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> | |
617 | <span class="k">if</span> <span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_length</span> <span class="o"><</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span> <span class="o">-</span> <span class="mi">2</span><span class="p">):</span> | |
618 | <span class="n">closeFid</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
619 | <span class="n">callback</span><span class="p">((</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'file_attributes'</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'offset'</span><span class="p">]</span><span class="o">+</span><span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_length</span> <span class="p">))</span> <span class="c"># Note that this is a tuple of 3-elements</span> | |
620 | <span class="k">else</span><span class="p">:</span> | |
621 | <span class="n">sendRead</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'offset'</span><span class="p">]</span><span class="o">+</span><span class="n">read_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data_length</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'file_attributes'</span><span class="p">])</span> | |
622 | <span class="k">else</span><span class="p">:</span> | |
623 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">read_message</span><span class="p">)</span> | |
624 | <span class="n">closeFid</span><span class="p">(</span><span class="n">read_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
625 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to retrieve </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Read failed'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
626 | ||
627 | <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">):</span> | |
628 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComCloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span> | |
629 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
630 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
631 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
632 | ||
633 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span> | |
634 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
635 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
636 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
637 | <span class="n">sendOpen</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
638 | <span class="k">else</span><span class="p">:</span> | |
639 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to retrieve </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to connect to shared device'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
640 | ||
641 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
642 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
643 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span> | |
644 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
645 | <span class="k">else</span><span class="p">:</span> | |
646 | <span class="n">sendOpen</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span> | |
647 | ||
648 | <span class="k">def</span> <span class="nf">_storeFile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
649 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
650 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
651 | ||
652 | <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
653 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
654 | ||
655 | <span class="k">def</span> <span class="nf">sendOpen</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
656 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComOpenAndxRequest</span><span class="p">(</span><span class="n">filename</span> <span class="o">=</span> <span class="n">path</span><span class="p">,</span> | |
657 | <span class="n">access_mode</span> <span class="o">=</span> <span class="mh">0x0041</span><span class="p">,</span> <span class="c"># Sharing mode: Deny nothing to others + Open for writing</span> | |
658 | <span class="n">open_mode</span> <span class="o">=</span> <span class="mh">0x0010</span><span class="p">,</span> <span class="c"># Create file if file does not exist</span> | |
659 | <span class="n">search_attributes</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span><span class="p">,</span> | |
660 | <span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">))</span> | |
661 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
662 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
663 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">openCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
664 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
665 | ||
666 | <span class="k">def</span> <span class="nf">openCB</span><span class="p">(</span><span class="n">open_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
667 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">open_message</span><span class="p">)</span> | |
668 | <span class="k">if</span> <span class="ow">not</span> <span class="n">open_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
669 | <span class="n">sendWrite</span><span class="p">(</span><span class="n">open_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">open_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="il">0L</span><span class="p">)</span> | |
670 | <span class="k">else</span><span class="p">:</span> | |
671 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to store </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to open file'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
672 | ||
673 | <span class="k">def</span> <span class="nf">sendWrite</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span><span class="p">):</span> | |
674 | <span class="n">write_count</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span><span class="p">,</span> <span class="mh">0xFFFF</span><span class="p">)</span> | |
675 | <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">file_obj</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">write_count</span><span class="p">)</span> | |
676 | <span class="k">if</span> <span class="n">data_bytes</span><span class="p">:</span> | |
677 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComWriteAndxRequest</span><span class="p">(</span><span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span><span class="p">))</span> | |
678 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
679 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
680 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">writeCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span><span class="o">+</span><span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">))</span> | |
681 | <span class="k">else</span><span class="p">:</span> | |
682 | <span class="n">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">)</span> | |
683 | <span class="n">callback</span><span class="p">((</span> <span class="n">file_obj</span><span class="p">,</span> <span class="n">offset</span> <span class="p">))</span> <span class="c"># Note that this is a tuple of 2-elements</span> | |
684 | ||
685 | <span class="k">def</span> <span class="nf">writeCB</span><span class="p">(</span><span class="n">write_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
686 | <span class="c"># To avoid crazy memory usage when saving large files, we do not save every write_message in messages_history.</span> | |
687 | <span class="k">if</span> <span class="ow">not</span> <span class="n">write_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
688 | <span class="n">sendWrite</span><span class="p">(</span><span class="n">write_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'offset'</span><span class="p">])</span> | |
689 | <span class="k">else</span><span class="p">:</span> | |
690 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">write_message</span><span class="p">)</span> | |
691 | <span class="n">closeFid</span><span class="p">(</span><span class="n">write_message</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">[</span><span class="s">'fid'</span><span class="p">])</span> | |
692 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to store </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Write failed'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
693 | ||
694 | <span class="k">def</span> <span class="nf">closeFid</span><span class="p">(</span><span class="n">tid</span><span class="p">,</span> <span class="n">fid</span><span class="p">):</span> | |
695 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComCloseRequest</span><span class="p">(</span><span class="n">fid</span><span class="p">))</span> | |
696 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
697 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
698 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
699 | ||
700 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span> | |
701 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
702 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
703 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
704 | <span class="n">sendOpen</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
705 | <span class="k">else</span><span class="p">:</span> | |
706 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to store </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to connect to shared device'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
707 | ||
708 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
709 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
710 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span> | |
711 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
712 | <span class="k">else</span><span class="p">:</span> | |
713 | <span class="n">sendOpen</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span> | |
714 | ||
715 | <span class="k">def</span> <span class="nf">_deleteFiles</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path_file_pattern</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
716 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
717 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
718 | ||
719 | <span class="n">path</span> <span class="o">=</span> <span class="n">path_file_pattern</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
720 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
721 | ||
722 | <span class="k">def</span> <span class="nf">sendDelete</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
723 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComDeleteRequest</span><span class="p">(</span><span class="n">filename_pattern</span> <span class="o">=</span> <span class="n">path</span><span class="p">,</span> | |
724 | <span class="n">search_attributes</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span><span class="p">))</span> | |
725 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
726 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
727 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
728 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
729 | ||
730 | <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">delete_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
731 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">delete_message</span><span class="p">)</span> | |
732 | <span class="k">if</span> <span class="ow">not</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
733 | <span class="n">callback</span><span class="p">(</span><span class="n">path_file_pattern</span><span class="p">)</span> | |
734 | <span class="k">else</span><span class="p">:</span> | |
735 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to store </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Delete failed'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
736 | ||
737 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span> | |
738 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
739 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
740 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
741 | <span class="n">sendDelete</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
742 | <span class="k">else</span><span class="p">:</span> | |
743 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to delete </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to connect to shared device'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
744 | ||
745 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
746 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
747 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span> | |
748 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
749 | <span class="k">else</span><span class="p">:</span> | |
750 | <span class="n">sendDelete</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span> | |
751 | ||
752 | <span class="k">def</span> <span class="nf">_createDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
753 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
754 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
755 | ||
756 | <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
757 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
758 | ||
759 | <span class="k">def</span> <span class="nf">sendCreate</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
760 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComCreateDirectoryRequest</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> | |
761 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
762 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
763 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">createCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
764 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
765 | ||
766 | <span class="k">def</span> <span class="nf">createCB</span><span class="p">(</span><span class="n">create_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
767 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">create_message</span><span class="p">)</span> | |
768 | <span class="k">if</span> <span class="ow">not</span> <span class="n">create_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
769 | <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> | |
770 | <span class="k">else</span><span class="p">:</span> | |
771 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to create directory </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Create failed'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
772 | ||
773 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span> | |
774 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
775 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
776 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
777 | <span class="n">sendCreate</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
778 | <span class="k">else</span><span class="p">:</span> | |
779 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to create directory </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to connect to shared device'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
780 | ||
781 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
782 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
783 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span> | |
784 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
785 | <span class="k">else</span><span class="p">:</span> | |
786 | <span class="n">sendCreate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span> | |
787 | ||
788 | <span class="k">def</span> <span class="nf">_deleteDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
789 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
790 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
791 | ||
792 | <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
793 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
794 | ||
795 | <span class="k">def</span> <span class="nf">sendDelete</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
796 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComDeleteDirectoryRequest</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> | |
797 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
798 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
799 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">deleteCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
800 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
801 | ||
802 | <span class="k">def</span> <span class="nf">deleteCB</span><span class="p">(</span><span class="n">delete_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
803 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">delete_message</span><span class="p">)</span> | |
804 | <span class="k">if</span> <span class="ow">not</span> <span class="n">delete_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
805 | <span class="n">callback</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> | |
806 | <span class="k">else</span><span class="p">:</span> | |
807 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to delete directory </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Delete failed'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
808 | ||
809 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span> | |
810 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
811 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
812 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
813 | <span class="n">sendDelete</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
814 | <span class="k">else</span><span class="p">:</span> | |
815 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to delete </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to connect to shared device'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
816 | ||
817 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
818 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
819 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span> | |
820 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
821 | <span class="k">else</span><span class="p">:</span> | |
822 | <span class="n">sendDelete</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span> | |
823 | ||
824 | <span class="k">def</span> <span class="nf">_rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
825 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_authenticated</span><span class="p">:</span> | |
826 | <span class="k">raise</span> <span class="n">NotReadyError</span><span class="p">(</span><span class="s">'SMB connection not authenticated'</span><span class="p">)</span> | |
827 | ||
828 | <span class="n">new_path</span> <span class="o">=</span> <span class="n">new_path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
829 | <span class="n">old_path</span> <span class="o">=</span> <span class="n">old_path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'/'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">'</span><span class="p">)</span> | |
830 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
831 | ||
832 | <span class="k">def</span> <span class="nf">sendRename</span><span class="p">(</span><span class="n">tid</span><span class="p">):</span> | |
833 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComRenameRequest</span><span class="p">(</span><span class="n">old_path</span> <span class="o">=</span> <span class="n">old_path</span><span class="p">,</span> | |
834 | <span class="n">new_path</span> <span class="o">=</span> <span class="n">new_path</span><span class="p">,</span> | |
835 | <span class="n">search_attributes</span> <span class="o">=</span> <span class="n">SMB_FILE_ATTRIBUTE_HIDDEN</span> <span class="o">|</span> <span class="n">SMB_FILE_ATTRIBUTE_SYSTEM</span><span class="p">))</span> | |
836 | <span class="n">m</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="n">tid</span> | |
837 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
838 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">renameCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
839 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
840 | ||
841 | <span class="k">def</span> <span class="nf">renameCB</span><span class="p">(</span><span class="n">rename_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
842 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rename_message</span><span class="p">)</span> | |
843 | <span class="k">if</span> <span class="ow">not</span> <span class="n">rename_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
844 | <span class="n">callback</span><span class="p">((</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span> <span class="p">))</span> <span class="c"># Note that this is a tuple of 2-elements</span> | |
845 | <span class="k">else</span><span class="p">:</span> | |
846 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to rename </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Rename failed'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
847 | ||
848 | <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">service_name</span><span class="p">):</span> | |
849 | <span class="k">def</span> <span class="nf">connectCB</span><span class="p">(</span><span class="n">connect_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
850 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connect_message</span><span class="p">)</span> | |
851 | <span class="k">if</span> <span class="ow">not</span> <span class="n">connect_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
852 | <span class="n">sendRename</span><span class="p">(</span><span class="n">connect_message</span><span class="o">.</span><span class="n">tid</span><span class="p">)</span> | |
853 | <span class="k">else</span><span class="p">:</span> | |
854 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Failed to rename </span><span class="si">%s</span><span class="s"> on </span><span class="si">%s</span><span class="s">: Unable to connect to shared device'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">messages_history</span><span class="p">))</span> | |
855 | ||
856 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="si">%s</span><span class="s">\</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">remote_name</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">service_name</span> <span class="p">),</span> <span class="n">SERVICE_ANY</span><span class="p">,</span> <span class="s">''</span><span class="p">))</span> | |
857 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
858 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">connectCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">service_name</span><span class="p">)</span> | |
859 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
860 | <span class="k">else</span><span class="p">:</span> | |
861 | <span class="n">sendRename</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">connected_trees</span><span class="p">[</span><span class="n">service_name</span><span class="p">])</span> | |
862 | ||
863 | <span class="k">def</span> <span class="nf">_echo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">30</span><span class="p">):</span> | |
864 | <span class="n">messages_history</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
865 | ||
866 | <span class="k">def</span> <span class="nf">echoCB</span><span class="p">(</span><span class="n">echo_message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
867 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">echo_message</span><span class="p">)</span> | |
868 | <span class="k">if</span> <span class="ow">not</span> <span class="n">echo_message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
869 | <span class="n">callback</span><span class="p">(</span><span class="n">echo_message</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> | |
870 | <span class="k">else</span><span class="p">:</span> | |
871 | <span class="n">errback</span><span class="p">(</span><span class="n">OperationFailure</span><span class="p">(</span><span class="s">'Echo failed'</span><span class="p">,</span> <span class="n">messages_history</span><span class="p">))</span> | |
872 | ||
873 | <span class="n">m</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="p">(</span><span class="n">ComEchoRequest</span><span class="p">(</span><span class="n">echo_data</span> <span class="o">=</span> <span class="n">data</span><span class="p">))</span> | |
874 | <span class="bp">self</span><span class="o">.</span><span class="n">_sendSMBMessage</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
875 | <span class="bp">self</span><span class="o">.</span><span class="n">pending_requests</span><span class="p">[</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PendingRequest</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">timeout</span><span class="p">,</span> <span class="n">echoCB</span><span class="p">,</span> <span class="n">errback</span><span class="p">)</span> | |
876 | <span class="n">messages_history</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">m</span><span class="p">)</span> | |
877 | ||
878 | ||
879 | <span class="k">class</span> <span class="nc">SharedDevice</span><span class="p">:</span> | |
880 | <div class="viewcode-block" id="SharedDevice"><a class="viewcode-back" href="../../api/smb_SharedDevice.html#smb.base.SharedDevice">[docs]</a> <span class="sd">"""</span> | |
881 | <span class="sd"> Contains information about a single shared device on the remote server.</span> | |
882 | <span class="sd"> """</span> | |
883 | ||
884 | <span class="c"># The following constants are taken from [MS-SRVS]: 2.2.2.4</span> | |
885 | <span class="c"># They are used to identify the type of shared resource from the results from the NetrShareEnum in Server Service RPC</span> | |
886 | <span class="n">DISK_TREE</span> <span class="o">=</span> <span class="mh">0x00</span> | |
887 | <span class="n">PRINT_QUEUE</span> <span class="o">=</span> <span class="mh">0x01</span> | |
888 | <span class="n">COMM_DEVICE</span> <span class="o">=</span> <span class="mh">0x02</span> | |
889 | <span class="n">IPC</span> <span class="o">=</span> <span class="mh">0x03</span> | |
890 | ||
891 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">comments</span><span class="p">):</span> | |
892 | <span class="bp">self</span><span class="o">.</span><span class="n">_type</span> <span class="o">=</span> <span class="nb">type</span> | |
893 | <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span> <span class="c">#: An unicode string containing the name of the shared device</span> | |
894 | <span class="bp">self</span><span class="o">.</span><span class="n">comments</span> <span class="o">=</span> <span class="n">comments</span> <span class="c">#: An unicode string containing the user description of the shared device</span> | |
895 | ||
896 | <span class="nd">@property</span> | |
897 | <span class="k">def</span> <span class="nf">type</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
898 | <div class="viewcode-block" id="SharedDevice.type"><a class="viewcode-back" href="../../api/smb_SharedDevice.html#smb.base.SharedDevice.type">[docs]</a> <span class="sd">"""</span> | |
899 | <span class="sd"> Returns one of the following integral constants.</span> | |
900 | <span class="sd"> - SharedDevice.DISK_TREE</span> | |
901 | <span class="sd"> - SharedDevice.PRINT_QUEUE</span> | |
902 | <span class="sd"> - SharedDevice.COMM_DEVICE</span> | |
903 | <span class="sd"> - SharedDevice.IPC</span> | |
904 | <span class="sd"> """</span> | |
905 | <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_type</span> <span class="o">&</span> <span class="mh">0xFFFF</span> | |
906 | ||
907 | <span class="nd">@property</span></div> | |
908 | <span class="k">def</span> <span class="nf">isSpecial</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
909 | <div class="viewcode-block" id="SharedDevice.isSpecial"><a class="viewcode-back" href="../../api/smb_SharedDevice.html#smb.base.SharedDevice.isSpecial">[docs]</a> <span class="sd">"""</span> | |
910 | <span class="sd"> Returns True if this shared device is a special share reserved for interprocess communication (IPC$)</span> | |
911 | <span class="sd"> or remote administration of the server (ADMIN$). Can also refer to administrative shares such as</span> | |
912 | <span class="sd"> C$, D$, E$, and so forth</span> | |
913 | <span class="sd"> """</span> | |
914 | <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_type</span> <span class="o">&</span> <span class="mh">0x80000000</span><span class="p">)</span> | |
915 | ||
916 | <span class="nd">@property</span></div> | |
917 | <span class="k">def</span> <span class="nf">isTemporary</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
918 | <div class="viewcode-block" id="SharedDevice.isTemporary"><a class="viewcode-back" href="../../api/smb_SharedDevice.html#smb.base.SharedDevice.isTemporary">[docs]</a> <span class="sd">"""</span> | |
919 | <span class="sd"> Returns True if this is a temporary share that is not persisted for creation each time the file server initializes.</span> | |
920 | <span class="sd"> """</span> | |
921 | <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_type</span> <span class="o">&</span> <span class="mh">0x40000000</span><span class="p">)</span> | |
922 | ||
923 | <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
924 | <span class="k">return</span> <span class="s">u'Shared device: </span><span class="si">%s</span><span class="s"> (type:0x</span><span class="si">%02x</span><span class="s"> comments:</span><span class="si">%s</span><span class="s">)'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">comments</span> <span class="p">)</span> | |
925 | ||
926 | ||
927 | <span class="k">class</span> <span class="nc">SharedFile</span><span class="p">:</span></div> | |
928 | <div class="viewcode-block" id="SharedFile"><a class="viewcode-back" href="../../api/smb_SharedFile.html#smb.base.SharedFile">[docs]</a> <span class="sd">"""</span> | |
929 | <span class="sd"> Contain information about a file/folder entry that is shared on the shared device.</span> | |
930 | ||
931 | <span class="sd"> As an application developer, you should not need to instantiate a *SharedFile* instance directly in your application.</span> | |
932 | <span class="sd"> These *SharedFile* instances are usually returned via a call to *listPath* method in :doc:`smb.SMBProtocol.SMBProtocolFactory<smb_SMBProtocolFactory>`.</span> | |
933 | ||
934 | <span class="sd"> If you encounter *SharedFile* instance where its short_name attribute is empty but the filename attribute contains a short name which does not correspond</span> | |
935 | <span class="sd"> to any files/folders on your remote shared device, it could be that the original filename on the file/folder entry on the shared device contains</span> | |
936 | <span class="sd"> one of these prohibited characters: "\/[]:+|<>=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).</span> | |
937 | <span class="sd"> """</span> | |
938 | ||
939 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">create_time</span><span class="p">,</span> <span class="n">last_access_time</span><span class="p">,</span> <span class="n">last_write_time</span><span class="p">,</span> <span class="n">last_attr_change_time</span><span class="p">,</span> <span class="n">file_size</span><span class="p">,</span> <span class="n">alloc_size</span><span class="p">,</span> <span class="n">file_attributes</span><span class="p">,</span> <span class="n">short_name</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span> | |
940 | <span class="bp">self</span><span class="o">.</span><span class="n">create_time</span> <span class="o">=</span> <span class="n">create_time</span> <span class="c">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server</span> | |
941 | <span class="bp">self</span><span class="o">.</span><span class="n">last_access_time</span> <span class="o">=</span> <span class="n">last_access_time</span> <span class="c">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server</span> | |
942 | <span class="bp">self</span><span class="o">.</span><span class="n">last_write_time</span> <span class="o">=</span> <span class="n">last_write_time</span> <span class="c">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server</span> | |
943 | <span class="bp">self</span><span class="o">.</span><span class="n">last_attr_change_time</span> <span class="o">=</span> <span class="n">last_attr_change_time</span> <span class="c">#: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server</span> | |
944 | <span class="bp">self</span><span class="o">.</span><span class="n">file_size</span> <span class="o">=</span> <span class="n">file_size</span> <span class="c">#: File size in number of bytes</span> | |
945 | <span class="bp">self</span><span class="o">.</span><span class="n">alloc_size</span> <span class="o">=</span> <span class="n">alloc_size</span> <span class="c">#: Total number of bytes allocated to store this file</span> | |
946 | <span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">=</span> <span class="n">file_attributes</span> <span class="c">#: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3</span> | |
947 | <span class="bp">self</span><span class="o">.</span><span class="n">short_name</span> <span class="o">=</span> <span class="n">short_name</span> <span class="c">#: Unicode string containing the short name of this file (usually in 8.3 notation)</span> | |
948 | <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span> <span class="c">#: Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.</span> | |
949 | ||
950 | <span class="nd">@property</span> | |
951 | <span class="k">def</span> <span class="nf">isDirectory</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
952 | <div class="viewcode-block" id="SharedFile.isDirectory"><a class="viewcode-back" href="../../api/smb_SharedFile.html#smb.base.SharedFile.isDirectory">[docs]</a> <span class="sd">"""A convenience property to return True if this file resource is a directory on the remote server"""</span> | |
953 | <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">&</span> <span class="n">ATTR_DIRECTORY</span><span class="p">)</span> | |
954 | ||
955 | <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></div> | |
956 | <span class="k">return</span> <span class="s">u'Shared file: </span><span class="si">%s</span><span class="s"> (FileSize:</span><span class="si">%d</span><span class="s"> bytes, isDirectory:</span><span class="si">%s</span><span class="s">)'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">isDirectory</span> <span class="p">)</span> | |
957 | ||
958 | ||
959 | <span class="k">class</span> <span class="nc">_PendingRequest</span><span class="p">:</span></div> | |
960 | ||
961 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mid</span><span class="p">,</span> <span class="n">expiry_time</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">errback</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> | |
962 | <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="n">mid</span> | |
963 | <span class="bp">self</span><span class="o">.</span><span class="n">expiry_time</span> <span class="o">=</span> <span class="n">expiry_time</span> | |
964 | <span class="bp">self</span><span class="o">.</span><span class="n">callback</span> <span class="o">=</span> <span class="n">callback</span> | |
965 | <span class="bp">self</span><span class="o">.</span><span class="n">errback</span> <span class="o">=</span> <span class="n">errback</span> | |
966 | <span class="bp">self</span><span class="o">.</span><span class="n">kwargs</span> <span class="o">=</span> <span class="n">kwargs</span> | |
967 | </pre></div> | |
968 | ||
969 | </div> | |
970 | </div> | |
971 | </div> | |
972 | <div class="clearer"></div> | |
973 | </div> | |
974 | <div class="related"> | |
975 | <h3>Navigation</h3> | |
976 | <ul> | |
977 | <li class="right" style="margin-right: 10px"> | |
978 | <a href="../../genindex.html" title="General Index" | |
979 | >index</a></li> | |
980 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
981 | <li><a href="../index.html" >Module code</a> »</li> | |
982 | </ul> | |
983 | </div> | |
984 | <div class="footer"> | |
985 | © Copyright 2011, Michael Teo. | |
986 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
987 | </div> | |
988 | </body> | |
989 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>smb.smb_structs — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../../index.html" /> | |
28 | <link rel="up" title="Module code" href="../index.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="../../genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
38 | <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |
39 | </ul> | |
40 | </div> | |
41 | <div class="sphinxsidebar"> | |
42 | <div class="sphinxsidebarwrapper"> | |
43 | <div id="searchbox" style="display: none"> | |
44 | <h3>Quick search</h3> | |
45 | <form class="search" action="../../search.html" method="get"> | |
46 | <input type="text" name="q" /> | |
47 | <input type="submit" value="Go" /> | |
48 | <input type="hidden" name="check_keywords" value="yes" /> | |
49 | <input type="hidden" name="area" value="default" /> | |
50 | </form> | |
51 | <p class="searchtip" style="font-size: 90%"> | |
52 | Enter search terms or a module, class or function name. | |
53 | </p> | |
54 | </div> | |
55 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
56 | </div> | |
57 | </div> | |
58 | ||
59 | <div class="document"> | |
60 | <div class="documentwrapper"> | |
61 | <div class="bodywrapper"> | |
62 | <div class="body"> | |
63 | ||
64 | <h1>Source code for smb.smb_structs</h1><div class="highlight"><pre> | |
65 | <span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">struct</span><span class="o">,</span> <span class="nn">types</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">binascii</span><span class="o">,</span> <span class="nn">time</span> | |
66 | <span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span> | |
67 | <span class="kn">from</span> <span class="nn">smb_constants</span> <span class="kn">import</span> <span class="o">*</span> | |
68 | ||
69 | ||
70 | <span class="c"># Set to True if you want to enable support for extended security. Required for Windows Vista and later</span> | |
71 | <span class="n">SUPPORT_EXTENDED_SECURITY</span> <span class="o">=</span> <span class="bp">True</span> | |
72 | ||
73 | <span class="c"># Supported dialects</span> | |
74 | <span class="n">DIALECTS</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> | |
75 | <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="n">dialect</span> <span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span> <span class="p">(</span> <span class="s">'NT_LAN_MANAGER_DIALECT'</span><span class="p">,</span> <span class="s">'NT LM 0.12'</span> <span class="p">),</span> <span class="p">]):</span> | |
76 | <span class="n">DIALECTS</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span> | |
77 | <span class="nb">globals</span><span class="p">()[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span> | |
78 | ||
79 | ||
80 | <span class="k">class</span> <span class="nc">UnsupportedFeature</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> | |
81 | <div class="viewcode-block" id="UnsupportedFeature"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.smb_structs.UnsupportedFeature">[docs]</a> <span class="sd">"""</span> | |
82 | <span class="sd"> Raised when an supported feature is present/required in the protocol but is not</span> | |
83 | <span class="sd"> currently supported by pysmb</span> | |
84 | <span class="sd"> """</span> | |
85 | <span class="k">pass</span> | |
86 | ||
87 | ||
88 | <span class="k">class</span> <span class="nc">ProtocolError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span></div> | |
89 | <div class="viewcode-block" id="ProtocolError"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.smb_structs.ProtocolError">[docs]</a> | |
90 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">data_buf</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">smb_message</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span> | |
91 | <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span> | |
92 | <span class="bp">self</span><span class="o">.</span><span class="n">data_buf</span> <span class="o">=</span> <span class="n">data_buf</span> | |
93 | <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span> <span class="o">=</span> <span class="n">smb_message</span> | |
94 | ||
95 | <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
96 | <span class="n">b</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span> | |
97 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
98 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="p">:</span> | |
99 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'='</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="s">' SMB Message '</span> <span class="o">+</span> <span class="s">'='</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
100 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">smb_message</span><span class="p">))</span> | |
101 | ||
102 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_buf</span><span class="p">:</span> | |
103 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'='</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="s">' SMB Data Packet (hex) '</span> <span class="o">+</span> <span class="s">'='</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
104 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_buf</span><span class="p">))</span> | |
105 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
106 | ||
107 | <span class="k">return</span> <span class="n">b</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span> | |
108 | ||
109 | ||
110 | <span class="k">class</span> <span class="nc">OperationFailure</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span></div> | |
111 | <div class="viewcode-block" id="OperationFailure"><a class="viewcode-back" href="../../api/smb_exceptions.html#smb.smb_structs.OperationFailure">[docs]</a> | |
112 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">smb_messages</span><span class="p">):</span> | |
113 | <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span> | |
114 | <span class="bp">self</span><span class="o">.</span><span class="n">smb_messages</span> <span class="o">=</span> <span class="n">smb_messages</span> | |
115 | ||
116 | <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
117 | <span class="n">b</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span> | |
118 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
119 | ||
120 | <span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">m</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">smb_messages</span><span class="p">):</span> | |
121 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'='</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="s">' SMB Message </span><span class="si">%d</span><span class="s"> '</span> <span class="o">%</span> <span class="n">idx</span> <span class="o">+</span> <span class="s">'='</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
122 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'SMB Header:'</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
123 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'-----------'</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
124 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">m</span><span class="p">))</span> | |
125 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'SMB Data Packet (hex):'</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
126 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'----------------------'</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
127 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">raw_data</span><span class="p">))</span> | |
128 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">)</span> | |
129 | ||
130 | <span class="k">return</span> <span class="n">b</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span> | |
131 | ||
132 | ||
133 | <span class="k">class</span> <span class="nc">SMBError</span><span class="p">:</span></div> | |
134 | ||
135 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
136 | <span class="bp">self</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span> | |
137 | ||
138 | <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
139 | <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">=</span> <span class="il">0L</span> | |
140 | <span class="bp">self</span><span class="o">.</span><span class="n">is_ntstatus</span> <span class="o">=</span> <span class="bp">True</span> | |
141 | ||
142 | <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
143 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_ntstatus</span><span class="p">:</span> | |
144 | <span class="k">return</span> <span class="s">'NTSTATUS=0x</span><span class="si">%08X</span><span class="s">'</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span> | |
145 | <span class="k">else</span><span class="p">:</span> | |
146 | <span class="k">return</span> <span class="s">'ErrorClass=0x</span><span class="si">%02X</span><span class="s"> ErrorCode=0x</span><span class="si">%04X</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">>></span> <span class="mi">24</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">&</span> <span class="mh">0xFFFF</span> <span class="p">)</span> | |
147 | ||
148 | <span class="nd">@property</span> | |
149 | <span class="k">def</span> <span class="nf">hasError</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
150 | <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">!=</span> <span class="mi">0</span> | |
151 | ||
152 | ||
153 | <span class="k">class</span> <span class="nc">SMBMessage</span><span class="p">:</span> | |
154 | ||
155 | <span class="n">HEADER_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">"<4sBIBHHQxxHHHHB"</span> | |
156 | <span class="n">HEADER_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">HEADER_STRUCT_FORMAT</span><span class="p">)</span> | |
157 | ||
158 | <span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">'SMB.SMBMessage'</span><span class="p">)</span> | |
159 | ||
160 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">payload</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span> | |
161 | <span class="bp">self</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span> | |
162 | <span class="k">if</span> <span class="n">payload</span><span class="p">:</span> | |
163 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">payload</span> | |
164 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |
165 | ||
166 | <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
167 | <span class="n">b</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span> | |
168 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'Command: 0x</span><span class="si">%02X</span><span class="s"> (</span><span class="si">%s</span><span class="s">) </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="n">SMB_COMMAND_NAMES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="s">'<unknown>'</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
169 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'Status: </span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">status</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
170 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'Flags: 0x</span><span class="si">%02X</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
171 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'Flags2: 0x</span><span class="si">%04X</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags2</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
172 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'PID: </span><span class="si">%d</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">pid</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
173 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'UID: </span><span class="si">%d</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
174 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'MID: </span><span class="si">%d</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
175 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'TID: </span><span class="si">%d</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
176 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'Security: 0x</span><span class="si">%016X</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">security</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
177 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'Parameters: </span><span class="si">%d</span><span class="s"> bytes </span><span class="si">%s%s</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
178 | <span class="n">b</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'Data: </span><span class="si">%d</span><span class="s"> bytes </span><span class="si">%s%s</span><span class="s"> </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span><span class="p">,</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">),</span> <span class="n">os</span><span class="o">.</span><span class="n">linesep</span> <span class="p">))</span> | |
179 | <span class="k">return</span> <span class="n">b</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span> | |
180 | ||
181 | <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
182 | <span class="bp">self</span><span class="o">.</span><span class="n">raw_data</span> <span class="o">=</span> <span class="s">''</span> | |
183 | <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="mi">0</span> | |
184 | <span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">SMBError</span><span class="p">()</span> | |
185 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span> | |
186 | <span class="bp">self</span><span class="o">.</span><span class="n">flags2</span> <span class="o">=</span> <span class="mi">0</span> | |
187 | <span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">=</span> <span class="mi">0</span> | |
188 | <span class="bp">self</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="mi">0</span> | |
189 | <span class="bp">self</span><span class="o">.</span><span class="n">uid</span> <span class="o">=</span> <span class="mi">0</span> | |
190 | <span class="bp">self</span><span class="o">.</span><span class="n">mid</span> <span class="o">=</span> <span class="mi">0</span> | |
191 | <span class="bp">self</span><span class="o">.</span><span class="n">security</span> <span class="o">=</span> <span class="il">0L</span> | |
192 | <span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s">''</span> | |
193 | <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">''</span> | |
194 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="bp">None</span> | |
195 | ||
196 | <span class="nd">@property</span> | |
197 | <span class="k">def</span> <span class="nf">isReply</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
198 | <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">&</span> <span class="n">SMB_FLAGS_REPLY</span><span class="p">)</span> | |
199 | ||
200 | <span class="nd">@property</span> | |
201 | <span class="k">def</span> <span class="nf">hasExtendedSecurity</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
202 | <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&</span> <span class="n">SMB_FLAGS2_EXTENDED_SECURITY</span><span class="p">)</span> | |
203 | ||
204 | <span class="k">def</span> <span class="nf">encode</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
205 | <span class="sd">"""</span> | |
206 | <span class="sd"> Encode this SMB message into a series of bytes suitable to be embedded with a NetBIOS session message.</span> | |
207 | <span class="sd"> AssertionError will be raised if this SMB message has not been initialized with a Payload instance</span> | |
208 | ||
209 | <span class="sd"> @return: a string containing the encoded SMB message</span> | |
210 | <span class="sd"> """</span> | |
211 | <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> | |
212 | ||
213 | <span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()</span> | |
214 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |
215 | ||
216 | <span class="n">parameters_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> | |
217 | <span class="k">assert</span> <span class="n">parameters_len</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span> | |
218 | ||
219 | <span class="n">headers_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_FORMAT</span><span class="p">,</span> | |
220 | <span class="s">'</span><span class="se">\xFF</span><span class="s">SMB'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> | |
221 | <span class="bp">self</span><span class="o">.</span><span class="n">flags2</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">>></span> <span class="mi">16</span><span class="p">)</span> <span class="o">&</span> <span class="mh">0xFFFF</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">security</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> | |
222 | <span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">&</span> <span class="mh">0xFFFF</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">parameters_len</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span> | |
223 | <span class="k">return</span> <span class="n">headers_data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">+</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> | |
224 | ||
225 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">buf</span><span class="p">):</span> | |
226 | <span class="sd">"""</span> | |
227 | <span class="sd"> Decodes the SMB message in buf.</span> | |
228 | <span class="sd"> All fields of the SMBMessage object will be reset to default values before decoding.</span> | |
229 | <span class="sd"> On errors, do not assume that the fields will be reinstated back to what they are before</span> | |
230 | <span class="sd"> this method is invoked.</span> | |
231 | ||
232 | <span class="sd"> @param buf: data containing one complete SMB message</span> | |
233 | <span class="sd"> @type buf: string</span> | |
234 | <span class="sd"> @return: a positive integer indicating the number of bytes used in buf to decode this SMB message</span> | |
235 | <span class="sd"> @raise ProtocolError: raised when decoding fails</span> | |
236 | <span class="sd"> """</span> | |
237 | <span class="n">buf_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> | |
238 | <span class="k">if</span> <span class="n">buf_len</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span><span class="p">:</span> | |
239 | <span class="c"># We need at least 32 bytes (header) + 1 byte (parameter count)</span> | |
240 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB header'</span><span class="p">,</span> <span class="n">buf</span><span class="p">)</span> | |
241 | ||
242 | <span class="bp">self</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span> | |
243 | ||
244 | <span class="n">protocol</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span><span class="p">,</span> <span class="n">status</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> \ | |
245 | <span class="bp">self</span><span class="o">.</span><span class="n">flags2</span><span class="p">,</span> <span class="n">pid_high</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">security</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">tid</span><span class="p">,</span> \ | |
246 | <span class="n">pid_low</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid</span><span class="p">,</span> <span class="n">params_count</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">buf</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span><span class="p">])</span> | |
247 | ||
248 | <span class="k">if</span> <span class="n">protocol</span> <span class="o">!=</span> <span class="s">'</span><span class="se">\xFF</span><span class="s">SMB'</span><span class="p">:</span> | |
249 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Invalid 4-byte protocol field'</span><span class="p">,</span> <span class="n">buf</span><span class="p">)</span> | |
250 | ||
251 | <span class="bp">self</span><span class="o">.</span><span class="n">pid</span> <span class="o">=</span> <span class="p">(</span><span class="n">pid_high</span> <span class="o"><<</span> <span class="mi">16</span><span class="p">)</span> <span class="o">|</span> <span class="n">pid_low</span> | |
252 | <span class="bp">self</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">=</span> <span class="n">status</span> | |
253 | <span class="bp">self</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">is_ntstatus</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&</span> <span class="n">SMB_FLAGS2_NT_STATUS</span><span class="p">)</span> | |
254 | ||
255 | <span class="n">offset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> | |
256 | <span class="k">if</span> <span class="n">buf_len</span> <span class="o"><</span> <span class="n">params_count</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span><span class="p">:</span> | |
257 | <span class="c"># Not enough data in buf to decode up to body length</span> | |
258 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data. Parameters list decoding failed'</span><span class="p">,</span> <span class="n">buf</span><span class="p">)</span> | |
259 | ||
260 | <span class="n">datalen_offset</span> <span class="o">=</span> <span class="n">offset</span> <span class="o">+</span> <span class="n">params_count</span><span class="o">*</span><span class="mi">2</span> | |
261 | <span class="n">body_len</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="n">buf</span><span class="p">[</span><span class="n">datalen_offset</span><span class="p">:</span><span class="n">datalen_offset</span><span class="o">+</span><span class="mi">2</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span> | |
262 | <span class="k">if</span> <span class="n">body_len</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">buf_len</span> <span class="o"><</span> <span class="p">(</span><span class="n">datalen_offset</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">+</span> <span class="n">body_len</span><span class="p">):</span> | |
263 | <span class="c"># Not enough data in buf to decode body</span> | |
264 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data. Body decoding failed'</span><span class="p">,</span> <span class="n">buf</span><span class="p">)</span> | |
265 | ||
266 | <span class="bp">self</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">datalen_offset</span><span class="p">]</span> | |
267 | ||
268 | <span class="k">if</span> <span class="n">body_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
269 | <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[</span><span class="n">datalen_offset</span><span class="o">+</span><span class="mi">2</span><span class="p">:</span><span class="n">datalen_offset</span><span class="o">+</span><span class="mi">2</span><span class="o">+</span><span class="n">body_len</span><span class="p">]</span> | |
270 | ||
271 | <span class="bp">self</span><span class="o">.</span><span class="n">raw_data</span> <span class="o">=</span> <span class="n">buf</span> | |
272 | <span class="bp">self</span><span class="o">.</span><span class="n">_decodePayload</span><span class="p">()</span> | |
273 | ||
274 | <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">params_count</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">+</span> <span class="n">body_len</span> | |
275 | ||
276 | <span class="k">def</span> <span class="nf">_decodePayload</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |
277 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_READ_ANDX</span><span class="p">:</span> | |
278 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComReadAndxResponse</span><span class="p">()</span> | |
279 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_WRITE_ANDX</span><span class="p">:</span> | |
280 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComWriteAndxResponse</span><span class="p">()</span> | |
281 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TRANSACTION</span><span class="p">:</span> | |
282 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComTransactionResponse</span><span class="p">()</span> | |
283 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TRANSACTION2</span><span class="p">:</span> | |
284 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComTransaction2Response</span><span class="p">()</span> | |
285 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_OPEN_ANDX</span><span class="p">:</span> | |
286 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComOpenAndxResponse</span><span class="p">()</span> | |
287 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_NT_CREATE_ANDX</span><span class="p">:</span> | |
288 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComNTCreateAndxResponse</span><span class="p">()</span> | |
289 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TREE_CONNECT_ANDX</span><span class="p">:</span> | |
290 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComTreeConnectAndxResponse</span><span class="p">()</span> | |
291 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_ECHO</span><span class="p">:</span> | |
292 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComEchoResponse</span><span class="p">()</span> | |
293 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_SESSION_SETUP_ANDX</span><span class="p">:</span> | |
294 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComSessionSetupAndxResponse</span><span class="p">()</span> | |
295 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_NEGOTIATE</span><span class="p">:</span> | |
296 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span> <span class="o">=</span> <span class="n">ComNegotiateResponse</span><span class="p">()</span> | |
297 | ||
298 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">payload</span><span class="p">:</span> | |
299 | <span class="bp">self</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |
300 | ||
301 | ||
302 | <span class="k">class</span> <span class="nc">Payload</span><span class="p">:</span> | |
303 | ||
304 | <span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">=</span> <span class="s">'</span><span class="se">\xFF\x00\x00\x00</span><span class="s">'</span> | |
305 | <span class="n">DEFAULT_ANDX_PARAM_SIZE</span> <span class="o">=</span> <span class="mi">4</span> | |
306 | ||
307 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
308 | <span class="c"># SMB_FLAGS2_UNICODE must always be enabled. Without this, almost all the Payload subclasses will need to be</span> | |
309 | <span class="c"># rewritten to check for OEM/Unicode strings which will be tedious. Fortunately, almost all tested CIFS services</span> | |
310 | <span class="c"># support SMB_FLAGS2_UNICODE by default.</span> | |
311 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span> <span class="o">==</span> <span class="bp">self</span> | |
312 | <span class="n">message</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">SMB_FLAGS_CASE_INSENSITIVE</span> | |
313 | <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">=</span> <span class="n">SMB_FLAGS2_UNICODE</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_NT_STATUS</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_IS_LONG_NAME</span> <span class="o">|</span> <span class="n">SMB_FLAGS2_LONG_NAMES</span> | |
314 | ||
315 | <span class="k">if</span> <span class="n">SUPPORT_EXTENDED_SECURITY</span><span class="p">:</span> | |
316 | <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">|=</span> <span class="n">SMB_FLAGS2_EXTENDED_SECURITY</span> | |
317 | ||
318 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
319 | <span class="k">raise</span> <span class="ne">NotImplementedError</span> | |
320 | ||
321 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
322 | <span class="k">raise</span> <span class="ne">NotImplementedError</span> | |
323 | ||
324 | ||
325 | <span class="k">class</span> <span class="nc">ComNegotiateRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
326 | <span class="sd">"""</span> | |
327 | <span class="sd"> References:</span> | |
328 | <span class="sd"> ===========</span> | |
329 | <span class="sd"> - [MS-CIFS]: 2.2.4.52.1</span> | |
330 | <span class="sd"> - [MS-SMB]: 2.2.4.5.1</span> | |
331 | <span class="sd"> """</span> | |
332 | ||
333 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
334 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
335 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_NEGOTIATE</span> | |
336 | ||
337 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
338 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">payload</span> <span class="o">==</span> <span class="bp">self</span> | |
339 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s">''</span> | |
340 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="s">'</span><span class="se">\x02</span><span class="s">'</span><span class="o">+</span><span class="n">s</span><span class="o">+</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">,</span> <span class="n">DIALECTS</span><span class="p">))</span> | |
341 | ||
342 | ||
343 | <span class="k">class</span> <span class="nc">ComNegotiateResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
344 | <span class="sd">"""</span> | |
345 | <span class="sd"> Contains information on the SMB_COM_NEGOTIATE response from server</span> | |
346 | ||
347 | <span class="sd"> After calling the decode method, each instance will contain the following attributes,</span> | |
348 | <span class="sd"> - security_mode (integer)</span> | |
349 | <span class="sd"> - max_mpx_count (integer)</span> | |
350 | <span class="sd"> - max_number_vcs (integer)</span> | |
351 | <span class="sd"> - max_buffer_size (long)</span> | |
352 | <span class="sd"> - max_raw_size (long)</span> | |
353 | <span class="sd"> - session_key (long)</span> | |
354 | <span class="sd"> - capabilities (long)</span> | |
355 | <span class="sd"> - system_time (long)</span> | |
356 | <span class="sd"> - server_time_zone (integer)</span> | |
357 | <span class="sd"> - challenge_length (integer)</span> | |
358 | ||
359 | <span class="sd"> If the underlying SMB message's flag2 does not have SMB_FLAGS2_EXTENDED_SECURITY bit enabled,</span> | |
360 | <span class="sd"> then the instance will have the following additional attributes,</span> | |
361 | <span class="sd"> - challenge (string)</span> | |
362 | <span class="sd"> - domain (unicode)</span> | |
363 | ||
364 | <span class="sd"> If the underlying SMB message's flags2 has SMB_FLAGS2_EXTENDED_SECURITY bit enabled,</span> | |
365 | <span class="sd"> then the instance will have the following additional attributes,</span> | |
366 | <span class="sd"> - server_guid (string)</span> | |
367 | <span class="sd"> - security_blob (string)</span> | |
368 | ||
369 | <span class="sd"> References:</span> | |
370 | <span class="sd"> ===========</span> | |
371 | <span class="sd"> - [MS-SMB]: 2.2.4.5.2.1</span> | |
372 | <span class="sd"> - [MS-CIFS]: 2.2.4.52.2</span> | |
373 | <span class="sd"> """</span> | |
374 | ||
375 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HBHHIIIIQHB'</span> | |
376 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
377 | ||
378 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
379 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_NEGOTIATE</span> | |
380 | ||
381 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">isReply</span><span class="p">:</span> | |
382 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not a SMB_COM_NEGOTIATE reply'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
383 | ||
384 | <span class="bp">self</span><span class="o">.</span><span class="n">security_mode</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_mpx_count</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_number_vcs</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_buffer_size</span><span class="p">,</span> \ | |
385 | <span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">capabilities</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">system_time</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">server_time_zone</span><span class="p">,</span> \ | |
386 | <span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span> <span class="o">=</span> <span class="p">(</span> <span class="mi">0</span><span class="p">,</span> <span class="p">)</span> <span class="o">*</span> <span class="mi">10</span> | |
387 | ||
388 | <span class="n">data_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> | |
389 | <span class="k">if</span> <span class="n">data_len</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span> | |
390 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_NEGOTIATE dialect_index field'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
391 | ||
392 | <span class="bp">self</span><span class="o">.</span><span class="n">dialect_index</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="mi">2</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span> | |
393 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">dialect_index</span> <span class="o">==</span> <span class="n">NT_LAN_MANAGER_DIALECT</span><span class="p">:</span> | |
394 | <span class="k">if</span> <span class="n">data_len</span> <span class="o">!=</span> <span class="p">(</span><span class="mh">0x11</span> <span class="o">*</span> <span class="mi">2</span><span class="p">):</span> | |
395 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'NT LAN Manager dialect selected in SMB_COM_NEGOTIATE but parameters bytes count (</span><span class="si">%d</span><span class="s">) does not meet specs'</span> <span class="o">%</span> <span class="n">data_len</span><span class="p">,</span> | |
396 | <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
397 | <span class="k">else</span><span class="p">:</span> | |
398 | <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">security_mode</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_mpx_count</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_number_vcs</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_buffer_size</span><span class="p">,</span> \ | |
399 | <span class="bp">self</span><span class="o">.</span><span class="n">max_raw_size</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">capabilities</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">system_time</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">server_time_zone</span><span class="p">,</span> \ | |
400 | <span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
401 | <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">dialect_index</span> <span class="o">==</span> <span class="mh">0xFFFF</span><span class="p">:</span> | |
402 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Server does not support any of the pysmb dialects. Please email pysmb to add in support for your OS'</span><span class="p">,</span> | |
403 | <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
404 | <span class="k">else</span><span class="p">:</span> | |
405 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Unknown dialect index (0x</span><span class="si">%04X</span><span class="s">)'</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">dialect_index</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
406 | ||
407 | <span class="n">data_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> | |
408 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span><span class="p">:</span> | |
409 | <span class="bp">self</span><span class="o">.</span><span class="n">challenge</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="s">''</span> | |
410 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
411 | <span class="k">if</span> <span class="n">data_len</span> <span class="o">>=</span> <span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span><span class="p">:</span> | |
412 | <span class="bp">self</span><span class="o">.</span><span class="n">challenge</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span><span class="p">]</span> | |
413 | ||
414 | <span class="n">s</span> <span class="o">=</span> <span class="s">''</span> | |
415 | <span class="n">offset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">challenge_length</span> | |
416 | <span class="k">while</span> <span class="n">offset</span> <span class="o"><</span> <span class="n">data_len</span><span class="p">:</span> | |
417 | <span class="n">_s</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> | |
418 | <span class="k">if</span> <span class="n">_s</span> <span class="o">==</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span><span class="p">:</span> | |
419 | <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> | |
420 | <span class="k">break</span> | |
421 | <span class="k">else</span><span class="p">:</span> | |
422 | <span class="n">s</span> <span class="o">+=</span> <span class="n">_s</span> | |
423 | <span class="n">offset</span> <span class="o">+=</span> <span class="mi">2</span> | |
424 | <span class="k">else</span><span class="p">:</span> | |
425 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_NEGOTIATE (without security extensions) Challenge field'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
426 | <span class="k">else</span><span class="p">:</span> | |
427 | <span class="k">if</span> <span class="n">data_len</span> <span class="o"><</span> <span class="mi">16</span><span class="p">:</span> | |
428 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_NEGOTIATE (with security extensions) ServerGUID field'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
429 | ||
430 | <span class="bp">self</span><span class="o">.</span><span class="n">server_guid</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[:</span><span class="mi">16</span><span class="p">]</span> | |
431 | <span class="bp">self</span><span class="o">.</span><span class="n">security_blob</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="mi">16</span><span class="p">:]</span> | |
432 | ||
433 | ||
434 | <span class="k">class</span> <span class="nc">ComSessionSetupAndxRequest__WithSecurityExtension</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
435 | <span class="sd">"""</span> | |
436 | <span class="sd"> References:</span> | |
437 | <span class="sd"> ===========</span> | |
438 | <span class="sd"> - [MS-SMB]: 2.2.4.6.1</span> | |
439 | <span class="sd"> """</span> | |
440 | ||
441 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HHHIHII'</span> | |
442 | ||
443 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session_key</span><span class="p">,</span> <span class="n">security_blob</span><span class="p">):</span> | |
444 | <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span> <span class="o">=</span> <span class="n">session_key</span> | |
445 | <span class="bp">self</span><span class="o">.</span><span class="n">security_blob</span> <span class="o">=</span> <span class="n">security_blob</span> | |
446 | ||
447 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
448 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
449 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_SESSION_SETUP_ANDX</span> | |
450 | ||
451 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
452 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span> | |
453 | ||
454 | <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">|=</span> <span class="n">SMB_FLAGS2_UNICODE</span> | |
455 | ||
456 | <span class="n">cap</span> <span class="o">=</span> <span class="n">CAP_UNICODE</span> <span class="o">|</span> <span class="n">CAP_STATUS32</span> <span class="o">|</span> <span class="n">CAP_EXTENDED_SECURITY</span> | |
457 | ||
458 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
459 | <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">+</span> \ | |
460 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
461 | <span class="mi">16644</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">security_blob</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">cap</span><span class="p">)</span> | |
462 | ||
463 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">security_blob</span> | |
464 | <span class="k">if</span> <span class="p">(</span><span class="n">SMBMessage</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
465 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
466 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> <span class="o">*</span> <span class="mi">4</span> | |
467 | ||
468 | ||
469 | <span class="k">class</span> <span class="nc">ComSessionSetupAndxRequest__NoSecurityExtension</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
470 | <span class="sd">"""</span> | |
471 | <span class="sd"> References:</span> | |
472 | <span class="sd"> ===========</span> | |
473 | <span class="sd"> - [MS-CIFS]: 2.2.4.53.1</span> | |
474 | <span class="sd"> """</span> | |
475 | ||
476 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HHHIHHII'</span> | |
477 | ||
478 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session_key</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">is_unicode</span><span class="p">,</span> <span class="n">domain</span><span class="p">):</span> | |
479 | <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span> | |
480 | <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span> <span class="o">=</span> <span class="n">session_key</span> | |
481 | <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span> | |
482 | <span class="bp">self</span><span class="o">.</span><span class="n">is_unicode</span> <span class="o">=</span> <span class="n">is_unicode</span> | |
483 | <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">domain</span> | |
484 | ||
485 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
486 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
487 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_SESSION_SETUP_ANDX</span> | |
488 | ||
489 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
490 | <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_unicode</span><span class="p">:</span> | |
491 | <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">|=</span> <span class="n">SMB_FLAGS2_UNICODE</span> | |
492 | <span class="k">else</span><span class="p">:</span> | |
493 | <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&=</span> <span class="p">(</span><span class="o">~</span><span class="n">SMB_FLAGS2_UNICODE</span> <span class="o">&</span> <span class="mh">0xFFFF</span><span class="p">)</span> | |
494 | ||
495 | <span class="n">password_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> | |
496 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
497 | <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">+</span> \ | |
498 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
499 | <span class="mi">16644</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">session_key</span><span class="p">,</span> | |
500 | <span class="p">(</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_unicode</span> <span class="ow">and</span> <span class="n">password_len</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">0</span><span class="p">,</span> | |
501 | <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">is_unicode</span> <span class="ow">and</span> <span class="n">password_len</span><span class="p">)</span> <span class="ow">or</span> <span class="mi">0</span><span class="p">,</span> | |
502 | <span class="mi">0</span><span class="p">,</span> | |
503 | <span class="n">CAP_UNICODE</span> <span class="o">|</span> <span class="n">CAP_LARGE_FILES</span> <span class="o">|</span> <span class="n">CAP_STATUS32</span><span class="p">)</span> | |
504 | ||
505 | <span class="n">est_offset</span> <span class="o">=</span> <span class="n">SMBMessage</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="c"># To check if data until SMB paramaters are aligned to a 16-bit boundary</span> | |
506 | ||
507 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span> | |
508 | <span class="k">if</span> <span class="p">(</span><span class="n">est_offset</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span> | |
509 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
510 | ||
511 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span> | |
512 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
513 | <span class="k">else</span><span class="p">:</span> | |
514 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
515 | ||
516 | <span class="k">if</span> <span class="p">(</span><span class="n">est_offset</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span> | |
517 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
518 | ||
519 | <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">flags2</span> <span class="o">&</span> <span class="n">SMB_FLAGS2_UNICODE</span><span class="p">:</span> | |
520 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> <span class="o">+</span> <span class="s">'pysmb'</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> | |
521 | <span class="k">else</span><span class="p">:</span> | |
522 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">pysmb</span><span class="se">\0</span><span class="s">'</span> | |
523 | ||
524 | ||
525 | <span class="k">class</span> <span class="nc">ComSessionSetupAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
526 | <span class="sd">"""</span> | |
527 | <span class="sd"> Contains information on the SMB_COM_SESSION_SETUP_ANDX response from server</span> | |
528 | ||
529 | <span class="sd"> If the underlying SMB message's flags2 does not have SMB_FLAGS2_EXTENDED_SECURITY bit enabled,</span> | |
530 | <span class="sd"> then the instance will have the following attributes,</span> | |
531 | <span class="sd"> - action</span> | |
532 | ||
533 | <span class="sd"> If the underlying SMB message's flags2 has SMB_FLAGS2_EXTENDED_SECURITY bit enabled</span> | |
534 | <span class="sd"> and the message status is STATUS_MORE_PROCESSING_REQUIRED or equals to 0x00 (no error),</span> | |
535 | <span class="sd"> then the instance will have the following attributes,</span> | |
536 | <span class="sd"> - action</span> | |
537 | <span class="sd"> - securityblob</span> | |
538 | ||
539 | <span class="sd"> If the underlying SMB message's flags2 has SMB_FLAGS2_EXTENDED_SECURITY bit enabled but</span> | |
540 | <span class="sd"> the message status is not STATUS_MORE_PROCESSING_REQUIRED</span> | |
541 | ||
542 | <span class="sd"> References:</span> | |
543 | <span class="sd"> ===========</span> | |
544 | <span class="sd"> - [MS-SMB]: 2.2.4.6.2</span> | |
545 | <span class="sd"> - [MS-CIFS]: 2.2.4.53.2</span> | |
546 | <span class="sd"> """</span> | |
547 | ||
548 | <span class="n">NOSECURE_PARAMETER_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BBHH'</span> | |
549 | <span class="n">NOSECURE_PARAMETER_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">NOSECURE_PARAMETER_STRUCT_FORMAT</span><span class="p">)</span> | |
550 | ||
551 | <span class="n">SECURE_PARAMETER_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BBHHH'</span> | |
552 | <span class="n">SECURE_PARAMETER_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">SECURE_PARAMETER_STRUCT_FORMAT</span><span class="p">)</span> | |
553 | ||
554 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
555 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_SESSION_SETUP_ANDX</span> | |
556 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">hasExtendedSecurity</span><span class="p">:</span> | |
557 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
558 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">NOSECURE_PARAMETER_STRUCT_SIZE</span><span class="p">:</span> | |
559 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_SESSION_SETUP_ANDX (no security extensions) parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
560 | ||
561 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">action</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">NOSECURE_PARAMETER_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">NOSECURE_PARAMETER_STRUCT_SIZE</span><span class="p">])</span> | |
562 | <span class="k">else</span><span class="p">:</span> | |
563 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span> <span class="ow">or</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">internal_value</span> <span class="o">==</span> <span class="mh">0xc0000016</span><span class="p">:</span> <span class="c"># STATUS_MORE_PROCESSING_REQUIRED</span> | |
564 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">SECURE_PARAMETER_STRUCT_SIZE</span><span class="p">:</span> | |
565 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_SESSION_SETUP_ANDX (with security extensions) parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
566 | ||
567 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">action</span><span class="p">,</span> <span class="n">blob_length</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">SECURE_PARAMETER_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">SECURE_PARAMETER_STRUCT_SIZE</span><span class="p">])</span> | |
568 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> <span class="o"><</span> <span class="n">blob_length</span><span class="p">:</span> | |
569 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_SESSION_SETUP_ANDX (with security extensions) security blob'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
570 | ||
571 | <span class="bp">self</span><span class="o">.</span><span class="n">security_blob</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[:</span><span class="n">blob_length</span><span class="p">]</span> | |
572 | ||
573 | ||
574 | <span class="k">class</span> <span class="nc">ComTreeConnectAndxRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
575 | <span class="sd">"""</span> | |
576 | <span class="sd"> References:</span> | |
577 | <span class="sd"> ===========</span> | |
578 | <span class="sd"> - [MS-CIFS]: 2.2.4.55.1</span> | |
579 | <span class="sd"> """</span> | |
580 | ||
581 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HH'</span> | |
582 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
583 | ||
584 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">service</span><span class="p">,</span> <span class="n">password</span> <span class="o">=</span> <span class="s">''</span><span class="p">):</span> | |
585 | <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span> | |
586 | <span class="bp">self</span><span class="o">.</span><span class="n">service</span> <span class="o">=</span> <span class="n">service</span> | |
587 | <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
588 | ||
589 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
590 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
591 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_TREE_CONNECT_ANDX</span> | |
592 | ||
593 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
594 | <span class="n">password_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> | |
595 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
596 | <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">+</span> \ | |
597 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
598 | <span class="mh">0x08</span> <span class="o">|</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">tid</span> <span class="ow">and</span> <span class="mh">0x0001</span><span class="p">)</span> <span class="ow">or</span> <span class="mh">0x00</span><span class="p">,</span> <span class="c"># Disconnect tid, if message.tid must be non-zero</span> | |
599 | <span class="n">password_len</span><span class="p">)</span> | |
600 | ||
601 | <span class="n">padding</span> <span class="o">=</span> <span class="s">''</span> | |
602 | <span class="k">if</span> <span class="n">password_len</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> | |
603 | <span class="n">padding</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
604 | ||
605 | <span class="c"># Note that service field is never encoded in UTF-16LE. [MS-CIFS]: 2.2.1.1</span> | |
606 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">+</span> <span class="n">padding</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">service</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
607 | ||
608 | ||
609 | <span class="k">class</span> <span class="nc">ComTreeConnectAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
610 | <span class="sd">"""</span> | |
611 | <span class="sd"> Contains information about the SMB_COM_TREE_CONNECT_ANDX response from the server.</span> | |
612 | ||
613 | <span class="sd"> If the message has no errors, each instance contains the following attributes:</span> | |
614 | <span class="sd"> - optional_support</span> | |
615 | ||
616 | <span class="sd"> References:</span> | |
617 | <span class="sd"> ===========</span> | |
618 | <span class="sd"> - [MS-CIFS]: 2.2.4.55.2</span> | |
619 | <span class="sd"> """</span> | |
620 | ||
621 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BBHH'</span> | |
622 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
623 | ||
624 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
625 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TREE_CONNECT_ANDX</span> | |
626 | ||
627 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
628 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span> | |
629 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_TREE_CONNECT_ANDX parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
630 | ||
631 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">optional_support</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
632 | ||
633 | ||
634 | <span class="k">class</span> <span class="nc">ComNTCreateAndxRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
635 | <span class="sd">"""</span> | |
636 | <span class="sd"> References:</span> | |
637 | <span class="sd"> ===========</span> | |
638 | <span class="sd"> - [MS-CIFS]: 2.2.4.64.1</span> | |
639 | <span class="sd"> - [MS-SMB]: 2.2.4.9.1</span> | |
640 | <span class="sd"> """</span> | |
641 | ||
642 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BHIIIQIIIIIB'</span> | |
643 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
644 | ||
645 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">root_fid</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">access_mask</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">allocation_size</span> <span class="o">=</span> <span class="il">0L</span><span class="p">,</span> <span class="n">ext_attr</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
646 | <span class="n">share_access</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">create_disp</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">create_options</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">impersonation</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">security_flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
647 | <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="p">(</span><span class="n">filename</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> | |
648 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span> | |
649 | <span class="bp">self</span><span class="o">.</span><span class="n">root_fid</span> <span class="o">=</span> <span class="n">root_fid</span> | |
650 | <span class="bp">self</span><span class="o">.</span><span class="n">access_mask</span> <span class="o">=</span> <span class="n">access_mask</span> | |
651 | <span class="bp">self</span><span class="o">.</span><span class="n">allocation_size</span> <span class="o">=</span> <span class="n">allocation_size</span> | |
652 | <span class="bp">self</span><span class="o">.</span><span class="n">ext_attr</span> <span class="o">=</span> <span class="n">ext_attr</span> | |
653 | <span class="bp">self</span><span class="o">.</span><span class="n">share_access</span> <span class="o">=</span> <span class="n">share_access</span> | |
654 | <span class="bp">self</span><span class="o">.</span><span class="n">create_disp</span> <span class="o">=</span> <span class="n">create_disp</span> | |
655 | <span class="bp">self</span><span class="o">.</span><span class="n">create_options</span> <span class="o">=</span> <span class="n">create_options</span> | |
656 | <span class="bp">self</span><span class="o">.</span><span class="n">impersonation</span> <span class="o">=</span> <span class="n">impersonation</span> | |
657 | <span class="bp">self</span><span class="o">.</span><span class="n">security_flags</span> <span class="o">=</span> <span class="n">security_flags</span> | |
658 | ||
659 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
660 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
661 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_NT_CREATE_ANDX</span> | |
662 | ||
663 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
664 | <span class="n">filename_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span> | |
665 | ||
666 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
667 | <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">+</span> \ | |
668 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
669 | <span class="mh">0x00</span><span class="p">,</span> <span class="c"># reserved</span> | |
670 | <span class="n">filename_len</span><span class="p">,</span> <span class="c"># NameLength</span> | |
671 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> <span class="c"># Flags</span> | |
672 | <span class="bp">self</span><span class="o">.</span><span class="n">root_fid</span><span class="p">,</span> <span class="c"># RootDirectoryFID</span> | |
673 | <span class="bp">self</span><span class="o">.</span><span class="n">access_mask</span><span class="p">,</span> <span class="c"># DesiredAccess</span> | |
674 | <span class="bp">self</span><span class="o">.</span><span class="n">allocation_size</span><span class="p">,</span> <span class="c"># AllocationSize</span> | |
675 | <span class="bp">self</span><span class="o">.</span><span class="n">ext_attr</span><span class="p">,</span> <span class="c"># ExtFileAttributes</span> | |
676 | <span class="bp">self</span><span class="o">.</span><span class="n">share_access</span><span class="p">,</span> <span class="c"># ShareAccess</span> | |
677 | <span class="bp">self</span><span class="o">.</span><span class="n">create_disp</span><span class="p">,</span> <span class="c"># CreateDisposition</span> | |
678 | <span class="bp">self</span><span class="o">.</span><span class="n">create_options</span><span class="p">,</span> <span class="c"># CreateOptions</span> | |
679 | <span class="bp">self</span><span class="o">.</span><span class="n">impersonation</span><span class="p">,</span> <span class="c"># ImpersonationLevel</span> | |
680 | <span class="bp">self</span><span class="o">.</span><span class="n">security_flags</span><span class="p">)</span> <span class="c"># SecurityFlags</span> | |
681 | ||
682 | <span class="n">padding</span> <span class="o">=</span> <span class="s">''</span> | |
683 | <span class="k">if</span> <span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">))</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
684 | <span class="n">padding</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
685 | ||
686 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">padding</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> | |
687 | ||
688 | ||
689 | <span class="k">class</span> <span class="nc">ComNTCreateAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
690 | <span class="sd">"""</span> | |
691 | <span class="sd"> Contains (partial) information about the SMB_COM_NT_CREATE_ANDX response from the server.</span> | |
692 | ||
693 | <span class="sd"> Each instance contains the following attributes after decoding:</span> | |
694 | <span class="sd"> - oplock_level</span> | |
695 | <span class="sd"> - fid</span> | |
696 | ||
697 | <span class="sd"> References:</span> | |
698 | <span class="sd"> ===========</span> | |
699 | <span class="sd"> - [MS-CIFS]: 2.2.4.64.2</span> | |
700 | <span class="sd"> """</span> | |
701 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BBHBH'</span> | |
702 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
703 | ||
704 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
705 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_NT_CREATE_ANDX</span> | |
706 | ||
707 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
708 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span> | |
709 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_NT_CREATE_ANDX parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
710 | ||
711 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">oplock_level</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fid</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
712 | ||
713 | ||
714 | <span class="k">class</span> <span class="nc">ComTransactionRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
715 | <span class="sd">"""</span> | |
716 | <span class="sd"> References:</span> | |
717 | <span class="sd"> ===========</span> | |
718 | <span class="sd"> - [MS-CIFS]: 2.2.4.33.1</span> | |
719 | <span class="sd"> """</span> | |
720 | ||
721 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HHHHBBHIHHHHHH'</span> | |
722 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
723 | ||
724 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span> | |
725 | <span class="n">total_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">total_data_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
726 | <span class="n">params_bytes</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> | |
727 | <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"</span><span class="se">\\</span><span class="s">PIPE</span><span class="se">\\</span><span class="s">"</span><span class="p">):</span> | |
728 | <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span> <span class="o">=</span> <span class="n">total_params_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">params_bytes</span><span class="p">)</span> | |
729 | <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span> <span class="o">=</span> <span class="n">total_data_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span> | |
730 | <span class="bp">self</span><span class="o">.</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="n">max_params_count</span> | |
731 | <span class="bp">self</span><span class="o">.</span><span class="n">max_data_count</span> <span class="o">=</span> <span class="n">max_data_count</span> | |
732 | <span class="bp">self</span><span class="o">.</span><span class="n">max_setup_count</span> <span class="o">=</span> <span class="n">max_setup_count</span> | |
733 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span> | |
734 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span> | |
735 | <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="n">params_bytes</span> | |
736 | <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span> | |
737 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">setup_bytes</span> | |
738 | <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span> | |
739 | ||
740 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
741 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
742 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_TRANSACTION</span> | |
743 | ||
744 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
745 | <span class="n">name</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> | |
746 | <span class="n">name_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> | |
747 | <span class="n">setup_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span><span class="p">)</span> | |
748 | <span class="n">params_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">)</span> | |
749 | <span class="n">data_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span> | |
750 | ||
751 | <span class="n">padding0</span> <span class="o">=</span> <span class="s">''</span> | |
752 | <span class="n">offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_bytes_len</span> <span class="o">+</span> <span class="mi">2</span> <span class="c"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span> | |
753 | <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
754 | <span class="n">padding0</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
755 | <span class="n">offset</span> <span class="o">+=</span> <span class="mi">1</span> | |
756 | ||
757 | <span class="n">offset</span> <span class="o">+=</span> <span class="n">name_len</span> <span class="c"># For the name field</span> | |
758 | <span class="n">padding1</span> <span class="o">=</span> <span class="s">''</span> | |
759 | <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
760 | <span class="n">padding1</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span> | |
761 | <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span> | |
762 | ||
763 | <span class="k">if</span> <span class="n">params_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
764 | <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="n">offset</span> | |
765 | <span class="n">offset</span> <span class="o">+=</span> <span class="n">params_bytes_len</span> | |
766 | <span class="k">else</span><span class="p">:</span> | |
767 | <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="mi">0</span> | |
768 | ||
769 | <span class="n">padding2</span> <span class="o">=</span> <span class="s">''</span> | |
770 | <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
771 | <span class="n">padding2</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span> | |
772 | <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span> | |
773 | ||
774 | <span class="k">if</span> <span class="n">data_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
775 | <span class="n">data_bytes_offset</span> <span class="o">=</span> <span class="n">offset</span> | |
776 | <span class="k">else</span><span class="p">:</span> | |
777 | <span class="n">data_bytes_offset</span> <span class="o">=</span> <span class="mi">0</span> | |
778 | ||
779 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
780 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
781 | <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span><span class="p">,</span> | |
782 | <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span> | |
783 | <span class="bp">self</span><span class="o">.</span><span class="n">max_params_count</span><span class="p">,</span> | |
784 | <span class="bp">self</span><span class="o">.</span><span class="n">max_data_count</span><span class="p">,</span> | |
785 | <span class="bp">self</span><span class="o">.</span><span class="n">max_setup_count</span><span class="p">,</span> | |
786 | <span class="mh">0x00</span><span class="p">,</span> <span class="c"># Reserved1. Must be 0x00</span> | |
787 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> | |
788 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">,</span> | |
789 | <span class="mh">0x0000</span><span class="p">,</span> <span class="c"># Reserved2. Must be 0x0000</span> | |
790 | <span class="n">params_bytes_len</span><span class="p">,</span> | |
791 | <span class="n">params_bytes_offset</span><span class="p">,</span> | |
792 | <span class="n">data_bytes_len</span><span class="p">,</span> | |
793 | <span class="n">data_bytes_offset</span><span class="p">,</span> | |
794 | <span class="nb">int</span><span class="p">(</span><span class="n">setup_bytes_len</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span> <span class="o">+</span> \ | |
795 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> | |
796 | ||
797 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">padding0</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="n">padding1</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">+</span> <span class="n">padding2</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> | |
798 | ||
799 | ||
800 | <span class="k">class</span> <span class="nc">ComTransactionResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
801 | <span class="sd">"""</span> | |
802 | <span class="sd"> Contains information about a SMB_COM_TRANSACTION response from the server</span> | |
803 | ||
804 | <span class="sd"> After decoding, each instance contains the following attributes:</span> | |
805 | <span class="sd"> - total_params_count (integer)</span> | |
806 | <span class="sd"> - total_data_count (integer)</span> | |
807 | <span class="sd"> - setup_bytes (string)</span> | |
808 | <span class="sd"> - data_bytes (string)</span> | |
809 | <span class="sd"> - params_bytes (string)</span> | |
810 | ||
811 | <span class="sd"> References:</span> | |
812 | <span class="sd"> ===========</span> | |
813 | <span class="sd"> - [MS-CIFS]: 2.2.4.33.2</span> | |
814 | <span class="sd"> """</span> | |
815 | ||
816 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HHHHHHHHHH'</span> | |
817 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
818 | ||
819 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
820 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TRANSACTION</span> | |
821 | ||
822 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
823 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span> | |
824 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_TRANSACTION parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
825 | ||
826 | <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> \ | |
827 | <span class="n">params_bytes_len</span><span class="p">,</span> <span class="n">params_bytes_offset</span><span class="p">,</span> <span class="n">params_bytes_displ</span><span class="p">,</span> \ | |
828 | <span class="n">data_bytes_len</span><span class="p">,</span> <span class="n">data_bytes_offset</span><span class="p">,</span> <span class="n">data_bytes_displ</span><span class="p">,</span> \ | |
829 | <span class="n">setup_count</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
830 | ||
831 | <span class="k">if</span> <span class="n">setup_count</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
832 | <span class="n">setup_bytes_len</span> <span class="o">=</span> <span class="n">setup_count</span> <span class="o">*</span> <span class="mi">2</span> | |
833 | ||
834 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_bytes_len</span><span class="p">:</span> | |
835 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_TRANSACTION parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
836 | ||
837 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="o">+</span><span class="n">setup_bytes_len</span><span class="p">]</span> | |
838 | <span class="k">else</span><span class="p">:</span> | |
839 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> <span class="o">=</span> <span class="s">''</span> | |
840 | ||
841 | <span class="n">offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_count</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span> <span class="c"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span> | |
842 | ||
843 | <span class="k">if</span> <span class="n">params_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
844 | <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">params_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="p">:</span><span class="n">params_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="o">+</span><span class="n">params_bytes_len</span><span class="p">]</span> | |
845 | <span class="k">else</span><span class="p">:</span> | |
846 | <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="s">''</span> | |
847 | ||
848 | <span class="k">if</span> <span class="n">data_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
849 | <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">data_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="p">:</span><span class="n">data_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="o">+</span><span class="n">data_bytes_len</span><span class="p">]</span> | |
850 | <span class="k">else</span><span class="p">:</span> | |
851 | <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="s">''</span> | |
852 | ||
853 | ||
854 | <span class="k">class</span> <span class="nc">ComTransaction2Request</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
855 | <span class="sd">"""</span> | |
856 | <span class="sd"> References:</span> | |
857 | <span class="sd"> ===========</span> | |
858 | <span class="sd"> - [MS-CIFS]: 2.2.4.46.1</span> | |
859 | <span class="sd"> """</span> | |
860 | ||
861 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'HHHHBBHIHHHHHH'</span> | |
862 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
863 | ||
864 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_params_count</span><span class="p">,</span> <span class="n">max_data_count</span><span class="p">,</span> <span class="n">max_setup_count</span><span class="p">,</span> | |
865 | <span class="n">total_params_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">total_data_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> | |
866 | <span class="n">params_bytes</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">data_bytes</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">setup_bytes</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> | |
867 | <span class="n">flags</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
868 | <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span> <span class="o">=</span> <span class="n">total_params_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">params_bytes</span><span class="p">)</span> | |
869 | <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span> <span class="o">=</span> <span class="n">total_data_count</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_bytes</span><span class="p">)</span> | |
870 | <span class="bp">self</span><span class="o">.</span><span class="n">max_params_count</span> <span class="o">=</span> <span class="n">max_params_count</span> | |
871 | <span class="bp">self</span><span class="o">.</span><span class="n">max_data_count</span> <span class="o">=</span> <span class="n">max_data_count</span> | |
872 | <span class="bp">self</span><span class="o">.</span><span class="n">max_setup_count</span> <span class="o">=</span> <span class="n">max_setup_count</span> | |
873 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span> | |
874 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span> | |
875 | <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="n">params_bytes</span> | |
876 | <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span> | |
877 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">setup_bytes</span> | |
878 | ||
879 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
880 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
881 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_TRANSACTION2</span> | |
882 | ||
883 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
884 | <span class="n">setup_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span><span class="p">)</span> | |
885 | <span class="n">params_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span><span class="p">)</span> | |
886 | <span class="n">data_bytes_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span> | |
887 | <span class="n">name</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> | |
888 | ||
889 | <span class="n">padding0</span> <span class="o">=</span> <span class="s">''</span> | |
890 | <span class="n">offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_bytes_len</span> <span class="o">+</span> <span class="mi">2</span> <span class="c"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span> | |
891 | <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
892 | <span class="n">padding0</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> | |
893 | <span class="n">offset</span> <span class="o">+=</span> <span class="mi">1</span> | |
894 | ||
895 | <span class="n">offset</span> <span class="o">+=</span> <span class="mi">2</span> <span class="c"># For the name field</span> | |
896 | <span class="n">padding1</span> <span class="o">=</span> <span class="s">''</span> | |
897 | <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
898 | <span class="n">padding1</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span> | |
899 | ||
900 | <span class="k">if</span> <span class="n">params_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
901 | <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="n">offset</span> | |
902 | <span class="n">offset</span> <span class="o">+=</span> <span class="n">params_bytes_len</span> | |
903 | <span class="k">else</span><span class="p">:</span> | |
904 | <span class="n">params_bytes_offset</span> <span class="o">=</span> <span class="mi">0</span> | |
905 | ||
906 | <span class="n">padding2</span> <span class="o">=</span> <span class="s">''</span> | |
907 | <span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="mi">4</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |
908 | <span class="n">padding2</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span><span class="o">*</span><span class="p">(</span><span class="mi">4</span><span class="o">-</span><span class="n">offset</span><span class="o">%</span><span class="mi">4</span><span class="p">)</span> | |
909 | ||
910 | <span class="k">if</span> <span class="n">data_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
911 | <span class="n">data_bytes_offset</span> <span class="o">=</span> <span class="n">offset</span> | |
912 | <span class="k">else</span><span class="p">:</span> | |
913 | <span class="n">data_bytes_offset</span> <span class="o">=</span> <span class="mi">0</span> | |
914 | ||
915 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
916 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
917 | <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span><span class="p">,</span> | |
918 | <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span> | |
919 | <span class="bp">self</span><span class="o">.</span><span class="n">max_params_count</span><span class="p">,</span> | |
920 | <span class="bp">self</span><span class="o">.</span><span class="n">max_data_count</span><span class="p">,</span> | |
921 | <span class="bp">self</span><span class="o">.</span><span class="n">max_setup_count</span><span class="p">,</span> | |
922 | <span class="mh">0x00</span><span class="p">,</span> <span class="c"># Reserved1. Must be 0x00</span> | |
923 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> | |
924 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">,</span> | |
925 | <span class="mh">0x0000</span><span class="p">,</span> <span class="c"># Reserved2. Must be 0x0000</span> | |
926 | <span class="n">params_bytes_len</span><span class="p">,</span> | |
927 | <span class="n">params_bytes_offset</span><span class="p">,</span> | |
928 | <span class="n">data_bytes_len</span><span class="p">,</span> | |
929 | <span class="n">data_bytes_offset</span><span class="p">,</span> | |
930 | <span class="nb">int</span><span class="p">(</span><span class="n">setup_bytes_len</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span> <span class="o">+</span> \ | |
931 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> | |
932 | ||
933 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">padding0</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="n">padding1</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">+</span> <span class="n">padding2</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> | |
934 | ||
935 | ||
936 | <span class="k">class</span> <span class="nc">ComTransaction2Response</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
937 | <span class="sd">"""</span> | |
938 | <span class="sd"> Contains information about a SMB_COM_TRANSACTION2 response from the server</span> | |
939 | ||
940 | <span class="sd"> After decoding, each instance contains the following attributes:</span> | |
941 | <span class="sd"> - total_params_count (integer)</span> | |
942 | <span class="sd"> - total_data_count (integer)</span> | |
943 | <span class="sd"> - setup_bytes (string)</span> | |
944 | <span class="sd"> - data_bytes (string)</span> | |
945 | <span class="sd"> - params_bytes (string)</span> | |
946 | ||
947 | <span class="sd"> References:</span> | |
948 | <span class="sd"> ===========</span> | |
949 | <span class="sd"> - [MS-CIFS]: 2.2.4.46.2</span> | |
950 | <span class="sd"> """</span> | |
951 | ||
952 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HHHHHHHHHBB'</span> | |
953 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
954 | ||
955 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
956 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_TRANSACTION2</span> | |
957 | ||
958 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
959 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span> | |
960 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_TRANSACTION2 parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
961 | ||
962 | <span class="bp">self</span><span class="o">.</span><span class="n">total_params_count</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">total_data_count</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> \ | |
963 | <span class="n">params_bytes_len</span><span class="p">,</span> <span class="n">params_bytes_offset</span><span class="p">,</span> <span class="n">params_bytes_displ</span><span class="p">,</span> \ | |
964 | <span class="n">data_bytes_len</span><span class="p">,</span> <span class="n">data_bytes_offset</span><span class="p">,</span> <span class="n">data_bytes_displ</span><span class="p">,</span> \ | |
965 | <span class="n">setup_count</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
966 | ||
967 | <span class="k">if</span> <span class="n">setup_count</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
968 | <span class="n">setup_bytes_len</span> <span class="o">=</span> <span class="n">setup_count</span> <span class="o">*</span> <span class="mi">2</span> | |
969 | ||
970 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_bytes_len</span><span class="p">:</span> | |
971 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_TRANSACTION parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
972 | ||
973 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="o">+</span><span class="n">setup_bytes_len</span><span class="p">]</span> | |
974 | <span class="k">else</span><span class="p">:</span> | |
975 | <span class="bp">self</span><span class="o">.</span><span class="n">setup_bytes</span> <span class="o">=</span> <span class="s">''</span> | |
976 | ||
977 | <span class="n">offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="n">setup_count</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span> <span class="c"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span> | |
978 | ||
979 | <span class="k">if</span> <span class="n">params_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
980 | <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">params_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="p">:</span><span class="n">params_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="o">+</span><span class="n">params_bytes_len</span><span class="p">]</span> | |
981 | <span class="k">else</span><span class="p">:</span> | |
982 | <span class="bp">self</span><span class="o">.</span><span class="n">params_bytes</span> <span class="o">=</span> <span class="s">''</span> | |
983 | ||
984 | <span class="k">if</span> <span class="n">data_bytes_len</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |
985 | <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">data_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="p">:</span><span class="n">data_bytes_offset</span><span class="o">-</span><span class="n">offset</span><span class="o">+</span><span class="n">data_bytes_len</span><span class="p">]</span> | |
986 | <span class="k">else</span><span class="p">:</span> | |
987 | <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="s">''</span> | |
988 | ||
989 | ||
990 | <span class="k">class</span> <span class="nc">ComCloseRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
991 | <span class="sd">"""</span> | |
992 | <span class="sd"> References:</span> | |
993 | <span class="sd"> ===========</span> | |
994 | <span class="sd"> - [MS-CIFS]: 2.2.4.5.1</span> | |
995 | <span class="sd"> """</span> | |
996 | ||
997 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HI'</span> | |
998 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
999 | ||
1000 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">last_modified_time</span> <span class="o">=</span> <span class="mh">0xFFFFFFFF</span><span class="p">):</span> | |
1001 | <span class="bp">self</span><span class="o">.</span><span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span> | |
1002 | <span class="bp">self</span><span class="o">.</span><span class="n">last_modified_time</span> <span class="o">=</span> <span class="n">last_modified_time</span> | |
1003 | ||
1004 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1005 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1006 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_CLOSE</span> | |
1007 | ||
1008 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1009 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_modified_time</span><span class="p">)</span> | |
1010 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">''</span> | |
1011 | ||
1012 | ||
1013 | <span class="k">class</span> <span class="nc">ComOpenAndxRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1014 | <span class="sd">"""</span> | |
1015 | <span class="sd"> References:</span> | |
1016 | <span class="sd"> ===========</span> | |
1017 | <span class="sd"> - [MS-CIFS]: 2.2.4.41.1</span> | |
1018 | <span class="sd"> """</span> | |
1019 | ||
1020 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HHHHIHIII'</span> | |
1021 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
1022 | ||
1023 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">access_mode</span><span class="p">,</span> <span class="n">open_mode</span><span class="p">,</span> <span class="n">flags</span> <span class="o">=</span> <span class="mh">0x0000</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">file_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">create_time</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
1024 | <span class="sd">"""</span> | |
1025 | <span class="sd"> @param create_time: Epoch time value to indicate the time of creation for this file. If zero, we will automatically assign the current time</span> | |
1026 | <span class="sd"> @type create_time: int</span> | |
1027 | <span class="sd"> @param timeout: Number of milliseconds to wait for blocked open request before failing</span> | |
1028 | <span class="sd"> @type timeout: int</span> | |
1029 | <span class="sd"> """</span> | |
1030 | <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span> | |
1031 | <span class="bp">self</span><span class="o">.</span><span class="n">access_mode</span> <span class="o">=</span> <span class="n">access_mode</span> | |
1032 | <span class="bp">self</span><span class="o">.</span><span class="n">open_mode</span> <span class="o">=</span> <span class="n">open_mode</span> | |
1033 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span> | |
1034 | <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span> <span class="o">=</span> <span class="n">search_attributes</span> | |
1035 | <span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span> <span class="o">=</span> <span class="n">file_attributes</span> | |
1036 | <span class="bp">self</span><span class="o">.</span><span class="n">create_time</span> <span class="o">=</span> <span class="n">create_time</span> <span class="ow">or</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> | |
1037 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span> | |
1038 | ||
1039 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1040 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1041 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_OPEN_ANDX</span> | |
1042 | ||
1043 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1044 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
1045 | <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">+</span> \ | |
1046 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
1047 | <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">,</span> | |
1048 | <span class="bp">self</span><span class="o">.</span><span class="n">access_mode</span><span class="p">,</span> | |
1049 | <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span><span class="p">,</span> | |
1050 | <span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">,</span> | |
1051 | <span class="bp">self</span><span class="o">.</span><span class="n">create_time</span><span class="p">,</span> | |
1052 | <span class="bp">self</span><span class="o">.</span><span class="n">open_mode</span><span class="p">,</span> | |
1053 | <span class="mi">0</span><span class="p">,</span> <span class="c"># AllocationSize</span> | |
1054 | <span class="mi">0</span><span class="p">,</span> <span class="c"># Timeout (in milli-secs)</span> | |
1055 | <span class="mi">0</span><span class="p">)</span> <span class="c"># Reserved</span> | |
1056 | ||
1057 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> | |
1058 | ||
1059 | ||
1060 | <span class="k">class</span> <span class="nc">ComOpenAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1061 | <span class="sd">"""</span> | |
1062 | <span class="sd"> Contains information about a SMB_COM_OPEN_ANDX response from the server</span> | |
1063 | ||
1064 | <span class="sd"> After decoding, each instance will contain the following attributes:</span> | |
1065 | <span class="sd"> - fid (integer)</span> | |
1066 | <span class="sd"> - file_attributes (integer)</span> | |
1067 | <span class="sd"> - last_write_time (long)</span> | |
1068 | <span class="sd"> - access_rights (integer)</span> | |
1069 | <span class="sd"> - resource_type (integer)</span> | |
1070 | <span class="sd"> - open_results (integer)</span> | |
1071 | ||
1072 | <span class="sd"> References:</span> | |
1073 | <span class="sd"> ===========</span> | |
1074 | <span class="sd"> - [MS-CIFS]: 2.2.4.41.2</span> | |
1075 | <span class="sd"> - [MS-SMB]: 2.2.4.1.2</span> | |
1076 | <span class="sd"> """</span> | |
1077 | ||
1078 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BBHHHIIHHHHHHH'</span> | |
1079 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
1080 | ||
1081 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1082 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_OPEN_ANDX</span> | |
1083 | ||
1084 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
1085 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span> | |
1086 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_OPEN_ANDX parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1087 | ||
1088 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_attributes</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_write_time</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> \ | |
1089 | <span class="bp">self</span><span class="o">.</span><span class="n">access_rights</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">resource_type</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">open_results</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
1090 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
1091 | ||
1092 | ||
1093 | <span class="k">class</span> <span class="nc">ComWriteAndxRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1094 | <span class="sd">"""</span> | |
1095 | <span class="sd"> References:</span> | |
1096 | <span class="sd"> ===========</span> | |
1097 | <span class="sd"> - [MS-CIFS]: 2.2.4.43.1</span> | |
1098 | <span class="sd"> - [MS-SMB]: 2.2.4.3.1</span> | |
1099 | <span class="sd"> """</span> | |
1100 | ||
1101 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HIIHHHHHI'</span> | |
1102 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
1103 | ||
1104 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">data_bytes</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">write_mode</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
1105 | <span class="sd">"""</span> | |
1106 | <span class="sd"> @param timeout: Number of milliseconds to wait for blocked write request before failing. Must be zero for writing to regular file</span> | |
1107 | <span class="sd"> @type timeout: int</span> | |
1108 | <span class="sd"> """</span> | |
1109 | <span class="bp">self</span><span class="o">.</span><span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span> | |
1110 | <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span> | |
1111 | <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> <span class="o">=</span> <span class="n">data_bytes</span> | |
1112 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span> | |
1113 | <span class="bp">self</span><span class="o">.</span><span class="n">write_mode</span> <span class="o">=</span> <span class="n">write_mode</span> | |
1114 | ||
1115 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1116 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1117 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_WRITE_ANDX</span> | |
1118 | ||
1119 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1120 | <span class="c"># constant 1 is to account for the pad byte in the message.data</span> | |
1121 | <span class="c"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span> | |
1122 | <span class="n">data_offset</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_SIZE</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span> | |
1123 | <span class="n">data_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">)</span> | |
1124 | ||
1125 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
1126 | <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">+</span> \ | |
1127 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
1128 | <span class="bp">self</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> | |
1129 | <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">&</span> <span class="mh">0xFFFFFFFF</span><span class="p">,</span> | |
1130 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span><span class="p">,</span> | |
1131 | <span class="bp">self</span><span class="o">.</span><span class="n">write_mode</span><span class="p">,</span> | |
1132 | <span class="n">data_len</span><span class="p">,</span> <span class="c"># Remaining</span> | |
1133 | <span class="mh">0x0000</span><span class="p">,</span> <span class="c"># Reserved</span> | |
1134 | <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span><span class="p">),</span> <span class="c"># DataLength</span> | |
1135 | <span class="n">data_offset</span><span class="p">,</span> <span class="c"># DataOffset</span> | |
1136 | <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">>></span> <span class="mi">32</span><span class="p">)</span> <span class="c"># OffsetHigh field defined in [MS-SMB]: 2.2.4.3.1</span> | |
1137 | ||
1138 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">'</span><span class="se">\0</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_bytes</span> | |
1139 | ||
1140 | ||
1141 | <span class="k">class</span> <span class="nc">ComWriteAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1142 | <span class="sd">"""</span> | |
1143 | <span class="sd"> References:</span> | |
1144 | <span class="sd"> ===========</span> | |
1145 | <span class="sd"> - [MS-CIFS]: 2.2.4.43.2</span> | |
1146 | <span class="sd"> - [MS-SMB]: 2.2.4.3.2</span> | |
1147 | <span class="sd"> """</span> | |
1148 | ||
1149 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BBHHHHH'</span> <span class="c"># We follow the SMB_COM_WRITEX_ANDX server extensions in [MS-SMB]: 2.2.4.3.2</span> | |
1150 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
1151 | ||
1152 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1153 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_WRITE_ANDX</span> | |
1154 | ||
1155 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
1156 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span> | |
1157 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_WRITE_ANDX parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1158 | ||
1159 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">available</span><span class="p">,</span> <span class="n">high_count</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
1160 | <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="p">(</span><span class="n">count</span> <span class="o">&</span> <span class="mh">0xFFFF</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">high_count</span> <span class="o"><<</span> <span class="mi">16</span><span class="p">)</span> | |
1161 | ||
1162 | ||
1163 | <span class="k">class</span> <span class="nc">ComReadAndxRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1164 | <span class="sd">"""</span> | |
1165 | <span class="sd"> References:</span> | |
1166 | <span class="sd"> ===========</span> | |
1167 | <span class="sd"> - [MS-CIFS]: 2.2.4.42.1</span> | |
1168 | <span class="sd"> - [MS-SMB]: 2.2.4.2.1</span> | |
1169 | <span class="sd"> """</span> | |
1170 | ||
1171 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<HIHHIHI'</span> | |
1172 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
1173 | ||
1174 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fid</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">max_return_bytes_count</span><span class="p">,</span> <span class="n">min_return_bytes_count</span><span class="p">,</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">remaining</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
1175 | <span class="sd">"""</span> | |
1176 | <span class="sd"> @param timeout: If reading from a regular file, this parameter must be 0.</span> | |
1177 | <span class="sd"> @type timeout: int</span> | |
1178 | <span class="sd"> """</span> | |
1179 | <span class="bp">self</span><span class="o">.</span><span class="n">fid</span> <span class="o">=</span> <span class="n">fid</span> | |
1180 | <span class="bp">self</span><span class="o">.</span><span class="n">remaining</span> <span class="o">=</span> <span class="n">remaining</span> | |
1181 | <span class="bp">self</span><span class="o">.</span><span class="n">max_return_bytes_count</span> <span class="o">=</span> <span class="n">max_return_bytes_count</span> | |
1182 | <span class="bp">self</span><span class="o">.</span><span class="n">min_return_bytes_count</span> <span class="o">=</span> <span class="n">min_return_bytes_count</span> | |
1183 | <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">=</span> <span class="n">offset</span> | |
1184 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">timeout</span> | |
1185 | ||
1186 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1187 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1188 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_READ_ANDX</span> | |
1189 | ||
1190 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1191 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> \ | |
1192 | <span class="bp">self</span><span class="o">.</span><span class="n">DEFAULT_ANDX_PARAM_HEADER</span> <span class="o">+</span> \ | |
1193 | <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
1194 | <span class="bp">self</span><span class="o">.</span><span class="n">fid</span><span class="p">,</span> | |
1195 | <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">&</span> <span class="mh">0xFFFFFFFF</span><span class="p">,</span> | |
1196 | <span class="bp">self</span><span class="o">.</span><span class="n">max_return_bytes_count</span><span class="p">,</span> | |
1197 | <span class="bp">self</span><span class="o">.</span><span class="n">min_return_bytes_count</span><span class="p">,</span> | |
1198 | <span class="bp">self</span><span class="o">.</span><span class="n">timeout</span> <span class="ow">or</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_return_bytes_count</span> <span class="o">>></span> <span class="mi">32</span><span class="p">),</span> <span class="c"># Note that in [MS-SMB]: 2.2.4.2.1, this field can also act as MaxCountHigh field</span> | |
1199 | <span class="bp">self</span><span class="o">.</span><span class="n">remaining</span><span class="p">,</span> <span class="c"># In [MS-CIFS]: 2.2.4.42.1, this field must be set to 0x0000</span> | |
1200 | <span class="bp">self</span><span class="o">.</span><span class="n">offset</span> <span class="o">>></span> <span class="mi">32</span><span class="p">)</span> | |
1201 | ||
1202 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">''</span> | |
1203 | ||
1204 | ||
1205 | <span class="k">class</span> <span class="nc">ComReadAndxResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1206 | <span class="sd">"""</span> | |
1207 | <span class="sd"> References:</span> | |
1208 | <span class="sd"> ===========</span> | |
1209 | <span class="sd"> - [MS-CIFS]: 2.2.4.42.2</span> | |
1210 | <span class="sd"> - [MS-SMB]: 2.2.4.2.2</span> | |
1211 | <span class="sd"> """</span> | |
1212 | ||
1213 | <span class="n">PAYLOAD_STRUCT_FORMAT</span> <span class="o">=</span> <span class="s">'<BBHHHHHHHHHHH'</span> | |
1214 | <span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">calcsize</span><span class="p">(</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">)</span> | |
1215 | ||
1216 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1217 | <span class="k">assert</span> <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">==</span> <span class="n">SMB_COM_READ_ANDX</span> | |
1218 | ||
1219 | <span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">hasError</span><span class="p">:</span> | |
1220 | <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">)</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">:</span> | |
1221 | <span class="k">raise</span> <span class="n">ProtocolError</span><span class="p">(</span><span class="s">'Not enough data to decode SMB_COM_READ_ANDX parameters'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">raw_data</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1222 | ||
1223 | <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_length</span><span class="p">,</span> <span class="n">data_offset</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_FORMAT</span><span class="p">,</span> | |
1224 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span><span class="p">])</span> | |
1225 | ||
1226 | <span class="n">offset</span> <span class="o">=</span> <span class="n">data_offset</span> <span class="o">-</span> <span class="n">message</span><span class="o">.</span><span class="n">HEADER_STRUCT_SIZE</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">PAYLOAD_STRUCT_SIZE</span> <span class="o">-</span> <span class="mi">2</span> <span class="c"># constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters)</span> | |
1227 | <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span><span class="o">+</span><span class="bp">self</span><span class="o">.</span><span class="n">data_length</span><span class="p">]</span> | |
1228 | <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_length</span> | |
1229 | ||
1230 | ||
1231 | <span class="k">class</span> <span class="nc">ComDeleteRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1232 | <span class="sd">"""</span> | |
1233 | <span class="sd"> References:</span> | |
1234 | <span class="sd"> ===========</span> | |
1235 | <span class="sd"> - [MS-CIFS]: 2.2.4.7.1</span> | |
1236 | <span class="sd"> """</span> | |
1237 | ||
1238 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename_pattern</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
1239 | <span class="bp">self</span><span class="o">.</span><span class="n">filename_pattern</span> <span class="o">=</span> <span class="n">filename_pattern</span> | |
1240 | <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span> <span class="o">=</span> <span class="n">search_attributes</span> | |
1241 | ||
1242 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1243 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1244 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_DELETE</span> | |
1245 | ||
1246 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1247 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span><span class="p">)</span> | |
1248 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">'</span><span class="se">\x04</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">filename_pattern</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> | |
1249 | ||
1250 | ||
1251 | <span class="k">class</span> <span class="nc">ComCreateDirectoryRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1252 | <span class="sd">"""</span> | |
1253 | <span class="sd"> Although this command has been marked deprecated in [MS-CIFS], we continue to use it for its simplicity</span> | |
1254 | <span class="sd"> as compared to its replacement TRANS2_CREATE_DIRECTORY sub-command [MS-CIFS]: 2.2.6.14</span> | |
1255 | ||
1256 | <span class="sd"> References:</span> | |
1257 | <span class="sd"> ===========</span> | |
1258 | <span class="sd"> - [MS-CIFS]: 2.2.4.1.1</span> | |
1259 | <span class="sd"> """</span> | |
1260 | ||
1261 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span> | |
1262 | <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span> | |
1263 | ||
1264 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1265 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1266 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_CREATE_DIRECTORY</span> | |
1267 | ||
1268 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1269 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s">''</span> | |
1270 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">'</span><span class="se">\x04</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> | |
1271 | ||
1272 | ||
1273 | <span class="k">class</span> <span class="nc">ComDeleteDirectoryRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1274 | <span class="sd">"""</span> | |
1275 | <span class="sd"> References:</span> | |
1276 | <span class="sd"> ===========</span> | |
1277 | <span class="sd"> - [MS-CIFS]: 2.2.4.2.1</span> | |
1278 | <span class="sd"> """</span> | |
1279 | ||
1280 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span> | |
1281 | <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span> | |
1282 | ||
1283 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1284 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1285 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_DELETE_DIRECTORY</span> | |
1286 | ||
1287 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1288 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="s">''</span> | |
1289 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">'</span><span class="se">\x04</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\0\0</span><span class="s">'</span> | |
1290 | ||
1291 | ||
1292 | <span class="k">class</span> <span class="nc">ComRenameRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1293 | <span class="sd">"""</span> | |
1294 | <span class="sd"> References:</span> | |
1295 | <span class="sd"> ===========</span> | |
1296 | <span class="sd"> - [MS-CIFS]: 2.2.4.8.1</span> | |
1297 | <span class="sd"> """</span> | |
1298 | ||
1299 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_path</span><span class="p">,</span> <span class="n">new_path</span><span class="p">,</span> <span class="n">search_attributes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span> | |
1300 | <span class="bp">self</span><span class="o">.</span><span class="n">old_path</span> <span class="o">=</span> <span class="n">old_path</span> | |
1301 | <span class="bp">self</span><span class="o">.</span><span class="n">new_path</span> <span class="o">=</span> <span class="n">new_path</span> | |
1302 | <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span> <span class="o">=</span> <span class="n">search_attributes</span> | |
1303 | ||
1304 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1305 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1306 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_RENAME</span> | |
1307 | ||
1308 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1309 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_attributes</span><span class="p">)</span> | |
1310 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">'</span><span class="se">\x04</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">old_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\x00\x00\x04\x00</span><span class="s">'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">new_path</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'UTF-16LE'</span><span class="p">)</span> <span class="o">+</span> <span class="s">'</span><span class="se">\x00\x00</span><span class="s">'</span> | |
1311 | ||
1312 | ||
1313 | <span class="k">class</span> <span class="nc">ComEchoRequest</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1314 | <span class="sd">"""</span> | |
1315 | <span class="sd"> References:</span> | |
1316 | <span class="sd"> ===========</span> | |
1317 | <span class="sd"> - [MS-CIFS]: 2.2.4.39.1</span> | |
1318 | <span class="sd"> """</span> | |
1319 | ||
1320 | <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">echo_data</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="n">echo_count</span> <span class="o">=</span> <span class="mi">1</span><span class="p">):</span> | |
1321 | <span class="bp">self</span><span class="o">.</span><span class="n">echo_count</span> <span class="o">=</span> <span class="n">echo_count</span> | |
1322 | <span class="bp">self</span><span class="o">.</span><span class="n">echo_data</span> <span class="o">=</span> <span class="n">echo_data</span> | |
1323 | ||
1324 | <span class="k">def</span> <span class="nf">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1325 | <span class="n">Payload</span><span class="o">.</span><span class="n">initMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span> | |
1326 | <span class="n">message</span><span class="o">.</span><span class="n">command</span> <span class="o">=</span> <span class="n">SMB_COM_ECHO</span> | |
1327 | <span class="n">message</span><span class="o">.</span><span class="n">tid</span> <span class="o">=</span> <span class="mh">0xFFFF</span> | |
1328 | ||
1329 | <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1330 | <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">echo_count</span><span class="p">)</span> | |
1331 | <span class="n">message</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">echo_data</span> | |
1332 | ||
1333 | ||
1334 | <span class="k">class</span> <span class="nc">ComEchoResponse</span><span class="p">(</span><span class="n">Payload</span><span class="p">):</span> | |
1335 | <span class="sd">"""</span> | |
1336 | <span class="sd"> References:</span> | |
1337 | <span class="sd"> ===========</span> | |
1338 | <span class="sd"> - [MS-CIFS]: 2.2.4.39.2</span> | |
1339 | <span class="sd"> """</span> | |
1340 | ||
1341 | <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |
1342 | <span class="bp">self</span><span class="o">.</span><span class="n">sequence_number</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s">'<H'</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">parameters_data</span><span class="p">[:</span><span class="mi">2</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span> | |
1343 | <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">data</span> | |
1344 | </pre></div> | |
1345 | ||
1346 | </div> | |
1347 | </div> | |
1348 | </div> | |
1349 | <div class="clearer"></div> | |
1350 | </div> | |
1351 | <div class="related"> | |
1352 | <h3>Navigation</h3> | |
1353 | <ul> | |
1354 | <li class="right" style="margin-right: 10px"> | |
1355 | <a href="../../genindex.html" title="General Index" | |
1356 | >index</a></li> | |
1357 | <li><a href="../../index.html">pysmb 1.0.0 documentation</a> »</li> | |
1358 | <li><a href="../index.html" >Module code</a> »</li> | |
1359 | </ul> | |
1360 | </div> | |
1361 | <div class="footer"> | |
1362 | © Copyright 2011, Michael Teo. | |
1363 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
1364 | </div> | |
1365 | </body> | |
1366 | </html>⏎ |
0 | ||
1 | NBNSProtocol Class | |
2 | ================== | |
3 | ||
4 | pysmb has a *NBNSProtocol* implementation for Twisted framework. | |
5 | This allows you to perform name query asynchronously without having your application to block and wait for the results. | |
6 | ||
7 | In your project, | |
8 | 1. Create a NBNSProtocol instance. | |
9 | 2. Just call *queryName* method which will return a *Deferred* instance. Add your callback function to the *Deferred* instance via *addCallback* method to receive the results of the name query. | |
10 | 3. When you are done with the NBNSProtocol instance, call its <NBNSProtocol instance>.transport.stopListening method to remove this instance from the reactor. | |
11 | ||
12 | .. autoclass:: nmb.NetBIOSProtocol.NBNSProtocol | |
13 | :members: | |
14 | :special-members: | |
15 | ||
16 | .. autoclass:: nmb.NetBIOSProtocol.NetBIOSTimeout | |
17 | :members: |
0 | ||
1 | NetBIOS class | |
2 | ============= | |
3 | ||
4 | To use the NetBIOS class in your application, | |
5 | 1. Create a new NetBIOS instance | |
6 | 2. Call *queryName* method for each name you wish to query. The method will block until a reply is received from the remote SMB/CIFS service, or until timeout. | |
7 | 3. When you are done, call *close* method to release the underlying resources. | |
8 | ||
9 | .. autoclass:: nmb.NetBIOS.NetBIOS | |
10 | :members: | |
11 | :special-members: |
0 | ||
1 | SMBConnection Class | |
2 | =================== | |
3 | ||
4 | The SMBConnection is suitable for developers who wish to use pysmb to perform file operations with a remote SMB/CIFS server sequentially. | |
5 | ||
6 | Each file operation method, when invoked, will block and return after it has completed or has encountered an error. | |
7 | ||
8 | Caveats | |
9 | ------- | |
10 | ||
11 | * It is not meant to be used asynchronously. | |
12 | * A single *SMBConnection* instance should not be used to perform more than one operation concurrently at the same time. | |
13 | * Do not keep a *SMBConnection* instance "idle" for too long, i.e. keeping a *SMBConnection* instance but not using it. | |
14 | Most SMB/CIFS servers have some sort of keepalive mechanism and impose a timeout limit. | |
15 | If the clients fail to respond within the timeout limit, the SMB/CIFS server may disconnect the client. | |
16 | ||
17 | .. autoclass:: smb.SMBConnection.SMBConnection | |
18 | :members: | |
19 | :special-members: |
0 | ||
1 | SMBProtocolFactory Class | |
2 | ======================== | |
3 | ||
4 | For those who want to utilize pysmb in Twisted framework, pysmb has a *smb.SMBProtocol.SMBProtocol* implementation. | |
5 | In most cases, you do not need to touch or import the *SMBProtocol* directly. All the SMB functionalities are exposed in the *SMBProtocolFactory*. | |
6 | ||
7 | In your project, | |
8 | 1. Create a new class and subclass *SMBProtocolFactory*. | |
9 | 2. Override the *SMBProtocolFactory.onAuthOK* and *SMBProtocolFactory.onAuthFailed* instance methods to provide your own post-authenthentication handling. | |
10 | Once *SMBProtocolFactory.onAuthOK* has been called by pymsb internals, your application is ready to communicate with the remote SMB/CIFS service through | |
11 | the *SMBProtocolFactory* public methods such as *SMBProtocolFactory.storeFile*, *SMBProtocolFactory.retrieveFile*, etc. | |
12 | 3. When you want to disconnect from the remote SMB/CIFS server, just call *SMBProtocolFactory.closeConnection* method. | |
13 | ||
14 | All the *SMBProtocolFactory* public methods that provide file functionlities will return a *twisted.internet.defer.Deferred* instance. | |
15 | A :doc:`NotReadyError<smb_exceptions>` exception is raised when the underlying SMB is not authenticated. | |
16 | If the underlying SMB connection has been terminated, a :doc:`NotConnectedError<smb_exceptions>` exception is raised. | |
17 | ||
18 | All the file operation methods in *SMBProtocolFactory* class accept a *timeout* parameter. This parameter specifies the time limit where pysmb will wait for the | |
19 | entire file operation (except *storeFile* and *retrieveFile* methods) to complete. If the file operation fails to complete within the timeout period, the returned | |
20 | *Deferred* instance's *errback* method will be called with a *SMBTimeout* exception. | |
21 | ||
22 | If you are interested in learning the results of the operation or to know when the operation has completed, you should | |
23 | add a handling method to the returned *Deferred* instance via *Deferred.addCallback*. If the file operation fails, the *Deferred.errback* function will be called | |
24 | with an :doc:`OperationFailure<smb_exceptions>`; on timeout, it will be called with a :doc:`SMBTimeout<smb_exceptions>`. | |
25 | ||
26 | Caveats | |
27 | ------- | |
28 | ||
29 | * A new factory instance must be created for each SMB connection to the remote SMB/CIFS service. Avoid reusing the same factory instance for more than one SMB connection. | |
30 | * The remote SMB/CIFS server usually imposes a limit of the number of concurrent file operations for each client. For example, to transfer a thousand files, you may need to setup a queue in your application and call *storeFile* or *retrieveFile* in batches. | |
31 | * The *timeout* parameter in the file operation methods are not precise; it is accurate to within 1 second interval, i.e. with a timeout of 0.5 sec, pysmb might raise | |
32 | *SMBTimeout* exception after 1.5 sec. | |
33 | ||
34 | .. autoclass:: smb.SMBProtocol.SMBProtocolFactory | |
35 | :members: | |
36 | :special-members: |
0 | ||
1 | SMB Exceptions | |
2 | ============== | |
3 | ||
4 | .. autoclass:: smb.base.SMBTimeout | |
5 | :members: | |
6 | ||
7 | .. autoclass:: smb.base.NotReadyError | |
8 | :members: | |
9 | ||
10 | .. autoclass:: smb.base.NotConnectedError | |
11 | :members: | |
12 | ||
13 | .. autoclass:: smb.smb_structs.UnsupportedFeature | |
14 | :members: | |
15 | ||
16 | .. autoclass:: smb.smb_structs.ProtocolError | |
17 | :members: | |
18 | ||
19 | .. autoclass:: smb.smb_structs.OperationFailure | |
20 | :members: |
0 | ||
1 | Extending pysmb For Other Frameworks | |
2 | ==================================== | |
3 | ||
4 | This page briefly describes the steps involved in extending pysmb for other frameworks. | |
5 | ||
6 | In general, you need to take care of the SMB TCP connection setup, i.e. finding the IP address of the remote server and connect to the SMB/CIFS service. | |
7 | Then you need to read/write synchronously or asynchronously from and to the SMB socket. And you need to handle post-authentication callback methods, and from these methods, | |
8 | initiate file operations with the remote SMB/CIFS server. | |
9 | ||
10 | Now the above steps in more technical details: | |
11 | 1. Create a new class which subclasses the *smb.base.SMB* class. Most often, the connection setup will be part of the *__init__* method. | |
12 | 2. Override the *write(self, data)* method to provide an implementation which will write *data* to the socket. | |
13 | 3. Write your own loop handling method to read data from the socket. Once data have been read, call *feedData* method with the parameter. | |
14 | The *feedData* method has its own internal buffer, so it can accept incomplete NetBIOS session packet data. | |
15 | 4. Override | |
16 | * *onAuthOK* method to include your own operations to perform when authentication is successful. You can initiate file operations in this method. | |
17 | * *onAuthFailed* method to include your own processing on what to do when authentication fails. You can report this as an error, or to try a different NTLM authentication algorithm (*use_ntlm_v2* parameter in the constructor). | |
18 | * *onNMBSessionFailed* method to include your own processing on what to do when pysmb fails to setup the NetBIOS session with the remote server. Usually, this is due to a wrong *remote_name* parameter in the constructor. |
0 | .. pysmb documentation master file, created by | |
1 | sphinx-quickstart on Sun Dec 18 15:54:40 2011. | |
2 | You can adapt this file completely to your liking, but it should at least | |
3 | contain the root `toctree` directive. | |
4 | ||
5 | Welcome to pysmb's documentation! | |
6 | ================================= | |
7 | ||
8 | pysmb is a pure Python implementation of the client-side SMB/CIFS protocol which is the underlying protocol that facilitates file sharing and printing between Windows machines, | |
9 | as well as with Linux machines via the Samba server application. | |
10 | pysmb is developed in Python 2.4.6 (and Python 2.7.1) and has been tested against shared folders on Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x. | |
11 | ||
12 | License | |
13 | ------- | |
14 | pysmb itself is licensed under an opensource license. | |
15 | You are free to use pysmb in any applications, including for commercial purposes. | |
16 | For more details on the terms of use, please read the LICENSE file that comes with your pysmb source. | |
17 | ||
18 | pysmb depends on other 3rd-party modules whose terms of use are not covered by pysmb. | |
19 | Use of these modules could possibly conflict with your licensing needs. Please exercise your own discretion to determine their suitabilities. | |
20 | I have listed these modules in the following section. | |
21 | ||
22 | Credits | |
23 | ------- | |
24 | pysmb is not alone. It is made possible with support from other modules. | |
25 | ||
26 | * **pyasn1** : Pure Python implementation of ASN.1 parsing and encoding (not included together with pysmb; needs to be installed separately) | |
27 | * **md4** and **U32** : Pure Python implementation of MD4 hashing algorithm and 32-bit unsigned integer by Dmitry Rozmanov. Licensed under LGPL and included together with pysmb. | |
28 | * **pyDes** : Pure python implementation of the DES encryption algorithm by Todd Whiteman. Free domain and included together with pysmb. | |
29 | ||
30 | In various places, there are references to different specifications. Most of these referenced specifications | |
31 | can be downloaded from Microsoft web site under Microsoft's "Open Specification Promise". If you need to download | |
32 | a copy of these specifications, please google for it. For example, google for "MS-CIFS" to download the CIFS specification for NT LM dialect. | |
33 | ||
34 | Package Contents and Description | |
35 | ================================ | |
36 | ||
37 | pysmb is organized into 2 main packages: smb and nmb. | |
38 | The smb package contains all the functionalities related to Server Message Block (SMB) implementation. | |
39 | As an application developer, you will be importing this module into your application. | |
40 | Hence, please take some time to familiarize yourself with the smb package contents. | |
41 | ||
42 | * **nmb/base.py** : | |
43 | Contains the NetBIOSSession and NBNS abstract class which implements NetBIOS session and NetBIOS Name Service communication | |
44 | without any network transport specifics. | |
45 | * **nmb/NetBIOS.py**: | |
46 | Provides a NBNS implementation to query IP addresses for machine names. All operations are blocking I/O. | |
47 | * **nmb/NetBIOSProtocol.py** : | |
48 | Provides the NBNS protocol implementation for use in Twisted framework. | |
49 | ||
50 | * **smb/base.py** : | |
51 | Contains the SMB abstract class which implements the SMB communication without any network transport specifics. | |
52 | * **smb/ntlm.py** : | |
53 | Contains the NTLMv1 and NTLMv2 authentication routines and the decoding/encoding of NTLM authentication messages within SMB messages. | |
54 | * **smb/securityblob.py** : | |
55 | Provides routines to encode/decode the NTLMSSP security blob in the SMB messages. | |
56 | * **smb/smb_constants.py** : | |
57 | All the constants used in the smb package | |
58 | * **smb/smb_structs.py** : | |
59 | Contains the internal classes used in the SMB package. These classes are usually used to encode/decode the parameter and data blocks of specific SMB message. | |
60 | * **smb/SMBConnection.py** : | |
61 | Contains a SMB protocol implementation. All operations are blocking I/O. | |
62 | * **smb/SMBProtocol.py** : | |
63 | Contains the SMB protocol implementation for use in the Twisted framework. | |
64 | ||
65 | Using pysmb | |
66 | =========== | |
67 | ||
68 | As an application developer who is looking to use pysmb to translate NetBIOS names to IP addresses, | |
69 | * To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read | |
70 | :doc:`nmb.NetBIOS.NetBIOS<api/nmb_NetBIOS>` documentation. | |
71 | * To use pysmb in Twisted, please read :doc:`nmb.NetBIOSProtocol.NBNSProtocol<api/nmb_NBNSProtocol>` documentation. | |
72 | ||
73 | As an application developer who is looking to use pysmb to implement file transfer or authentication over SMB: | |
74 | * To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read | |
75 | :doc:`smb.SMBConnection.SMBConnection<api/smb_SMBConnection>` documentation. | |
76 | * To use pysmb in Twisted, please read :doc:`smb.SMBProtocol.SMBProtocolFactory<api/smb_SMBProtocolFactory>` documentation. | |
77 | ||
78 | As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks: | |
79 | * Read :doc:`extending` | |
80 | ||
81 | ||
82 | ||
83 | Indices and tables | |
84 | ================== | |
85 | ||
86 | .. toctree:: | |
87 | :glob: | |
88 | :maxdepth: 1 | |
89 | ||
90 | api/* | |
91 | extending | |
92 | ||
93 | * :ref:`genindex` | |
94 | * :ref:`search` |
Binary diff not shown
0 | /* | |
1 | * basic.css | |
2 | * ~~~~~~~~~ | |
3 | * | |
4 | * Sphinx stylesheet -- basic theme. | |
5 | * | |
6 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. | |
7 | * :license: BSD, see LICENSE for details. | |
8 | * | |
9 | */ | |
10 | ||
11 | /* -- main layout ----------------------------------------------------------- */ | |
12 | ||
13 | div.clearer { | |
14 | clear: both; | |
15 | } | |
16 | ||
17 | /* -- relbar ---------------------------------------------------------------- */ | |
18 | ||
19 | div.related { | |
20 | width: 100%; | |
21 | font-size: 90%; | |
22 | } | |
23 | ||
24 | div.related h3 { | |
25 | display: none; | |
26 | } | |
27 | ||
28 | div.related ul { | |
29 | margin: 0; | |
30 | padding: 0 0 0 10px; | |
31 | list-style: none; | |
32 | } | |
33 | ||
34 | div.related li { | |
35 | display: inline; | |
36 | } | |
37 | ||
38 | div.related li.right { | |
39 | float: right; | |
40 | margin-right: 5px; | |
41 | } | |
42 | ||
43 | /* -- sidebar --------------------------------------------------------------- */ | |
44 | ||
45 | div.sphinxsidebarwrapper { | |
46 | padding: 10px 5px 0 10px; | |
47 | } | |
48 | ||
49 | div.sphinxsidebar { | |
50 | float: left; | |
51 | width: 230px; | |
52 | margin-left: -100%; | |
53 | font-size: 90%; | |
54 | } | |
55 | ||
56 | div.sphinxsidebar ul { | |
57 | list-style: none; | |
58 | } | |
59 | ||
60 | div.sphinxsidebar ul ul, | |
61 | div.sphinxsidebar ul.want-points { | |
62 | margin-left: 20px; | |
63 | list-style: square; | |
64 | } | |
65 | ||
66 | div.sphinxsidebar ul ul { | |
67 | margin-top: 0; | |
68 | margin-bottom: 0; | |
69 | } | |
70 | ||
71 | div.sphinxsidebar form { | |
72 | margin-top: 10px; | |
73 | } | |
74 | ||
75 | div.sphinxsidebar input { | |
76 | border: 1px solid #98dbcc; | |
77 | font-family: sans-serif; | |
78 | font-size: 1em; | |
79 | } | |
80 | ||
81 | div.sphinxsidebar input[type="text"] { | |
82 | width: 170px; | |
83 | } | |
84 | ||
85 | div.sphinxsidebar input[type="submit"] { | |
86 | width: 30px; | |
87 | } | |
88 | ||
89 | img { | |
90 | border: 0; | |
91 | } | |
92 | ||
93 | /* -- search page ----------------------------------------------------------- */ | |
94 | ||
95 | ul.search { | |
96 | margin: 10px 0 0 20px; | |
97 | padding: 0; | |
98 | } | |
99 | ||
100 | ul.search li { | |
101 | padding: 5px 0 5px 20px; | |
102 | background-image: url(file.png); | |
103 | background-repeat: no-repeat; | |
104 | background-position: 0 7px; | |
105 | } | |
106 | ||
107 | ul.search li a { | |
108 | font-weight: bold; | |
109 | } | |
110 | ||
111 | ul.search li div.context { | |
112 | color: #888; | |
113 | margin: 2px 0 0 30px; | |
114 | text-align: left; | |
115 | } | |
116 | ||
117 | ul.keywordmatches li.goodmatch a { | |
118 | font-weight: bold; | |
119 | } | |
120 | ||
121 | /* -- index page ------------------------------------------------------------ */ | |
122 | ||
123 | table.contentstable { | |
124 | width: 90%; | |
125 | } | |
126 | ||
127 | table.contentstable p.biglink { | |
128 | line-height: 150%; | |
129 | } | |
130 | ||
131 | a.biglink { | |
132 | font-size: 1.3em; | |
133 | } | |
134 | ||
135 | span.linkdescr { | |
136 | font-style: italic; | |
137 | padding-top: 5px; | |
138 | font-size: 90%; | |
139 | } | |
140 | ||
141 | /* -- general index --------------------------------------------------------- */ | |
142 | ||
143 | table.indextable { | |
144 | width: 100%; | |
145 | } | |
146 | ||
147 | table.indextable td { | |
148 | text-align: left; | |
149 | vertical-align: top; | |
150 | } | |
151 | ||
152 | table.indextable dl, table.indextable dd { | |
153 | margin-top: 0; | |
154 | margin-bottom: 0; | |
155 | } | |
156 | ||
157 | table.indextable tr.pcap { | |
158 | height: 10px; | |
159 | } | |
160 | ||
161 | table.indextable tr.cap { | |
162 | margin-top: 10px; | |
163 | background-color: #f2f2f2; | |
164 | } | |
165 | ||
166 | img.toggler { | |
167 | margin-right: 3px; | |
168 | margin-top: 3px; | |
169 | cursor: pointer; | |
170 | } | |
171 | ||
172 | div.modindex-jumpbox { | |
173 | border-top: 1px solid #ddd; | |
174 | border-bottom: 1px solid #ddd; | |
175 | margin: 1em 0 1em 0; | |
176 | padding: 0.4em; | |
177 | } | |
178 | ||
179 | div.genindex-jumpbox { | |
180 | border-top: 1px solid #ddd; | |
181 | border-bottom: 1px solid #ddd; | |
182 | margin: 1em 0 1em 0; | |
183 | padding: 0.4em; | |
184 | } | |
185 | ||
186 | /* -- general body styles --------------------------------------------------- */ | |
187 | ||
188 | a.headerlink { | |
189 | visibility: hidden; | |
190 | } | |
191 | ||
192 | h1:hover > a.headerlink, | |
193 | h2:hover > a.headerlink, | |
194 | h3:hover > a.headerlink, | |
195 | h4:hover > a.headerlink, | |
196 | h5:hover > a.headerlink, | |
197 | h6:hover > a.headerlink, | |
198 | dt:hover > a.headerlink { | |
199 | visibility: visible; | |
200 | } | |
201 | ||
202 | div.body p.caption { | |
203 | text-align: inherit; | |
204 | } | |
205 | ||
206 | div.body td { | |
207 | text-align: left; | |
208 | } | |
209 | ||
210 | .field-list ul { | |
211 | padding-left: 1em; | |
212 | } | |
213 | ||
214 | .first { | |
215 | margin-top: 0 !important; | |
216 | } | |
217 | ||
218 | p.rubric { | |
219 | margin-top: 30px; | |
220 | font-weight: bold; | |
221 | } | |
222 | ||
223 | img.align-left, .figure.align-left, object.align-left { | |
224 | clear: left; | |
225 | float: left; | |
226 | margin-right: 1em; | |
227 | } | |
228 | ||
229 | img.align-right, .figure.align-right, object.align-right { | |
230 | clear: right; | |
231 | float: right; | |
232 | margin-left: 1em; | |
233 | } | |
234 | ||
235 | img.align-center, .figure.align-center, object.align-center { | |
236 | display: block; | |
237 | margin-left: auto; | |
238 | margin-right: auto; | |
239 | } | |
240 | ||
241 | .align-left { | |
242 | text-align: left; | |
243 | } | |
244 | ||
245 | .align-center { | |
246 | text-align: center; | |
247 | } | |
248 | ||
249 | .align-right { | |
250 | text-align: right; | |
251 | } | |
252 | ||
253 | /* -- sidebars -------------------------------------------------------------- */ | |
254 | ||
255 | div.sidebar { | |
256 | margin: 0 0 0.5em 1em; | |
257 | border: 1px solid #ddb; | |
258 | padding: 7px 7px 0 7px; | |
259 | background-color: #ffe; | |
260 | width: 40%; | |
261 | float: right; | |
262 | } | |
263 | ||
264 | p.sidebar-title { | |
265 | font-weight: bold; | |
266 | } | |
267 | ||
268 | /* -- topics ---------------------------------------------------------------- */ | |
269 | ||
270 | div.topic { | |
271 | border: 1px solid #ccc; | |
272 | padding: 7px 7px 0 7px; | |
273 | margin: 10px 0 10px 0; | |
274 | } | |
275 | ||
276 | p.topic-title { | |
277 | font-size: 1.1em; | |
278 | font-weight: bold; | |
279 | margin-top: 10px; | |
280 | } | |
281 | ||
282 | /* -- admonitions ----------------------------------------------------------- */ | |
283 | ||
284 | div.admonition { | |
285 | margin-top: 10px; | |
286 | margin-bottom: 10px; | |
287 | padding: 7px; | |
288 | } | |
289 | ||
290 | div.admonition dt { | |
291 | font-weight: bold; | |
292 | } | |
293 | ||
294 | div.admonition dl { | |
295 | margin-bottom: 0; | |
296 | } | |
297 | ||
298 | p.admonition-title { | |
299 | margin: 0px 10px 5px 0px; | |
300 | font-weight: bold; | |
301 | } | |
302 | ||
303 | div.body p.centered { | |
304 | text-align: center; | |
305 | margin-top: 25px; | |
306 | } | |
307 | ||
308 | /* -- tables ---------------------------------------------------------------- */ | |
309 | ||
310 | table.docutils { | |
311 | border: 0; | |
312 | border-collapse: collapse; | |
313 | } | |
314 | ||
315 | table.docutils td, table.docutils th { | |
316 | padding: 1px 8px 1px 5px; | |
317 | border-top: 0; | |
318 | border-left: 0; | |
319 | border-right: 0; | |
320 | border-bottom: 1px solid #aaa; | |
321 | } | |
322 | ||
323 | table.field-list td, table.field-list th { | |
324 | border: 0 !important; | |
325 | } | |
326 | ||
327 | table.footnote td, table.footnote th { | |
328 | border: 0 !important; | |
329 | } | |
330 | ||
331 | th { | |
332 | text-align: left; | |
333 | padding-right: 5px; | |
334 | } | |
335 | ||
336 | table.citation { | |
337 | border-left: solid 1px gray; | |
338 | margin-left: 1px; | |
339 | } | |
340 | ||
341 | table.citation td { | |
342 | border-bottom: none; | |
343 | } | |
344 | ||
345 | /* -- other body styles ----------------------------------------------------- */ | |
346 | ||
347 | ol.arabic { | |
348 | list-style: decimal; | |
349 | } | |
350 | ||
351 | ol.loweralpha { | |
352 | list-style: lower-alpha; | |
353 | } | |
354 | ||
355 | ol.upperalpha { | |
356 | list-style: upper-alpha; | |
357 | } | |
358 | ||
359 | ol.lowerroman { | |
360 | list-style: lower-roman; | |
361 | } | |
362 | ||
363 | ol.upperroman { | |
364 | list-style: upper-roman; | |
365 | } | |
366 | ||
367 | dl { | |
368 | margin-bottom: 15px; | |
369 | } | |
370 | ||
371 | dd p { | |
372 | margin-top: 0px; | |
373 | } | |
374 | ||
375 | dd ul, dd table { | |
376 | margin-bottom: 10px; | |
377 | } | |
378 | ||
379 | dd { | |
380 | margin-top: 3px; | |
381 | margin-bottom: 10px; | |
382 | margin-left: 30px; | |
383 | } | |
384 | ||
385 | dt:target, .highlighted { | |
386 | background-color: #fbe54e; | |
387 | } | |
388 | ||
389 | dl.glossary dt { | |
390 | font-weight: bold; | |
391 | font-size: 1.1em; | |
392 | } | |
393 | ||
394 | .field-list ul { | |
395 | margin: 0; | |
396 | padding-left: 1em; | |
397 | } | |
398 | ||
399 | .field-list p { | |
400 | margin: 0; | |
401 | } | |
402 | ||
403 | .refcount { | |
404 | color: #060; | |
405 | } | |
406 | ||
407 | .optional { | |
408 | font-size: 1.3em; | |
409 | } | |
410 | ||
411 | .versionmodified { | |
412 | font-style: italic; | |
413 | } | |
414 | ||
415 | .system-message { | |
416 | background-color: #fda; | |
417 | padding: 5px; | |
418 | border: 3px solid red; | |
419 | } | |
420 | ||
421 | .footnote:target { | |
422 | background-color: #ffa; | |
423 | } | |
424 | ||
425 | .line-block { | |
426 | display: block; | |
427 | margin-top: 1em; | |
428 | margin-bottom: 1em; | |
429 | } | |
430 | ||
431 | .line-block .line-block { | |
432 | margin-top: 0; | |
433 | margin-bottom: 0; | |
434 | margin-left: 1.5em; | |
435 | } | |
436 | ||
437 | .guilabel, .menuselection { | |
438 | font-family: sans-serif; | |
439 | } | |
440 | ||
441 | .accelerator { | |
442 | text-decoration: underline; | |
443 | } | |
444 | ||
445 | .classifier { | |
446 | font-style: oblique; | |
447 | } | |
448 | ||
449 | abbr, acronym { | |
450 | border-bottom: dotted 1px; | |
451 | cursor: help; | |
452 | } | |
453 | ||
454 | /* -- code displays --------------------------------------------------------- */ | |
455 | ||
456 | pre { | |
457 | overflow: auto; | |
458 | overflow-y: hidden; /* fixes display issues on Chrome browsers */ | |
459 | } | |
460 | ||
461 | td.linenos pre { | |
462 | padding: 5px 0px; | |
463 | border: 0; | |
464 | background-color: transparent; | |
465 | color: #aaa; | |
466 | } | |
467 | ||
468 | table.highlighttable { | |
469 | margin-left: 0.5em; | |
470 | } | |
471 | ||
472 | table.highlighttable td { | |
473 | padding: 0 0.5em 0 0.5em; | |
474 | } | |
475 | ||
476 | tt.descname { | |
477 | background-color: transparent; | |
478 | font-weight: bold; | |
479 | font-size: 1.2em; | |
480 | } | |
481 | ||
482 | tt.descclassname { | |
483 | background-color: transparent; | |
484 | } | |
485 | ||
486 | tt.xref, a tt { | |
487 | background-color: transparent; | |
488 | font-weight: bold; | |
489 | } | |
490 | ||
491 | h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { | |
492 | background-color: transparent; | |
493 | } | |
494 | ||
495 | .viewcode-link { | |
496 | float: right; | |
497 | } | |
498 | ||
499 | .viewcode-back { | |
500 | float: right; | |
501 | font-family: sans-serif; | |
502 | } | |
503 | ||
504 | div.viewcode-block:target { | |
505 | margin: -1px -10px; | |
506 | padding: 0 10px; | |
507 | } | |
508 | ||
509 | /* -- math display ---------------------------------------------------------- */ | |
510 | ||
511 | img.math { | |
512 | vertical-align: middle; | |
513 | } | |
514 | ||
515 | div.body div.math p { | |
516 | text-align: center; | |
517 | } | |
518 | ||
519 | span.eqno { | |
520 | float: right; | |
521 | } | |
522 | ||
523 | /* -- printout stylesheet --------------------------------------------------- */ | |
524 | ||
525 | @media print { | |
526 | div.document, | |
527 | div.documentwrapper, | |
528 | div.bodywrapper { | |
529 | margin: 0 !important; | |
530 | width: 100%; | |
531 | } | |
532 | ||
533 | div.sphinxsidebar, | |
534 | div.related, | |
535 | div.footer, | |
536 | #top-link { | |
537 | display: none; | |
538 | } | |
539 | }⏎ |
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 | /* | |
1 | * doctools.js | |
2 | * ~~~~~~~~~~~ | |
3 | * | |
4 | * Sphinx JavaScript utilities for all documentation. | |
5 | * | |
6 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. | |
7 | * :license: BSD, see LICENSE for details. | |
8 | * | |
9 | */ | |
10 | ||
11 | /** | |
12 | * select a different prefix for underscore | |
13 | */ | |
14 | $u = _.noConflict(); | |
15 | ||
16 | /** | |
17 | * make the code below compatible with browsers without | |
18 | * an installed firebug like debugger | |
19 | if (!window.console || !console.firebug) { | |
20 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", | |
21 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", | |
22 | "profile", "profileEnd"]; | |
23 | window.console = {}; | |
24 | for (var i = 0; i < names.length; ++i) | |
25 | window.console[names[i]] = function() {}; | |
26 | } | |
27 | */ | |
28 | ||
29 | /** | |
30 | * small helper function to urldecode strings | |
31 | */ | |
32 | jQuery.urldecode = function(x) { | |
33 | return decodeURIComponent(x).replace(/\+/g, ' '); | |
34 | } | |
35 | ||
36 | /** | |
37 | * small helper function to urlencode strings | |
38 | */ | |
39 | jQuery.urlencode = encodeURIComponent; | |
40 | ||
41 | /** | |
42 | * This function returns the parsed url parameters of the | |
43 | * current request. Multiple values per key are supported, | |
44 | * it will always return arrays of strings for the value parts. | |
45 | */ | |
46 | jQuery.getQueryParameters = function(s) { | |
47 | if (typeof s == 'undefined') | |
48 | s = document.location.search; | |
49 | var parts = s.substr(s.indexOf('?') + 1).split('&'); | |
50 | var result = {}; | |
51 | for (var i = 0; i < parts.length; i++) { | |
52 | var tmp = parts[i].split('=', 2); | |
53 | var key = jQuery.urldecode(tmp[0]); | |
54 | var value = jQuery.urldecode(tmp[1]); | |
55 | if (key in result) | |
56 | result[key].push(value); | |
57 | else | |
58 | result[key] = [value]; | |
59 | } | |
60 | return result; | |
61 | }; | |
62 | ||
63 | /** | |
64 | * small function to check if an array contains | |
65 | * a given item. | |
66 | */ | |
67 | jQuery.contains = function(arr, item) { | |
68 | for (var i = 0; i < arr.length; i++) { | |
69 | if (arr[i] == item) | |
70 | return true; | |
71 | } | |
72 | return false; | |
73 | }; | |
74 | ||
75 | /** | |
76 | * highlight a given string on a jquery object by wrapping it in | |
77 | * span elements with the given class name. | |
78 | */ | |
79 | jQuery.fn.highlightText = function(text, className) { | |
80 | function highlight(node) { | |
81 | if (node.nodeType == 3) { | |
82 | var val = node.nodeValue; | |
83 | var pos = val.toLowerCase().indexOf(text); | |
84 | if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { | |
85 | var span = document.createElement("span"); | |
86 | span.className = className; | |
87 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); | |
88 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( | |
89 | document.createTextNode(val.substr(pos + text.length)), | |
90 | node.nextSibling)); | |
91 | node.nodeValue = val.substr(0, pos); | |
92 | } | |
93 | } | |
94 | else if (!jQuery(node).is("button, select, textarea")) { | |
95 | jQuery.each(node.childNodes, function() { | |
96 | highlight(this); | |
97 | }); | |
98 | } | |
99 | } | |
100 | return this.each(function() { | |
101 | highlight(this); | |
102 | }); | |
103 | }; | |
104 | ||
105 | /** | |
106 | * Small JavaScript module for the documentation. | |
107 | */ | |
108 | var Documentation = { | |
109 | ||
110 | init : function() { | |
111 | this.fixFirefoxAnchorBug(); | |
112 | this.highlightSearchWords(); | |
113 | this.initIndexTable(); | |
114 | }, | |
115 | ||
116 | /** | |
117 | * i18n support | |
118 | */ | |
119 | TRANSLATIONS : {}, | |
120 | PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, | |
121 | LOCALE : 'unknown', | |
122 | ||
123 | // gettext and ngettext don't access this so that the functions | |
124 | // can safely bound to a different name (_ = Documentation.gettext) | |
125 | gettext : function(string) { | |
126 | var translated = Documentation.TRANSLATIONS[string]; | |
127 | if (typeof translated == 'undefined') | |
128 | return string; | |
129 | return (typeof translated == 'string') ? translated : translated[0]; | |
130 | }, | |
131 | ||
132 | ngettext : function(singular, plural, n) { | |
133 | var translated = Documentation.TRANSLATIONS[singular]; | |
134 | if (typeof translated == 'undefined') | |
135 | return (n == 1) ? singular : plural; | |
136 | return translated[Documentation.PLURALEXPR(n)]; | |
137 | }, | |
138 | ||
139 | addTranslations : function(catalog) { | |
140 | for (var key in catalog.messages) | |
141 | this.TRANSLATIONS[key] = catalog.messages[key]; | |
142 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); | |
143 | this.LOCALE = catalog.locale; | |
144 | }, | |
145 | ||
146 | /** | |
147 | * add context elements like header anchor links | |
148 | */ | |
149 | addContextElements : function() { | |
150 | $('div[id] > :header:first').each(function() { | |
151 | $('<a class="headerlink">\u00B6</a>'). | |
152 | attr('href', '#' + this.id). | |
153 | attr('title', _('Permalink to this headline')). | |
154 | appendTo(this); | |
155 | }); | |
156 | $('dt[id]').each(function() { | |
157 | $('<a class="headerlink">\u00B6</a>'). | |
158 | attr('href', '#' + this.id). | |
159 | attr('title', _('Permalink to this definition')). | |
160 | appendTo(this); | |
161 | }); | |
162 | }, | |
163 | ||
164 | /** | |
165 | * workaround a firefox stupidity | |
166 | */ | |
167 | fixFirefoxAnchorBug : function() { | |
168 | if (document.location.hash && $.browser.mozilla) | |
169 | window.setTimeout(function() { | |
170 | document.location.href += ''; | |
171 | }, 10); | |
172 | }, | |
173 | ||
174 | /** | |
175 | * highlight the search words provided in the url in the text | |
176 | */ | |
177 | highlightSearchWords : function() { | |
178 | var params = $.getQueryParameters(); | |
179 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; | |
180 | if (terms.length) { | |
181 | var body = $('div.body'); | |
182 | window.setTimeout(function() { | |
183 | $.each(terms, function() { | |
184 | body.highlightText(this.toLowerCase(), 'highlighted'); | |
185 | }); | |
186 | }, 10); | |
187 | $('<p class="highlight-link"><a href="javascript:Documentation.' + | |
188 | 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>') | |
189 | .appendTo($('#searchbox')); | |
190 | } | |
191 | }, | |
192 | ||
193 | /** | |
194 | * init the domain index toggle buttons | |
195 | */ | |
196 | initIndexTable : function() { | |
197 | var togglers = $('img.toggler').click(function() { | |
198 | var src = $(this).attr('src'); | |
199 | var idnum = $(this).attr('id').substr(7); | |
200 | $('tr.cg-' + idnum).toggle(); | |
201 | if (src.substr(-9) == 'minus.png') | |
202 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); | |
203 | else | |
204 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); | |
205 | }).css('display', ''); | |
206 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { | |
207 | togglers.click(); | |
208 | } | |
209 | }, | |
210 | ||
211 | /** | |
212 | * helper function to hide the search marks again | |
213 | */ | |
214 | hideSearchWords : function() { | |
215 | $('#searchbox .highlight-link').fadeOut(300); | |
216 | $('span.highlighted').removeClass('highlighted'); | |
217 | }, | |
218 | ||
219 | /** | |
220 | * make the url absolute | |
221 | */ | |
222 | makeURL : function(relativeURL) { | |
223 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; | |
224 | }, | |
225 | ||
226 | /** | |
227 | * get the current relative url | |
228 | */ | |
229 | getCurrentURL : function() { | |
230 | var path = document.location.pathname; | |
231 | var parts = path.split(/\//); | |
232 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { | |
233 | if (this == '..') | |
234 | parts.pop(); | |
235 | }); | |
236 | var url = parts.join('/'); | |
237 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); | |
238 | } | |
239 | }; | |
240 | ||
241 | // quick alias for translations | |
242 | _ = Documentation.gettext; | |
243 | ||
244 | $(document).ready(function() { | |
245 | Documentation.init(); | |
246 | }); |
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 | /*! | |
1 | * jQuery JavaScript Library v1.4.2 | |
2 | * http://jquery.com/ | |
3 | * | |
4 | * Copyright 2010, John Resig | |
5 | * Dual licensed under the MIT or GPL Version 2 licenses. | |
6 | * http://jquery.org/license | |
7 | * | |
8 | * Includes Sizzle.js | |
9 | * http://sizzlejs.com/ | |
10 | * Copyright 2010, The Dojo Foundation | |
11 | * Released under the MIT, BSD, and GPL Licenses. | |
12 | * | |
13 | * Date: Sat Feb 13 22:33:48 2010 -0500 | |
14 | */ | |
15 | (function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i? | |
16 | e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r= | |
17 | j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g, | |
18 | "&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e= | |
19 | true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, | |
20 | Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& | |
21 | (d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, | |
22 | a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== | |
23 | "find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, | |
24 | function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)|| | |
25 | c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded", | |
26 | L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype, | |
27 | "isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+ | |
28 | a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f], | |
29 | d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]=== | |
30 | a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&& | |
31 | !c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari= | |
32 | true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; | |
33 | var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, | |
34 | parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= | |
35 | false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= | |
36 | s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, | |
37 | applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; | |
38 | else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, | |
39 | a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== | |
40 | w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, | |
41 | cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ", | |
42 | i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ", | |
43 | " ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className= | |
44 | this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i= | |
45 | e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= | |
46 | c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); | |
47 | a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, | |
48 | function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); | |
49 | k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), | |
50 | C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!= | |
51 | null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type= | |
52 | e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& | |
53 | f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; | |
54 | if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), | |
55 | fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop|| | |
56 | d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this, | |
57 | "events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent= | |
58 | a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y, | |
59 | isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit= | |
60 | {setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}}; | |
61 | if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", | |
62 | e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, | |
63 | "_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, | |
64 | d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&& | |
65 | !a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}}, | |
66 | toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector, | |
67 | u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "), | |
68 | function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q]; | |
69 | if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, | |
70 | e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); | |
71 | t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| | |
72 | g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[]; | |
73 | for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length- | |
74 | 1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, | |
75 | CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}}, | |
76 | relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]= | |
77 | l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[]; | |
78 | h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, | |
79 | CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, | |
80 | g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, | |
81 | text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, | |
82 | setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= | |
83 | h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m= | |
84 | m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== | |
85 | "="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, | |
86 | h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition|| | |
87 | !h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m= | |
88 | h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& | |
89 | q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>"; | |
90 | if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); | |
91 | (function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: | |
92 | function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/, | |
93 | gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length; | |
94 | c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= | |
95 | {},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== | |
96 | "string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", | |
97 | d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? | |
98 | a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== | |
99 | 1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)? | |
100 | a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= | |
101 | c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, | |
102 | wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, | |
103 | prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, | |
104 | this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); | |
105 | return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, | |
106 | ""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&& | |
107 | this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]|| | |
108 | u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length=== | |
109 | 1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); | |
110 | return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", | |
111 | ""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= | |
112 | c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? | |
113 | c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= | |
114 | function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= | |
115 | Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, | |
116 | "border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= | |
117 | a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= | |
118 | a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== | |
119 | "string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, | |
120 | serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), | |
121 | function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, | |
122 | global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& | |
123 | e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? | |
124 | "&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== | |
125 | false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= | |
126 | false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", | |
127 | c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| | |
128 | d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); | |
129 | g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== | |
130 | 1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== | |
131 | "json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; | |
132 | if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay"); | |
133 | this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a], | |
134 | "olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)}, | |
135 | animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing= | |
136 | j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]); | |
137 | this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== | |
138 | "number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| | |
139 | c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; | |
140 | this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= | |
141 | this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, | |
142 | e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length|| | |
143 | c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement? | |
144 | function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b= | |
145 | this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle; | |
146 | k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&& | |
147 | f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; | |
148 | a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); | |
149 | c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, | |
150 | d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- | |
151 | f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": | |
152 | "pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in | |
153 | e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); |
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 | .highlight .hll { background-color: #ffffcc } | |
1 | .highlight { background: #eeffcc; } | |
2 | .highlight .c { color: #408090; font-style: italic } /* Comment */ | |
3 | .highlight .err { border: 1px solid #FF0000 } /* Error */ | |
4 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */ | |
5 | .highlight .o { color: #666666 } /* Operator */ | |
6 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ | |
7 | .highlight .cp { color: #007020 } /* Comment.Preproc */ | |
8 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ | |
9 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ | |
10 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ | |
11 | .highlight .ge { font-style: italic } /* Generic.Emph */ | |
12 | .highlight .gr { color: #FF0000 } /* Generic.Error */ | |
13 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ | |
14 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ | |
15 | .highlight .go { color: #303030 } /* Generic.Output */ | |
16 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ | |
17 | .highlight .gs { font-weight: bold } /* Generic.Strong */ | |
18 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ | |
19 | .highlight .gt { color: #0040D0 } /* Generic.Traceback */ | |
20 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ | |
21 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ | |
22 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ | |
23 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */ | |
24 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ | |
25 | .highlight .kt { color: #902000 } /* Keyword.Type */ | |
26 | .highlight .m { color: #208050 } /* Literal.Number */ | |
27 | .highlight .s { color: #4070a0 } /* Literal.String */ | |
28 | .highlight .na { color: #4070a0 } /* Name.Attribute */ | |
29 | .highlight .nb { color: #007020 } /* Name.Builtin */ | |
30 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ | |
31 | .highlight .no { color: #60add5 } /* Name.Constant */ | |
32 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ | |
33 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ | |
34 | .highlight .ne { color: #007020 } /* Name.Exception */ | |
35 | .highlight .nf { color: #06287e } /* Name.Function */ | |
36 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ | |
37 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ | |
38 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ | |
39 | .highlight .nv { color: #bb60d5 } /* Name.Variable */ | |
40 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ | |
41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ | |
42 | .highlight .mf { color: #208050 } /* Literal.Number.Float */ | |
43 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */ | |
44 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */ | |
45 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */ | |
46 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ | |
47 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */ | |
48 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ | |
49 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ | |
50 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ | |
51 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ | |
52 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ | |
53 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */ | |
54 | .highlight .sr { color: #235388 } /* Literal.String.Regex */ | |
55 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ | |
56 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */ | |
57 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ | |
58 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ | |
59 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ | |
60 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ | |
61 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */⏎ |
0 | /* | |
1 | * searchtools.js_t | |
2 | * ~~~~~~~~~~~~~~~~ | |
3 | * | |
4 | * Sphinx JavaScript utilties for the full-text search. | |
5 | * | |
6 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. | |
7 | * :license: BSD, see LICENSE for details. | |
8 | * | |
9 | */ | |
10 | ||
11 | /** | |
12 | * helper function to return a node containing the | |
13 | * search summary for a given text. keywords is a list | |
14 | * of stemmed words, hlwords is the list of normal, unstemmed | |
15 | * words. the first one is used to find the occurance, the | |
16 | * latter for highlighting it. | |
17 | */ | |
18 | ||
19 | jQuery.makeSearchSummary = function(text, keywords, hlwords) { | |
20 | var textLower = text.toLowerCase(); | |
21 | var start = 0; | |
22 | $.each(keywords, function() { | |
23 | var i = textLower.indexOf(this.toLowerCase()); | |
24 | if (i > -1) | |
25 | start = i; | |
26 | }); | |
27 | start = Math.max(start - 120, 0); | |
28 | var excerpt = ((start > 0) ? '...' : '') + | |
29 | $.trim(text.substr(start, 240)) + | |
30 | ((start + 240 - text.length) ? '...' : ''); | |
31 | var rv = $('<div class="context"></div>').text(excerpt); | |
32 | $.each(hlwords, function() { | |
33 | rv = rv.highlightText(this, 'highlighted'); | |
34 | }); | |
35 | return rv; | |
36 | } | |
37 | ||
38 | ||
39 | /** | |
40 | * Porter Stemmer | |
41 | */ | |
42 | var Stemmer = function() { | |
43 | ||
44 | var step2list = { | |
45 | ational: 'ate', | |
46 | tional: 'tion', | |
47 | enci: 'ence', | |
48 | anci: 'ance', | |
49 | izer: 'ize', | |
50 | bli: 'ble', | |
51 | alli: 'al', | |
52 | entli: 'ent', | |
53 | eli: 'e', | |
54 | ousli: 'ous', | |
55 | ization: 'ize', | |
56 | ation: 'ate', | |
57 | ator: 'ate', | |
58 | alism: 'al', | |
59 | iveness: 'ive', | |
60 | fulness: 'ful', | |
61 | ousness: 'ous', | |
62 | aliti: 'al', | |
63 | iviti: 'ive', | |
64 | biliti: 'ble', | |
65 | logi: 'log' | |
66 | }; | |
67 | ||
68 | var step3list = { | |
69 | icate: 'ic', | |
70 | ative: '', | |
71 | alize: 'al', | |
72 | iciti: 'ic', | |
73 | ical: 'ic', | |
74 | ful: '', | |
75 | ness: '' | |
76 | }; | |
77 | ||
78 | var c = "[^aeiou]"; // consonant | |
79 | var v = "[aeiouy]"; // vowel | |
80 | var C = c + "[^aeiouy]*"; // consonant sequence | |
81 | var V = v + "[aeiou]*"; // vowel sequence | |
82 | ||
83 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 | |
84 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 | |
85 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 | |
86 | var s_v = "^(" + C + ")?" + v; // vowel in stem | |
87 | ||
88 | this.stemWord = function (w) { | |
89 | var stem; | |
90 | var suffix; | |
91 | var firstch; | |
92 | var origword = w; | |
93 | ||
94 | if (w.length < 3) | |
95 | return w; | |
96 | ||
97 | var re; | |
98 | var re2; | |
99 | var re3; | |
100 | var re4; | |
101 | ||
102 | firstch = w.substr(0,1); | |
103 | if (firstch == "y") | |
104 | w = firstch.toUpperCase() + w.substr(1); | |
105 | ||
106 | // Step 1a | |
107 | re = /^(.+?)(ss|i)es$/; | |
108 | re2 = /^(.+?)([^s])s$/; | |
109 | ||
110 | if (re.test(w)) | |
111 | w = w.replace(re,"$1$2"); | |
112 | else if (re2.test(w)) | |
113 | w = w.replace(re2,"$1$2"); | |
114 | ||
115 | // Step 1b | |
116 | re = /^(.+?)eed$/; | |
117 | re2 = /^(.+?)(ed|ing)$/; | |
118 | if (re.test(w)) { | |
119 | var fp = re.exec(w); | |
120 | re = new RegExp(mgr0); | |
121 | if (re.test(fp[1])) { | |
122 | re = /.$/; | |
123 | w = w.replace(re,""); | |
124 | } | |
125 | } | |
126 | else if (re2.test(w)) { | |
127 | var fp = re2.exec(w); | |
128 | stem = fp[1]; | |
129 | re2 = new RegExp(s_v); | |
130 | if (re2.test(stem)) { | |
131 | w = stem; | |
132 | re2 = /(at|bl|iz)$/; | |
133 | re3 = new RegExp("([^aeiouylsz])\\1$"); | |
134 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); | |
135 | if (re2.test(w)) | |
136 | w = w + "e"; | |
137 | else if (re3.test(w)) { | |
138 | re = /.$/; | |
139 | w = w.replace(re,""); | |
140 | } | |
141 | else if (re4.test(w)) | |
142 | w = w + "e"; | |
143 | } | |
144 | } | |
145 | ||
146 | // Step 1c | |
147 | re = /^(.+?)y$/; | |
148 | if (re.test(w)) { | |
149 | var fp = re.exec(w); | |
150 | stem = fp[1]; | |
151 | re = new RegExp(s_v); | |
152 | if (re.test(stem)) | |
153 | w = stem + "i"; | |
154 | } | |
155 | ||
156 | // Step 2 | |
157 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; | |
158 | if (re.test(w)) { | |
159 | var fp = re.exec(w); | |
160 | stem = fp[1]; | |
161 | suffix = fp[2]; | |
162 | re = new RegExp(mgr0); | |
163 | if (re.test(stem)) | |
164 | w = stem + step2list[suffix]; | |
165 | } | |
166 | ||
167 | // Step 3 | |
168 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; | |
169 | if (re.test(w)) { | |
170 | var fp = re.exec(w); | |
171 | stem = fp[1]; | |
172 | suffix = fp[2]; | |
173 | re = new RegExp(mgr0); | |
174 | if (re.test(stem)) | |
175 | w = stem + step3list[suffix]; | |
176 | } | |
177 | ||
178 | // Step 4 | |
179 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; | |
180 | re2 = /^(.+?)(s|t)(ion)$/; | |
181 | if (re.test(w)) { | |
182 | var fp = re.exec(w); | |
183 | stem = fp[1]; | |
184 | re = new RegExp(mgr1); | |
185 | if (re.test(stem)) | |
186 | w = stem; | |
187 | } | |
188 | else if (re2.test(w)) { | |
189 | var fp = re2.exec(w); | |
190 | stem = fp[1] + fp[2]; | |
191 | re2 = new RegExp(mgr1); | |
192 | if (re2.test(stem)) | |
193 | w = stem; | |
194 | } | |
195 | ||
196 | // Step 5 | |
197 | re = /^(.+?)e$/; | |
198 | if (re.test(w)) { | |
199 | var fp = re.exec(w); | |
200 | stem = fp[1]; | |
201 | re = new RegExp(mgr1); | |
202 | re2 = new RegExp(meq1); | |
203 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); | |
204 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) | |
205 | w = stem; | |
206 | } | |
207 | re = /ll$/; | |
208 | re2 = new RegExp(mgr1); | |
209 | if (re.test(w) && re2.test(w)) { | |
210 | re = /.$/; | |
211 | w = w.replace(re,""); | |
212 | } | |
213 | ||
214 | // and turn initial Y back to y | |
215 | if (firstch == "y") | |
216 | w = firstch.toLowerCase() + w.substr(1); | |
217 | return w; | |
218 | } | |
219 | } | |
220 | ||
221 | ||
222 | /** | |
223 | * Search Module | |
224 | */ | |
225 | var Search = { | |
226 | ||
227 | _index : null, | |
228 | _queued_query : null, | |
229 | _pulse_status : -1, | |
230 | ||
231 | init : function() { | |
232 | var params = $.getQueryParameters(); | |
233 | if (params.q) { | |
234 | var query = params.q[0]; | |
235 | $('input[name="q"]')[0].value = query; | |
236 | this.performSearch(query); | |
237 | } | |
238 | }, | |
239 | ||
240 | loadIndex : function(url) { | |
241 | $.ajax({type: "GET", url: url, data: null, success: null, | |
242 | dataType: "script", cache: true}); | |
243 | }, | |
244 | ||
245 | setIndex : function(index) { | |
246 | var q; | |
247 | this._index = index; | |
248 | if ((q = this._queued_query) !== null) { | |
249 | this._queued_query = null; | |
250 | Search.query(q); | |
251 | } | |
252 | }, | |
253 | ||
254 | hasIndex : function() { | |
255 | return this._index !== null; | |
256 | }, | |
257 | ||
258 | deferQuery : function(query) { | |
259 | this._queued_query = query; | |
260 | }, | |
261 | ||
262 | stopPulse : function() { | |
263 | this._pulse_status = 0; | |
264 | }, | |
265 | ||
266 | startPulse : function() { | |
267 | if (this._pulse_status >= 0) | |
268 | return; | |
269 | function pulse() { | |
270 | Search._pulse_status = (Search._pulse_status + 1) % 4; | |
271 | var dotString = ''; | |
272 | for (var i = 0; i < Search._pulse_status; i++) | |
273 | dotString += '.'; | |
274 | Search.dots.text(dotString); | |
275 | if (Search._pulse_status > -1) | |
276 | window.setTimeout(pulse, 500); | |
277 | }; | |
278 | pulse(); | |
279 | }, | |
280 | ||
281 | /** | |
282 | * perform a search for something | |
283 | */ | |
284 | performSearch : function(query) { | |
285 | // create the required interface elements | |
286 | this.out = $('#search-results'); | |
287 | this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out); | |
288 | this.dots = $('<span></span>').appendTo(this.title); | |
289 | this.status = $('<p style="display: none"></p>').appendTo(this.out); | |
290 | this.output = $('<ul class="search"/>').appendTo(this.out); | |
291 | ||
292 | $('#search-progress').text(_('Preparing search...')); | |
293 | this.startPulse(); | |
294 | ||
295 | // index already loaded, the browser was quick! | |
296 | if (this.hasIndex()) | |
297 | this.query(query); | |
298 | else | |
299 | this.deferQuery(query); | |
300 | }, | |
301 | ||
302 | query : function(query) { | |
303 | var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"]; | |
304 | ||
305 | // Stem the searchterms and add them to the correct list | |
306 | var stemmer = new Stemmer(); | |
307 | var searchterms = []; | |
308 | var excluded = []; | |
309 | var hlterms = []; | |
310 | var tmp = query.split(/\s+/); | |
311 | var objectterms = []; | |
312 | for (var i = 0; i < tmp.length; i++) { | |
313 | if (tmp[i] != "") { | |
314 | objectterms.push(tmp[i].toLowerCase()); | |
315 | } | |
316 | ||
317 | if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) || | |
318 | tmp[i] == "") { | |
319 | // skip this "word" | |
320 | continue; | |
321 | } | |
322 | // stem the word | |
323 | var word = stemmer.stemWord(tmp[i]).toLowerCase(); | |
324 | // select the correct list | |
325 | if (word[0] == '-') { | |
326 | var toAppend = excluded; | |
327 | word = word.substr(1); | |
328 | } | |
329 | else { | |
330 | var toAppend = searchterms; | |
331 | hlterms.push(tmp[i].toLowerCase()); | |
332 | } | |
333 | // only add if not already in the list | |
334 | if (!$.contains(toAppend, word)) | |
335 | toAppend.push(word); | |
336 | }; | |
337 | var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" ")); | |
338 | ||
339 | // console.debug('SEARCH: searching for:'); | |
340 | // console.info('required: ', searchterms); | |
341 | // console.info('excluded: ', excluded); | |
342 | ||
343 | // prepare search | |
344 | var filenames = this._index.filenames; | |
345 | var titles = this._index.titles; | |
346 | var terms = this._index.terms; | |
347 | var fileMap = {}; | |
348 | var files = null; | |
349 | // different result priorities | |
350 | var importantResults = []; | |
351 | var objectResults = []; | |
352 | var regularResults = []; | |
353 | var unimportantResults = []; | |
354 | $('#search-progress').empty(); | |
355 | ||
356 | // lookup as object | |
357 | for (var i = 0; i < objectterms.length; i++) { | |
358 | var others = [].concat(objectterms.slice(0,i), | |
359 | objectterms.slice(i+1, objectterms.length)) | |
360 | var results = this.performObjectSearch(objectterms[i], others); | |
361 | // Assume first word is most likely to be the object, | |
362 | // other words more likely to be in description. | |
363 | // Therefore put matches for earlier words first. | |
364 | // (Results are eventually used in reverse order). | |
365 | objectResults = results[0].concat(objectResults); | |
366 | importantResults = results[1].concat(importantResults); | |
367 | unimportantResults = results[2].concat(unimportantResults); | |
368 | } | |
369 | ||
370 | // perform the search on the required terms | |
371 | for (var i = 0; i < searchterms.length; i++) { | |
372 | var word = searchterms[i]; | |
373 | // no match but word was a required one | |
374 | if ((files = terms[word]) == null) | |
375 | break; | |
376 | if (files.length == undefined) { | |
377 | files = [files]; | |
378 | } | |
379 | // create the mapping | |
380 | for (var j = 0; j < files.length; j++) { | |
381 | var file = files[j]; | |
382 | if (file in fileMap) | |
383 | fileMap[file].push(word); | |
384 | else | |
385 | fileMap[file] = [word]; | |
386 | } | |
387 | } | |
388 | ||
389 | // now check if the files don't contain excluded terms | |
390 | for (var file in fileMap) { | |
391 | var valid = true; | |
392 | ||
393 | // check if all requirements are matched | |
394 | if (fileMap[file].length != searchterms.length) | |
395 | continue; | |
396 | ||
397 | // ensure that none of the excluded terms is in the | |
398 | // search result. | |
399 | for (var i = 0; i < excluded.length; i++) { | |
400 | if (terms[excluded[i]] == file || | |
401 | $.contains(terms[excluded[i]] || [], file)) { | |
402 | valid = false; | |
403 | break; | |
404 | } | |
405 | } | |
406 | ||
407 | // if we have still a valid result we can add it | |
408 | // to the result list | |
409 | if (valid) | |
410 | regularResults.push([filenames[file], titles[file], '', null]); | |
411 | } | |
412 | ||
413 | // delete unused variables in order to not waste | |
414 | // memory until list is retrieved completely | |
415 | delete filenames, titles, terms; | |
416 | ||
417 | // now sort the regular results descending by title | |
418 | regularResults.sort(function(a, b) { | |
419 | var left = a[1].toLowerCase(); | |
420 | var right = b[1].toLowerCase(); | |
421 | return (left > right) ? -1 : ((left < right) ? 1 : 0); | |
422 | }); | |
423 | ||
424 | // combine all results | |
425 | var results = unimportantResults.concat(regularResults) | |
426 | .concat(objectResults).concat(importantResults); | |
427 | ||
428 | // print the results | |
429 | var resultCount = results.length; | |
430 | function displayNextItem() { | |
431 | // results left, load the summary and display it | |
432 | if (results.length) { | |
433 | var item = results.pop(); | |
434 | var listItem = $('<li style="display:none"></li>'); | |
435 | if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') { | |
436 | // dirhtml builder | |
437 | var dirname = item[0] + '/'; | |
438 | if (dirname.match(/\/index\/$/)) { | |
439 | dirname = dirname.substring(0, dirname.length-6); | |
440 | } else if (dirname == 'index/') { | |
441 | dirname = ''; | |
442 | } | |
443 | listItem.append($('<a/>').attr('href', | |
444 | DOCUMENTATION_OPTIONS.URL_ROOT + dirname + | |
445 | highlightstring + item[2]).html(item[1])); | |
446 | } else { | |
447 | // normal html builders | |
448 | listItem.append($('<a/>').attr('href', | |
449 | item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX + | |
450 | highlightstring + item[2]).html(item[1])); | |
451 | } | |
452 | if (item[3]) { | |
453 | listItem.append($('<span> (' + item[3] + ')</span>')); | |
454 | Search.output.append(listItem); | |
455 | listItem.slideDown(5, function() { | |
456 | displayNextItem(); | |
457 | }); | |
458 | } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { | |
459 | $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + | |
460 | item[0] + '.txt', function(data) { | |
461 | if (data != '') { | |
462 | listItem.append($.makeSearchSummary(data, searchterms, hlterms)); | |
463 | Search.output.append(listItem); | |
464 | } | |
465 | listItem.slideDown(5, function() { | |
466 | displayNextItem(); | |
467 | }); | |
468 | }, "text"); | |
469 | } else { | |
470 | // no source available, just display title | |
471 | Search.output.append(listItem); | |
472 | listItem.slideDown(5, function() { | |
473 | displayNextItem(); | |
474 | }); | |
475 | } | |
476 | } | |
477 | // search finished, update title and status message | |
478 | else { | |
479 | Search.stopPulse(); | |
480 | Search.title.text(_('Search Results')); | |
481 | if (!resultCount) | |
482 | Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.')); | |
483 | else | |
484 | Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount)); | |
485 | Search.status.fadeIn(500); | |
486 | } | |
487 | } | |
488 | displayNextItem(); | |
489 | }, | |
490 | ||
491 | performObjectSearch : function(object, otherterms) { | |
492 | var filenames = this._index.filenames; | |
493 | var objects = this._index.objects; | |
494 | var objnames = this._index.objnames; | |
495 | var titles = this._index.titles; | |
496 | ||
497 | var importantResults = []; | |
498 | var objectResults = []; | |
499 | var unimportantResults = []; | |
500 | ||
501 | for (var prefix in objects) { | |
502 | for (var name in objects[prefix]) { | |
503 | var fullname = (prefix ? prefix + '.' : '') + name; | |
504 | if (fullname.toLowerCase().indexOf(object) > -1) { | |
505 | var match = objects[prefix][name]; | |
506 | var objname = objnames[match[1]][2]; | |
507 | var title = titles[match[0]]; | |
508 | // If more than one term searched for, we require other words to be | |
509 | // found in the name/title/description | |
510 | if (otherterms.length > 0) { | |
511 | var haystack = (prefix + ' ' + name + ' ' + | |
512 | objname + ' ' + title).toLowerCase(); | |
513 | var allfound = true; | |
514 | for (var i = 0; i < otherterms.length; i++) { | |
515 | if (haystack.indexOf(otherterms[i]) == -1) { | |
516 | allfound = false; | |
517 | break; | |
518 | } | |
519 | } | |
520 | if (!allfound) { | |
521 | continue; | |
522 | } | |
523 | } | |
524 | var descr = objname + _(', in ') + title; | |
525 | anchor = match[3]; | |
526 | if (anchor == '') | |
527 | anchor = fullname; | |
528 | else if (anchor == '-') | |
529 | anchor = objnames[match[1]][1] + '-' + fullname; | |
530 | result = [filenames[match[0]], fullname, '#'+anchor, descr]; | |
531 | switch (match[2]) { | |
532 | case 1: objectResults.push(result); break; | |
533 | case 0: importantResults.push(result); break; | |
534 | case 2: unimportantResults.push(result); break; | |
535 | } | |
536 | } | |
537 | } | |
538 | } | |
539 | ||
540 | // sort results descending | |
541 | objectResults.sort(function(a, b) { | |
542 | return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); | |
543 | }); | |
544 | ||
545 | importantResults.sort(function(a, b) { | |
546 | return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); | |
547 | }); | |
548 | ||
549 | unimportantResults.sort(function(a, b) { | |
550 | return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); | |
551 | }); | |
552 | ||
553 | return [importantResults, objectResults, unimportantResults] | |
554 | } | |
555 | } | |
556 | ||
557 | $(document).ready(function() { | |
558 | Search.init(); | |
559 | });⏎ |
0 | /* | |
1 | * sphinxdoc.css_t | |
2 | * ~~~~~~~~~~~~~~~ | |
3 | * | |
4 | * Sphinx stylesheet -- sphinxdoc theme. Originally created by | |
5 | * Armin Ronacher for Werkzeug. | |
6 | * | |
7 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. | |
8 | * :license: BSD, see LICENSE for details. | |
9 | * | |
10 | */ | |
11 | ||
12 | @import url("basic.css"); | |
13 | ||
14 | /* -- page layout ----------------------------------------------------------- */ | |
15 | ||
16 | body { | |
17 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', | |
18 | 'Verdana', sans-serif; | |
19 | font-size: 14px; | |
20 | letter-spacing: -0.01em; | |
21 | line-height: 150%; | |
22 | text-align: center; | |
23 | background-color: #BFD1D4; | |
24 | color: black; | |
25 | padding: 0; | |
26 | border: 1px solid #aaa; | |
27 | ||
28 | margin: 0px 80px 0px 80px; | |
29 | min-width: 740px; | |
30 | } | |
31 | ||
32 | div.document { | |
33 | background-color: white; | |
34 | text-align: left; | |
35 | background-image: url(contents.png); | |
36 | background-repeat: repeat-x; | |
37 | } | |
38 | ||
39 | div.bodywrapper { | |
40 | margin: 0 240px 0 0; | |
41 | border-right: 1px solid #ccc; | |
42 | } | |
43 | ||
44 | div.body { | |
45 | margin: 0; | |
46 | padding: 0.5em 20px 20px 20px; | |
47 | } | |
48 | ||
49 | div.related { | |
50 | font-size: 1em; | |
51 | } | |
52 | ||
53 | div.related ul { | |
54 | background-image: url(navigation.png); | |
55 | height: 2em; | |
56 | border-top: 1px solid #ddd; | |
57 | border-bottom: 1px solid #ddd; | |
58 | } | |
59 | ||
60 | div.related ul li { | |
61 | margin: 0; | |
62 | padding: 0; | |
63 | height: 2em; | |
64 | float: left; | |
65 | } | |
66 | ||
67 | div.related ul li.right { | |
68 | float: right; | |
69 | margin-right: 5px; | |
70 | } | |
71 | ||
72 | div.related ul li a { | |
73 | margin: 0; | |
74 | padding: 0 5px 0 5px; | |
75 | line-height: 1.75em; | |
76 | color: #EE9816; | |
77 | } | |
78 | ||
79 | div.related ul li a:hover { | |
80 | color: #3CA8E7; | |
81 | } | |
82 | ||
83 | div.sphinxsidebarwrapper { | |
84 | padding: 0; | |
85 | } | |
86 | ||
87 | div.sphinxsidebar { | |
88 | margin: 0; | |
89 | padding: 0.5em 15px 15px 0; | |
90 | width: 210px; | |
91 | float: right; | |
92 | font-size: 1em; | |
93 | text-align: left; | |
94 | } | |
95 | ||
96 | div.sphinxsidebar h3, div.sphinxsidebar h4 { | |
97 | margin: 1em 0 0.5em 0; | |
98 | font-size: 1em; | |
99 | padding: 0.1em 0 0.1em 0.5em; | |
100 | color: white; | |
101 | border: 1px solid #86989B; | |
102 | background-color: #AFC1C4; | |
103 | } | |
104 | ||
105 | div.sphinxsidebar h3 a { | |
106 | color: white; | |
107 | } | |
108 | ||
109 | div.sphinxsidebar ul { | |
110 | padding-left: 1.5em; | |
111 | margin-top: 7px; | |
112 | padding: 0; | |
113 | line-height: 130%; | |
114 | } | |
115 | ||
116 | div.sphinxsidebar ul ul { | |
117 | margin-left: 20px; | |
118 | } | |
119 | ||
120 | div.footer { | |
121 | background-color: #E3EFF1; | |
122 | color: #86989B; | |
123 | padding: 3px 8px 3px 0; | |
124 | clear: both; | |
125 | font-size: 0.8em; | |
126 | text-align: right; | |
127 | } | |
128 | ||
129 | div.footer a { | |
130 | color: #86989B; | |
131 | text-decoration: underline; | |
132 | } | |
133 | ||
134 | /* -- body styles ----------------------------------------------------------- */ | |
135 | ||
136 | p { | |
137 | margin: 0.8em 0 0.5em 0; | |
138 | } | |
139 | ||
140 | a { | |
141 | color: #CA7900; | |
142 | text-decoration: none; | |
143 | } | |
144 | ||
145 | a:hover { | |
146 | color: #2491CF; | |
147 | } | |
148 | ||
149 | div.body a { | |
150 | text-decoration: underline; | |
151 | } | |
152 | ||
153 | h1 { | |
154 | margin: 0; | |
155 | padding: 0.7em 0 0.3em 0; | |
156 | font-size: 1.5em; | |
157 | color: #11557C; | |
158 | } | |
159 | ||
160 | h2 { | |
161 | margin: 1.3em 0 0.2em 0; | |
162 | font-size: 1.35em; | |
163 | padding: 0; | |
164 | } | |
165 | ||
166 | h3 { | |
167 | margin: 1em 0 -0.3em 0; | |
168 | font-size: 1.2em; | |
169 | } | |
170 | ||
171 | div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { | |
172 | color: black!important; | |
173 | } | |
174 | ||
175 | h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { | |
176 | display: none; | |
177 | margin: 0 0 0 0.3em; | |
178 | padding: 0 0.2em 0 0.2em; | |
179 | color: #aaa!important; | |
180 | } | |
181 | ||
182 | h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, | |
183 | h5:hover a.anchor, h6:hover a.anchor { | |
184 | display: inline; | |
185 | } | |
186 | ||
187 | h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, | |
188 | h5 a.anchor:hover, h6 a.anchor:hover { | |
189 | color: #777; | |
190 | background-color: #eee; | |
191 | } | |
192 | ||
193 | a.headerlink { | |
194 | color: #c60f0f!important; | |
195 | font-size: 1em; | |
196 | margin-left: 6px; | |
197 | padding: 0 4px 0 4px; | |
198 | text-decoration: none!important; | |
199 | } | |
200 | ||
201 | a.headerlink:hover { | |
202 | background-color: #ccc; | |
203 | color: white!important; | |
204 | } | |
205 | ||
206 | cite, code, tt { | |
207 | font-family: 'Consolas', 'Deja Vu Sans Mono', | |
208 | 'Bitstream Vera Sans Mono', monospace; | |
209 | font-size: 0.95em; | |
210 | letter-spacing: 0.01em; | |
211 | } | |
212 | ||
213 | tt { | |
214 | background-color: #f2f2f2; | |
215 | border-bottom: 1px solid #ddd; | |
216 | color: #333; | |
217 | } | |
218 | ||
219 | tt.descname, tt.descclassname, tt.xref { | |
220 | border: 0; | |
221 | } | |
222 | ||
223 | hr { | |
224 | border: 1px solid #abc; | |
225 | margin: 2em; | |
226 | } | |
227 | ||
228 | a tt { | |
229 | border: 0; | |
230 | color: #CA7900; | |
231 | } | |
232 | ||
233 | a tt:hover { | |
234 | color: #2491CF; | |
235 | } | |
236 | ||
237 | pre { | |
238 | font-family: 'Consolas', 'Deja Vu Sans Mono', | |
239 | 'Bitstream Vera Sans Mono', monospace; | |
240 | font-size: 0.95em; | |
241 | letter-spacing: 0.015em; | |
242 | line-height: 120%; | |
243 | padding: 0.5em; | |
244 | border: 1px solid #ccc; | |
245 | background-color: #f8f8f8; | |
246 | } | |
247 | ||
248 | pre a { | |
249 | color: inherit; | |
250 | text-decoration: underline; | |
251 | } | |
252 | ||
253 | td.linenos pre { | |
254 | padding: 0.5em 0; | |
255 | } | |
256 | ||
257 | div.quotebar { | |
258 | background-color: #f8f8f8; | |
259 | max-width: 250px; | |
260 | float: right; | |
261 | padding: 2px 7px; | |
262 | border: 1px solid #ccc; | |
263 | } | |
264 | ||
265 | div.topic { | |
266 | background-color: #f8f8f8; | |
267 | } | |
268 | ||
269 | table { | |
270 | border-collapse: collapse; | |
271 | margin: 0 -0.5em 0 -0.5em; | |
272 | } | |
273 | ||
274 | table td, table th { | |
275 | padding: 0.2em 0.5em 0.2em 0.5em; | |
276 | } | |
277 | ||
278 | div.admonition, div.warning { | |
279 | font-size: 0.9em; | |
280 | margin: 1em 0 1em 0; | |
281 | border: 1px solid #86989B; | |
282 | background-color: #f7f7f7; | |
283 | padding: 0; | |
284 | } | |
285 | ||
286 | div.admonition p, div.warning p { | |
287 | margin: 0.5em 1em 0.5em 1em; | |
288 | padding: 0; | |
289 | } | |
290 | ||
291 | div.admonition pre, div.warning pre { | |
292 | margin: 0.4em 1em 0.4em 1em; | |
293 | } | |
294 | ||
295 | div.admonition p.admonition-title, | |
296 | div.warning p.admonition-title { | |
297 | margin: 0; | |
298 | padding: 0.1em 0 0.1em 0.5em; | |
299 | color: white; | |
300 | border-bottom: 1px solid #86989B; | |
301 | font-weight: bold; | |
302 | background-color: #AFC1C4; | |
303 | } | |
304 | ||
305 | div.warning { | |
306 | border: 1px solid #940000; | |
307 | } | |
308 | ||
309 | div.warning p.admonition-title { | |
310 | background-color: #CF0000; | |
311 | border-bottom-color: #940000; | |
312 | } | |
313 | ||
314 | div.admonition ul, div.admonition ol, | |
315 | div.warning ul, div.warning ol { | |
316 | margin: 0.1em 0.5em 0.5em 3em; | |
317 | padding: 0; | |
318 | } | |
319 | ||
320 | div.versioninfo { | |
321 | margin: 1em 0 0 0; | |
322 | border: 1px solid #ccc; | |
323 | background-color: #DDEAF0; | |
324 | padding: 8px; | |
325 | line-height: 1.3em; | |
326 | font-size: 0.9em; | |
327 | } | |
328 | ||
329 | .viewcode-back { | |
330 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', | |
331 | 'Verdana', sans-serif; | |
332 | } | |
333 | ||
334 | div.viewcode-block:target { | |
335 | background-color: #f4debf; | |
336 | border-top: 1px solid #ac9; | |
337 | border-bottom: 1px solid #ac9; | |
338 | }⏎ |
0 | // Underscore.js 0.5.5 | |
1 | // (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. | |
2 | // Underscore is freely distributable under the terms of the MIT license. | |
3 | // Portions of Underscore are inspired by or borrowed from Prototype.js, | |
4 | // Oliver Steele's Functional, and John Resig's Micro-Templating. | |
5 | // For all details and documentation: | |
6 | // http://documentcloud.github.com/underscore/ | |
7 | (function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d, | |
8 | a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c); | |
9 | var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c, | |
10 | d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck= | |
11 | function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a, | |
12 | function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a, | |
13 | 0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d, | |
14 | e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d= | |
15 | a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)}); | |
16 | return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length); | |
17 | var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false; | |
18 | if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length== | |
19 | 0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&& | |
20 | a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g, | |
21 | " ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments); | |
22 | o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})(); |
Binary diff not shown
Binary diff not shown
0 | /* | |
1 | * websupport.js | |
2 | * ~~~~~~~~~~~~~ | |
3 | * | |
4 | * sphinx.websupport utilties for all documentation. | |
5 | * | |
6 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. | |
7 | * :license: BSD, see LICENSE for details. | |
8 | * | |
9 | */ | |
10 | ||
11 | (function($) { | |
12 | $.fn.autogrow = function() { | |
13 | return this.each(function() { | |
14 | var textarea = this; | |
15 | ||
16 | $.fn.autogrow.resize(textarea); | |
17 | ||
18 | $(textarea) | |
19 | .focus(function() { | |
20 | textarea.interval = setInterval(function() { | |
21 | $.fn.autogrow.resize(textarea); | |
22 | }, 500); | |
23 | }) | |
24 | .blur(function() { | |
25 | clearInterval(textarea.interval); | |
26 | }); | |
27 | }); | |
28 | }; | |
29 | ||
30 | $.fn.autogrow.resize = function(textarea) { | |
31 | var lineHeight = parseInt($(textarea).css('line-height'), 10); | |
32 | var lines = textarea.value.split('\n'); | |
33 | var columns = textarea.cols; | |
34 | var lineCount = 0; | |
35 | $.each(lines, function() { | |
36 | lineCount += Math.ceil(this.length / columns) || 1; | |
37 | }); | |
38 | var height = lineHeight * (lineCount + 1); | |
39 | $(textarea).css('height', height); | |
40 | }; | |
41 | })(jQuery); | |
42 | ||
43 | (function($) { | |
44 | var comp, by; | |
45 | ||
46 | function init() { | |
47 | initEvents(); | |
48 | initComparator(); | |
49 | } | |
50 | ||
51 | function initEvents() { | |
52 | $('a.comment-close').live("click", function(event) { | |
53 | event.preventDefault(); | |
54 | hide($(this).attr('id').substring(2)); | |
55 | }); | |
56 | $('a.vote').live("click", function(event) { | |
57 | event.preventDefault(); | |
58 | handleVote($(this)); | |
59 | }); | |
60 | $('a.reply').live("click", function(event) { | |
61 | event.preventDefault(); | |
62 | openReply($(this).attr('id').substring(2)); | |
63 | }); | |
64 | $('a.close-reply').live("click", function(event) { | |
65 | event.preventDefault(); | |
66 | closeReply($(this).attr('id').substring(2)); | |
67 | }); | |
68 | $('a.sort-option').live("click", function(event) { | |
69 | event.preventDefault(); | |
70 | handleReSort($(this)); | |
71 | }); | |
72 | $('a.show-proposal').live("click", function(event) { | |
73 | event.preventDefault(); | |
74 | showProposal($(this).attr('id').substring(2)); | |
75 | }); | |
76 | $('a.hide-proposal').live("click", function(event) { | |
77 | event.preventDefault(); | |
78 | hideProposal($(this).attr('id').substring(2)); | |
79 | }); | |
80 | $('a.show-propose-change').live("click", function(event) { | |
81 | event.preventDefault(); | |
82 | showProposeChange($(this).attr('id').substring(2)); | |
83 | }); | |
84 | $('a.hide-propose-change').live("click", function(event) { | |
85 | event.preventDefault(); | |
86 | hideProposeChange($(this).attr('id').substring(2)); | |
87 | }); | |
88 | $('a.accept-comment').live("click", function(event) { | |
89 | event.preventDefault(); | |
90 | acceptComment($(this).attr('id').substring(2)); | |
91 | }); | |
92 | $('a.delete-comment').live("click", function(event) { | |
93 | event.preventDefault(); | |
94 | deleteComment($(this).attr('id').substring(2)); | |
95 | }); | |
96 | $('a.comment-markup').live("click", function(event) { | |
97 | event.preventDefault(); | |
98 | toggleCommentMarkupBox($(this).attr('id').substring(2)); | |
99 | }); | |
100 | } | |
101 | ||
102 | /** | |
103 | * Set comp, which is a comparator function used for sorting and | |
104 | * inserting comments into the list. | |
105 | */ | |
106 | function setComparator() { | |
107 | // If the first three letters are "asc", sort in ascending order | |
108 | // and remove the prefix. | |
109 | if (by.substring(0,3) == 'asc') { | |
110 | var i = by.substring(3); | |
111 | comp = function(a, b) { return a[i] - b[i]; }; | |
112 | } else { | |
113 | // Otherwise sort in descending order. | |
114 | comp = function(a, b) { return b[by] - a[by]; }; | |
115 | } | |
116 | ||
117 | // Reset link styles and format the selected sort option. | |
118 | $('a.sel').attr('href', '#').removeClass('sel'); | |
119 | $('a.by' + by).removeAttr('href').addClass('sel'); | |
120 | } | |
121 | ||
122 | /** | |
123 | * Create a comp function. If the user has preferences stored in | |
124 | * the sortBy cookie, use those, otherwise use the default. | |
125 | */ | |
126 | function initComparator() { | |
127 | by = 'rating'; // Default to sort by rating. | |
128 | // If the sortBy cookie is set, use that instead. | |
129 | if (document.cookie.length > 0) { | |
130 | var start = document.cookie.indexOf('sortBy='); | |
131 | if (start != -1) { | |
132 | start = start + 7; | |
133 | var end = document.cookie.indexOf(";", start); | |
134 | if (end == -1) { | |
135 | end = document.cookie.length; | |
136 | by = unescape(document.cookie.substring(start, end)); | |
137 | } | |
138 | } | |
139 | } | |
140 | setComparator(); | |
141 | } | |
142 | ||
143 | /** | |
144 | * Show a comment div. | |
145 | */ | |
146 | function show(id) { | |
147 | $('#ao' + id).hide(); | |
148 | $('#ah' + id).show(); | |
149 | var context = $.extend({id: id}, opts); | |
150 | var popup = $(renderTemplate(popupTemplate, context)).hide(); | |
151 | popup.find('textarea[name="proposal"]').hide(); | |
152 | popup.find('a.by' + by).addClass('sel'); | |
153 | var form = popup.find('#cf' + id); | |
154 | form.submit(function(event) { | |
155 | event.preventDefault(); | |
156 | addComment(form); | |
157 | }); | |
158 | $('#s' + id).after(popup); | |
159 | popup.slideDown('fast', function() { | |
160 | getComments(id); | |
161 | }); | |
162 | } | |
163 | ||
164 | /** | |
165 | * Hide a comment div. | |
166 | */ | |
167 | function hide(id) { | |
168 | $('#ah' + id).hide(); | |
169 | $('#ao' + id).show(); | |
170 | var div = $('#sc' + id); | |
171 | div.slideUp('fast', function() { | |
172 | div.remove(); | |
173 | }); | |
174 | } | |
175 | ||
176 | /** | |
177 | * Perform an ajax request to get comments for a node | |
178 | * and insert the comments into the comments tree. | |
179 | */ | |
180 | function getComments(id) { | |
181 | $.ajax({ | |
182 | type: 'GET', | |
183 | url: opts.getCommentsURL, | |
184 | data: {node: id}, | |
185 | success: function(data, textStatus, request) { | |
186 | var ul = $('#cl' + id); | |
187 | var speed = 100; | |
188 | $('#cf' + id) | |
189 | .find('textarea[name="proposal"]') | |
190 | .data('source', data.source); | |
191 | ||
192 | if (data.comments.length === 0) { | |
193 | ul.html('<li>No comments yet.</li>'); | |
194 | ul.data('empty', true); | |
195 | } else { | |
196 | // If there are comments, sort them and put them in the list. | |
197 | var comments = sortComments(data.comments); | |
198 | speed = data.comments.length * 100; | |
199 | appendComments(comments, ul); | |
200 | ul.data('empty', false); | |
201 | } | |
202 | $('#cn' + id).slideUp(speed + 200); | |
203 | ul.slideDown(speed); | |
204 | }, | |
205 | error: function(request, textStatus, error) { | |
206 | showError('Oops, there was a problem retrieving the comments.'); | |
207 | }, | |
208 | dataType: 'json' | |
209 | }); | |
210 | } | |
211 | ||
212 | /** | |
213 | * Add a comment via ajax and insert the comment into the comment tree. | |
214 | */ | |
215 | function addComment(form) { | |
216 | var node_id = form.find('input[name="node"]').val(); | |
217 | var parent_id = form.find('input[name="parent"]').val(); | |
218 | var text = form.find('textarea[name="comment"]').val(); | |
219 | var proposal = form.find('textarea[name="proposal"]').val(); | |
220 | ||
221 | if (text == '') { | |
222 | showError('Please enter a comment.'); | |
223 | return; | |
224 | } | |
225 | ||
226 | // Disable the form that is being submitted. | |
227 | form.find('textarea,input').attr('disabled', 'disabled'); | |
228 | ||
229 | // Send the comment to the server. | |
230 | $.ajax({ | |
231 | type: "POST", | |
232 | url: opts.addCommentURL, | |
233 | dataType: 'json', | |
234 | data: { | |
235 | node: node_id, | |
236 | parent: parent_id, | |
237 | text: text, | |
238 | proposal: proposal | |
239 | }, | |
240 | success: function(data, textStatus, error) { | |
241 | // Reset the form. | |
242 | if (node_id) { | |
243 | hideProposeChange(node_id); | |
244 | } | |
245 | form.find('textarea') | |
246 | .val('') | |
247 | .add(form.find('input')) | |
248 | .removeAttr('disabled'); | |
249 | var ul = $('#cl' + (node_id || parent_id)); | |
250 | if (ul.data('empty')) { | |
251 | $(ul).empty(); | |
252 | ul.data('empty', false); | |
253 | } | |
254 | insertComment(data.comment); | |
255 | var ao = $('#ao' + node_id); | |
256 | ao.find('img').attr({'src': opts.commentBrightImage}); | |
257 | if (node_id) { | |
258 | // if this was a "root" comment, remove the commenting box | |
259 | // (the user can get it back by reopening the comment popup) | |
260 | $('#ca' + node_id).slideUp(); | |
261 | } | |
262 | }, | |
263 | error: function(request, textStatus, error) { | |
264 | form.find('textarea,input').removeAttr('disabled'); | |
265 | showError('Oops, there was a problem adding the comment.'); | |
266 | } | |
267 | }); | |
268 | } | |
269 | ||
270 | /** | |
271 | * Recursively append comments to the main comment list and children | |
272 | * lists, creating the comment tree. | |
273 | */ | |
274 | function appendComments(comments, ul) { | |
275 | $.each(comments, function() { | |
276 | var div = createCommentDiv(this); | |
277 | ul.append($(document.createElement('li')).html(div)); | |
278 | appendComments(this.children, div.find('ul.comment-children')); | |
279 | // To avoid stagnating data, don't store the comments children in data. | |
280 | this.children = null; | |
281 | div.data('comment', this); | |
282 | }); | |
283 | } | |
284 | ||
285 | /** | |
286 | * After adding a new comment, it must be inserted in the correct | |
287 | * location in the comment tree. | |
288 | */ | |
289 | function insertComment(comment) { | |
290 | var div = createCommentDiv(comment); | |
291 | ||
292 | // To avoid stagnating data, don't store the comments children in data. | |
293 | comment.children = null; | |
294 | div.data('comment', comment); | |
295 | ||
296 | var ul = $('#cl' + (comment.node || comment.parent)); | |
297 | var siblings = getChildren(ul); | |
298 | ||
299 | var li = $(document.createElement('li')); | |
300 | li.hide(); | |
301 | ||
302 | // Determine where in the parents children list to insert this comment. | |
303 | for(i=0; i < siblings.length; i++) { | |
304 | if (comp(comment, siblings[i]) <= 0) { | |
305 | $('#cd' + siblings[i].id) | |
306 | .parent() | |
307 | .before(li.html(div)); | |
308 | li.slideDown('fast'); | |
309 | return; | |
310 | } | |
311 | } | |
312 | ||
313 | // If we get here, this comment rates lower than all the others, | |
314 | // or it is the only comment in the list. | |
315 | ul.append(li.html(div)); | |
316 | li.slideDown('fast'); | |
317 | } | |
318 | ||
319 | function acceptComment(id) { | |
320 | $.ajax({ | |
321 | type: 'POST', | |
322 | url: opts.acceptCommentURL, | |
323 | data: {id: id}, | |
324 | success: function(data, textStatus, request) { | |
325 | $('#cm' + id).fadeOut('fast'); | |
326 | $('#cd' + id).removeClass('moderate'); | |
327 | }, | |
328 | error: function(request, textStatus, error) { | |
329 | showError('Oops, there was a problem accepting the comment.'); | |
330 | } | |
331 | }); | |
332 | } | |
333 | ||
334 | function deleteComment(id) { | |
335 | $.ajax({ | |
336 | type: 'POST', | |
337 | url: opts.deleteCommentURL, | |
338 | data: {id: id}, | |
339 | success: function(data, textStatus, request) { | |
340 | var div = $('#cd' + id); | |
341 | if (data == 'delete') { | |
342 | // Moderator mode: remove the comment and all children immediately | |
343 | div.slideUp('fast', function() { | |
344 | div.remove(); | |
345 | }); | |
346 | return; | |
347 | } | |
348 | // User mode: only mark the comment as deleted | |
349 | div | |
350 | .find('span.user-id:first') | |
351 | .text('[deleted]').end() | |
352 | .find('div.comment-text:first') | |
353 | .text('[deleted]').end() | |
354 | .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id + | |
355 | ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id) | |
356 | .remove(); | |
357 | var comment = div.data('comment'); | |
358 | comment.username = '[deleted]'; | |
359 | comment.text = '[deleted]'; | |
360 | div.data('comment', comment); | |
361 | }, | |
362 | error: function(request, textStatus, error) { | |
363 | showError('Oops, there was a problem deleting the comment.'); | |
364 | } | |
365 | }); | |
366 | } | |
367 | ||
368 | function showProposal(id) { | |
369 | $('#sp' + id).hide(); | |
370 | $('#hp' + id).show(); | |
371 | $('#pr' + id).slideDown('fast'); | |
372 | } | |
373 | ||
374 | function hideProposal(id) { | |
375 | $('#hp' + id).hide(); | |
376 | $('#sp' + id).show(); | |
377 | $('#pr' + id).slideUp('fast'); | |
378 | } | |
379 | ||
380 | function showProposeChange(id) { | |
381 | $('#pc' + id).hide(); | |
382 | $('#hc' + id).show(); | |
383 | var textarea = $('#pt' + id); | |
384 | textarea.val(textarea.data('source')); | |
385 | $.fn.autogrow.resize(textarea[0]); | |
386 | textarea.slideDown('fast'); | |
387 | } | |
388 | ||
389 | function hideProposeChange(id) { | |
390 | $('#hc' + id).hide(); | |
391 | $('#pc' + id).show(); | |
392 | var textarea = $('#pt' + id); | |
393 | textarea.val('').removeAttr('disabled'); | |
394 | textarea.slideUp('fast'); | |
395 | } | |
396 | ||
397 | function toggleCommentMarkupBox(id) { | |
398 | $('#mb' + id).toggle(); | |
399 | } | |
400 | ||
401 | /** Handle when the user clicks on a sort by link. */ | |
402 | function handleReSort(link) { | |
403 | var classes = link.attr('class').split(/\s+/); | |
404 | for (var i=0; i<classes.length; i++) { | |
405 | if (classes[i] != 'sort-option') { | |
406 | by = classes[i].substring(2); | |
407 | } | |
408 | } | |
409 | setComparator(); | |
410 | // Save/update the sortBy cookie. | |
411 | var expiration = new Date(); | |
412 | expiration.setDate(expiration.getDate() + 365); | |
413 | document.cookie= 'sortBy=' + escape(by) + | |
414 | ';expires=' + expiration.toUTCString(); | |
415 | $('ul.comment-ul').each(function(index, ul) { | |
416 | var comments = getChildren($(ul), true); | |
417 | comments = sortComments(comments); | |
418 | appendComments(comments, $(ul).empty()); | |
419 | }); | |
420 | } | |
421 | ||
422 | /** | |
423 | * Function to process a vote when a user clicks an arrow. | |
424 | */ | |
425 | function handleVote(link) { | |
426 | if (!opts.voting) { | |
427 | showError("You'll need to login to vote."); | |
428 | return; | |
429 | } | |
430 | ||
431 | var id = link.attr('id'); | |
432 | if (!id) { | |
433 | // Didn't click on one of the voting arrows. | |
434 | return; | |
435 | } | |
436 | // If it is an unvote, the new vote value is 0, | |
437 | // Otherwise it's 1 for an upvote, or -1 for a downvote. | |
438 | var value = 0; | |
439 | if (id.charAt(1) != 'u') { | |
440 | value = id.charAt(0) == 'u' ? 1 : -1; | |
441 | } | |
442 | // The data to be sent to the server. | |
443 | var d = { | |
444 | comment_id: id.substring(2), | |
445 | value: value | |
446 | }; | |
447 | ||
448 | // Swap the vote and unvote links. | |
449 | link.hide(); | |
450 | $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id) | |
451 | .show(); | |
452 | ||
453 | // The div the comment is displayed in. | |
454 | var div = $('div#cd' + d.comment_id); | |
455 | var data = div.data('comment'); | |
456 | ||
457 | // If this is not an unvote, and the other vote arrow has | |
458 | // already been pressed, unpress it. | |
459 | if ((d.value !== 0) && (data.vote === d.value * -1)) { | |
460 | $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide(); | |
461 | $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show(); | |
462 | } | |
463 | ||
464 | // Update the comments rating in the local data. | |
465 | data.rating += (data.vote === 0) ? d.value : (d.value - data.vote); | |
466 | data.vote = d.value; | |
467 | div.data('comment', data); | |
468 | ||
469 | // Change the rating text. | |
470 | div.find('.rating:first') | |
471 | .text(data.rating + ' point' + (data.rating == 1 ? '' : 's')); | |
472 | ||
473 | // Send the vote information to the server. | |
474 | $.ajax({ | |
475 | type: "POST", | |
476 | url: opts.processVoteURL, | |
477 | data: d, | |
478 | error: function(request, textStatus, error) { | |
479 | showError('Oops, there was a problem casting that vote.'); | |
480 | } | |
481 | }); | |
482 | } | |
483 | ||
484 | /** | |
485 | * Open a reply form used to reply to an existing comment. | |
486 | */ | |
487 | function openReply(id) { | |
488 | // Swap out the reply link for the hide link | |
489 | $('#rl' + id).hide(); | |
490 | $('#cr' + id).show(); | |
491 | ||
492 | // Add the reply li to the children ul. | |
493 | var div = $(renderTemplate(replyTemplate, {id: id})).hide(); | |
494 | $('#cl' + id) | |
495 | .prepend(div) | |
496 | // Setup the submit handler for the reply form. | |
497 | .find('#rf' + id) | |
498 | .submit(function(event) { | |
499 | event.preventDefault(); | |
500 | addComment($('#rf' + id)); | |
501 | closeReply(id); | |
502 | }) | |
503 | .find('input[type=button]') | |
504 | .click(function() { | |
505 | closeReply(id); | |
506 | }); | |
507 | div.slideDown('fast', function() { | |
508 | $('#rf' + id).find('textarea').focus(); | |
509 | }); | |
510 | } | |
511 | ||
512 | /** | |
513 | * Close the reply form opened with openReply. | |
514 | */ | |
515 | function closeReply(id) { | |
516 | // Remove the reply div from the DOM. | |
517 | $('#rd' + id).slideUp('fast', function() { | |
518 | $(this).remove(); | |
519 | }); | |
520 | ||
521 | // Swap out the hide link for the reply link | |
522 | $('#cr' + id).hide(); | |
523 | $('#rl' + id).show(); | |
524 | } | |
525 | ||
526 | /** | |
527 | * Recursively sort a tree of comments using the comp comparator. | |
528 | */ | |
529 | function sortComments(comments) { | |
530 | comments.sort(comp); | |
531 | $.each(comments, function() { | |
532 | this.children = sortComments(this.children); | |
533 | }); | |
534 | return comments; | |
535 | } | |
536 | ||
537 | /** | |
538 | * Get the children comments from a ul. If recursive is true, | |
539 | * recursively include childrens' children. | |
540 | */ | |
541 | function getChildren(ul, recursive) { | |
542 | var children = []; | |
543 | ul.children().children("[id^='cd']") | |
544 | .each(function() { | |
545 | var comment = $(this).data('comment'); | |
546 | if (recursive) | |
547 | comment.children = getChildren($(this).find('#cl' + comment.id), true); | |
548 | children.push(comment); | |
549 | }); | |
550 | return children; | |
551 | } | |
552 | ||
553 | /** Create a div to display a comment in. */ | |
554 | function createCommentDiv(comment) { | |
555 | if (!comment.displayed && !opts.moderator) { | |
556 | return $('<div class="moderate">Thank you! Your comment will show up ' | |
557 | + 'once it is has been approved by a moderator.</div>'); | |
558 | } | |
559 | // Prettify the comment rating. | |
560 | comment.pretty_rating = comment.rating + ' point' + | |
561 | (comment.rating == 1 ? '' : 's'); | |
562 | // Make a class (for displaying not yet moderated comments differently) | |
563 | comment.css_class = comment.displayed ? '' : ' moderate'; | |
564 | // Create a div for this comment. | |
565 | var context = $.extend({}, opts, comment); | |
566 | var div = $(renderTemplate(commentTemplate, context)); | |
567 | ||
568 | // If the user has voted on this comment, highlight the correct arrow. | |
569 | if (comment.vote) { | |
570 | var direction = (comment.vote == 1) ? 'u' : 'd'; | |
571 | div.find('#' + direction + 'v' + comment.id).hide(); | |
572 | div.find('#' + direction + 'u' + comment.id).show(); | |
573 | } | |
574 | ||
575 | if (opts.moderator || comment.text != '[deleted]') { | |
576 | div.find('a.reply').show(); | |
577 | if (comment.proposal_diff) | |
578 | div.find('#sp' + comment.id).show(); | |
579 | if (opts.moderator && !comment.displayed) | |
580 | div.find('#cm' + comment.id).show(); | |
581 | if (opts.moderator || (opts.username == comment.username)) | |
582 | div.find('#dc' + comment.id).show(); | |
583 | } | |
584 | return div; | |
585 | } | |
586 | ||
587 | /** | |
588 | * A simple template renderer. Placeholders such as <%id%> are replaced | |
589 | * by context['id'] with items being escaped. Placeholders such as <#id#> | |
590 | * are not escaped. | |
591 | */ | |
592 | function renderTemplate(template, context) { | |
593 | var esc = $(document.createElement('div')); | |
594 | ||
595 | function handle(ph, escape) { | |
596 | var cur = context; | |
597 | $.each(ph.split('.'), function() { | |
598 | cur = cur[this]; | |
599 | }); | |
600 | return escape ? esc.text(cur || "").html() : cur; | |
601 | } | |
602 | ||
603 | return template.replace(/<([%#])([\w\.]*)\1>/g, function() { | |
604 | return handle(arguments[2], arguments[1] == '%' ? true : false); | |
605 | }); | |
606 | } | |
607 | ||
608 | /** Flash an error message briefly. */ | |
609 | function showError(message) { | |
610 | $(document.createElement('div')).attr({'class': 'popup-error'}) | |
611 | .append($(document.createElement('div')) | |
612 | .attr({'class': 'error-message'}).text(message)) | |
613 | .appendTo('body') | |
614 | .fadeIn("slow") | |
615 | .delay(2000) | |
616 | .fadeOut("slow"); | |
617 | } | |
618 | ||
619 | /** Add a link the user uses to open the comments popup. */ | |
620 | $.fn.comment = function() { | |
621 | return this.each(function() { | |
622 | var id = $(this).attr('id').substring(1); | |
623 | var count = COMMENT_METADATA[id]; | |
624 | var title = count + ' comment' + (count == 1 ? '' : 's'); | |
625 | var image = count > 0 ? opts.commentBrightImage : opts.commentImage; | |
626 | var addcls = count == 0 ? ' nocomment' : ''; | |
627 | $(this) | |
628 | .append( | |
629 | $(document.createElement('a')).attr({ | |
630 | href: '#', | |
631 | 'class': 'sphinx-comment-open' + addcls, | |
632 | id: 'ao' + id | |
633 | }) | |
634 | .append($(document.createElement('img')).attr({ | |
635 | src: image, | |
636 | alt: 'comment', | |
637 | title: title | |
638 | })) | |
639 | .click(function(event) { | |
640 | event.preventDefault(); | |
641 | show($(this).attr('id').substring(2)); | |
642 | }) | |
643 | ) | |
644 | .append( | |
645 | $(document.createElement('a')).attr({ | |
646 | href: '#', | |
647 | 'class': 'sphinx-comment-close hidden', | |
648 | id: 'ah' + id | |
649 | }) | |
650 | .append($(document.createElement('img')).attr({ | |
651 | src: opts.closeCommentImage, | |
652 | alt: 'close', | |
653 | title: 'close' | |
654 | })) | |
655 | .click(function(event) { | |
656 | event.preventDefault(); | |
657 | hide($(this).attr('id').substring(2)); | |
658 | }) | |
659 | ); | |
660 | }); | |
661 | }; | |
662 | ||
663 | var opts = { | |
664 | processVoteURL: '/_process_vote', | |
665 | addCommentURL: '/_add_comment', | |
666 | getCommentsURL: '/_get_comments', | |
667 | acceptCommentURL: '/_accept_comment', | |
668 | deleteCommentURL: '/_delete_comment', | |
669 | commentImage: '/static/_static/comment.png', | |
670 | closeCommentImage: '/static/_static/comment-close.png', | |
671 | loadingImage: '/static/_static/ajax-loader.gif', | |
672 | commentBrightImage: '/static/_static/comment-bright.png', | |
673 | upArrow: '/static/_static/up.png', | |
674 | downArrow: '/static/_static/down.png', | |
675 | upArrowPressed: '/static/_static/up-pressed.png', | |
676 | downArrowPressed: '/static/_static/down-pressed.png', | |
677 | voting: false, | |
678 | moderator: false | |
679 | }; | |
680 | ||
681 | if (typeof COMMENT_OPTIONS != "undefined") { | |
682 | opts = jQuery.extend(opts, COMMENT_OPTIONS); | |
683 | } | |
684 | ||
685 | var popupTemplate = '\ | |
686 | <div class="sphinx-comments" id="sc<%id%>">\ | |
687 | <p class="sort-options">\ | |
688 | Sort by:\ | |
689 | <a href="#" class="sort-option byrating">best rated</a>\ | |
690 | <a href="#" class="sort-option byascage">newest</a>\ | |
691 | <a href="#" class="sort-option byage">oldest</a>\ | |
692 | </p>\ | |
693 | <div class="comment-header">Comments</div>\ | |
694 | <div class="comment-loading" id="cn<%id%>">\ | |
695 | loading comments... <img src="<%loadingImage%>" alt="" /></div>\ | |
696 | <ul id="cl<%id%>" class="comment-ul"></ul>\ | |
697 | <div id="ca<%id%>">\ | |
698 | <p class="add-a-comment">Add a comment\ | |
699 | (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\ | |
700 | <div class="comment-markup-box" id="mb<%id%>">\ | |
701 | reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \ | |
702 | <tt>``code``</tt>, \ | |
703 | code blocks: <tt>::</tt> and an indented block after blank line</div>\ | |
704 | <form method="post" id="cf<%id%>" class="comment-form" action="">\ | |
705 | <textarea name="comment" cols="80"></textarea>\ | |
706 | <p class="propose-button">\ | |
707 | <a href="#" id="pc<%id%>" class="show-propose-change">\ | |
708 | Propose a change ▹\ | |
709 | </a>\ | |
710 | <a href="#" id="hc<%id%>" class="hide-propose-change">\ | |
711 | Propose a change ▿\ | |
712 | </a>\ | |
713 | </p>\ | |
714 | <textarea name="proposal" id="pt<%id%>" cols="80"\ | |
715 | spellcheck="false"></textarea>\ | |
716 | <input type="submit" value="Add comment" />\ | |
717 | <input type="hidden" name="node" value="<%id%>" />\ | |
718 | <input type="hidden" name="parent" value="" />\ | |
719 | </form>\ | |
720 | </div>\ | |
721 | </div>'; | |
722 | ||
723 | var commentTemplate = '\ | |
724 | <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\ | |
725 | <div class="vote">\ | |
726 | <div class="arrow">\ | |
727 | <a href="#" id="uv<%id%>" class="vote" title="vote up">\ | |
728 | <img src="<%upArrow%>" />\ | |
729 | </a>\ | |
730 | <a href="#" id="uu<%id%>" class="un vote" title="vote up">\ | |
731 | <img src="<%upArrowPressed%>" />\ | |
732 | </a>\ | |
733 | </div>\ | |
734 | <div class="arrow">\ | |
735 | <a href="#" id="dv<%id%>" class="vote" title="vote down">\ | |
736 | <img src="<%downArrow%>" id="da<%id%>" />\ | |
737 | </a>\ | |
738 | <a href="#" id="du<%id%>" class="un vote" title="vote down">\ | |
739 | <img src="<%downArrowPressed%>" />\ | |
740 | </a>\ | |
741 | </div>\ | |
742 | </div>\ | |
743 | <div class="comment-content">\ | |
744 | <p class="tagline comment">\ | |
745 | <span class="user-id"><%username%></span>\ | |
746 | <span class="rating"><%pretty_rating%></span>\ | |
747 | <span class="delta"><%time.delta%></span>\ | |
748 | </p>\ | |
749 | <div class="comment-text comment"><#text#></div>\ | |
750 | <p class="comment-opts comment">\ | |
751 | <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\ | |
752 | <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\ | |
753 | <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\ | |
754 | <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\ | |
755 | <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\ | |
756 | <span id="cm<%id%>" class="moderation hidden">\ | |
757 | <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\ | |
758 | </span>\ | |
759 | </p>\ | |
760 | <pre class="proposal" id="pr<%id%>">\ | |
761 | <#proposal_diff#>\ | |
762 | </pre>\ | |
763 | <ul class="comment-children" id="cl<%id%>"></ul>\ | |
764 | </div>\ | |
765 | <div class="clearleft"></div>\ | |
766 | </div>\ | |
767 | </div>'; | |
768 | ||
769 | var replyTemplate = '\ | |
770 | <li>\ | |
771 | <div class="reply-div" id="rd<%id%>">\ | |
772 | <form id="rf<%id%>">\ | |
773 | <textarea name="comment" cols="80"></textarea>\ | |
774 | <input type="submit" value="Add reply" />\ | |
775 | <input type="button" value="Cancel" />\ | |
776 | <input type="hidden" name="parent" value="<%id%>" />\ | |
777 | <input type="hidden" name="node" value="" />\ | |
778 | </form>\ | |
779 | </div>\ | |
780 | </li>'; | |
781 | ||
782 | $(document).ready(function() { | |
783 | init(); | |
784 | }); | |
785 | })(jQuery); | |
786 | ||
787 | $(document).ready(function() { | |
788 | // add comment anchors for all paragraphs that are commentable | |
789 | $('.sphinx-has-comment').comment(); | |
790 | ||
791 | // highlight search words in search results | |
792 | $("div.context").each(function() { | |
793 | var params = $.getQueryParameters(); | |
794 | var terms = (params.q) ? params.q[0].split(/\s+/) : []; | |
795 | var result = $(this); | |
796 | $.each(terms, function() { | |
797 | result.highlightText(this.toLowerCase(), 'highlighted'); | |
798 | }); | |
799 | }); | |
800 | ||
801 | // directly open comment window if requested | |
802 | var anchor = document.location.hash; | |
803 | if (anchor.substring(0, 9) == '#comment-') { | |
804 | $('#ao' + anchor.substring(9)).click(); | |
805 | document.location.hash = '#s' + anchor.substring(9); | |
806 | } | |
807 | }); |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>NBNSProtocol Class — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | <link rel="next" title="NetBIOS class" href="nmb_NetBIOS.html" /> | |
29 | <link rel="prev" title="Welcome to pysmb’s documentation!" href="../index.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="../genindex.html" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li class="right" > | |
39 | <a href="nmb_NetBIOS.html" title="NetBIOS class" | |
40 | accesskey="N">next</a> |</li> | |
41 | <li class="right" > | |
42 | <a href="../index.html" title="Welcome to pysmb’s documentation!" | |
43 | accesskey="P">previous</a> |</li> | |
44 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
45 | </ul> | |
46 | </div> | |
47 | <div class="sphinxsidebar"> | |
48 | <div class="sphinxsidebarwrapper"> | |
49 | <h4>Previous topic</h4> | |
50 | <p class="topless"><a href="../index.html" | |
51 | title="previous chapter">Welcome to pysmb’s documentation!</a></p> | |
52 | <h4>Next topic</h4> | |
53 | <p class="topless"><a href="nmb_NetBIOS.html" | |
54 | title="next chapter">NetBIOS class</a></p> | |
55 | <h3>This Page</h3> | |
56 | <ul class="this-page-menu"> | |
57 | <li><a href="../_sources/api/nmb_NBNSProtocol.txt" | |
58 | rel="nofollow">Show Source</a></li> | |
59 | </ul> | |
60 | <div id="searchbox" style="display: none"> | |
61 | <h3>Quick search</h3> | |
62 | <form class="search" action="../search.html" method="get"> | |
63 | <input type="text" name="q" /> | |
64 | <input type="submit" value="Go" /> | |
65 | <input type="hidden" name="check_keywords" value="yes" /> | |
66 | <input type="hidden" name="area" value="default" /> | |
67 | </form> | |
68 | <p class="searchtip" style="font-size: 90%"> | |
69 | Enter search terms or a module, class or function name. | |
70 | </p> | |
71 | </div> | |
72 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
73 | </div> | |
74 | </div> | |
75 | ||
76 | <div class="document"> | |
77 | <div class="documentwrapper"> | |
78 | <div class="bodywrapper"> | |
79 | <div class="body"> | |
80 | ||
81 | <div class="section" id="nbnsprotocol-class"> | |
82 | <h1>NBNSProtocol Class<a class="headerlink" href="#nbnsprotocol-class" title="Permalink to this headline">¶</a></h1> | |
83 | <p>pysmb has a <em>NBNSProtocol</em> implementation for Twisted framework. | |
84 | This allows you to perform name query asynchronously without having your application to block and wait for the results.</p> | |
85 | <dl class="docutils"> | |
86 | <dt>In your project,</dt> | |
87 | <dd><ol class="first last arabic simple"> | |
88 | <li>Create a NBNSProtocol instance.</li> | |
89 | <li>Just call <em>queryName</em> method which will return a <em>Deferred</em> instance. Add your callback function to the <em>Deferred</em> instance via <em>addCallback</em> method to receive the results of the name query.</li> | |
90 | <li>When you are done with the NBNSProtocol instance, call its <NBNSProtocol instance>.transport.stopListening method to remove this instance from the reactor.</li> | |
91 | </ol> | |
92 | </dd> | |
93 | </dl> | |
94 | <dl class="class"> | |
95 | <dt id="nmb.NetBIOSProtocol.NBNSProtocol"> | |
96 | <em class="property">class </em><tt class="descclassname">nmb.NetBIOSProtocol.</tt><tt class="descname">NBNSProtocol</tt><big>(</big><em>broadcast=True</em>, <em>listen_port=0</em><big>)</big><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NBNSProtocol"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NBNSProtocol" title="Permalink to this definition">¶</a></dt> | |
97 | <dd><dl class="method"> | |
98 | <dt id="nmb.NetBIOSProtocol.NBNSProtocol.__init__"> | |
99 | <tt class="descname">__init__</tt><big>(</big><em>broadcast=True</em>, <em>listen_port=0</em><big>)</big><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NBNSProtocol.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NBNSProtocol.__init__" title="Permalink to this definition">¶</a></dt> | |
100 | <dd><p>Instantiate a NBNSProtocol instance.</p> | |
101 | <p>This automatically calls reactor.listenUDP method to start listening for incoming packets, so you <strong>must not</strong> call the listenUDP method again.</p> | |
102 | <table class="docutils field-list" frame="void" rules="none"> | |
103 | <col class="field-name" /> | |
104 | <col class="field-body" /> | |
105 | <tbody valign="top"> | |
106 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple"> | |
107 | <li><strong>broadcast</strong> (<em>boolean</em>) – A boolean flag to indicate if we should setup the listening UDP port in broadcast mode</li> | |
108 | <li><strong>listen_port</strong> (<em>integer</em>) – Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.</li> | |
109 | </ul> | |
110 | </td> | |
111 | </tr> | |
112 | </tbody> | |
113 | </table> | |
114 | </dd></dl> | |
115 | ||
116 | <dl class="method"> | |
117 | <dt id="nmb.NetBIOSProtocol.NBNSProtocol.queryName"> | |
118 | <tt class="descname">queryName</tt><big>(</big><em>name</em>, <em>ip=''</em>, <em>port=137</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NBNSProtocol.queryName"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NBNSProtocol.queryName" title="Permalink to this definition">¶</a></dt> | |
119 | <dd><p>Send a query on the network and hopes that if machine matching the <em>name</em> will reply with its IP address.</p> | |
120 | <table class="docutils field-list" frame="void" rules="none"> | |
121 | <col class="field-name" /> | |
122 | <col class="field-body" /> | |
123 | <tbody valign="top"> | |
124 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
125 | <li><strong>ip</strong> (<em>string</em>) – If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address. | |
126 | If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</li> | |
127 | <li><strong>port</strong> (<em>integer</em>) – The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</li> | |
128 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds to wait for a reply, after which the returned Deferred instance will be called with a NetBIOSTimeout exception.</li> | |
129 | </ul> | |
130 | </td> | |
131 | </tr> | |
132 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of IP addresses in dotted notation (aaa.bbb.ccc.ddd). | |
133 | On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception</p> | |
134 | </td> | |
135 | </tr> | |
136 | </tbody> | |
137 | </table> | |
138 | </dd></dl> | |
139 | ||
140 | </dd></dl> | |
141 | ||
142 | <dl class="class"> | |
143 | <dt id="nmb.NetBIOSProtocol.NetBIOSTimeout"> | |
144 | <em class="property">class </em><tt class="descclassname">nmb.NetBIOSProtocol.</tt><tt class="descname">NetBIOSTimeout</tt><a class="reference internal" href="../_modules/nmb/NetBIOSProtocol.html#NetBIOSTimeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOSProtocol.NetBIOSTimeout" title="Permalink to this definition">¶</a></dt> | |
145 | <dd><p>Raised in NBNSProtocol via Deferred.errback method when queryName method has timeout waiting for reply</p> | |
146 | </dd></dl> | |
147 | ||
148 | </div> | |
149 | ||
150 | ||
151 | </div> | |
152 | </div> | |
153 | </div> | |
154 | <div class="clearer"></div> | |
155 | </div> | |
156 | <div class="related"> | |
157 | <h3>Navigation</h3> | |
158 | <ul> | |
159 | <li class="right" style="margin-right: 10px"> | |
160 | <a href="../genindex.html" title="General Index" | |
161 | >index</a></li> | |
162 | <li class="right" > | |
163 | <a href="nmb_NetBIOS.html" title="NetBIOS class" | |
164 | >next</a> |</li> | |
165 | <li class="right" > | |
166 | <a href="../index.html" title="Welcome to pysmb’s documentation!" | |
167 | >previous</a> |</li> | |
168 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
169 | </ul> | |
170 | </div> | |
171 | <div class="footer"> | |
172 | © Copyright 2011, Michael Teo. | |
173 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
174 | </div> | |
175 | </body> | |
176 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>NetBIOS class — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | <link rel="next" title="SMBConnection Class" href="smb_SMBConnection.html" /> | |
29 | <link rel="prev" title="NBNSProtocol Class" href="nmb_NBNSProtocol.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="../genindex.html" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li class="right" > | |
39 | <a href="smb_SMBConnection.html" title="SMBConnection Class" | |
40 | accesskey="N">next</a> |</li> | |
41 | <li class="right" > | |
42 | <a href="nmb_NBNSProtocol.html" title="NBNSProtocol Class" | |
43 | accesskey="P">previous</a> |</li> | |
44 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
45 | </ul> | |
46 | </div> | |
47 | <div class="sphinxsidebar"> | |
48 | <div class="sphinxsidebarwrapper"> | |
49 | <h4>Previous topic</h4> | |
50 | <p class="topless"><a href="nmb_NBNSProtocol.html" | |
51 | title="previous chapter">NBNSProtocol Class</a></p> | |
52 | <h4>Next topic</h4> | |
53 | <p class="topless"><a href="smb_SMBConnection.html" | |
54 | title="next chapter">SMBConnection Class</a></p> | |
55 | <h3>This Page</h3> | |
56 | <ul class="this-page-menu"> | |
57 | <li><a href="../_sources/api/nmb_NetBIOS.txt" | |
58 | rel="nofollow">Show Source</a></li> | |
59 | </ul> | |
60 | <div id="searchbox" style="display: none"> | |
61 | <h3>Quick search</h3> | |
62 | <form class="search" action="../search.html" method="get"> | |
63 | <input type="text" name="q" /> | |
64 | <input type="submit" value="Go" /> | |
65 | <input type="hidden" name="check_keywords" value="yes" /> | |
66 | <input type="hidden" name="area" value="default" /> | |
67 | </form> | |
68 | <p class="searchtip" style="font-size: 90%"> | |
69 | Enter search terms or a module, class or function name. | |
70 | </p> | |
71 | </div> | |
72 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
73 | </div> | |
74 | </div> | |
75 | ||
76 | <div class="document"> | |
77 | <div class="documentwrapper"> | |
78 | <div class="bodywrapper"> | |
79 | <div class="body"> | |
80 | ||
81 | <div class="section" id="netbios-class"> | |
82 | <h1>NetBIOS class<a class="headerlink" href="#netbios-class" title="Permalink to this headline">¶</a></h1> | |
83 | <dl class="docutils"> | |
84 | <dt>To use the NetBIOS class in your application,</dt> | |
85 | <dd><ol class="first last arabic simple"> | |
86 | <li>Create a new NetBIOS instance</li> | |
87 | <li>Call <em>queryName</em> method for each name you wish to query. The method will block until a reply is received from the remote SMB/CIFS service, or until timeout.</li> | |
88 | <li>When you are done, call <em>close</em> method to release the underlying resources.</li> | |
89 | </ol> | |
90 | </dd> | |
91 | </dl> | |
92 | <dl class="class"> | |
93 | <dt id="nmb.NetBIOS.NetBIOS"> | |
94 | <em class="property">class </em><tt class="descclassname">nmb.NetBIOS.</tt><tt class="descname">NetBIOS</tt><big>(</big><em>broadcast=True</em>, <em>listen_port=0</em><big>)</big><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS" title="Permalink to this definition">¶</a></dt> | |
95 | <dd><dl class="method"> | |
96 | <dt id="nmb.NetBIOS.NetBIOS.__init__"> | |
97 | <tt class="descname">__init__</tt><big>(</big><em>broadcast=True</em>, <em>listen_port=0</em><big>)</big><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.__init__" title="Permalink to this definition">¶</a></dt> | |
98 | <dd><p>Instantiate a NetBIOS instance, and creates a IPv4 UDP socket to listen/send NBNS packets.</p> | |
99 | <table class="docutils field-list" frame="void" rules="none"> | |
100 | <col class="field-name" /> | |
101 | <col class="field-body" /> | |
102 | <tbody valign="top"> | |
103 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple"> | |
104 | <li><strong>broadcast</strong> (<em>boolean</em>) – A boolean flag to indicate if we should setup the listening UDP port in broadcast mode</li> | |
105 | <li><strong>listen_port</strong> (<em>integer</em>) – Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number.</li> | |
106 | </ul> | |
107 | </td> | |
108 | </tr> | |
109 | </tbody> | |
110 | </table> | |
111 | </dd></dl> | |
112 | ||
113 | <dl class="method"> | |
114 | <dt id="nmb.NetBIOS.NetBIOS.close"> | |
115 | <tt class="descname">close</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.close" title="Permalink to this definition">¶</a></dt> | |
116 | <dd><p>Close the underlying and free resources.</p> | |
117 | <p>The NetBIOS instance should not be used to perform any operations after this method returns.</p> | |
118 | <table class="docutils field-list" frame="void" rules="none"> | |
119 | <col class="field-name" /> | |
120 | <col class="field-body" /> | |
121 | <tbody valign="top"> | |
122 | <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">None</td> | |
123 | </tr> | |
124 | </tbody> | |
125 | </table> | |
126 | </dd></dl> | |
127 | ||
128 | <dl class="method"> | |
129 | <dt id="nmb.NetBIOS.NetBIOS.queryName"> | |
130 | <tt class="descname">queryName</tt><big>(</big><em>name</em>, <em>ip=''</em>, <em>port=137</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/nmb/NetBIOS.html#NetBIOS.queryName"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#nmb.NetBIOS.NetBIOS.queryName" title="Permalink to this definition">¶</a></dt> | |
131 | <dd><p>Send a query on the network and hopes that if machine matching the <em>name</em> will reply with its IP address.</p> | |
132 | <table class="docutils field-list" frame="void" rules="none"> | |
133 | <col class="field-name" /> | |
134 | <col class="field-body" /> | |
135 | <tbody valign="top"> | |
136 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
137 | <li><strong>ip</strong> (<em>string</em>) – If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address. | |
138 | If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query.</li> | |
139 | <li><strong>port</strong> (<em>integer</em>) – The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing.</li> | |
140 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds to wait for a reply, after which the method will return None</li> | |
141 | </ul> | |
142 | </td> | |
143 | </tr> | |
144 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A list of IP addresses in dotted notation (aaa.bbb.ccc.ddd). On timeout, returns None.</p> | |
145 | </td> | |
146 | </tr> | |
147 | </tbody> | |
148 | </table> | |
149 | </dd></dl> | |
150 | ||
151 | </dd></dl> | |
152 | ||
153 | </div> | |
154 | ||
155 | ||
156 | </div> | |
157 | </div> | |
158 | </div> | |
159 | <div class="clearer"></div> | |
160 | </div> | |
161 | <div class="related"> | |
162 | <h3>Navigation</h3> | |
163 | <ul> | |
164 | <li class="right" style="margin-right: 10px"> | |
165 | <a href="../genindex.html" title="General Index" | |
166 | >index</a></li> | |
167 | <li class="right" > | |
168 | <a href="smb_SMBConnection.html" title="SMBConnection Class" | |
169 | >next</a> |</li> | |
170 | <li class="right" > | |
171 | <a href="nmb_NBNSProtocol.html" title="NBNSProtocol Class" | |
172 | >previous</a> |</li> | |
173 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
174 | </ul> | |
175 | </div> | |
176 | <div class="footer"> | |
177 | © Copyright 2011, Michael Teo. | |
178 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
179 | </div> | |
180 | </body> | |
181 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>SMBConnection Class — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | <link rel="next" title="SMBProtocolFactory Class" href="smb_SMBProtocolFactory.html" /> | |
29 | <link rel="prev" title="NetBIOS class" href="nmb_NetBIOS.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="../genindex.html" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li class="right" > | |
39 | <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class" | |
40 | accesskey="N">next</a> |</li> | |
41 | <li class="right" > | |
42 | <a href="nmb_NetBIOS.html" title="NetBIOS class" | |
43 | accesskey="P">previous</a> |</li> | |
44 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
45 | </ul> | |
46 | </div> | |
47 | <div class="sphinxsidebar"> | |
48 | <div class="sphinxsidebarwrapper"> | |
49 | <h3><a href="../index.html">Table Of Contents</a></h3> | |
50 | <ul> | |
51 | <li><a class="reference internal" href="#">SMBConnection Class</a><ul> | |
52 | <li><a class="reference internal" href="#caveats">Caveats</a></li> | |
53 | </ul> | |
54 | </li> | |
55 | </ul> | |
56 | ||
57 | <h4>Previous topic</h4> | |
58 | <p class="topless"><a href="nmb_NetBIOS.html" | |
59 | title="previous chapter">NetBIOS class</a></p> | |
60 | <h4>Next topic</h4> | |
61 | <p class="topless"><a href="smb_SMBProtocolFactory.html" | |
62 | title="next chapter">SMBProtocolFactory Class</a></p> | |
63 | <h3>This Page</h3> | |
64 | <ul class="this-page-menu"> | |
65 | <li><a href="../_sources/api/smb_SMBConnection.txt" | |
66 | rel="nofollow">Show Source</a></li> | |
67 | </ul> | |
68 | <div id="searchbox" style="display: none"> | |
69 | <h3>Quick search</h3> | |
70 | <form class="search" action="../search.html" method="get"> | |
71 | <input type="text" name="q" /> | |
72 | <input type="submit" value="Go" /> | |
73 | <input type="hidden" name="check_keywords" value="yes" /> | |
74 | <input type="hidden" name="area" value="default" /> | |
75 | </form> | |
76 | <p class="searchtip" style="font-size: 90%"> | |
77 | Enter search terms or a module, class or function name. | |
78 | </p> | |
79 | </div> | |
80 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
81 | </div> | |
82 | </div> | |
83 | ||
84 | <div class="document"> | |
85 | <div class="documentwrapper"> | |
86 | <div class="bodywrapper"> | |
87 | <div class="body"> | |
88 | ||
89 | <div class="section" id="smbconnection-class"> | |
90 | <h1>SMBConnection Class<a class="headerlink" href="#smbconnection-class" title="Permalink to this headline">¶</a></h1> | |
91 | <p>The SMBConnection is suitable for developers who wish to use pysmb to perform file operations with a remote SMB/CIFS server sequentially.</p> | |
92 | <p>Each file operation method, when invoked, will block and return after it has completed or has encountered an error.</p> | |
93 | <div class="section" id="caveats"> | |
94 | <h2>Caveats<a class="headerlink" href="#caveats" title="Permalink to this headline">¶</a></h2> | |
95 | <ul class="simple"> | |
96 | <li>It is not meant to be used asynchronously.</li> | |
97 | <li>A single <em>SMBConnection</em> instance should not be used to perform more than one operation concurrently at the same time.</li> | |
98 | <li>Do not keep a <em>SMBConnection</em> instance “idle” for too long, i.e. keeping a <em>SMBConnection</em> instance but not using it. | |
99 | Most SMB/CIFS servers have some sort of keepalive mechanism and impose a timeout limit. | |
100 | If the clients fail to respond within the timeout limit, the SMB/CIFS server may disconnect the client.</li> | |
101 | </ul> | |
102 | <dl class="class"> | |
103 | <dt id="smb.SMBConnection.SMBConnection"> | |
104 | <em class="property">class </em><tt class="descclassname">smb.SMBConnection.</tt><tt class="descname">SMBConnection</tt><big>(</big><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection" title="Permalink to this definition">¶</a></dt> | |
105 | <dd><dl class="method"> | |
106 | <dt id="smb.SMBConnection.SMBConnection.__init__"> | |
107 | <tt class="descname">__init__</tt><big>(</big><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.__init__" title="Permalink to this definition">¶</a></dt> | |
108 | <dd><p>Create a new SMBConnection instance.</p> | |
109 | <p><em>username</em> and <em>password</em> are the user credentials required to authenticate the underlying SMB connection with the remote server. | |
110 | File operations can only be proceeded after the connection has been authenticated successfully.</p> | |
111 | <p>Note that you need to call <em>connect</em> method to actually establish the SMB connection to the remote server and perform authentication.</p> | |
112 | <table class="docutils field-list" frame="void" rules="none"> | |
113 | <col class="field-name" /> | |
114 | <col class="field-body" /> | |
115 | <tbody valign="top"> | |
116 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple"> | |
117 | <li><strong>my_name</strong> (<em>string</em>) – The local NetBIOS machine name that will identify where this connection is originating from. | |
118 | You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of <tt class="docutils literal"><span class="pre">\/:*?";|+</span></tt></li> | |
119 | <li><strong>remote_name</strong> (<em>string</em>) – The NetBIOS machine name of the remote server. | |
120 | On windows, you can find out the machine name by right-clicking on the “My Computer” and selecting “Properties”. | |
121 | This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</li> | |
122 | <li><strong>domain</strong> (<em>string</em>) – The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string.</li> | |
123 | <li><strong>use_ntlm_v2</strong> (<em>boolean</em>) – Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication. | |
124 | The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured. | |
125 | Hence, we can only “guess” or try both algorithms. | |
126 | On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2.</li> | |
127 | </ul> | |
128 | </td> | |
129 | </tr> | |
130 | </tbody> | |
131 | </table> | |
132 | </dd></dl> | |
133 | ||
134 | <dl class="method"> | |
135 | <dt id="smb.SMBConnection.SMBConnection.close"> | |
136 | <tt class="descname">close</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.close" title="Permalink to this definition">¶</a></dt> | |
137 | <dd><p>Terminate the SMB connection (if it has been started) and release any sources held by the underlying socket.</p> | |
138 | </dd></dl> | |
139 | ||
140 | <dl class="method"> | |
141 | <dt id="smb.SMBConnection.SMBConnection.connect"> | |
142 | <tt class="descname">connect</tt><big>(</big><em>ip</em>, <em>port</em>, <em>sock_family=2</em>, <em>timeout=60</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.connect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.connect" title="Permalink to this definition">¶</a></dt> | |
143 | <dd><p>Establish the SMB connection to the remote SMB/CIFS server.</p> | |
144 | <p>You must call this method before attempting any of the file operations with the remote server. | |
145 | This method will block until the SMB connection has attempted at least one authentication.</p> | |
146 | <table class="docutils field-list" frame="void" rules="none"> | |
147 | <col class="field-name" /> | |
148 | <col class="field-body" /> | |
149 | <tbody valign="top"> | |
150 | <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">A boolean value indicating the result of the authentication atttempt: True if authentication is successful; False, if otherwise.</td> | |
151 | </tr> | |
152 | </tbody> | |
153 | </table> | |
154 | </dd></dl> | |
155 | ||
156 | <dl class="method"> | |
157 | <dt id="smb.SMBConnection.SMBConnection.createDirectory"> | |
158 | <tt class="descname">createDirectory</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.createDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.createDirectory" title="Permalink to this definition">¶</a></dt> | |
159 | <dd><p>Creates a new directory <em>path</em> on the <em>service_name</em>.</p> | |
160 | <table class="docutils field-list" frame="void" rules="none"> | |
161 | <col class="field-name" /> | |
162 | <col class="field-body" /> | |
163 | <tbody valign="top"> | |
164 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
165 | <li><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</li> | |
166 | <li><strong>path</strong> (<em>string/unicode</em>) – The path of the new folder (relative to) the shared folder. | |
167 | If the path contains non-English characters, an unicode string must be used to pass in the path.</li> | |
168 | </ul> | |
169 | </td> | |
170 | </tr> | |
171 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p> | |
172 | </td> | |
173 | </tr> | |
174 | </tbody> | |
175 | </table> | |
176 | </dd></dl> | |
177 | ||
178 | <dl class="method"> | |
179 | <dt id="smb.SMBConnection.SMBConnection.deleteDirectory"> | |
180 | <tt class="descname">deleteDirectory</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.deleteDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.deleteDirectory" title="Permalink to this definition">¶</a></dt> | |
181 | <dd><p>Delete the empty folder at <em>path</em> on <em>service_name</em></p> | |
182 | <table class="docutils field-list" frame="void" rules="none"> | |
183 | <col class="field-name" /> | |
184 | <col class="field-body" /> | |
185 | <tbody valign="top"> | |
186 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
187 | <li><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</li> | |
188 | <li><strong>path</strong> (<em>string/unicode</em>) – The path of the to-be-deleted folder (relative to) the shared folder. | |
189 | If the path contains non-English characters, an unicode string must be used to pass in the path.</li> | |
190 | </ul> | |
191 | </td> | |
192 | </tr> | |
193 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p> | |
194 | </td> | |
195 | </tr> | |
196 | </tbody> | |
197 | </table> | |
198 | </dd></dl> | |
199 | ||
200 | <dl class="method"> | |
201 | <dt id="smb.SMBConnection.SMBConnection.deleteFiles"> | |
202 | <tt class="descname">deleteFiles</tt><big>(</big><em>service_name</em>, <em>path_file_pattern</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.deleteFiles"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.deleteFiles" title="Permalink to this definition">¶</a></dt> | |
203 | <dd><p>Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</p> | |
204 | <table class="docutils field-list" frame="void" rules="none"> | |
205 | <col class="field-name" /> | |
206 | <col class="field-body" /> | |
207 | <tbody valign="top"> | |
208 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
209 | <li><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</li> | |
210 | <li><strong>path_file_pattern</strong> (<em>string/unicode</em>) – The pathname of the file(s) to be deleted, relative to the service_name. | |
211 | Wildcards may be used in th filename component of the path. | |
212 | If your path/filename contains non-English characters, you must pass in an unicode string.</li> | |
213 | </ul> | |
214 | </td> | |
215 | </tr> | |
216 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">None</p> | |
217 | </td> | |
218 | </tr> | |
219 | </tbody> | |
220 | </table> | |
221 | </dd></dl> | |
222 | ||
223 | <dl class="method"> | |
224 | <dt id="smb.SMBConnection.SMBConnection.echo"> | |
225 | <tt class="descname">echo</tt><big>(</big><em>data</em>, <em>timeout=10</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.echo"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.echo" title="Permalink to this definition">¶</a></dt> | |
226 | <dd><p>Send an echo command containing <em>data</em> to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same <em>data</em>.</p> | |
227 | <table class="docutils field-list" frame="void" rules="none"> | |
228 | <col class="field-name" /> | |
229 | <col class="field-body" /> | |
230 | <tbody valign="top"> | |
231 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>data</strong> (<em>string</em>) – Data to send to the remote server.</td> | |
232 | </tr> | |
233 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">The <em>data</em> parameter</td> | |
234 | </tr> | |
235 | </tbody> | |
236 | </table> | |
237 | </dd></dl> | |
238 | ||
239 | <dl class="method"> | |
240 | <dt id="smb.SMBConnection.SMBConnection.listPath"> | |
241 | <tt class="descname">listPath</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>search=55</em>, <em>pattern='\*'</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listPath"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listPath" title="Permalink to this definition">¶</a></dt> | |
242 | <dd><p>Retrieve a directory listing of files/folders at <em>path</em></p> | |
243 | <table class="docutils field-list" frame="void" rules="none"> | |
244 | <col class="field-name" /> | |
245 | <col class="field-body" /> | |
246 | <tbody valign="top"> | |
247 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
248 | <li><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></li> | |
249 | <li><strong>path</strong> (<em>string/unicode</em>) – path relative to the <em>service_name</em> where we are interested to learn about its files/sub-folders.</li> | |
250 | <li><strong>search</strong> (<em>integer</em>) – integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py). | |
251 | The default <em>search</em> value will query for all read-only, hidden, system, archive files and directories.</li> | |
252 | <li><strong>pattern</strong> (<em>string/unicode</em>) – the filter to apply to the results before returning to the client.</li> | |
253 | </ul> | |
254 | </td> | |
255 | </tr> | |
256 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A list of <a class="reference internal" href="smb_SharedFile.html"><em>smb.base.SharedFile</em></a> instances.</p> | |
257 | </td> | |
258 | </tr> | |
259 | </tbody> | |
260 | </table> | |
261 | </dd></dl> | |
262 | ||
263 | <dl class="method"> | |
264 | <dt id="smb.SMBConnection.SMBConnection.listShares"> | |
265 | <tt class="descname">listShares</tt><big>(</big><em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.listShares"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.listShares" title="Permalink to this definition">¶</a></dt> | |
266 | <dd><p>Retrieve a list of shared resources on remote server.</p> | |
267 | <table class="docutils field-list" frame="void" rules="none"> | |
268 | <col class="field-name" /> | |
269 | <col class="field-body" /> | |
270 | <tbody valign="top"> | |
271 | <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">A list of <a class="reference internal" href="smb_SharedDevice.html"><em>smb.base.SharedDevice</em></a> instances describing the shared resource</td> | |
272 | </tr> | |
273 | </tbody> | |
274 | </table> | |
275 | </dd></dl> | |
276 | ||
277 | <dl class="method"> | |
278 | <dt id="smb.SMBConnection.SMBConnection.rename"> | |
279 | <tt class="descname">rename</tt><big>(</big><em>service_name</em>, <em>old_path</em>, <em>new_path</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.rename"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.rename" title="Permalink to this definition">¶</a></dt> | |
280 | <dd><p>Rename a file or folder at <em>old_path</em> to <em>new_path</em> shared at <em>service_name</em>. Note that this method cannot be used to rename file/folder across different shared folders</p> | |
281 | <p><em>old_path</em> and <em>new_path</em> are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder. | |
282 | If the path contains non-English characters, an unicode string must be used to pass in the path.</p> | |
283 | <table class="docutils field-list" frame="void" rules="none"> | |
284 | <col class="field-name" /> | |
285 | <col class="field-body" /> | |
286 | <tbody valign="top"> | |
287 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</td> | |
288 | </tr> | |
289 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">None</td> | |
290 | </tr> | |
291 | </tbody> | |
292 | </table> | |
293 | </dd></dl> | |
294 | ||
295 | <dl class="method"> | |
296 | <dt id="smb.SMBConnection.SMBConnection.retrieveFile"> | |
297 | <tt class="descname">retrieveFile</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.retrieveFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.retrieveFile" title="Permalink to this definition">¶</a></dt> | |
298 | <dd><p>Retrieve the contents of the file at <em>path</em> on the <em>service_name</em> and write these contents to the provided <em>file_obj</em>.</p> | |
299 | <table class="docutils field-list" frame="void" rules="none"> | |
300 | <col class="field-name" /> | |
301 | <col class="field-body" /> | |
302 | <tbody valign="top"> | |
303 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
304 | <li><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></li> | |
305 | <li><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be called in the returned <em>Deferred</em> errback.</li> | |
306 | <li><strong>file_obj</strong> – A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> until EOF is received from the remote service.</li> | |
307 | </ul> | |
308 | </td> | |
309 | </tr> | |
310 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A 2-element tuple of ( file attributes of the file on server, number of bytes retrieved ). | |
311 | The file attributes is an integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py)</p> | |
312 | </td> | |
313 | </tr> | |
314 | </tbody> | |
315 | </table> | |
316 | </dd></dl> | |
317 | ||
318 | <dl class="method"> | |
319 | <dt id="smb.SMBConnection.SMBConnection.storeFile"> | |
320 | <tt class="descname">storeFile</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBConnection.html#SMBConnection.storeFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBConnection.SMBConnection.storeFile" title="Permalink to this definition">¶</a></dt> | |
321 | <dd><p>Store the contents of the <em>file_obj</em> at <em>path</em> on the <em>service_name</em>.</p> | |
322 | <table class="docutils field-list" frame="void" rules="none"> | |
323 | <col class="field-name" /> | |
324 | <col class="field-body" /> | |
325 | <tbody valign="top"> | |
326 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
327 | <li><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></li> | |
328 | <li><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file at <em>path</em> does not exist, it will be created. Otherwise, it will be overwritten. | |
329 | If the <em>path</em> refers to a folder or the file cannot be opened for writing, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be called in the returned <em>Deferred</em> errback.</li> | |
330 | <li><strong>file_obj</strong> – A file-like object that has a <em>read</em> method. Data will read continuously from <em>file_obj</em> until EOF.</li> | |
331 | </ul> | |
332 | </td> | |
333 | </tr> | |
334 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">Number of bytes uploaded</p> | |
335 | </td> | |
336 | </tr> | |
337 | </tbody> | |
338 | </table> | |
339 | </dd></dl> | |
340 | ||
341 | </dd></dl> | |
342 | ||
343 | </div> | |
344 | </div> | |
345 | ||
346 | ||
347 | </div> | |
348 | </div> | |
349 | </div> | |
350 | <div class="clearer"></div> | |
351 | </div> | |
352 | <div class="related"> | |
353 | <h3>Navigation</h3> | |
354 | <ul> | |
355 | <li class="right" style="margin-right: 10px"> | |
356 | <a href="../genindex.html" title="General Index" | |
357 | >index</a></li> | |
358 | <li class="right" > | |
359 | <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class" | |
360 | >next</a> |</li> | |
361 | <li class="right" > | |
362 | <a href="nmb_NetBIOS.html" title="NetBIOS class" | |
363 | >previous</a> |</li> | |
364 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
365 | </ul> | |
366 | </div> | |
367 | <div class="footer"> | |
368 | © Copyright 2011, Michael Teo. | |
369 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
370 | </div> | |
371 | </body> | |
372 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>SMBProtocolFactory Class — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | <link rel="next" title="SharedDevice Class" href="smb_SharedDevice.html" /> | |
29 | <link rel="prev" title="SMBConnection Class" href="smb_SMBConnection.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="../genindex.html" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li class="right" > | |
39 | <a href="smb_SharedDevice.html" title="SharedDevice Class" | |
40 | accesskey="N">next</a> |</li> | |
41 | <li class="right" > | |
42 | <a href="smb_SMBConnection.html" title="SMBConnection Class" | |
43 | accesskey="P">previous</a> |</li> | |
44 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
45 | </ul> | |
46 | </div> | |
47 | <div class="sphinxsidebar"> | |
48 | <div class="sphinxsidebarwrapper"> | |
49 | <h3><a href="../index.html">Table Of Contents</a></h3> | |
50 | <ul> | |
51 | <li><a class="reference internal" href="#">SMBProtocolFactory Class</a><ul> | |
52 | <li><a class="reference internal" href="#caveats">Caveats</a></li> | |
53 | </ul> | |
54 | </li> | |
55 | </ul> | |
56 | ||
57 | <h4>Previous topic</h4> | |
58 | <p class="topless"><a href="smb_SMBConnection.html" | |
59 | title="previous chapter">SMBConnection Class</a></p> | |
60 | <h4>Next topic</h4> | |
61 | <p class="topless"><a href="smb_SharedDevice.html" | |
62 | title="next chapter">SharedDevice Class</a></p> | |
63 | <h3>This Page</h3> | |
64 | <ul class="this-page-menu"> | |
65 | <li><a href="../_sources/api/smb_SMBProtocolFactory.txt" | |
66 | rel="nofollow">Show Source</a></li> | |
67 | </ul> | |
68 | <div id="searchbox" style="display: none"> | |
69 | <h3>Quick search</h3> | |
70 | <form class="search" action="../search.html" method="get"> | |
71 | <input type="text" name="q" /> | |
72 | <input type="submit" value="Go" /> | |
73 | <input type="hidden" name="check_keywords" value="yes" /> | |
74 | <input type="hidden" name="area" value="default" /> | |
75 | </form> | |
76 | <p class="searchtip" style="font-size: 90%"> | |
77 | Enter search terms or a module, class or function name. | |
78 | </p> | |
79 | </div> | |
80 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
81 | </div> | |
82 | </div> | |
83 | ||
84 | <div class="document"> | |
85 | <div class="documentwrapper"> | |
86 | <div class="bodywrapper"> | |
87 | <div class="body"> | |
88 | ||
89 | <div class="section" id="smbprotocolfactory-class"> | |
90 | <h1>SMBProtocolFactory Class<a class="headerlink" href="#smbprotocolfactory-class" title="Permalink to this headline">¶</a></h1> | |
91 | <p>For those who want to utilize pysmb in Twisted framework, pysmb has a <em>smb.SMBProtocol.SMBProtocol</em> implementation. | |
92 | In most cases, you do not need to touch or import the <em>SMBProtocol</em> directly. All the SMB functionalities are exposed in the <em>SMBProtocolFactory</em>.</p> | |
93 | <dl class="docutils"> | |
94 | <dt>In your project,</dt> | |
95 | <dd><ol class="first last arabic simple"> | |
96 | <li>Create a new class and subclass <em>SMBProtocolFactory</em>.</li> | |
97 | <li>Override the <em>SMBProtocolFactory.onAuthOK</em> and <em>SMBProtocolFactory.onAuthFailed</em> instance methods to provide your own post-authenthentication handling. | |
98 | Once <em>SMBProtocolFactory.onAuthOK</em> has been called by pymsb internals, your application is ready to communicate with the remote SMB/CIFS service through | |
99 | the <em>SMBProtocolFactory</em> public methods such as <em>SMBProtocolFactory.storeFile</em>, <em>SMBProtocolFactory.retrieveFile</em>, etc.</li> | |
100 | <li>When you want to disconnect from the remote SMB/CIFS server, just call <em>SMBProtocolFactory.closeConnection</em> method.</li> | |
101 | </ol> | |
102 | </dd> | |
103 | </dl> | |
104 | <p>All the <em>SMBProtocolFactory</em> public methods that provide file functionlities will return a <em>twisted.internet.defer.Deferred</em> instance. | |
105 | A <a class="reference internal" href="smb_exceptions.html"><em>NotReadyError</em></a> exception is raised when the underlying SMB is not authenticated. | |
106 | If the underlying SMB connection has been terminated, a <a class="reference internal" href="smb_exceptions.html"><em>NotConnectedError</em></a> exception is raised.</p> | |
107 | <p>All the file operation methods in <em>SMBProtocolFactory</em> class accept a <em>timeout</em> parameter. This parameter specifies the time limit where pysmb will wait for the | |
108 | entire file operation (except <em>storeFile</em> and <em>retrieveFile</em> methods) to complete. If the file operation fails to complete within the timeout period, the returned | |
109 | <em>Deferred</em> instance’s <em>errback</em> method will be called with a <em>SMBTimeout</em> exception.</p> | |
110 | <p>If you are interested in learning the results of the operation or to know when the operation has completed, you should | |
111 | add a handling method to the returned <em>Deferred</em> instance via <em>Deferred.addCallback</em>. If the file operation fails, the <em>Deferred.errback</em> function will be called | |
112 | with an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a>; on timeout, it will be called with a <a class="reference internal" href="smb_exceptions.html"><em>SMBTimeout</em></a>.</p> | |
113 | <div class="section" id="caveats"> | |
114 | <h2>Caveats<a class="headerlink" href="#caveats" title="Permalink to this headline">¶</a></h2> | |
115 | <ul class="simple"> | |
116 | <li>A new factory instance must be created for each SMB connection to the remote SMB/CIFS service. Avoid reusing the same factory instance for more than one SMB connection.</li> | |
117 | <li>The remote SMB/CIFS server usually imposes a limit of the number of concurrent file operations for each client. For example, to transfer a thousand files, you may need to setup a queue in your application and call <em>storeFile</em> or <em>retrieveFile</em> in batches.</li> | |
118 | <li>The <em>timeout</em> parameter in the file operation methods are not precise; it is accurate to within 1 second interval, i.e. with a timeout of 0.5 sec, pysmb might raise | |
119 | <em>SMBTimeout</em> exception after 1.5 sec.</li> | |
120 | </ul> | |
121 | <dl class="class"> | |
122 | <dt id="smb.SMBProtocol.SMBProtocolFactory"> | |
123 | <em class="property">class </em><tt class="descclassname">smb.SMBProtocol.</tt><tt class="descname">SMBProtocolFactory</tt><big>(</big><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory" title="Permalink to this definition">¶</a></dt> | |
124 | <dd><dl class="method"> | |
125 | <dt id="smb.SMBProtocol.SMBProtocolFactory.__init__"> | |
126 | <tt class="descname">__init__</tt><big>(</big><em>username</em>, <em>password</em>, <em>my_name</em>, <em>remote_name</em>, <em>domain=''</em>, <em>use_ntlm_v2=True</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.__init__" title="Permalink to this definition">¶</a></dt> | |
127 | <dd><p>Create a new SMBProtocolFactory instance.</p> | |
128 | <p><em>username</em> and <em>password</em> are the user credentials required to authenticate the underlying SMB connection with the remote server. | |
129 | File operations can only be proceeded after the connection has been authenticated successfully.</p> | |
130 | <table class="docutils field-list" frame="void" rules="none"> | |
131 | <col class="field-name" /> | |
132 | <col class="field-body" /> | |
133 | <tbody valign="top"> | |
134 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple"> | |
135 | <li><strong>my_name</strong> (<em>string</em>) – The local NetBIOS machine name that will identify where this connection is originating from. | |
136 | You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of <tt class="docutils literal"><span class="pre">\/:*?";|+</span></tt></li> | |
137 | <li><strong>remote_name</strong> (<em>string</em>) – The NetBIOS machine name of the remote server. | |
138 | On windows, you can find out the machine name by right-clicking on the “My Computer” and selecting “Properties”. | |
139 | This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected.</li> | |
140 | <li><strong>domain</strong> (<em>string</em>) – The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string.</li> | |
141 | <li><strong>use_ntlm_v2</strong> (<em>boolean</em>) – Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication. | |
142 | The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured. | |
143 | Hence, we can only “guess” or try both algorithms. | |
144 | On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2.</li> | |
145 | </ul> | |
146 | </td> | |
147 | </tr> | |
148 | </tbody> | |
149 | </table> | |
150 | </dd></dl> | |
151 | ||
152 | <dl class="method"> | |
153 | <dt id="smb.SMBProtocol.SMBProtocolFactory.closeConnection"> | |
154 | <tt class="descname">closeConnection</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.closeConnection"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.closeConnection" title="Permalink to this definition">¶</a></dt> | |
155 | <dd><p>Disconnect from the remote SMB/CIFS server. The TCP connection will be closed at the earliest opportunity after this method returns.</p> | |
156 | <table class="docutils field-list" frame="void" rules="none"> | |
157 | <col class="field-name" /> | |
158 | <col class="field-body" /> | |
159 | <tbody valign="top"> | |
160 | <tr class="field-odd field"><th class="field-name">Returns:</th><td class="field-body">None</td> | |
161 | </tr> | |
162 | </tbody> | |
163 | </table> | |
164 | </dd></dl> | |
165 | ||
166 | <dl class="method"> | |
167 | <dt id="smb.SMBProtocol.SMBProtocolFactory.createDirectory"> | |
168 | <tt class="descname">createDirectory</tt><big>(</big><em>service_name</em>, <em>path</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.createDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.createDirectory" title="Permalink to this definition">¶</a></dt> | |
169 | <dd><p>Creates a new directory <em>path</em> on the <em>service_name</em>.</p> | |
170 | <table class="docutils field-list" frame="void" rules="none"> | |
171 | <col class="field-name" /> | |
172 | <col class="field-body" /> | |
173 | <tbody valign="top"> | |
174 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
175 | <li><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</li> | |
176 | <li><strong>path</strong> (<em>string/unicode</em>) – The path of the new folder (relative to) the shared folder. | |
177 | If the path contains non-English characters, an unicode string must be used to pass in the path.</li> | |
178 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance’s <em>errback</em> method.</li> | |
179 | </ul> | |
180 | </td> | |
181 | </tr> | |
182 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>path</em> parameter.</p> | |
183 | </td> | |
184 | </tr> | |
185 | </tbody> | |
186 | </table> | |
187 | </dd></dl> | |
188 | ||
189 | <dl class="method"> | |
190 | <dt id="smb.SMBProtocol.SMBProtocolFactory.deleteDirectory"> | |
191 | <tt class="descname">deleteDirectory</tt><big>(</big><em>service_name</em>, <em>path</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.deleteDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.deleteDirectory" title="Permalink to this definition">¶</a></dt> | |
192 | <dd><p>Delete the empty folder at <em>path</em> on <em>service_name</em></p> | |
193 | <table class="docutils field-list" frame="void" rules="none"> | |
194 | <col class="field-name" /> | |
195 | <col class="field-body" /> | |
196 | <tbody valign="top"> | |
197 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
198 | <li><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</li> | |
199 | <li><strong>path</strong> (<em>string/unicode</em>) – The path of the to-be-deleted folder (relative to) the shared folder. | |
200 | If the path contains non-English characters, an unicode string must be used to pass in the path.</li> | |
201 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance’s <em>errback</em> method.</li> | |
202 | </ul> | |
203 | </td> | |
204 | </tr> | |
205 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>path</em> parameter.</p> | |
206 | </td> | |
207 | </tr> | |
208 | </tbody> | |
209 | </table> | |
210 | </dd></dl> | |
211 | ||
212 | <dl class="method"> | |
213 | <dt id="smb.SMBProtocol.SMBProtocolFactory.deleteFiles"> | |
214 | <tt class="descname">deleteFiles</tt><big>(</big><em>service_name</em>, <em>path_file_pattern</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.deleteFiles"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.deleteFiles" title="Permalink to this definition">¶</a></dt> | |
215 | <dd><p>Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request.</p> | |
216 | <table class="docutils field-list" frame="void" rules="none"> | |
217 | <col class="field-name" /> | |
218 | <col class="field-body" /> | |
219 | <tbody valign="top"> | |
220 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
221 | <li><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</li> | |
222 | <li><strong>path_file_pattern</strong> (<em>string/unicode</em>) – The pathname of the file(s) to be deleted, relative to the service_name. | |
223 | Wildcards may be used in th filename component of the path. | |
224 | If your path/filename contains non-English characters, you must pass in an unicode string.</li> | |
225 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance’s <em>errback</em> method.</li> | |
226 | </ul> | |
227 | </td> | |
228 | </tr> | |
229 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>path_file_pattern</em> parameter.</p> | |
230 | </td> | |
231 | </tr> | |
232 | </tbody> | |
233 | </table> | |
234 | </dd></dl> | |
235 | ||
236 | <dl class="method"> | |
237 | <dt id="smb.SMBProtocol.SMBProtocolFactory.echo"> | |
238 | <tt class="descname">echo</tt><big>(</big><em>data</em>, <em>timeout=10</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.echo"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.echo" title="Permalink to this definition">¶</a></dt> | |
239 | <dd><p>Send an echo command containing <em>data</em> to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same <em>data</em>.</p> | |
240 | <table class="docutils field-list" frame="void" rules="none"> | |
241 | <col class="field-name" /> | |
242 | <col class="field-body" /> | |
243 | <tbody valign="top"> | |
244 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
245 | <li><strong>data</strong> (<em>string</em>) – Data to send to the remote server.</li> | |
246 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance’s <em>errback</em> method.</li> | |
247 | </ul> | |
248 | </td> | |
249 | </tr> | |
250 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with the <em>data</em> parameter.</p> | |
251 | </td> | |
252 | </tr> | |
253 | </tbody> | |
254 | </table> | |
255 | </dd></dl> | |
256 | ||
257 | <dl class="method"> | |
258 | <dt id="smb.SMBProtocol.SMBProtocolFactory.listPath"> | |
259 | <tt class="descname">listPath</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>search=55</em>, <em>pattern='\*'</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.listPath"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.listPath" title="Permalink to this definition">¶</a></dt> | |
260 | <dd><p>Retrieve a directory listing of files/folders at <em>path</em></p> | |
261 | <table class="docutils field-list" frame="void" rules="none"> | |
262 | <col class="field-name" /> | |
263 | <col class="field-body" /> | |
264 | <tbody valign="top"> | |
265 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
266 | <li><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></li> | |
267 | <li><strong>path</strong> (<em>string/unicode</em>) – path relative to the <em>service_name</em> where we are interested to learn about its files/sub-folders.</li> | |
268 | <li><strong>search</strong> (<em>integer</em>) – integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py). | |
269 | The default <em>search</em> value will query for all read-only, hidden, system, archive files and directories.</li> | |
270 | <li><strong>pattern</strong> (<em>string/unicode</em>) – the filter to apply to the results before returning to the client.</li> | |
271 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance’s <em>errback</em> method.</li> | |
272 | </ul> | |
273 | </td> | |
274 | </tr> | |
275 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of <a class="reference internal" href="smb_SharedFile.html"><em>smb.base.SharedFile</em></a> instances.</p> | |
276 | </td> | |
277 | </tr> | |
278 | </tbody> | |
279 | </table> | |
280 | </dd></dl> | |
281 | ||
282 | <dl class="method"> | |
283 | <dt id="smb.SMBProtocol.SMBProtocolFactory.listShares"> | |
284 | <tt class="descname">listShares</tt><big>(</big><em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.listShares"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.listShares" title="Permalink to this definition">¶</a></dt> | |
285 | <dd><p>Retrieve a list of shared resources on remote server.</p> | |
286 | <table class="docutils field-list" frame="void" rules="none"> | |
287 | <col class="field-name" /> | |
288 | <col class="field-body" /> | |
289 | <tbody valign="top"> | |
290 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance’s <em>errback</em> method.</td> | |
291 | </tr> | |
292 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a list of <a class="reference internal" href="smb_SharedDevice.html"><em>smb.base.SharedDevice</em></a> instances.</td> | |
293 | </tr> | |
294 | </tbody> | |
295 | </table> | |
296 | </dd></dl> | |
297 | ||
298 | <dl class="method"> | |
299 | <dt id="smb.SMBProtocol.SMBProtocolFactory.onAuthFailed"> | |
300 | <tt class="descname">onAuthFailed</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.onAuthFailed"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.onAuthFailed" title="Permalink to this definition">¶</a></dt> | |
301 | <dd><p>Override this method in your <em>SMBProtocolFactory</em> subclass to add in post-authentication handling. | |
302 | This method will be called when the server has replied that the SMB connection has been successfully authenticated.</p> | |
303 | <dl class="docutils"> | |
304 | <dt>If you want to retry authenticating from this method,</dt> | |
305 | <dd><ol class="first last arabic simple"> | |
306 | <li>Disconnect the underlying SMB connection (call <tt class="docutils literal"><span class="pre">self.instance.transport.loseConnection()</span></tt>)</li> | |
307 | <li>Create a new SMBProtocolFactory subclass instance with different user credientials or different NTLM algorithm flag.</li> | |
308 | <li>Call <tt class="docutils literal"><span class="pre">reactor.connectTCP</span></tt> with the new instance to re-establish the SMB connection</li> | |
309 | </ol> | |
310 | </dd> | |
311 | </dl> | |
312 | </dd></dl> | |
313 | ||
314 | <dl class="method"> | |
315 | <dt id="smb.SMBProtocol.SMBProtocolFactory.onAuthOK"> | |
316 | <tt class="descname">onAuthOK</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.onAuthOK"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.onAuthOK" title="Permalink to this definition">¶</a></dt> | |
317 | <dd><p>Override this method in your <em>SMBProtocolFactory</em> subclass to add in post-authentication handling. | |
318 | This method will be called when the server has replied that the SMB connection has been successfully authenticated. | |
319 | File operations can proceed when this method has been called.</p> | |
320 | </dd></dl> | |
321 | ||
322 | <dl class="method"> | |
323 | <dt id="smb.SMBProtocol.SMBProtocolFactory.rename"> | |
324 | <tt class="descname">rename</tt><big>(</big><em>service_name</em>, <em>old_path</em>, <em>new_path</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.rename"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.rename" title="Permalink to this definition">¶</a></dt> | |
325 | <dd><p>Rename a file or folder at <em>old_path</em> to <em>new_path</em> shared at <em>service_name</em>. Note that this method cannot be used to rename file/folder across different shared folders</p> | |
326 | <p><em>old_path</em> and <em>new_path</em> are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder. | |
327 | If the path contains non-English characters, an unicode string must be used to pass in the path.</p> | |
328 | <table class="docutils field-list" frame="void" rules="none"> | |
329 | <col class="field-name" /> | |
330 | <col class="field-body" /> | |
331 | <tbody valign="top"> | |
332 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
333 | <li><strong>service_name</strong> (<em>string/unicode</em>) – Contains the name of the shared folder.</li> | |
334 | <li><strong>timeout</strong> (<em>integer/float</em>) – Number of seconds that pysmb will wait before raising <em>SMBTimeout</em> via the returned <em>Deferred</em> instance’s <em>errback</em> method.</li> | |
335 | </ul> | |
336 | </td> | |
337 | </tr> | |
338 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a 2-element tuple of ( <em>old_path</em>, <em>new_path</em> ).</p> | |
339 | </td> | |
340 | </tr> | |
341 | </tbody> | |
342 | </table> | |
343 | </dd></dl> | |
344 | ||
345 | <dl class="method"> | |
346 | <dt id="smb.SMBProtocol.SMBProtocolFactory.retrieveFile"> | |
347 | <tt class="descname">retrieveFile</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.retrieveFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.retrieveFile" title="Permalink to this definition">¶</a></dt> | |
348 | <dd><p>Retrieve the contents of the file at <em>path</em> on the <em>service_name</em> and write these contents to the provided <em>file_obj</em>.</p> | |
349 | <p>The meaning of the <em>timeout</em> parameter will be different from other file operation methods. As the downloaded file usually exceeeds the maximum size | |
350 | of each SMB/CIFS data message, it will be packetized into a series of request messages (each message will request about about 60kBytes). | |
351 | The <em>timeout</em> parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and downloaded from the remote SMB/CIFS server.</p> | |
352 | <table class="docutils field-list" frame="void" rules="none"> | |
353 | <col class="field-name" /> | |
354 | <col class="field-body" /> | |
355 | <tbody valign="top"> | |
356 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
357 | <li><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></li> | |
358 | <li><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file cannot be opened for reading, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be called in the returned <em>Deferred</em> errback.</li> | |
359 | <li><strong>file_obj</strong> – A file-like object that has a <em>write</em> method. Data will be written continuously to <em>file_obj</em> until EOF is received from the remote service.</li> | |
360 | </ul> | |
361 | </td> | |
362 | </tr> | |
363 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a 3-element tuple of ( <em>file_obj</em>, file attributes of the file on server, number of bytes retrieved ). | |
364 | The file attributes is an integer value made up from a bitwise-OR of <em>SMB_FILE_ATTRIBUTE_xxx</em> bits (see smb_constants.py)</p> | |
365 | </td> | |
366 | </tr> | |
367 | </tbody> | |
368 | </table> | |
369 | </dd></dl> | |
370 | ||
371 | <dl class="method"> | |
372 | <dt id="smb.SMBProtocol.SMBProtocolFactory.storeFile"> | |
373 | <tt class="descname">storeFile</tt><big>(</big><em>service_name</em>, <em>path</em>, <em>file_obj</em>, <em>timeout=30</em><big>)</big><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.storeFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.storeFile" title="Permalink to this definition">¶</a></dt> | |
374 | <dd><p>Store the contents of the <em>file_obj</em> at <em>path</em> on the <em>service_name</em>.</p> | |
375 | <p>The meaning of the <em>timeout</em> parameter will be different from other file operation methods. As the uploaded file usually exceeeds the maximum size | |
376 | of each SMB/CIFS data message, it will be packetized into a series of messages (usually about 60kBytes). | |
377 | The <em>timeout</em> parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and acknowledged | |
378 | by the remote SMB/CIFS server.</p> | |
379 | <table class="docutils field-list" frame="void" rules="none"> | |
380 | <col class="field-name" /> | |
381 | <col class="field-body" /> | |
382 | <tbody valign="top"> | |
383 | <tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> | |
384 | <li><strong>service_name</strong> (<em>string/unicode</em>) – the name of the shared folder for the <em>path</em></li> | |
385 | <li><strong>path</strong> (<em>string/unicode</em>) – Path of the file on the remote server. If the file at <em>path</em> does not exist, it will be created. Otherwise, it will be overwritten. | |
386 | If the <em>path</em> refers to a folder or the file cannot be opened for writing, an <a class="reference internal" href="smb_exceptions.html"><em>OperationFailure</em></a> will be called in the returned <em>Deferred</em> errback.</li> | |
387 | <li><strong>file_obj</strong> – A file-like object that has a <em>read</em> method. Data will read continuously from <em>file_obj</em> until EOF.</li> | |
388 | </ul> | |
389 | </td> | |
390 | </tr> | |
391 | <tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">A <em>twisted.internet.defer.Deferred</em> instance. The callback function will be called with a 2-element tuple of ( <em>file_obj</em>, number of bytes uploaded ).</p> | |
392 | </td> | |
393 | </tr> | |
394 | </tbody> | |
395 | </table> | |
396 | </dd></dl> | |
397 | ||
398 | <dl class="attribute"> | |
399 | <dt id="smb.SMBProtocol.SMBProtocolFactory.instance"> | |
400 | <tt class="descname">instance</tt><em class="property"> = None</em><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.instance" title="Permalink to this definition">¶</a></dt> | |
401 | <dd><p>The single SMBProtocol instance for each SMBProtocolFactory instance. Usually, you should not need to touch this attribute directly.</p> | |
402 | </dd></dl> | |
403 | ||
404 | <dl class="attribute"> | |
405 | <dt id="smb.SMBProtocol.SMBProtocolFactory.isReady"> | |
406 | <tt class="descname">isReady</tt><a class="reference internal" href="../_modules/smb/SMBProtocol.html#SMBProtocolFactory.isReady"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.SMBProtocol.SMBProtocolFactory.isReady" title="Permalink to this definition">¶</a></dt> | |
407 | <dd><p>A convenient property to return True if the underlying SMB connection has connected to remote server, has successfully authenticated itself and is ready for file operations.</p> | |
408 | </dd></dl> | |
409 | ||
410 | </dd></dl> | |
411 | ||
412 | </div> | |
413 | </div> | |
414 | ||
415 | ||
416 | </div> | |
417 | </div> | |
418 | </div> | |
419 | <div class="clearer"></div> | |
420 | </div> | |
421 | <div class="related"> | |
422 | <h3>Navigation</h3> | |
423 | <ul> | |
424 | <li class="right" style="margin-right: 10px"> | |
425 | <a href="../genindex.html" title="General Index" | |
426 | >index</a></li> | |
427 | <li class="right" > | |
428 | <a href="smb_SharedDevice.html" title="SharedDevice Class" | |
429 | >next</a> |</li> | |
430 | <li class="right" > | |
431 | <a href="smb_SMBConnection.html" title="SMBConnection Class" | |
432 | >previous</a> |</li> | |
433 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
434 | </ul> | |
435 | </div> | |
436 | <div class="footer"> | |
437 | © Copyright 2011, Michael Teo. | |
438 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
439 | </div> | |
440 | </body> | |
441 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>SharedDevice Class — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | <link rel="next" title="SharedFile Class" href="smb_SharedFile.html" /> | |
29 | <link rel="prev" title="SMBProtocolFactory Class" href="smb_SMBProtocolFactory.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="../genindex.html" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li class="right" > | |
39 | <a href="smb_SharedFile.html" title="SharedFile Class" | |
40 | accesskey="N">next</a> |</li> | |
41 | <li class="right" > | |
42 | <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class" | |
43 | accesskey="P">previous</a> |</li> | |
44 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
45 | </ul> | |
46 | </div> | |
47 | <div class="sphinxsidebar"> | |
48 | <div class="sphinxsidebarwrapper"> | |
49 | <h4>Previous topic</h4> | |
50 | <p class="topless"><a href="smb_SMBProtocolFactory.html" | |
51 | title="previous chapter">SMBProtocolFactory Class</a></p> | |
52 | <h4>Next topic</h4> | |
53 | <p class="topless"><a href="smb_SharedFile.html" | |
54 | title="next chapter">SharedFile Class</a></p> | |
55 | <h3>This Page</h3> | |
56 | <ul class="this-page-menu"> | |
57 | <li><a href="../_sources/api/smb_SharedDevice.txt" | |
58 | rel="nofollow">Show Source</a></li> | |
59 | </ul> | |
60 | <div id="searchbox" style="display: none"> | |
61 | <h3>Quick search</h3> | |
62 | <form class="search" action="../search.html" method="get"> | |
63 | <input type="text" name="q" /> | |
64 | <input type="submit" value="Go" /> | |
65 | <input type="hidden" name="check_keywords" value="yes" /> | |
66 | <input type="hidden" name="area" value="default" /> | |
67 | </form> | |
68 | <p class="searchtip" style="font-size: 90%"> | |
69 | Enter search terms or a module, class or function name. | |
70 | </p> | |
71 | </div> | |
72 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
73 | </div> | |
74 | </div> | |
75 | ||
76 | <div class="document"> | |
77 | <div class="documentwrapper"> | |
78 | <div class="bodywrapper"> | |
79 | <div class="body"> | |
80 | ||
81 | <div class="section" id="shareddevice-class"> | |
82 | <h1>SharedDevice Class<a class="headerlink" href="#shareddevice-class" title="Permalink to this headline">¶</a></h1> | |
83 | <dl class="class"> | |
84 | <dt id="smb.base.SharedDevice"> | |
85 | <em class="property">class </em><tt class="descclassname">smb.base.</tt><tt class="descname">SharedDevice</tt><big>(</big><em>type</em>, <em>name</em>, <em>comments</em><big>)</big><a class="reference internal" href="../_modules/smb/base.html#SharedDevice"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedDevice" title="Permalink to this definition">¶</a></dt> | |
86 | <dd><p>Contains information about a single shared device on the remote server.</p> | |
87 | <dl class="attribute"> | |
88 | <dt id="smb.base.SharedDevice.comments"> | |
89 | <tt class="descname">comments</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedDevice.comments" title="Permalink to this definition">¶</a></dt> | |
90 | <dd><p>An unicode string containing the user description of the shared device</p> | |
91 | </dd></dl> | |
92 | ||
93 | <dl class="attribute"> | |
94 | <dt id="smb.base.SharedDevice.isSpecial"> | |
95 | <tt class="descname">isSpecial</tt><a class="reference internal" href="../_modules/smb/base.html#SharedDevice.isSpecial"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedDevice.isSpecial" title="Permalink to this definition">¶</a></dt> | |
96 | <dd><p>Returns True if this shared device is a special share reserved for interprocess communication (IPC$) | |
97 | or remote administration of the server (ADMIN$). Can also refer to administrative shares such as | |
98 | C$, D$, E$, and so forth</p> | |
99 | </dd></dl> | |
100 | ||
101 | <dl class="attribute"> | |
102 | <dt id="smb.base.SharedDevice.isTemporary"> | |
103 | <tt class="descname">isTemporary</tt><a class="reference internal" href="../_modules/smb/base.html#SharedDevice.isTemporary"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedDevice.isTemporary" title="Permalink to this definition">¶</a></dt> | |
104 | <dd><p>Returns True if this is a temporary share that is not persisted for creation each time the file server initializes.</p> | |
105 | </dd></dl> | |
106 | ||
107 | <dl class="attribute"> | |
108 | <dt id="smb.base.SharedDevice.name"> | |
109 | <tt class="descname">name</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedDevice.name" title="Permalink to this definition">¶</a></dt> | |
110 | <dd><p>An unicode string containing the name of the shared device</p> | |
111 | </dd></dl> | |
112 | ||
113 | <dl class="attribute"> | |
114 | <dt id="smb.base.SharedDevice.type"> | |
115 | <tt class="descname">type</tt><a class="reference internal" href="../_modules/smb/base.html#SharedDevice.type"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedDevice.type" title="Permalink to this definition">¶</a></dt> | |
116 | <dd><dl class="docutils"> | |
117 | <dt>Returns one of the following integral constants.</dt> | |
118 | <dd><ul class="first last simple"> | |
119 | <li>SharedDevice.DISK_TREE</li> | |
120 | <li>SharedDevice.PRINT_QUEUE</li> | |
121 | <li>SharedDevice.COMM_DEVICE</li> | |
122 | <li>SharedDevice.IPC</li> | |
123 | </ul> | |
124 | </dd> | |
125 | </dl> | |
126 | </dd></dl> | |
127 | ||
128 | </dd></dl> | |
129 | ||
130 | </div> | |
131 | ||
132 | ||
133 | </div> | |
134 | </div> | |
135 | </div> | |
136 | <div class="clearer"></div> | |
137 | </div> | |
138 | <div class="related"> | |
139 | <h3>Navigation</h3> | |
140 | <ul> | |
141 | <li class="right" style="margin-right: 10px"> | |
142 | <a href="../genindex.html" title="General Index" | |
143 | >index</a></li> | |
144 | <li class="right" > | |
145 | <a href="smb_SharedFile.html" title="SharedFile Class" | |
146 | >next</a> |</li> | |
147 | <li class="right" > | |
148 | <a href="smb_SMBProtocolFactory.html" title="SMBProtocolFactory Class" | |
149 | >previous</a> |</li> | |
150 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
151 | </ul> | |
152 | </div> | |
153 | <div class="footer"> | |
154 | © Copyright 2011, Michael Teo. | |
155 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
156 | </div> | |
157 | </body> | |
158 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>SharedFile Class — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | <link rel="next" title="SMB Exceptions" href="smb_exceptions.html" /> | |
29 | <link rel="prev" title="SharedDevice Class" href="smb_SharedDevice.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="../genindex.html" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li class="right" > | |
39 | <a href="smb_exceptions.html" title="SMB Exceptions" | |
40 | accesskey="N">next</a> |</li> | |
41 | <li class="right" > | |
42 | <a href="smb_SharedDevice.html" title="SharedDevice Class" | |
43 | accesskey="P">previous</a> |</li> | |
44 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
45 | </ul> | |
46 | </div> | |
47 | <div class="sphinxsidebar"> | |
48 | <div class="sphinxsidebarwrapper"> | |
49 | <h4>Previous topic</h4> | |
50 | <p class="topless"><a href="smb_SharedDevice.html" | |
51 | title="previous chapter">SharedDevice Class</a></p> | |
52 | <h4>Next topic</h4> | |
53 | <p class="topless"><a href="smb_exceptions.html" | |
54 | title="next chapter">SMB Exceptions</a></p> | |
55 | <h3>This Page</h3> | |
56 | <ul class="this-page-menu"> | |
57 | <li><a href="../_sources/api/smb_SharedFile.txt" | |
58 | rel="nofollow">Show Source</a></li> | |
59 | </ul> | |
60 | <div id="searchbox" style="display: none"> | |
61 | <h3>Quick search</h3> | |
62 | <form class="search" action="../search.html" method="get"> | |
63 | <input type="text" name="q" /> | |
64 | <input type="submit" value="Go" /> | |
65 | <input type="hidden" name="check_keywords" value="yes" /> | |
66 | <input type="hidden" name="area" value="default" /> | |
67 | </form> | |
68 | <p class="searchtip" style="font-size: 90%"> | |
69 | Enter search terms or a module, class or function name. | |
70 | </p> | |
71 | </div> | |
72 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
73 | </div> | |
74 | </div> | |
75 | ||
76 | <div class="document"> | |
77 | <div class="documentwrapper"> | |
78 | <div class="bodywrapper"> | |
79 | <div class="body"> | |
80 | ||
81 | <div class="section" id="sharedfile-class"> | |
82 | <h1>SharedFile Class<a class="headerlink" href="#sharedfile-class" title="Permalink to this headline">¶</a></h1> | |
83 | <dl class="class"> | |
84 | <dt id="smb.base.SharedFile"> | |
85 | <em class="property">class </em><tt class="descclassname">smb.base.</tt><tt class="descname">SharedFile</tt><big>(</big><em>create_time</em>, <em>last_access_time</em>, <em>last_write_time</em>, <em>last_attr_change_time</em>, <em>file_size</em>, <em>alloc_size</em>, <em>file_attributes</em>, <em>short_name</em>, <em>filename</em><big>)</big><a class="reference internal" href="../_modules/smb/base.html#SharedFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedFile" title="Permalink to this definition">¶</a></dt> | |
86 | <dd><p>Contain information about a file/folder entry that is shared on the shared device.</p> | |
87 | <p>As an application developer, you should not need to instantiate a <em>SharedFile</em> instance directly in your application. | |
88 | These <em>SharedFile</em> instances are usually returned via a call to <em>listPath</em> method in <a class="reference internal" href="smb_SMBProtocolFactory.html"><em>smb.SMBProtocol.SMBProtocolFactory</em></a>.</p> | |
89 | <p>If you encounter <em>SharedFile</em> instance where its short_name attribute is empty but the filename attribute contains a short name which does not correspond | |
90 | to any files/folders on your remote shared device, it could be that the original filename on the file/folder entry on the shared device contains | |
91 | one of these prohibited characters: “/[]:+|<>=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details).</p> | |
92 | <dl class="attribute"> | |
93 | <dt id="smb.base.SharedFile.alloc_size"> | |
94 | <tt class="descname">alloc_size</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.alloc_size" title="Permalink to this definition">¶</a></dt> | |
95 | <dd><p>Total number of bytes allocated to store this file</p> | |
96 | </dd></dl> | |
97 | ||
98 | <dl class="attribute"> | |
99 | <dt id="smb.base.SharedFile.create_time"> | |
100 | <tt class="descname">create_time</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.create_time" title="Permalink to this definition">¶</a></dt> | |
101 | <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server</p> | |
102 | </dd></dl> | |
103 | ||
104 | <dl class="attribute"> | |
105 | <dt id="smb.base.SharedFile.file_attributes"> | |
106 | <tt class="descname">file_attributes</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.file_attributes" title="Permalink to this definition">¶</a></dt> | |
107 | <dd><p>A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3</p> | |
108 | </dd></dl> | |
109 | ||
110 | <dl class="attribute"> | |
111 | <dt id="smb.base.SharedFile.file_size"> | |
112 | <tt class="descname">file_size</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.file_size" title="Permalink to this definition">¶</a></dt> | |
113 | <dd><p>File size in number of bytes</p> | |
114 | </dd></dl> | |
115 | ||
116 | <dl class="attribute"> | |
117 | <dt id="smb.base.SharedFile.filename"> | |
118 | <tt class="descname">filename</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.filename" title="Permalink to this definition">¶</a></dt> | |
119 | <dd><p>Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters.</p> | |
120 | </dd></dl> | |
121 | ||
122 | <dl class="attribute"> | |
123 | <dt id="smb.base.SharedFile.isDirectory"> | |
124 | <tt class="descname">isDirectory</tt><a class="reference internal" href="../_modules/smb/base.html#SharedFile.isDirectory"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SharedFile.isDirectory" title="Permalink to this definition">¶</a></dt> | |
125 | <dd><p>A convenience property to return True if this file resource is a directory on the remote server</p> | |
126 | </dd></dl> | |
127 | ||
128 | <dl class="attribute"> | |
129 | <dt id="smb.base.SharedFile.last_access_time"> | |
130 | <tt class="descname">last_access_time</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.last_access_time" title="Permalink to this definition">¶</a></dt> | |
131 | <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server</p> | |
132 | </dd></dl> | |
133 | ||
134 | <dl class="attribute"> | |
135 | <dt id="smb.base.SharedFile.last_attr_change_time"> | |
136 | <tt class="descname">last_attr_change_time</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.last_attr_change_time" title="Permalink to this definition">¶</a></dt> | |
137 | <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server</p> | |
138 | </dd></dl> | |
139 | ||
140 | <dl class="attribute"> | |
141 | <dt id="smb.base.SharedFile.last_write_time"> | |
142 | <tt class="descname">last_write_time</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.last_write_time" title="Permalink to this definition">¶</a></dt> | |
143 | <dd><p>Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server</p> | |
144 | </dd></dl> | |
145 | ||
146 | <dl class="attribute"> | |
147 | <dt id="smb.base.SharedFile.short_name"> | |
148 | <tt class="descname">short_name</tt><em class="property"> = None</em><a class="headerlink" href="#smb.base.SharedFile.short_name" title="Permalink to this definition">¶</a></dt> | |
149 | <dd><p>Unicode string containing the short name of this file (usually in 8.3 notation)</p> | |
150 | </dd></dl> | |
151 | ||
152 | </dd></dl> | |
153 | ||
154 | </div> | |
155 | ||
156 | ||
157 | </div> | |
158 | </div> | |
159 | </div> | |
160 | <div class="clearer"></div> | |
161 | </div> | |
162 | <div class="related"> | |
163 | <h3>Navigation</h3> | |
164 | <ul> | |
165 | <li class="right" style="margin-right: 10px"> | |
166 | <a href="../genindex.html" title="General Index" | |
167 | >index</a></li> | |
168 | <li class="right" > | |
169 | <a href="smb_exceptions.html" title="SMB Exceptions" | |
170 | >next</a> |</li> | |
171 | <li class="right" > | |
172 | <a href="smb_SharedDevice.html" title="SharedDevice Class" | |
173 | >previous</a> |</li> | |
174 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
175 | </ul> | |
176 | </div> | |
177 | <div class="footer"> | |
178 | © Copyright 2011, Michael Teo. | |
179 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
180 | </div> | |
181 | </body> | |
182 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>SMB Exceptions — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '../', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="../_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="../_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="../_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="../index.html" /> | |
28 | <link rel="next" title="Extending pysmb For Other Frameworks" href="../extending.html" /> | |
29 | <link rel="prev" title="SharedFile Class" href="smb_SharedFile.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="../genindex.html" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li class="right" > | |
39 | <a href="../extending.html" title="Extending pysmb For Other Frameworks" | |
40 | accesskey="N">next</a> |</li> | |
41 | <li class="right" > | |
42 | <a href="smb_SharedFile.html" title="SharedFile Class" | |
43 | accesskey="P">previous</a> |</li> | |
44 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
45 | </ul> | |
46 | </div> | |
47 | <div class="sphinxsidebar"> | |
48 | <div class="sphinxsidebarwrapper"> | |
49 | <h4>Previous topic</h4> | |
50 | <p class="topless"><a href="smb_SharedFile.html" | |
51 | title="previous chapter">SharedFile Class</a></p> | |
52 | <h4>Next topic</h4> | |
53 | <p class="topless"><a href="../extending.html" | |
54 | title="next chapter">Extending pysmb For Other Frameworks</a></p> | |
55 | <h3>This Page</h3> | |
56 | <ul class="this-page-menu"> | |
57 | <li><a href="../_sources/api/smb_exceptions.txt" | |
58 | rel="nofollow">Show Source</a></li> | |
59 | </ul> | |
60 | <div id="searchbox" style="display: none"> | |
61 | <h3>Quick search</h3> | |
62 | <form class="search" action="../search.html" method="get"> | |
63 | <input type="text" name="q" /> | |
64 | <input type="submit" value="Go" /> | |
65 | <input type="hidden" name="check_keywords" value="yes" /> | |
66 | <input type="hidden" name="area" value="default" /> | |
67 | </form> | |
68 | <p class="searchtip" style="font-size: 90%"> | |
69 | Enter search terms or a module, class or function name. | |
70 | </p> | |
71 | </div> | |
72 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
73 | </div> | |
74 | </div> | |
75 | ||
76 | <div class="document"> | |
77 | <div class="documentwrapper"> | |
78 | <div class="bodywrapper"> | |
79 | <div class="body"> | |
80 | ||
81 | <div class="section" id="smb-exceptions"> | |
82 | <h1>SMB Exceptions<a class="headerlink" href="#smb-exceptions" title="Permalink to this headline">¶</a></h1> | |
83 | <dl class="class"> | |
84 | <dt id="smb.base.SMBTimeout"> | |
85 | <em class="property">class </em><tt class="descclassname">smb.base.</tt><tt class="descname">SMBTimeout</tt><a class="reference internal" href="../_modules/smb/base.html#SMBTimeout"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.SMBTimeout" title="Permalink to this definition">¶</a></dt> | |
86 | <dd><p>Raised when a timeout has occurred while waiting for a response or for a SMB/CIFS operation to complete.</p> | |
87 | </dd></dl> | |
88 | ||
89 | <dl class="class"> | |
90 | <dt id="smb.base.NotReadyError"> | |
91 | <em class="property">class </em><tt class="descclassname">smb.base.</tt><tt class="descname">NotReadyError</tt><a class="reference internal" href="../_modules/smb/base.html#NotReadyError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.NotReadyError" title="Permalink to this definition">¶</a></dt> | |
92 | <dd><p>Raised when SMB connection is not ready (i.e. not authenticated or authentication failed)</p> | |
93 | </dd></dl> | |
94 | ||
95 | <dl class="class"> | |
96 | <dt id="smb.base.NotConnectedError"> | |
97 | <em class="property">class </em><tt class="descclassname">smb.base.</tt><tt class="descname">NotConnectedError</tt><a class="reference internal" href="../_modules/smb/base.html#NotConnectedError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.base.NotConnectedError" title="Permalink to this definition">¶</a></dt> | |
98 | <dd><p>Raised when underlying SMB connection has been disconnected or not connected yet</p> | |
99 | </dd></dl> | |
100 | ||
101 | <dl class="class"> | |
102 | <dt id="smb.smb_structs.UnsupportedFeature"> | |
103 | <em class="property">class </em><tt class="descclassname">smb.smb_structs.</tt><tt class="descname">UnsupportedFeature</tt><a class="reference internal" href="../_modules/smb/smb_structs.html#UnsupportedFeature"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.smb_structs.UnsupportedFeature" title="Permalink to this definition">¶</a></dt> | |
104 | <dd><p>Raised when an supported feature is present/required in the protocol but is not | |
105 | currently supported by pysmb</p> | |
106 | </dd></dl> | |
107 | ||
108 | <dl class="class"> | |
109 | <dt id="smb.smb_structs.ProtocolError"> | |
110 | <em class="property">class </em><tt class="descclassname">smb.smb_structs.</tt><tt class="descname">ProtocolError</tt><big>(</big><em>message</em>, <em>data_buf=None</em>, <em>smb_message=None</em><big>)</big><a class="reference internal" href="../_modules/smb/smb_structs.html#ProtocolError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.smb_structs.ProtocolError" title="Permalink to this definition">¶</a></dt> | |
111 | <dd></dd></dl> | |
112 | ||
113 | <dl class="class"> | |
114 | <dt id="smb.smb_structs.OperationFailure"> | |
115 | <em class="property">class </em><tt class="descclassname">smb.smb_structs.</tt><tt class="descname">OperationFailure</tt><big>(</big><em>message</em>, <em>smb_messages</em><big>)</big><a class="reference internal" href="../_modules/smb/smb_structs.html#OperationFailure"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#smb.smb_structs.OperationFailure" title="Permalink to this definition">¶</a></dt> | |
116 | <dd></dd></dl> | |
117 | ||
118 | </div> | |
119 | ||
120 | ||
121 | </div> | |
122 | </div> | |
123 | </div> | |
124 | <div class="clearer"></div> | |
125 | </div> | |
126 | <div class="related"> | |
127 | <h3>Navigation</h3> | |
128 | <ul> | |
129 | <li class="right" style="margin-right: 10px"> | |
130 | <a href="../genindex.html" title="General Index" | |
131 | >index</a></li> | |
132 | <li class="right" > | |
133 | <a href="../extending.html" title="Extending pysmb For Other Frameworks" | |
134 | >next</a> |</li> | |
135 | <li class="right" > | |
136 | <a href="smb_SharedFile.html" title="SharedFile Class" | |
137 | >previous</a> |</li> | |
138 | <li><a href="../index.html">pysmb 1.0.0 documentation</a> »</li> | |
139 | </ul> | |
140 | </div> | |
141 | <div class="footer"> | |
142 | © Copyright 2011, Michael Teo. | |
143 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
144 | </div> | |
145 | </body> | |
146 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>Extending pysmb For Other Frameworks — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="index.html" /> | |
28 | <link rel="prev" title="SMB Exceptions" href="api/smb_exceptions.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li class="right" > | |
38 | <a href="api/smb_exceptions.html" title="SMB Exceptions" | |
39 | accesskey="P">previous</a> |</li> | |
40 | <li><a href="index.html">pysmb 1.0.0 documentation</a> »</li> | |
41 | </ul> | |
42 | </div> | |
43 | <div class="sphinxsidebar"> | |
44 | <div class="sphinxsidebarwrapper"> | |
45 | <h4>Previous topic</h4> | |
46 | <p class="topless"><a href="api/smb_exceptions.html" | |
47 | title="previous chapter">SMB Exceptions</a></p> | |
48 | <h3>This Page</h3> | |
49 | <ul class="this-page-menu"> | |
50 | <li><a href="_sources/extending.txt" | |
51 | rel="nofollow">Show Source</a></li> | |
52 | </ul> | |
53 | <div id="searchbox" style="display: none"> | |
54 | <h3>Quick search</h3> | |
55 | <form class="search" action="search.html" method="get"> | |
56 | <input type="text" name="q" /> | |
57 | <input type="submit" value="Go" /> | |
58 | <input type="hidden" name="check_keywords" value="yes" /> | |
59 | <input type="hidden" name="area" value="default" /> | |
60 | </form> | |
61 | <p class="searchtip" style="font-size: 90%"> | |
62 | Enter search terms or a module, class or function name. | |
63 | </p> | |
64 | </div> | |
65 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
66 | </div> | |
67 | </div> | |
68 | ||
69 | <div class="document"> | |
70 | <div class="documentwrapper"> | |
71 | <div class="bodywrapper"> | |
72 | <div class="body"> | |
73 | ||
74 | <div class="section" id="extending-pysmb-for-other-frameworks"> | |
75 | <h1>Extending pysmb For Other Frameworks<a class="headerlink" href="#extending-pysmb-for-other-frameworks" title="Permalink to this headline">¶</a></h1> | |
76 | <p>This page briefly describes the steps involved in extending pysmb for other frameworks.</p> | |
77 | <p>In general, you need to take care of the SMB TCP connection setup, i.e. finding the IP address of the remote server and connect to the SMB/CIFS service. | |
78 | Then you need to read/write synchronously or asynchronously from and to the SMB socket. And you need to handle post-authentication callback methods, and from these methods, | |
79 | initiate file operations with the remote SMB/CIFS server.</p> | |
80 | <dl class="docutils"> | |
81 | <dt>Now the above steps in more technical details:</dt> | |
82 | <dd><ol class="first arabic simple"> | |
83 | <li>Create a new class which subclasses the <em>smb.base.SMB</em> class. Most often, the connection setup will be part of the <em>__init__</em> method.</li> | |
84 | <li>Override the <em>write(self, data)</em> method to provide an implementation which will write <em>data</em> to the socket.</li> | |
85 | <li>Write your own loop handling method to read data from the socket. Once data have been read, call <em>feedData</em> method with the parameter. | |
86 | The <em>feedData</em> method has its own internal buffer, so it can accept incomplete NetBIOS session packet data.</li> | |
87 | <li>Override</li> | |
88 | </ol> | |
89 | <blockquote class="last"> | |
90 | <div><ul class="simple"> | |
91 | <li><em>onAuthOK</em> method to include your own operations to perform when authentication is successful. You can initiate file operations in this method.</li> | |
92 | <li><em>onAuthFailed</em> method to include your own processing on what to do when authentication fails. You can report this as an error, or to try a different NTLM authentication algorithm (<em>use_ntlm_v2</em> parameter in the constructor).</li> | |
93 | <li><em>onNMBSessionFailed</em> method to include your own processing on what to do when pysmb fails to setup the NetBIOS session with the remote server. Usually, this is due to a wrong <em>remote_name</em> parameter in the constructor.</li> | |
94 | </ul> | |
95 | </div></blockquote> | |
96 | </dd> | |
97 | </dl> | |
98 | </div> | |
99 | ||
100 | ||
101 | </div> | |
102 | </div> | |
103 | </div> | |
104 | <div class="clearer"></div> | |
105 | </div> | |
106 | <div class="related"> | |
107 | <h3>Navigation</h3> | |
108 | <ul> | |
109 | <li class="right" style="margin-right: 10px"> | |
110 | <a href="genindex.html" title="General Index" | |
111 | >index</a></li> | |
112 | <li class="right" > | |
113 | <a href="api/smb_exceptions.html" title="SMB Exceptions" | |
114 | >previous</a> |</li> | |
115 | <li><a href="index.html">pysmb 1.0.0 documentation</a> »</li> | |
116 | </ul> | |
117 | </div> | |
118 | <div class="footer"> | |
119 | © Copyright 2011, Michael Teo. | |
120 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
121 | </div> | |
122 | </body> | |
123 | </html>⏎ |
0 | ||
1 | ||
2 | ||
3 | ||
4 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
5 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
6 | ||
7 | ||
8 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
9 | <head> | |
10 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
11 | ||
12 | <title>Index — pysmb 1.0.0 documentation</title> | |
13 | ||
14 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> | |
15 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |
16 | ||
17 | <script type="text/javascript"> | |
18 | var DOCUMENTATION_OPTIONS = { | |
19 | URL_ROOT: '', | |
20 | VERSION: '1.0.0', | |
21 | COLLAPSE_INDEX: false, | |
22 | FILE_SUFFIX: '.html', | |
23 | HAS_SOURCE: true | |
24 | }; | |
25 | </script> | |
26 | <script type="text/javascript" src="_static/jquery.js"></script> | |
27 | <script type="text/javascript" src="_static/underscore.js"></script> | |
28 | <script type="text/javascript" src="_static/doctools.js"></script> | |
29 | <link rel="top" title="pysmb 1.0.0 documentation" href="index.html" /> | |
30 | </head> | |
31 | <body> | |
32 | <div class="related"> | |
33 | <h3>Navigation</h3> | |
34 | <ul> | |
35 | <li class="right" style="margin-right: 10px"> | |
36 | <a href="#" title="General Index" | |
37 | accesskey="I">index</a></li> | |
38 | <li><a href="index.html">pysmb 1.0.0 documentation</a> »</li> | |
39 | </ul> | |
40 | </div> | |
41 | <div class="sphinxsidebar"> | |
42 | <div class="sphinxsidebarwrapper"> | |
43 | ||
44 | ||
45 | ||
46 | <div id="searchbox" style="display: none"> | |
47 | <h3>Quick search</h3> | |
48 | <form class="search" action="search.html" method="get"> | |
49 | <input type="text" name="q" /> | |
50 | <input type="submit" value="Go" /> | |
51 | <input type="hidden" name="check_keywords" value="yes" /> | |
52 | <input type="hidden" name="area" value="default" /> | |
53 | </form> | |
54 | <p class="searchtip" style="font-size: 90%"> | |
55 | Enter search terms or a module, class or function name. | |
56 | </p> | |
57 | </div> | |
58 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
59 | </div> | |
60 | </div> | |
61 | ||
62 | <div class="document"> | |
63 | <div class="documentwrapper"> | |
64 | <div class="bodywrapper"> | |
65 | <div class="body"> | |
66 | ||
67 | ||
68 | <h1 id="index">Index</h1> | |
69 | ||
70 | <div class="genindex-jumpbox"> | |
71 | <a href="#_"><strong>_</strong></a> | |
72 | | <a href="#A"><strong>A</strong></a> | |
73 | | <a href="#C"><strong>C</strong></a> | |
74 | | <a href="#D"><strong>D</strong></a> | |
75 | | <a href="#E"><strong>E</strong></a> | |
76 | | <a href="#F"><strong>F</strong></a> | |
77 | | <a href="#I"><strong>I</strong></a> | |
78 | | <a href="#L"><strong>L</strong></a> | |
79 | | <a href="#N"><strong>N</strong></a> | |
80 | | <a href="#O"><strong>O</strong></a> | |
81 | | <a href="#P"><strong>P</strong></a> | |
82 | | <a href="#Q"><strong>Q</strong></a> | |
83 | | <a href="#R"><strong>R</strong></a> | |
84 | | <a href="#S"><strong>S</strong></a> | |
85 | | <a href="#T"><strong>T</strong></a> | |
86 | | <a href="#U"><strong>U</strong></a> | |
87 | ||
88 | </div> | |
89 | <h2 id="_">_</h2> | |
90 | <table style="width: 100%" class="indextable genindextable"><tr> | |
91 | <td style="width: 33%" valign="top"><dl> | |
92 | ||
93 | <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.__init__">__init__() (nmb.NetBIOS.NetBIOS method)</a> | |
94 | </dt> | |
95 | ||
96 | <dd><dl> | |
97 | ||
98 | <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.__init__">(nmb.NetBIOSProtocol.NBNSProtocol method)</a> | |
99 | </dt> | |
100 | ||
101 | ||
102 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.__init__">(smb.SMBConnection.SMBConnection method)</a> | |
103 | </dt> | |
104 | ||
105 | ||
106 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.__init__">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
107 | </dt> | |
108 | ||
109 | </dl></dd> | |
110 | </dl></td> | |
111 | </tr></table> | |
112 | ||
113 | <h2 id="A">A</h2> | |
114 | <table style="width: 100%" class="indextable genindextable"><tr> | |
115 | <td style="width: 33%" valign="top"><dl> | |
116 | ||
117 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.alloc_size">alloc_size (smb.base.SharedFile attribute)</a> | |
118 | </dt> | |
119 | ||
120 | </dl></td> | |
121 | </tr></table> | |
122 | ||
123 | <h2 id="C">C</h2> | |
124 | <table style="width: 100%" class="indextable genindextable"><tr> | |
125 | <td style="width: 33%" valign="top"><dl> | |
126 | ||
127 | <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.close">close() (nmb.NetBIOS.NetBIOS method)</a> | |
128 | </dt> | |
129 | ||
130 | <dd><dl> | |
131 | ||
132 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.close">(smb.SMBConnection.SMBConnection method)</a> | |
133 | </dt> | |
134 | ||
135 | </dl></dd> | |
136 | ||
137 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.closeConnection">closeConnection() (smb.SMBProtocol.SMBProtocolFactory method)</a> | |
138 | </dt> | |
139 | ||
140 | ||
141 | <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.comments">comments (smb.base.SharedDevice attribute)</a> | |
142 | </dt> | |
143 | ||
144 | </dl></td> | |
145 | <td style="width: 33%" valign="top"><dl> | |
146 | ||
147 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.connect">connect() (smb.SMBConnection.SMBConnection method)</a> | |
148 | </dt> | |
149 | ||
150 | ||
151 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.create_time">create_time (smb.base.SharedFile attribute)</a> | |
152 | </dt> | |
153 | ||
154 | ||
155 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.createDirectory">createDirectory() (smb.SMBConnection.SMBConnection method)</a> | |
156 | </dt> | |
157 | ||
158 | <dd><dl> | |
159 | ||
160 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.createDirectory">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
161 | </dt> | |
162 | ||
163 | </dl></dd> | |
164 | </dl></td> | |
165 | </tr></table> | |
166 | ||
167 | <h2 id="D">D</h2> | |
168 | <table style="width: 100%" class="indextable genindextable"><tr> | |
169 | <td style="width: 33%" valign="top"><dl> | |
170 | ||
171 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteDirectory">deleteDirectory() (smb.SMBConnection.SMBConnection method)</a> | |
172 | </dt> | |
173 | ||
174 | <dd><dl> | |
175 | ||
176 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteDirectory">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
177 | </dt> | |
178 | ||
179 | </dl></dd> | |
180 | </dl></td> | |
181 | <td style="width: 33%" valign="top"><dl> | |
182 | ||
183 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.deleteFiles">deleteFiles() (smb.SMBConnection.SMBConnection method)</a> | |
184 | </dt> | |
185 | ||
186 | <dd><dl> | |
187 | ||
188 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.deleteFiles">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
189 | </dt> | |
190 | ||
191 | </dl></dd> | |
192 | </dl></td> | |
193 | </tr></table> | |
194 | ||
195 | <h2 id="E">E</h2> | |
196 | <table style="width: 100%" class="indextable genindextable"><tr> | |
197 | <td style="width: 33%" valign="top"><dl> | |
198 | ||
199 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.echo">echo() (smb.SMBConnection.SMBConnection method)</a> | |
200 | </dt> | |
201 | ||
202 | <dd><dl> | |
203 | ||
204 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.echo">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
205 | </dt> | |
206 | ||
207 | </dl></dd> | |
208 | </dl></td> | |
209 | </tr></table> | |
210 | ||
211 | <h2 id="F">F</h2> | |
212 | <table style="width: 100%" class="indextable genindextable"><tr> | |
213 | <td style="width: 33%" valign="top"><dl> | |
214 | ||
215 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.file_attributes">file_attributes (smb.base.SharedFile attribute)</a> | |
216 | </dt> | |
217 | ||
218 | ||
219 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.file_size">file_size (smb.base.SharedFile attribute)</a> | |
220 | </dt> | |
221 | ||
222 | </dl></td> | |
223 | <td style="width: 33%" valign="top"><dl> | |
224 | ||
225 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.filename">filename (smb.base.SharedFile attribute)</a> | |
226 | </dt> | |
227 | ||
228 | </dl></td> | |
229 | </tr></table> | |
230 | ||
231 | <h2 id="I">I</h2> | |
232 | <table style="width: 100%" class="indextable genindextable"><tr> | |
233 | <td style="width: 33%" valign="top"><dl> | |
234 | ||
235 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.instance">instance (smb.SMBProtocol.SMBProtocolFactory attribute)</a> | |
236 | </dt> | |
237 | ||
238 | ||
239 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.isDirectory">isDirectory (smb.base.SharedFile attribute)</a> | |
240 | </dt> | |
241 | ||
242 | ||
243 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.isReady">isReady (smb.SMBProtocol.SMBProtocolFactory attribute)</a> | |
244 | </dt> | |
245 | ||
246 | </dl></td> | |
247 | <td style="width: 33%" valign="top"><dl> | |
248 | ||
249 | <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.isSpecial">isSpecial (smb.base.SharedDevice attribute)</a> | |
250 | </dt> | |
251 | ||
252 | ||
253 | <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.isTemporary">isTemporary (smb.base.SharedDevice attribute)</a> | |
254 | </dt> | |
255 | ||
256 | </dl></td> | |
257 | </tr></table> | |
258 | ||
259 | <h2 id="L">L</h2> | |
260 | <table style="width: 100%" class="indextable genindextable"><tr> | |
261 | <td style="width: 33%" valign="top"><dl> | |
262 | ||
263 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_access_time">last_access_time (smb.base.SharedFile attribute)</a> | |
264 | </dt> | |
265 | ||
266 | ||
267 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_attr_change_time">last_attr_change_time (smb.base.SharedFile attribute)</a> | |
268 | </dt> | |
269 | ||
270 | ||
271 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.last_write_time">last_write_time (smb.base.SharedFile attribute)</a> | |
272 | </dt> | |
273 | ||
274 | </dl></td> | |
275 | <td style="width: 33%" valign="top"><dl> | |
276 | ||
277 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listPath">listPath() (smb.SMBConnection.SMBConnection method)</a> | |
278 | </dt> | |
279 | ||
280 | <dd><dl> | |
281 | ||
282 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listPath">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
283 | </dt> | |
284 | ||
285 | </dl></dd> | |
286 | ||
287 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listShares">listShares() (smb.SMBConnection.SMBConnection method)</a> | |
288 | </dt> | |
289 | ||
290 | <dd><dl> | |
291 | ||
292 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.listShares">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
293 | </dt> | |
294 | ||
295 | </dl></dd> | |
296 | </dl></td> | |
297 | </tr></table> | |
298 | ||
299 | <h2 id="N">N</h2> | |
300 | <table style="width: 100%" class="indextable genindextable"><tr> | |
301 | <td style="width: 33%" valign="top"><dl> | |
302 | ||
303 | <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.name">name (smb.base.SharedDevice attribute)</a> | |
304 | </dt> | |
305 | ||
306 | ||
307 | <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol">NBNSProtocol (class in nmb.NetBIOSProtocol)</a> | |
308 | </dt> | |
309 | ||
310 | ||
311 | <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS">NetBIOS (class in nmb.NetBIOS)</a> | |
312 | </dt> | |
313 | ||
314 | </dl></td> | |
315 | <td style="width: 33%" valign="top"><dl> | |
316 | ||
317 | <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NetBIOSTimeout">NetBIOSTimeout (class in nmb.NetBIOSProtocol)</a> | |
318 | </dt> | |
319 | ||
320 | ||
321 | <dt><a href="api/smb_exceptions.html#smb.base.NotConnectedError">NotConnectedError (class in smb.base)</a> | |
322 | </dt> | |
323 | ||
324 | ||
325 | <dt><a href="api/smb_exceptions.html#smb.base.NotReadyError">NotReadyError (class in smb.base)</a> | |
326 | </dt> | |
327 | ||
328 | </dl></td> | |
329 | </tr></table> | |
330 | ||
331 | <h2 id="O">O</h2> | |
332 | <table style="width: 100%" class="indextable genindextable"><tr> | |
333 | <td style="width: 33%" valign="top"><dl> | |
334 | ||
335 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.onAuthFailed">onAuthFailed() (smb.SMBProtocol.SMBProtocolFactory method)</a> | |
336 | </dt> | |
337 | ||
338 | ||
339 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.onAuthOK">onAuthOK() (smb.SMBProtocol.SMBProtocolFactory method)</a> | |
340 | </dt> | |
341 | ||
342 | </dl></td> | |
343 | <td style="width: 33%" valign="top"><dl> | |
344 | ||
345 | <dt><a href="api/smb_exceptions.html#smb.smb_structs.OperationFailure">OperationFailure (class in smb.smb_structs)</a> | |
346 | </dt> | |
347 | ||
348 | </dl></td> | |
349 | </tr></table> | |
350 | ||
351 | <h2 id="P">P</h2> | |
352 | <table style="width: 100%" class="indextable genindextable"><tr> | |
353 | <td style="width: 33%" valign="top"><dl> | |
354 | ||
355 | <dt><a href="api/smb_exceptions.html#smb.smb_structs.ProtocolError">ProtocolError (class in smb.smb_structs)</a> | |
356 | </dt> | |
357 | ||
358 | </dl></td> | |
359 | </tr></table> | |
360 | ||
361 | <h2 id="Q">Q</h2> | |
362 | <table style="width: 100%" class="indextable genindextable"><tr> | |
363 | <td style="width: 33%" valign="top"><dl> | |
364 | ||
365 | <dt><a href="api/nmb_NetBIOS.html#nmb.NetBIOS.NetBIOS.queryName">queryName() (nmb.NetBIOS.NetBIOS method)</a> | |
366 | </dt> | |
367 | ||
368 | <dd><dl> | |
369 | ||
370 | <dt><a href="api/nmb_NBNSProtocol.html#nmb.NetBIOSProtocol.NBNSProtocol.queryName">(nmb.NetBIOSProtocol.NBNSProtocol method)</a> | |
371 | </dt> | |
372 | ||
373 | </dl></dd> | |
374 | </dl></td> | |
375 | </tr></table> | |
376 | ||
377 | <h2 id="R">R</h2> | |
378 | <table style="width: 100%" class="indextable genindextable"><tr> | |
379 | <td style="width: 33%" valign="top"><dl> | |
380 | ||
381 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.rename">rename() (smb.SMBConnection.SMBConnection method)</a> | |
382 | </dt> | |
383 | ||
384 | <dd><dl> | |
385 | ||
386 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.rename">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
387 | </dt> | |
388 | ||
389 | </dl></dd> | |
390 | </dl></td> | |
391 | <td style="width: 33%" valign="top"><dl> | |
392 | ||
393 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.retrieveFile">retrieveFile() (smb.SMBConnection.SMBConnection method)</a> | |
394 | </dt> | |
395 | ||
396 | <dd><dl> | |
397 | ||
398 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.retrieveFile">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
399 | </dt> | |
400 | ||
401 | </dl></dd> | |
402 | </dl></td> | |
403 | </tr></table> | |
404 | ||
405 | <h2 id="S">S</h2> | |
406 | <table style="width: 100%" class="indextable genindextable"><tr> | |
407 | <td style="width: 33%" valign="top"><dl> | |
408 | ||
409 | <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice">SharedDevice (class in smb.base)</a> | |
410 | </dt> | |
411 | ||
412 | ||
413 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile">SharedFile (class in smb.base)</a> | |
414 | </dt> | |
415 | ||
416 | ||
417 | <dt><a href="api/smb_SharedFile.html#smb.base.SharedFile.short_name">short_name (smb.base.SharedFile attribute)</a> | |
418 | </dt> | |
419 | ||
420 | ||
421 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection">SMBConnection (class in smb.SMBConnection)</a> | |
422 | </dt> | |
423 | ||
424 | </dl></td> | |
425 | <td style="width: 33%" valign="top"><dl> | |
426 | ||
427 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory">SMBProtocolFactory (class in smb.SMBProtocol)</a> | |
428 | </dt> | |
429 | ||
430 | ||
431 | <dt><a href="api/smb_exceptions.html#smb.base.SMBTimeout">SMBTimeout (class in smb.base)</a> | |
432 | </dt> | |
433 | ||
434 | ||
435 | <dt><a href="api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.storeFile">storeFile() (smb.SMBConnection.SMBConnection method)</a> | |
436 | </dt> | |
437 | ||
438 | <dd><dl> | |
439 | ||
440 | <dt><a href="api/smb_SMBProtocolFactory.html#smb.SMBProtocol.SMBProtocolFactory.storeFile">(smb.SMBProtocol.SMBProtocolFactory method)</a> | |
441 | </dt> | |
442 | ||
443 | </dl></dd> | |
444 | </dl></td> | |
445 | </tr></table> | |
446 | ||
447 | <h2 id="T">T</h2> | |
448 | <table style="width: 100%" class="indextable genindextable"><tr> | |
449 | <td style="width: 33%" valign="top"><dl> | |
450 | ||
451 | <dt><a href="api/smb_SharedDevice.html#smb.base.SharedDevice.type">type (smb.base.SharedDevice attribute)</a> | |
452 | </dt> | |
453 | ||
454 | </dl></td> | |
455 | </tr></table> | |
456 | ||
457 | <h2 id="U">U</h2> | |
458 | <table style="width: 100%" class="indextable genindextable"><tr> | |
459 | <td style="width: 33%" valign="top"><dl> | |
460 | ||
461 | <dt><a href="api/smb_exceptions.html#smb.smb_structs.UnsupportedFeature">UnsupportedFeature (class in smb.smb_structs)</a> | |
462 | </dt> | |
463 | ||
464 | </dl></td> | |
465 | </tr></table> | |
466 | ||
467 | ||
468 | ||
469 | </div> | |
470 | </div> | |
471 | </div> | |
472 | <div class="clearer"></div> | |
473 | </div> | |
474 | <div class="related"> | |
475 | <h3>Navigation</h3> | |
476 | <ul> | |
477 | <li class="right" style="margin-right: 10px"> | |
478 | <a href="#" title="General Index" | |
479 | >index</a></li> | |
480 | <li><a href="index.html">pysmb 1.0.0 documentation</a> »</li> | |
481 | </ul> | |
482 | </div> | |
483 | <div class="footer"> | |
484 | © Copyright 2011, Michael Teo. | |
485 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
486 | </div> | |
487 | </body> | |
488 | </html>⏎ |
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>Welcome to pysmb’s documentation! — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="_static/doctools.js"></script> | |
27 | <link rel="top" title="pysmb 1.0.0 documentation" href="#" /> | |
28 | <link rel="next" title="NBNSProtocol Class" href="api/nmb_NBNSProtocol.html" /> | |
29 | </head> | |
30 | <body> | |
31 | <div class="related"> | |
32 | <h3>Navigation</h3> | |
33 | <ul> | |
34 | <li class="right" style="margin-right: 10px"> | |
35 | <a href="genindex.html" title="General Index" | |
36 | accesskey="I">index</a></li> | |
37 | <li class="right" > | |
38 | <a href="api/nmb_NBNSProtocol.html" title="NBNSProtocol Class" | |
39 | accesskey="N">next</a> |</li> | |
40 | <li><a href="#">pysmb 1.0.0 documentation</a> »</li> | |
41 | </ul> | |
42 | </div> | |
43 | <div class="sphinxsidebar"> | |
44 | <div class="sphinxsidebarwrapper"> | |
45 | <h3><a href="#">Table Of Contents</a></h3> | |
46 | <ul> | |
47 | <li><a class="reference internal" href="#">Welcome to pysmb’s documentation!</a><ul> | |
48 | <li><a class="reference internal" href="#license">License</a></li> | |
49 | <li><a class="reference internal" href="#credits">Credits</a></li> | |
50 | </ul> | |
51 | </li> | |
52 | <li><a class="reference internal" href="#package-contents-and-description">Package Contents and Description</a></li> | |
53 | <li><a class="reference internal" href="#using-pysmb">Using pysmb</a></li> | |
54 | <li><a class="reference internal" href="#indices-and-tables">Indices and tables</a><ul> | |
55 | </ul> | |
56 | </li> | |
57 | </ul> | |
58 | ||
59 | <h4>Next topic</h4> | |
60 | <p class="topless"><a href="api/nmb_NBNSProtocol.html" | |
61 | title="next chapter">NBNSProtocol Class</a></p> | |
62 | <h3>This Page</h3> | |
63 | <ul class="this-page-menu"> | |
64 | <li><a href="_sources/index.txt" | |
65 | rel="nofollow">Show Source</a></li> | |
66 | </ul> | |
67 | <div id="searchbox" style="display: none"> | |
68 | <h3>Quick search</h3> | |
69 | <form class="search" action="search.html" method="get"> | |
70 | <input type="text" name="q" /> | |
71 | <input type="submit" value="Go" /> | |
72 | <input type="hidden" name="check_keywords" value="yes" /> | |
73 | <input type="hidden" name="area" value="default" /> | |
74 | </form> | |
75 | <p class="searchtip" style="font-size: 90%"> | |
76 | Enter search terms or a module, class or function name. | |
77 | </p> | |
78 | </div> | |
79 | <script type="text/javascript">$('#searchbox').show(0);</script> | |
80 | </div> | |
81 | </div> | |
82 | ||
83 | <div class="document"> | |
84 | <div class="documentwrapper"> | |
85 | <div class="bodywrapper"> | |
86 | <div class="body"> | |
87 | ||
88 | <div class="section" id="welcome-to-pysmb-s-documentation"> | |
89 | <h1>Welcome to pysmb’s documentation!<a class="headerlink" href="#welcome-to-pysmb-s-documentation" title="Permalink to this headline">¶</a></h1> | |
90 | <p>pysmb is a pure Python implementation of the client-side SMB/CIFS protocol which is the underlying protocol that facilitates file sharing and printing between Windows machines, | |
91 | as well as with Linux machines via the Samba server application. | |
92 | pysmb is developed in Python 2.4.6 (and Python 2.7.1) and has been tested against shared folders on Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x.</p> | |
93 | <div class="section" id="license"> | |
94 | <h2>License<a class="headerlink" href="#license" title="Permalink to this headline">¶</a></h2> | |
95 | <p>pysmb itself is licensed under an opensource license. | |
96 | You are free to use pysmb in any applications, including for commercial purposes. | |
97 | For more details on the terms of use, please read the LICENSE file that comes with your pysmb source.</p> | |
98 | <p>pysmb depends on other 3rd-party modules whose terms of use are not covered by pysmb. | |
99 | Use of these modules could possibly conflict with your licensing needs. Please exercise your own discretion to determine their suitabilities. | |
100 | I have listed these modules in the following section.</p> | |
101 | </div> | |
102 | <div class="section" id="credits"> | |
103 | <h2>Credits<a class="headerlink" href="#credits" title="Permalink to this headline">¶</a></h2> | |
104 | <p>pysmb is not alone. It is made possible with support from other modules.</p> | |
105 | <ul class="simple"> | |
106 | <li><strong>pyasn1</strong> : Pure Python implementation of ASN.1 parsing and encoding (not included together with pysmb; needs to be installed separately)</li> | |
107 | <li><strong>md4</strong> and <strong>U32</strong> : Pure Python implementation of MD4 hashing algorithm and 32-bit unsigned integer by Dmitry Rozmanov. Licensed under LGPL and included together with pysmb.</li> | |
108 | <li><strong>pyDes</strong> : Pure python implementation of the DES encryption algorithm by Todd Whiteman. Free domain and included together with pysmb.</li> | |
109 | </ul> | |
110 | <p>In various places, there are references to different specifications. Most of these referenced specifications | |
111 | can be downloaded from Microsoft web site under Microsoft’s “Open Specification Promise”. If you need to download | |
112 | a copy of these specifications, please google for it. For example, google for “MS-CIFS” to download the CIFS specification for NT LM dialect.</p> | |
113 | </div> | |
114 | </div> | |
115 | <div class="section" id="package-contents-and-description"> | |
116 | <h1>Package Contents and Description<a class="headerlink" href="#package-contents-and-description" title="Permalink to this headline">¶</a></h1> | |
117 | <p>pysmb is organized into 2 main packages: smb and nmb. | |
118 | The smb package contains all the functionalities related to Server Message Block (SMB) implementation. | |
119 | As an application developer, you will be importing this module into your application. | |
120 | Hence, please take some time to familiarize yourself with the smb package contents.</p> | |
121 | <ul class="simple"> | |
122 | <li><strong>nmb/base.py</strong> : | |
123 | Contains the NetBIOSSession and NBNS abstract class which implements NetBIOS session and NetBIOS Name Service communication | |
124 | without any network transport specifics.</li> | |
125 | <li><strong>nmb/NetBIOS.py</strong>: | |
126 | Provides a NBNS implementation to query IP addresses for machine names. All operations are blocking I/O.</li> | |
127 | <li><strong>nmb/NetBIOSProtocol.py</strong> : | |
128 | Provides the NBNS protocol implementation for use in Twisted framework.</li> | |
129 | <li><strong>smb/base.py</strong> : | |
130 | Contains the SMB abstract class which implements the SMB communication without any network transport specifics.</li> | |
131 | <li><strong>smb/ntlm.py</strong> : | |
132 | Contains the NTLMv1 and NTLMv2 authentication routines and the decoding/encoding of NTLM authentication messages within SMB messages.</li> | |
133 | <li><strong>smb/securityblob.py</strong> : | |
134 | Provides routines to encode/decode the NTLMSSP security blob in the SMB messages.</li> | |
135 | <li><strong>smb/smb_constants.py</strong> : | |
136 | All the constants used in the smb package</li> | |
137 | <li><strong>smb/smb_structs.py</strong> : | |
138 | Contains the internal classes used in the SMB package. These classes are usually used to encode/decode the parameter and data blocks of specific SMB message.</li> | |
139 | <li><strong>smb/SMBConnection.py</strong> : | |
140 | Contains a SMB protocol implementation. All operations are blocking I/O.</li> | |
141 | <li><strong>smb/SMBProtocol.py</strong> : | |
142 | Contains the SMB protocol implementation for use in the Twisted framework.</li> | |
143 | </ul> | |
144 | </div> | |
145 | <div class="section" id="using-pysmb"> | |
146 | <h1>Using pysmb<a class="headerlink" href="#using-pysmb" title="Permalink to this headline">¶</a></h1> | |
147 | <dl class="docutils"> | |
148 | <dt>As an application developer who is looking to use pysmb to translate NetBIOS names to IP addresses,</dt> | |
149 | <dd><ul class="first last simple"> | |
150 | <li>To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read | |
151 | <a class="reference internal" href="api/nmb_NetBIOS.html"><em>nmb.NetBIOS.NetBIOS</em></a> documentation.</li> | |
152 | <li>To use pysmb in Twisted, please read <a class="reference internal" href="api/nmb_NBNSProtocol.html"><em>nmb.NetBIOSProtocol.NBNSProtocol</em></a> documentation.</li> | |
153 | </ul> | |
154 | </dd> | |
155 | <dt>As an application developer who is looking to use pysmb to implement file transfer or authentication over SMB:</dt> | |
156 | <dd><ul class="first last simple"> | |
157 | <li>To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read | |
158 | <a class="reference internal" href="api/smb_SMBConnection.html"><em>smb.SMBConnection.SMBConnection</em></a> documentation.</li> | |
159 | <li>To use pysmb in Twisted, please read <a class="reference internal" href="api/smb_SMBProtocolFactory.html"><em>smb.SMBProtocol.SMBProtocolFactory</em></a> documentation.</li> | |
160 | </ul> | |
161 | </dd> | |
162 | <dt>As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks:</dt> | |
163 | <dd><ul class="first last simple"> | |
164 | <li>Read <a class="reference internal" href="extending.html"><em>Extending pysmb For Other Frameworks</em></a></li> | |
165 | </ul> | |
166 | </dd> | |
167 | </dl> | |
168 | </div> | |
169 | <div class="section" id="indices-and-tables"> | |
170 | <h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1> | |
171 | <div class="toctree-wrapper compound"> | |
172 | <ul> | |
173 | <li class="toctree-l1"><a class="reference internal" href="api/nmb_NBNSProtocol.html">NBNSProtocol Class</a></li> | |
174 | <li class="toctree-l1"><a class="reference internal" href="api/nmb_NetBIOS.html">NetBIOS class</a></li> | |
175 | <li class="toctree-l1"><a class="reference internal" href="api/smb_SMBConnection.html">SMBConnection Class</a></li> | |
176 | <li class="toctree-l1"><a class="reference internal" href="api/smb_SMBProtocolFactory.html">SMBProtocolFactory Class</a></li> | |
177 | <li class="toctree-l1"><a class="reference internal" href="api/smb_SharedDevice.html">SharedDevice Class</a></li> | |
178 | <li class="toctree-l1"><a class="reference internal" href="api/smb_SharedFile.html">SharedFile Class</a></li> | |
179 | <li class="toctree-l1"><a class="reference internal" href="api/smb_exceptions.html">SMB Exceptions</a></li> | |
180 | <li class="toctree-l1"><a class="reference internal" href="extending.html">Extending pysmb For Other Frameworks</a></li> | |
181 | </ul> | |
182 | </div> | |
183 | <ul class="simple"> | |
184 | <li><a class="reference internal" href="genindex.html"><em>Index</em></a></li> | |
185 | <li><a class="reference internal" href="search.html"><em>Search Page</em></a></li> | |
186 | </ul> | |
187 | </div> | |
188 | ||
189 | ||
190 | </div> | |
191 | </div> | |
192 | </div> | |
193 | <div class="clearer"></div> | |
194 | </div> | |
195 | <div class="related"> | |
196 | <h3>Navigation</h3> | |
197 | <ul> | |
198 | <li class="right" style="margin-right: 10px"> | |
199 | <a href="genindex.html" title="General Index" | |
200 | >index</a></li> | |
201 | <li class="right" > | |
202 | <a href="api/nmb_NBNSProtocol.html" title="NBNSProtocol Class" | |
203 | >next</a> |</li> | |
204 | <li><a href="#">pysmb 1.0.0 documentation</a> »</li> | |
205 | </ul> | |
206 | </div> | |
207 | <div class="footer"> | |
208 | © Copyright 2011, Michael Teo. | |
209 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
210 | </div> | |
211 | </body> | |
212 | </html>⏎ |
Binary diff not shown
0 | ||
1 | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
4 | ||
5 | ||
6 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
7 | <head> | |
8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
9 | ||
10 | <title>Search — pysmb 1.0.0 documentation</title> | |
11 | ||
12 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> | |
13 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |
14 | ||
15 | <script type="text/javascript"> | |
16 | var DOCUMENTATION_OPTIONS = { | |
17 | URL_ROOT: '', | |
18 | VERSION: '1.0.0', | |
19 | COLLAPSE_INDEX: false, | |
20 | FILE_SUFFIX: '.html', | |
21 | HAS_SOURCE: true | |
22 | }; | |
23 | </script> | |
24 | <script type="text/javascript" src="_static/jquery.js"></script> | |
25 | <script type="text/javascript" src="_static/underscore.js"></script> | |
26 | <script type="text/javascript" src="_static/doctools.js"></script> | |
27 | <script type="text/javascript" src="_static/searchtools.js"></script> | |
28 | <link rel="top" title="pysmb 1.0.0 documentation" href="index.html" /> | |
29 | <script type="text/javascript"> | |
30 | jQuery(function() { Search.loadIndex("searchindex.js"); }); | |
31 | </script> | |
32 | ||
33 | ||
34 | </head> | |
35 | <body> | |
36 | <div class="related"> | |
37 | <h3>Navigation</h3> | |
38 | <ul> | |
39 | <li class="right" style="margin-right: 10px"> | |
40 | <a href="genindex.html" title="General Index" | |
41 | accesskey="I">index</a></li> | |
42 | <li><a href="index.html">pysmb 1.0.0 documentation</a> »</li> | |
43 | </ul> | |
44 | </div> | |
45 | <div class="sphinxsidebar"> | |
46 | <div class="sphinxsidebarwrapper"> | |
47 | </div> | |
48 | </div> | |
49 | ||
50 | <div class="document"> | |
51 | <div class="documentwrapper"> | |
52 | <div class="bodywrapper"> | |
53 | <div class="body"> | |
54 | ||
55 | <h1 id="search-documentation">Search</h1> | |
56 | <div id="fallback" class="admonition warning"> | |
57 | <script type="text/javascript">$('#fallback').hide();</script> | |
58 | <p> | |
59 | Please activate JavaScript to enable the search | |
60 | functionality. | |
61 | </p> | |
62 | </div> | |
63 | <p> | |
64 | From here you can search these documents. Enter your search | |
65 | words into the box below and click "search". Note that the search | |
66 | function will automatically search for all of the words. Pages | |
67 | containing fewer words won't appear in the result list. | |
68 | </p> | |
69 | <form action="" method="get"> | |
70 | <input type="text" name="q" value="" /> | |
71 | <input type="submit" value="search" /> | |
72 | <span id="search-progress" style="padding-left: 10px"></span> | |
73 | </form> | |
74 | ||
75 | <div id="search-results"> | |
76 | ||
77 | </div> | |
78 | ||
79 | </div> | |
80 | </div> | |
81 | </div> | |
82 | <div class="clearer"></div> | |
83 | </div> | |
84 | <div class="related"> | |
85 | <h3>Navigation</h3> | |
86 | <ul> | |
87 | <li class="right" style="margin-right: 10px"> | |
88 | <a href="genindex.html" title="General Index" | |
89 | >index</a></li> | |
90 | <li><a href="index.html">pysmb 1.0.0 documentation</a> »</li> | |
91 | </ul> | |
92 | </div> | |
93 | <div class="footer"> | |
94 | © Copyright 2011, Michael Teo. | |
95 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2. | |
96 | </div> | |
97 | </body> | |
98 | </html>⏎ |
0 | Search.setIndex({objects:{"nmb.NetBIOS":{NetBIOS:[1,1,1,""]},"nmb.NetBIOSProtocol":{NBNSProtocol:[8,1,1,""],NetBIOSTimeout:[8,1,1,""]},"smb.SMBProtocol":{SMBProtocolFactory:[4,1,1,""]},"nmb.NetBIOSProtocol.NBNSProtocol":{queryName:[8,2,1,""],"__init__":[8,2,1,""]},"smb.base":{SharedDevice:[2,1,1,""],NotReadyError:[6,1,1,""],SharedFile:[3,1,1,""],SMBTimeout:[6,1,1,""],NotConnectedError:[6,1,1,""]},"smb.SMBConnection.SMBConnection":{rename:[7,2,1,""],deleteDirectory:[7,2,1,""],deleteFiles:[7,2,1,""],retrieveFile:[7,2,1,""],listPath:[7,2,1,""],storeFile:[7,2,1,""],connect:[7,2,1,""],close:[7,2,1,""],createDirectory:[7,2,1,""],echo:[7,2,1,""],listShares:[7,2,1,""],"__init__":[7,2,1,""]},"smb.base.SharedFile":{short_name:[3,0,1,""],last_access_time:[3,0,1,""],last_attr_change_time:[3,0,1,""],last_write_time:[3,0,1,""],file_attributes:[3,0,1,""],filename:[3,0,1,""],isDirectory:[3,0,1,""],create_time:[3,0,1,""],file_size:[3,0,1,""],alloc_size:[3,0,1,""]},"smb.SMBProtocol.SMBProtocolFactory":{rename:[4,2,1,""],deleteDirectory:[4,2,1,""],isReady:[4,0,1,""],retrieveFile:[4,2,1,""],onAuthFailed:[4,2,1,""],listShares:[4,2,1,""],listPath:[4,2,1,""],instance:[4,0,1,""],closeConnection:[4,2,1,""],storeFile:[4,2,1,""],onAuthOK:[4,2,1,""],createDirectory:[4,2,1,""],echo:[4,2,1,""],deleteFiles:[4,2,1,""],"__init__":[4,2,1,""]},"smb.SMBConnection":{SMBConnection:[7,1,1,""]},"nmb.NetBIOS.NetBIOS":{close:[1,2,1,""],queryName:[1,2,1,""],"__init__":[1,2,1,""]},"smb.smb_structs":{UnsupportedFeature:[6,1,1,""],ProtocolError:[6,1,1,""],OperationFailure:[6,1,1,""]},"smb.base.SharedDevice":{isSpecial:[2,0,1,""],type:[2,0,1,""],comments:[2,0,1,""],isTemporary:[2,0,1,""],name:[2,0,1,""]}},terms:{all:[4,0,7],queri:[4,0,8,1,7],follow:[0,2],whose:0,accur:4,depend:0,listen_port:[1,8],netbiostimeout:8,service_nam:[4,7],send:[4,1,8,7],those:4,under:0,last_write_tim:3,sourc:[0,1,2,3,4,6,7,8],string:[1,2,3,4,7,8],fals:[1,7,8],util:4,mechan:[4,7],failur:8,administr:2,list:[4,0,8,1,7],upload:[4,7],smb:[0,1,2,3,4,5,6,7],"try":[4,5,7],concurr:[4,7],ddd:[1,8],pleas:0,batch:4,deletedirectori:[4,7],zero:[1,8],nbn:[1,0],pass:[4,7],sock_famili:7,port:[1,7,8],index:0,what:[4,1,7,8,5],sub:[4,7],repli:[4,1,8,7],section:0,invok:7,access:3,delet:[4,7],u32:0,"new":[4,1,7,5],method:[1,3,4,5,7,8],hash:0,gener:5,my_nam:[4,7],lgpl:0,modif:3,address:[1,0,8,5],path:[4,7],modifi:0,sinc:3,valu:[4,7,3],wait:[4,1,8,6],search:[4,0,7],queue:4,credit:0,nmb:[1,0,8],implement:[4,0,8,5],stoplisten:8,ipc:2,via:[4,0,8,3],ntlmv2:[4,0,7],ntlmv1:[4,0,7],defer:[4,7,8],appli:[4,7],modul:0,filenam:[4,7,3],"boolean":[4,1,8,7],listshar:[4,7],instal:0,total:3,establish:[4,7],select:[4,1,8,7],from:[0,1,4,5,7,8],describ:[5,7],commun:[4,0,2],call:[1,3,4,5,7,8],type:2,until:[4,1,7],more:[4,0,7,3,5],sort:7,relat:0,sambda:[4,7],flag:[4,1,8],accept:[4,5],known:[4,7],must:[4,7,8],none:[1,2,3,4,6,7],retriev:[4,7],setup:[4,1,8,5],dmitri:0,archiv:[4,7],can:[0,1,2,4,5,7,8],caveat:[4,7],learn:[4,7],purpos:0,overrid:[4,5],meant:7,process:5,share:[4,0,7,3,2],sharedfil:[4,0,3,7],indic:[4,0,8,1,7],want:[4,0],opensourc:0,unsign:0,occur:6,addcallback:[4,8],multipl:[4,7],secur:0,write:[4,5,7],pure:0,reject:[4,7],onauthfail:[4,5],old_path:[4,7],dialect:0,resourc:[4,1,3,7],referenc:0,sp3:0,befor:[4,7],wrong:5,mai:[4,7],smb_ext_file_attr:3,data:[4,0,7,5],alloc:3,"short":3,attempt:7,bind:[1,8],credenti:[4,7],correspond:3,element:[4,7],inform:[3,2],allow:[4,7,8],origin:[4,7,3],over:0,file_s:3,held:7,through:4,paramet:[0,1,4,5,7,8],style:0,disconnect:[4,7,6],window:[4,0,3,7],persist:2,hidden:[4,7],main:0,might:4,shareddevic:[4,0,7,2],non:[4,7],within:[4,0,7],"return":[0,1,2,3,4,7,8],thei:0,handl:[4,5],auto:[4,7],safe:[4,7],initi:[5,2],framework:[4,0,8,5],promis:0,facilit:0,now:5,choic:[4,7],term:0,name:[0,1,2,3,4,7,8],ntlm:[4,0,5],authent:[4,0,7,6,5],separ:0,isreadi:4,mode:[1,8],timeout:[4,1,8,6,7],each:[4,1,7,3,2],unicod:[4,7,3,2],side:0,errback:[4,7,8],prohibit:3,domain:[4,0,7],smbtimeout:[4,6],individu:4,instiant:[1,8],continu:[4,7],connect:[4,5,6,7],todd:0,special:2,out:[4,7],network:[4,0,8,1,7],"3rd":0,space:[4,7],ntlmssp:0,content:[4,0,7],suitabl:[0,7],rel:[4,7],internet:[4,8],print:0,forth:2,factori:4,after:[4,0,8,1,7],querynam:[1,8],guess:[4,7],free:[1,0,8],standard:[1,8],base:[0,2,3,4,5,6,7],connecttcp:4,releas:[1,7],"byte":[4,7,3],earliest:4,asn:0,md4:0,care:5,english:[4,7],last_access_tim:3,could:[0,3],synchron:[0,5],success:[5,7],keep:7,filter:[4,7],length:3,place:0,oper:[0,1,4,5,6,7],softwar:0,directli:[4,3],onc:[4,5],number:[4,1,8,3,7],yourself:0,done:[1,8],messag:[4,0,6],path_file_pattern:[4,7],open:[4,0,7],size:[4,3],differ:[4,0,7,5],notreadyerror:[4,6],licens:0,system:[4,7],least:7,too:7,termin:[4,7],conveni:[4,3],store:[4,7,3],listen:[1,8],udp:[1,8],copi:0,specifi:[4,1,8],broadcast:[1,8],part:5,pars:0,than:[4,7],aaa:[1,8],target:[1,8],provid:[0,1,4,5,7,8],remov:8,second:[4,1,8,3],charact:[4,7,3],project:[4,8],reus:4,seri:4,comput:[4,7],ani:[4,0,1,3,7],download:[4,0],netbiossess:0,have:[7,0,8,5],close:[4,1,7],need:[4,0,7,3,5],bitwis:[4,7],callback:[4,5,8],self:[4,5],comm_devic:2,click:[4,7],note:[4,7],also:2,exampl:[4,0],take:[0,5],which:[0,1,3,4,5,7,8],transmit:4,singl:[4,7,2],unless:[1,8],usernam:[4,7],who:[4,0,7],smb_file_attribute_xxx:[4,7],most:[4,0,7,5],regular:[4,7],smbprotocolfactori:[4,0,3],"class":[0,1,2,3,4,5,6,7,8],smbconnect:[0,7],renam:[4,7],request:[4,7],doe:[4,7,3],wildcard:[4,7],microsoft:0,dot:[1,8],reactor:[4,8],netbiosprotocol:[0,8],session:[0,5],identifi:[4,7],find:[4,5,7],involv:5,current:6,onli:[4,7],configur:[4,7],should:[4,1,8,3,7],folder:[4,0,3,7],local:[4,7],hope:[1,8],overwritten:[4,7],disk_tre:2,listenudp:8,variou:0,familiar:0,interprocess:2,cannot:[4,7],report:5,requir:[4,7,6],enabl:[4,7],organ:0,"public":4,remot:[1,2,3,4,5,7],integr:[0,2],contain:[4,0,7,3,2],feeddata:5,where:[4,0,3,7],respond:7,proce:4,packet:[4,1,8,5],deletefil:[4,7],see:[4,7,3],sec:4,result:[4,7,8],respons:6,fail:[4,5,6,7],reserv:2,asynchron:[5,8,7],detect:[4,7],new_path:[4,7],pattern:[4,7],written:[4,7],smb_constant:[4,0,7],between:0,"import":[4,0],across:[4,7],attribut:[4,7,3],extend:[0,5],entir:4,come:0,both:[4,7],last:3,admin:2,alon:0,against:0,etc:4,instanc:[4,1,8,3,7],onnmbsessionfail:5,freeli:[4,7],comment:2,technic:5,instanti:[1,8,3],last_attr_change_tim:3,period:4,except:[4,0,8,6],securityblob:0,onauthok:[4,5],rozmanov:0,short_nam:3,devic:[3,2],bbb:[1,8],been:[4,0,7,6,5],compon:[4,7],operationfailur:[4,7,6],interest:[4,7],use_ntlm_v2:[4,5,7],smb_struct:[0,6],thousand:4,wish:[1,7],togeth:0,present:6,"case":4,look:0,packag:0,servic:[4,0,7,1,5],properti:[4,7,3],commerci:0,defin:[1,8],"while":6,abov:5,error:[5,7],loop:5,readi:[4,6],alloc_s:3,tabl:0,henc:[4,0,7],site:0,itself:[4,0],incom:8,"__init__":[4,1,7,8,5],precis:4,isdirectori:3,develop:[0,3,7],welcom:0,perform:[1,5,8,7],parti:0,isspeci:2,same:[4,7],python:0,decod:0,create_tim:3,document:0,conflict:0,complet:[4,0,6,7],closeconnect:4,keepal:7,rais:[4,8,6],temporari:2,user:[4,7,2],protocolerror:6,chang:3,excee:4,nbnsprotocol:[1,0,8],appropri:[1,8],entri:3,well:0,without:[0,8],command:[4,7],thi:[0,1,2,3,4,5,7,8],choos:[4,7],file_obj:[4,7],sequenti:7,ccc:[1,8],usual:[4,0,7,3,5],protocol:[0,6],just:[4,8],createdirectori:[4,7],tcp:[4,5],notconnectederror:[4,6],touch:[4,1,8],yet:6,iana:[1,8],storefil:[4,7],web:0,samba:0,expos:4,remote_nam:[4,5,7],add:[4,8],discret:0,blob:0,exercis:0,els:[4,7],match:[1,8],applic:[4,0,1,3,8],around:8,read:[4,0,7,5],know:[4,1,8],bit:[4,0,7],password:[4,7],like:[4,7],specif:0,integ:[0,1,3,4,7,8],server:[0,2,3,4,5,7],print_queu:2,page:[0,5],underli:[4,0,1,6,7],encount:[7,3],right:[4,7],old:[4,7],often:5,acknowledg:4,interv:4,linux:0,some:[0,7],intern:[4,0,5],istemporari:2,successfulli:[4,7],transport:[4,0,8],smbprotocol:[4,0,3],avoid:4,subclass:[4,5],buffer:5,retri:4,leav:[4,1,8,7],ipv4:1,pysmb:[0,4,5,6,7,8],refer:[4,0,7,2],machin:[4,0,8,1,7],object:[4,7],workgroup:[4,7],atttempt:7,step:5,loseconnect:4,post:[4,5],impos:[4,7],proceed:[4,7],about:[4,7,3,2],actual:7,socket:[1,5,7],idl:7,pymsb:4,constructor:5,mean:4,pyasn1:0,block:[1,0,8,7],routin:0,client:[4,0,7],own:[4,0,5],"float":[4,1,8,3],encod:0,automat:[1,8],due:5,empti:[4,1,8,3,7],wrap:8,opportun:4,your:[0,1,3,4,5,7,8],transfer:[4,0],support:[4,0,6,7],"long":[4,7,3],smb_messag:6,start:[7,8],includ:[0,5],"function":[4,0,8],creation:[3,2],tupl:[4,7],whiteman:0,translat:0,"true":[1,2,3,4,7,8],notat:[1,8,3],made:[4,0,7],cif:[0,1,3,4,5,6,7],possibl:0,whether:[4,7],pyde:0,maximum:[4,7],"60kbyte":4,limit:[4,7,3],otherwis:[4,7],listpath:[4,7,3],netbio:[0,1,4,5,7,8],credienti:4,featur:6,constant:[0,2],creat:[4,1,7,8,5],cover:0,"abstract":0,unsupportedfeatur:6,twist:[4,0,8],incomplet:5,exist:[4,7],file:[0,2,3,4,5,7],echo:[4,7],again:8,vista:[4,0,7],encrypt:0,googl:0,retrievefil:[4,7],when:[1,4,5,6,7,8],detail:[0,3,5],data_buf:6,"default":[4,7],other:[4,0,5],test:0,you:[0,1,3,4,5,7,8],functionl:4,determin:[1,0,8],file_attribut:3,authenthent:4,briefli:5,receiv:[4,1,8,7],eof:[4,7],algorithm:[4,0,7,5],directori:[4,7,3],descript:[0,2],alphanumer:[4,7],pathnam:[4,7],time:[4,0,7,3,2]},objtypes:{"0":"py:attribute","1":"py:class","2":"py:method"},titles:["Welcome to pysmb’s documentation!","NetBIOS class","SharedDevice Class","SharedFile Class","SMBProtocolFactory Class","Extending pysmb For Other Frameworks","SMB Exceptions","SMBConnection Class","NBNSProtocol Class"],objnames:{"0":["py","attribute","Python attribute"],"1":["py","class","Python class"],"2":["py","method","Python method"]},filenames:["index","api/nmb_NetBIOS","api/smb_SharedDevice","api/smb_SharedFile","api/smb_SMBProtocolFactory","extending","api/smb_exceptions","api/smb_SMBConnection","api/nmb_NBNSProtocol"]})⏎ |
0 | ||
1 | import os, logging, random, socket, time, select | |
2 | from base import NBNS | |
3 | ||
4 | class NetBIOS(NBNS): | |
5 | ||
6 | log = logging.getLogger('NMB.NetBIOS') | |
7 | ||
8 | def __init__(self, broadcast = True, listen_port = 0): | |
9 | """ | |
10 | Instantiate a NetBIOS instance, and creates a IPv4 UDP socket to listen/send NBNS packets. | |
11 | ||
12 | :param boolean broadcast: A boolean flag to indicate if we should setup the listening UDP port in broadcast mode | |
13 | :param integer listen_port: Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number. | |
14 | """ | |
15 | self.broadcast = broadcast | |
16 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
17 | if self.broadcast: | |
18 | self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) | |
19 | if listen_port: | |
20 | self.sock.bind(( '', listen_port )) | |
21 | ||
22 | def close(self): | |
23 | """ | |
24 | Close the underlying and free resources. | |
25 | ||
26 | The NetBIOS instance should not be used to perform any operations after this method returns. | |
27 | ||
28 | :return: None | |
29 | """ | |
30 | self.sock.close() | |
31 | self.sock = None | |
32 | ||
33 | def write(self, data, ip, port): | |
34 | assert self.sock, 'Socket is already closed' | |
35 | self.sock.sendto(data, ( ip, port )) | |
36 | ||
37 | def queryName(self, name, ip = '', port = 137, timeout = 30): | |
38 | """ | |
39 | Send a query on the network and hopes that if machine matching the *name* will reply with its IP address. | |
40 | ||
41 | :param string ip: If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address. | |
42 | If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query. | |
43 | :param integer port: The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing. | |
44 | :param integer/float timeout: Number of seconds to wait for a reply, after which the method will return None | |
45 | :return: A list of IP addresses in dotted notation (aaa.bbb.ccc.ddd). On timeout, returns None. | |
46 | """ | |
47 | assert self.sock, 'Socket is already closed' | |
48 | ||
49 | trn_id = random.randint(1, 0xFFFF) | |
50 | data = self.prepareNameQuery(trn_id, name) | |
51 | if self.broadcast and not ip: | |
52 | ip = '<broadcast>' | |
53 | elif not ip: | |
54 | self.log.warning('queryName: ip parameter is empty. OS might not transmit this query to the network') | |
55 | ||
56 | self.write(data, ip, port) | |
57 | ||
58 | return self._pollForNetBIOSPacket(trn_id, timeout) | |
59 | ||
60 | # | |
61 | # Protected Methods | |
62 | # | |
63 | ||
64 | def _pollForNetBIOSPacket(self, wait_trn_id, timeout): | |
65 | end_time = time.time() - timeout | |
66 | while True: | |
67 | try: | |
68 | _timeout = time.time()-end_time | |
69 | if _timeout <= 0: | |
70 | return None | |
71 | ||
72 | ready, _, _ = select.select([ self.sock.fileno() ], [ ], [ ], _timeout) | |
73 | if not ready: | |
74 | return None | |
75 | ||
76 | data, _ = self.sock.recvfrom(0xFFFF) | |
77 | trn_id, ret = self.decodePacket(data) | |
78 | ||
79 | if trn_id == wait_trn_id: | |
80 | return ret | |
81 | except select.error, ex: | |
82 | if type(ex) is types.TupleType: | |
83 | if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN: | |
84 | raise ex | |
85 | else: | |
86 | raise ex |
0 | ||
1 | import os, logging, random, socket, time | |
2 | from twisted.internet import reactor, defer | |
3 | from twisted.internet.protocol import DatagramProtocol | |
4 | from base import NBNS | |
5 | ||
6 | class NetBIOSTimeout(Exception): | |
7 | """Raised in NBNSProtocol via Deferred.errback method when queryName method has timeout waiting for reply""" | |
8 | pass | |
9 | ||
10 | class NBNSProtocol(DatagramProtocol, NBNS): | |
11 | ||
12 | log = logging.getLogger('NMB.NBNSProtocol') | |
13 | ||
14 | def __init__(self, broadcast = True, listen_port = 0): | |
15 | """ | |
16 | Instantiate a NBNSProtocol instance. | |
17 | ||
18 | This automatically calls reactor.listenUDP method to start listening for incoming packets, so you **must not** call the listenUDP method again. | |
19 | ||
20 | :param boolean broadcast: A boolean flag to indicate if we should setup the listening UDP port in broadcast mode | |
21 | :param integer listen_port: Specifies the UDP port number to bind to for listening. If zero, OS will automatically select a free port number. | |
22 | """ | |
23 | self.broadcast = broadcast | |
24 | self.pending_trns = { } # TRN ID -> ( expiry_time, name, Deferred instance ) | |
25 | self.transport = reactor.listenUDP(listen_port, self) | |
26 | if self.broadcast: | |
27 | self.transport.getHandle().setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) | |
28 | reactor.callLater(1, self.cleanupPendingTrns) | |
29 | ||
30 | def datagramReceived(self, data, (host, port)): | |
31 | trn_id, ret = self.decodePacket(data) | |
32 | ||
33 | _, _, d = self.pending_trns.pop(trn_id, None) | |
34 | if d: | |
35 | d.callback(ret) | |
36 | ||
37 | def write(self, data, ip, port): | |
38 | # We don't use the transport.write method directly as it keeps raising DeprecationWarning for ip='<broadcast>' | |
39 | self.transport.getHandle().sendto(data, ( ip, port )) | |
40 | ||
41 | def queryName(self, name, ip = '', port = 137, timeout = 30): | |
42 | """ | |
43 | Send a query on the network and hopes that if machine matching the *name* will reply with its IP address. | |
44 | ||
45 | :param string ip: If the NBNSProtocol instance was instianted with broadcast=True, then this parameter can be an empty string. We will leave it to the OS to determine an appropriate broadcast address. | |
46 | If the NBNSProtocol instance was instianted with broadcast=False, then you should provide a target IP to send the query. | |
47 | :param integer port: The NetBIOS-NS port (IANA standard defines this port to be 137). You should not touch this parameter unless you know what you are doing. | |
48 | :param integer/float timeout: Number of seconds to wait for a reply, after which the returned Deferred instance will be called with a NetBIOSTimeout exception. | |
49 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of IP addresses in dotted notation (aaa.bbb.ccc.ddd). | |
50 | On timeout, the errback function will be called with a Failure instance wrapping around a NetBIOSTimeout exception | |
51 | """ | |
52 | trn_id = random.randint(1, 0xFFFF) | |
53 | while True: | |
54 | if not self.pending_trns.has_key(trn_id): | |
55 | break | |
56 | else: | |
57 | trn_id = (trn_id + 1) & 0xFFFF | |
58 | ||
59 | data = self.prepareNameQuery(trn_id, name) | |
60 | if self.broadcast and not ip: | |
61 | ip = '<broadcast>' | |
62 | elif not ip: | |
63 | self.log.warning('queryName: ip parameter is empty. OS might not transmit this query to the network') | |
64 | ||
65 | self.write(data, ip, port) | |
66 | ||
67 | d = defer.Deferred() | |
68 | self.pending_trns[trn_id] = ( time.time()+timeout, name, d ) | |
69 | return d | |
70 | ||
71 | def stopProtocol(self): | |
72 | DatagramProtocol.stopProtocol(self) | |
73 | ||
74 | def cleanupPendingTrns(self): | |
75 | now = time.time() | |
76 | for trn_id, ( expiry_time, name, d ) in self.pending_trns.items(): | |
77 | if expiry_time < now: | |
78 | del self.pending_trns[trn_id] | |
79 | try: | |
80 | d.errback(NetBIOSTimeout(name)) | |
81 | except: pass | |
82 | ||
83 | if self.transport: | |
84 | reactor.callLater(1, self.cleanupPendingTrns) |
0 | ||
1 | import struct, logging, random | |
2 | from nmb_constants import * | |
3 | from nmb_structs import * | |
4 | from utils import encode_name | |
5 | ||
6 | class NMBSession: | |
7 | ||
8 | log = logging.getLogger('NMB.NMBSession') | |
9 | ||
10 | def __init__(self, my_name, remote_name, host_type = TYPE_SERVER): | |
11 | self.my_name = my_name.upper() | |
12 | self.remote_name = remote_name.upper() | |
13 | self.host_type = host_type | |
14 | self.data_buf = '' | |
15 | self.data_nmb = NMBSessionMessage() | |
16 | ||
17 | # | |
18 | # Overridden Methods | |
19 | # | |
20 | ||
21 | def write(self, data): | |
22 | raise NotImplementedError | |
23 | ||
24 | def onNMBSessionMessage(self, flags, data): | |
25 | pass | |
26 | ||
27 | def onNMBSessionOK(self): | |
28 | pass | |
29 | ||
30 | def onNMBSessionFailed(self): | |
31 | pass | |
32 | ||
33 | # | |
34 | # Public Methods | |
35 | # | |
36 | ||
37 | def feedData(self, data): | |
38 | self.data_buf = self.data_buf + data | |
39 | ||
40 | offset = 0 | |
41 | while True: | |
42 | length = self.data_nmb.decode(self.data_buf, offset) | |
43 | if length == 0: | |
44 | break | |
45 | elif length > 0: | |
46 | offset += length | |
47 | self._processNMBSessionPacket(self.data_nmb) | |
48 | else: | |
49 | raise NMBError | |
50 | ||
51 | if offset > 0: | |
52 | self.data_buf = self.data_buf[offset:] | |
53 | ||
54 | def sendNMBMessage(self, data): | |
55 | self.sendNMBPacket(SESSION_MESSAGE, data) | |
56 | ||
57 | def sendNMBPacket(self, packet_type, data): | |
58 | length = len(data) | |
59 | assert length <= 0x01FFFF | |
60 | flags = 0 | |
61 | if length > 0xFFFF: | |
62 | flags |= 0x01 | |
63 | length &= 0xFFFF | |
64 | self.write(struct.pack('>BBH', packet_type, flags, length) + data) | |
65 | ||
66 | def requestNMBSession(self): | |
67 | my_name_encoded = encode_name(self.my_name, TYPE_WORKSTATION) | |
68 | remote_name_encoded = encode_name(self.remote_name, self.host_type) | |
69 | self.sendNMBPacket(SESSION_REQUEST, remote_name_encoded + my_name_encoded) | |
70 | ||
71 | # | |
72 | # Protected Methods | |
73 | # | |
74 | ||
75 | def _processNMBSessionPacket(self, packet): | |
76 | if packet.type == SESSION_MESSAGE: | |
77 | self.onNMBSessionMessage(packet.flags, packet.data) | |
78 | elif packet.type == POSITIVE_SESSION_RESPONSE: | |
79 | self.onNMBSessionOK() | |
80 | elif packet.type == NEGATIVE_SESSION_RESPONSE: | |
81 | self.onNMBSessionFailed() | |
82 | else: | |
83 | self.log.warning('Unrecognized NMB session type: 0x%02x', packet.type) | |
84 | ||
85 | ||
86 | class NBNS: | |
87 | ||
88 | log = logging.getLogger('NMB.NBNS') | |
89 | ||
90 | HEADER_STRUCT_FORMAT = '>HHHHHH' | |
91 | HEADER_STRUCT_SIZE = struct.calcsize(HEADER_STRUCT_FORMAT) | |
92 | ||
93 | def write(self, data, ip, port): | |
94 | raise NotImplementedError | |
95 | ||
96 | def decodePacket(self, data): | |
97 | if len(data) < self.HEADER_STRUCT_SIZE: | |
98 | raise Exception | |
99 | ||
100 | trn_id, code, question_count, answer_count, authority_count, additional_count = struct.unpack(self.HEADER_STRUCT_FORMAT, data[:self.HEADER_STRUCT_SIZE]) | |
101 | ||
102 | is_response = bool((code >> 15) & 0x01) | |
103 | opcode = (code >> 11) & 0x0F | |
104 | flags = (code >> 4) & 0x7F | |
105 | rcode = code & 0x0F | |
106 | ||
107 | if opcode == 0x0000 and is_response: | |
108 | name_len = ord(data[self.HEADER_STRUCT_SIZE]) | |
109 | offset = self.HEADER_STRUCT_SIZE+2+name_len+8 # constant 2 for the padding bytes before/after the Name and constant 8 for the Type, Class and TTL fields in the Answer section after the Name | |
110 | record_count = (struct.unpack('>H', data[offset:offset+2])[0]) / 6 | |
111 | ||
112 | offset += 4 # Constant 4 for the Data Length and Flags field | |
113 | ret = [ ] | |
114 | for i in range(0, record_count): | |
115 | ret.append('%d.%d.%d.%d' % struct.unpack('4B', (data[offset:offset + 4]))) | |
116 | offset += 6 | |
117 | return trn_id, ret | |
118 | else: | |
119 | return trn_id, None | |
120 | ||
121 | ||
122 | def prepareNameQuery(self, trn_id, name, is_broadcast = True): | |
123 | header = struct.pack(self.HEADER_STRUCT_FORMAT, | |
124 | trn_id, (is_broadcast and 0x0110) or 0x0100, 1, 0, 0, 0) | |
125 | payload = encode_name(name, 0x20) + '\x00\x20\x00\x01' | |
126 | ||
127 | return header + payload |
0 | ||
1 | # Default port for NetBIOS name service | |
2 | NETBIOS_NS_PORT = 137 | |
3 | ||
4 | # Default port for NetBIOS session service | |
5 | NETBIOS_SESSION_PORT = 139 | |
6 | ||
7 | # Owner Node Type Constants | |
8 | NODE_B = 0x00 | |
9 | NODE_P = 0x01 | |
10 | NODE_M = 0x10 | |
11 | NODE_RESERVED = 0x11 | |
12 | ||
13 | # Name Type Constants | |
14 | TYPE_UNKNOWN = 0x01 | |
15 | TYPE_WORKSTATION = 0x00 | |
16 | TYPE_CLIENT = 0x03 | |
17 | TYPE_SERVER = 0x20 | |
18 | TYPE_DOMAIN_MASTER = 0x1B | |
19 | TYPE_MASTER_BROWSER = 0x1D | |
20 | TYPE_BROWSER = 0x1E | |
21 | ||
22 | TYPE_NAMES = { TYPE_UNKNOWN: 'Unknown', | |
23 | TYPE_WORKSTATION: 'Workstation', | |
24 | TYPE_CLIENT: 'Client', | |
25 | TYPE_SERVER: 'Server', | |
26 | TYPE_MASTER_BROWSER: 'Master Browser', | |
27 | TYPE_BROWSER: 'Browser Server', | |
28 | TYPE_DOMAIN_MASTER: 'Domain Master' | |
29 | } | |
30 | ||
31 | # Values for Session Packet Type field in Session Packets | |
32 | SESSION_MESSAGE = 0x00 | |
33 | SESSION_REQUEST = 0x81 | |
34 | POSITIVE_SESSION_RESPONSE = 0x82 | |
35 | NEGATIVE_SESSION_RESPONSE = 0x83 | |
36 | REGTARGET_SESSION_RESPONSE = 0x84 | |
37 | SESSION_KEEPALIVE = 0x85 |
0 | ||
1 | import struct | |
2 | ||
3 | class NMBError(Exception): pass | |
4 | ||
5 | ||
6 | class NMBSessionMessage: | |
7 | ||
8 | HEADER_STRUCT_FORMAT = '>BBH' | |
9 | HEADER_STRUCT_SIZE = struct.calcsize(HEADER_STRUCT_FORMAT) | |
10 | ||
11 | def __init__(self): | |
12 | self.reset() | |
13 | ||
14 | def reset(self): | |
15 | self.type = 0 | |
16 | self.flags = 0 | |
17 | self.data = '' | |
18 | ||
19 | def decode(self, data, offset): | |
20 | data_len = len(data) | |
21 | ||
22 | if data_len < offset + self.HEADER_STRUCT_SIZE: | |
23 | # Not enough data for decoding | |
24 | return 0 | |
25 | ||
26 | self.reset() | |
27 | self.type, self.flags, length = struct.unpack(self.HEADER_STRUCT_FORMAT, data[offset:offset+self.HEADER_STRUCT_SIZE]) | |
28 | ||
29 | if self.flags & 0x01: | |
30 | length |= 0x010000 | |
31 | ||
32 | if data_len < offset + self.HEADER_STRUCT_SIZE + length: | |
33 | return 0 | |
34 | ||
35 | self.data = data[offset+self.HEADER_STRUCT_SIZE:offset+self.HEADER_STRUCT_SIZE+length] | |
36 | return self.HEADER_STRUCT_SIZE + length |
0 | ||
1 | import string, re | |
2 | ||
3 | ||
4 | def encode_name(name, type, scope = None): | |
5 | """ | |
6 | Perform first and second level encoding of name as specified in RFC 1001 (Section 4) | |
7 | """ | |
8 | if name == '*': | |
9 | name = name + '\0' * 15 | |
10 | elif len(name) > 15: | |
11 | name = name[:15] + chr(type) | |
12 | else: | |
13 | name = string.ljust(name, 15) + chr(type) | |
14 | ||
15 | def _do_first_level_encoding(m): | |
16 | s = ord(m.group(0)) | |
17 | return string.uppercase[s >> 4] + string.uppercase[s & 0x0f] | |
18 | ||
19 | encoded_name = chr(len(name) * 2) + re.sub('.', _do_first_level_encoding, name) | |
20 | if scope: | |
21 | encoded_scope = '' | |
22 | for s in string.split(scope, '.'): | |
23 | encoded_scope = encoded_scope + chr(len(s)) + s | |
24 | return encoded_name + encoded_scope + '\0' | |
25 | else: | |
26 | return encoded_name + '\0' | |
27 | ||
28 | ||
29 | def decode_name(name): | |
30 | name_length = ord(name[0]) | |
31 | assert name_length == 32 | |
32 | ||
33 | def _do_first_level_decoding(m): | |
34 | s = m.group(0) | |
35 | return chr(((ord(s[0]) - ord('A')) << 4) | (ord(s[1]) - ord('A'))) | |
36 | ||
37 | decoded_name = re.sub('..', _do_first_level_decoding, name[1:33]) | |
38 | if name[33] == '\0': | |
39 | return 34, decoded_name, '' | |
40 | else: | |
41 | decoded_domain = '' | |
42 | offset = 34 | |
43 | while 1: | |
44 | domain_length = ord(name[offset]) | |
45 | if domain_length == 0: | |
46 | break | |
47 | decoded_domain = '.' + name[offset:offset + domain_length] | |
48 | offset = offset + domain_length | |
49 | return offset + 1, decoded_name, decoded_domain |
0 | <?xml version="1.0" encoding="UTF-8"?> | |
1 | <!-- Komodo Project File - DO NOT EDIT --> | |
2 | <project id="dc8461e7-32f2-492f-9ec9-c5ddcbca553b" kpf_version="5" name="pysmb.komodoproject"> | |
3 | </project> |
0 | import os | |
1 | from distutils.core import setup | |
2 | ||
3 | setup( | |
4 | name = "pysmb", | |
5 | version = "1.0.0", | |
6 | author = "Michael Teo", | |
7 | author_email = "[email protected]", | |
8 | license = "zlib/libpng", | |
9 | description = "pysmb is an experimental SMB/CIFS library written in Python to support file sharing between Windows and Linux machines", | |
10 | keywords = "windows samba cifs sharing ftp smb linux", | |
11 | url = "http://miketeo.net/projects/pysmb", | |
12 | packages = [ 'smb', 'nmb' ], | |
13 | requires = [ 'pyasn1' ], | |
14 | long_description="""pysmb is an experimental SMB/CIFS library written in Python. It implements the client-side SMB/CIFS protocol which allows your Python application to access and transfer files to/from SMB/CIFS shared folders like your Windows file sharing and Samba folders.""", | |
15 | classifiers = [ | |
16 | "Development Status :: 5 - Production/Stable", | |
17 | "Environment :: Win32 (MS Windows)", | |
18 | "Environment :: Console", | |
19 | "License :: OSI Approved :: zlib/libpng License", | |
20 | "Operating System :: Microsoft :: Windows", | |
21 | "Operating System :: POSIX", | |
22 | "Programming Language :: Python :: 2.4", | |
23 | "Programming Language :: Python :: 2.5", | |
24 | "Programming Language :: Python :: 2.6", | |
25 | "Programming Language :: Python :: 2.7", | |
26 | "Topic :: Communications :: File Sharing", | |
27 | "Topic :: Software Development :: Libraries :: Python Modules", | |
28 | "Topic :: System :: Networking", | |
29 | ], | |
30 | ) |
0 | ||
1 | import os, logging, select, socket, types, struct | |
2 | from smb_constants import * | |
3 | from smb_structs import * | |
4 | from base import SMB, NotConnectedError, NotReadyError, SMBTimeout | |
5 | ||
6 | ||
7 | class SMBConnection(SMB): | |
8 | ||
9 | log = logging.getLogger('SMB.SMBConnection') | |
10 | ||
11 | def __init__(self, username, password, my_name, remote_name, domain = '', use_ntlm_v2 = True): | |
12 | """ | |
13 | Create a new SMBConnection instance. | |
14 | ||
15 | *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server. | |
16 | File operations can only be proceeded after the connection has been authenticated successfully. | |
17 | ||
18 | Note that you need to call *connect* method to actually establish the SMB connection to the remote server and perform authentication. | |
19 | ||
20 | :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from. | |
21 | You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?";|+`` | |
22 | :param string remote_name: The NetBIOS machine name of the remote server. | |
23 | On windows, you can find out the machine name by right-clicking on the "My Computer" and selecting "Properties". | |
24 | This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected. | |
25 | :param string domain: The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string. | |
26 | :param boolean use_ntlm_v2: Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication. | |
27 | The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured. | |
28 | Hence, we can only "guess" or try both algorithms. | |
29 | On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2. | |
30 | """ | |
31 | SMB.__init__(self, username, password, my_name, remote_name, domain, use_ntlm_v2) | |
32 | self.sock = None | |
33 | self.auth_result = None | |
34 | self.is_busy = False | |
35 | ||
36 | # | |
37 | # SMB (and its superclass) Methods | |
38 | # | |
39 | ||
40 | def onAuthOK(self): | |
41 | self.auth_result = True | |
42 | ||
43 | def onAuthFailed(self): | |
44 | self.auth_result = False | |
45 | ||
46 | def write(self, data): | |
47 | assert self.sock | |
48 | data_len = len(data) | |
49 | assert self.sock.send(data) == data_len | |
50 | ||
51 | # | |
52 | # Public Methods | |
53 | # | |
54 | ||
55 | def connect(self, ip, port, sock_family = socket.AF_INET, timeout = 60): | |
56 | """ | |
57 | Establish the SMB connection to the remote SMB/CIFS server. | |
58 | ||
59 | You must call this method before attempting any of the file operations with the remote server. | |
60 | This method will block until the SMB connection has attempted at least one authentication. | |
61 | ||
62 | :return: A boolean value indicating the result of the authentication atttempt: True if authentication is successful; False, if otherwise. | |
63 | """ | |
64 | if self.sock: | |
65 | self.sock.close() | |
66 | ||
67 | self.auth_result = None | |
68 | self.sock = socket.socket(sock_family) | |
69 | self.sock.connect_ex(( ip, port )) | |
70 | ||
71 | self.is_busy = True | |
72 | try: | |
73 | self.requestNMBSession() | |
74 | while self.auth_result is None: | |
75 | self._pollForNetBIOSPacket(timeout) | |
76 | finally: | |
77 | self.is_busy = False | |
78 | ||
79 | return self.auth_result | |
80 | ||
81 | def close(self): | |
82 | """ | |
83 | Terminate the SMB connection (if it has been started) and release any sources held by the underlying socket. | |
84 | """ | |
85 | if self.sock: | |
86 | self.sock.close() | |
87 | self.sock = None | |
88 | ||
89 | def listShares(self, timeout = 30): | |
90 | """ | |
91 | Retrieve a list of shared resources on remote server. | |
92 | ||
93 | :return: A list of :doc:`smb.base.SharedDevice<smb_SharedDevice>` instances describing the shared resource | |
94 | """ | |
95 | if not self.sock: | |
96 | raise NotConnectedError('Not connected to server') | |
97 | ||
98 | results = [ ] | |
99 | ||
100 | def cb(entries): | |
101 | self.is_busy = False | |
102 | results.extend(entries) | |
103 | ||
104 | def eb(failure): | |
105 | self.is_busy = False | |
106 | raise failure | |
107 | ||
108 | self.is_busy = True | |
109 | try: | |
110 | self._listShares(cb, eb, timeout) | |
111 | while self.is_busy: | |
112 | self._pollForNetBIOSPacket(timeout) | |
113 | finally: | |
114 | self.is_busy = False | |
115 | ||
116 | return results | |
117 | ||
118 | def listPath(self, service_name, path, | |
119 | search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE, | |
120 | pattern = '\\*', timeout = 30): | |
121 | """ | |
122 | Retrieve a directory listing of files/folders at *path* | |
123 | ||
124 | :param string/unicode service_name: the name of the shared folder for the *path* | |
125 | :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders. | |
126 | :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py). | |
127 | The default *search* value will query for all read-only, hidden, system, archive files and directories. | |
128 | :param string/unicode pattern: the filter to apply to the results before returning to the client. | |
129 | :return: A list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances. | |
130 | """ | |
131 | if not self.sock: | |
132 | raise NotConnectedError('Not connected to server') | |
133 | ||
134 | results = [ ] | |
135 | ||
136 | def cb(entries): | |
137 | self.is_busy = False | |
138 | results.extend(entries) | |
139 | ||
140 | def eb(failure): | |
141 | self.is_busy = False | |
142 | raise failure | |
143 | ||
144 | self.is_busy = True | |
145 | try: | |
146 | self._listPath(service_name, path, cb, eb, search = search, pattern = pattern, timeout = timeout) | |
147 | while self.is_busy: | |
148 | self._pollForNetBIOSPacket(timeout) | |
149 | finally: | |
150 | self.is_busy = False | |
151 | ||
152 | return results | |
153 | ||
154 | def retrieveFile(self, service_name, path, file_obj, timeout = 30): | |
155 | """ | |
156 | Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*. | |
157 | ||
158 | :param string/unicode service_name: the name of the shared folder for the *path* | |
159 | :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback. | |
160 | :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service. | |
161 | :return: A 2-element tuple of ( file attributes of the file on server, number of bytes retrieved ). | |
162 | The file attributes is an integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py) | |
163 | """ | |
164 | if not self.sock: | |
165 | raise NotConnectedError('Not connected to server') | |
166 | ||
167 | results = [ ] | |
168 | ||
169 | def cb(r): | |
170 | self.is_busy = False | |
171 | results.append(r[1:]) | |
172 | ||
173 | def eb(failure): | |
174 | self.is_busy = False | |
175 | raise failure | |
176 | ||
177 | self.is_busy = True | |
178 | try: | |
179 | self._retrieveFile(service_name, path, file_obj, cb, eb, timeout = timeout) | |
180 | while self.is_busy: | |
181 | self._pollForNetBIOSPacket(timeout) | |
182 | finally: | |
183 | self.is_busy = False | |
184 | ||
185 | return results[0] | |
186 | ||
187 | def storeFile(self, service_name, path, file_obj, timeout = 30): | |
188 | """ | |
189 | Store the contents of the *file_obj* at *path* on the *service_name*. | |
190 | ||
191 | :param string/unicode service_name: the name of the shared folder for the *path* | |
192 | :param string/unicode path: Path of the file on the remote server. If the file at *path* does not exist, it will be created. Otherwise, it will be overwritten. | |
193 | If the *path* refers to a folder or the file cannot be opened for writing, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback. | |
194 | :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF. | |
195 | :return: Number of bytes uploaded | |
196 | """ | |
197 | if not self.sock: | |
198 | raise NotConnectedError('Not connected to server') | |
199 | ||
200 | results = [ ] | |
201 | ||
202 | def cb(r): | |
203 | self.is_busy = False | |
204 | results.append(r[1]) | |
205 | ||
206 | def eb(failure): | |
207 | self.is_busy = False | |
208 | raise failure | |
209 | ||
210 | self.is_busy = True | |
211 | try: | |
212 | self._storeFile(service_name, path, file_obj, cb, eb, timeout = timeout) | |
213 | while self.is_busy: | |
214 | self._pollForNetBIOSPacket(timeout) | |
215 | finally: | |
216 | self.is_busy = False | |
217 | ||
218 | return results[0] | |
219 | ||
220 | def deleteFiles(self, service_name, path_file_pattern, timeout = 30): | |
221 | """ | |
222 | Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request. | |
223 | ||
224 | :param string/unicode service_name: Contains the name of the shared folder. | |
225 | :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name. | |
226 | Wildcards may be used in th filename component of the path. | |
227 | If your path/filename contains non-English characters, you must pass in an unicode string. | |
228 | :return: None | |
229 | """ | |
230 | if not self.sock: | |
231 | raise NotConnectedError('Not connected to server') | |
232 | ||
233 | def cb(r): | |
234 | self.is_busy = False | |
235 | ||
236 | def eb(failure): | |
237 | self.is_busy = False | |
238 | raise failure | |
239 | ||
240 | self.is_busy = True | |
241 | try: | |
242 | self._deleteFiles(service_name, path_file_pattern, cb, eb, timeout = timeout) | |
243 | while self.is_busy: | |
244 | self._pollForNetBIOSPacket(timeout) | |
245 | finally: | |
246 | self.is_busy = False | |
247 | ||
248 | def createDirectory(self, service_name, path, timeout = 30): | |
249 | """ | |
250 | Creates a new directory *path* on the *service_name*. | |
251 | ||
252 | :param string/unicode service_name: Contains the name of the shared folder. | |
253 | :param string/unicode path: The path of the new folder (relative to) the shared folder. | |
254 | If the path contains non-English characters, an unicode string must be used to pass in the path. | |
255 | :return: None | |
256 | """ | |
257 | if not self.sock: | |
258 | raise NotConnectedError('Not connected to server') | |
259 | ||
260 | def cb(r): | |
261 | self.is_busy = False | |
262 | ||
263 | def eb(failure): | |
264 | self.is_busy = False | |
265 | raise failure | |
266 | ||
267 | self.is_busy = True | |
268 | try: | |
269 | self._createDirectory(service_name, path, cb, eb, timeout = timeout) | |
270 | while self.is_busy: | |
271 | self._pollForNetBIOSPacket(timeout) | |
272 | finally: | |
273 | self.is_busy = False | |
274 | ||
275 | def deleteDirectory(self, service_name, path, timeout = 30): | |
276 | """ | |
277 | Delete the empty folder at *path* on *service_name* | |
278 | ||
279 | :param string/unicode service_name: Contains the name of the shared folder. | |
280 | :param string/unicode path: The path of the to-be-deleted folder (relative to) the shared folder. | |
281 | If the path contains non-English characters, an unicode string must be used to pass in the path. | |
282 | :return: None | |
283 | """ | |
284 | if not self.sock: | |
285 | raise NotConnectedError('Not connected to server') | |
286 | ||
287 | def cb(r): | |
288 | self.is_busy = False | |
289 | ||
290 | def eb(failure): | |
291 | self.is_busy = False | |
292 | raise failure | |
293 | ||
294 | self.is_busy = True | |
295 | try: | |
296 | self._deleteDirectory(service_name, path, cb, eb, timeout = timeout) | |
297 | while self.is_busy: | |
298 | self._pollForNetBIOSPacket(timeout) | |
299 | finally: | |
300 | self.is_busy = False | |
301 | ||
302 | def rename(self, service_name, old_path, new_path, timeout = 30): | |
303 | """ | |
304 | Rename a file or folder at *old_path* to *new_path* shared at *service_name*. Note that this method cannot be used to rename file/folder across different shared folders | |
305 | ||
306 | *old_path* and *new_path* are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder. | |
307 | If the path contains non-English characters, an unicode string must be used to pass in the path. | |
308 | ||
309 | :param string/unicode service_name: Contains the name of the shared folder. | |
310 | :return: None | |
311 | """ | |
312 | if not self.sock: | |
313 | raise NotConnectedError('Not connected to server') | |
314 | ||
315 | def cb(r): | |
316 | self.is_busy = False | |
317 | ||
318 | def eb(failure): | |
319 | self.is_busy = False | |
320 | raise failure | |
321 | ||
322 | self.is_busy = True | |
323 | try: | |
324 | self._rename(service_name, old_path, new_path, cb, eb) | |
325 | while self.is_busy: | |
326 | self._pollForNetBIOSPacket(timeout) | |
327 | finally: | |
328 | self.is_busy = False | |
329 | ||
330 | def echo(self, data, timeout = 10): | |
331 | """ | |
332 | Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*. | |
333 | ||
334 | :param string data: Data to send to the remote server. | |
335 | :return: The *data* parameter | |
336 | """ | |
337 | if not self.sock: | |
338 | raise NotConnectedError('Not connected to server') | |
339 | ||
340 | results = [ ] | |
341 | ||
342 | def cb(r): | |
343 | self.is_busy = False | |
344 | results.append(r) | |
345 | ||
346 | def eb(failure): | |
347 | self.is_busy = False | |
348 | raise failure | |
349 | ||
350 | self.is_busy = True | |
351 | try: | |
352 | self._echo(data, cb, eb) | |
353 | while self.is_busy: | |
354 | self._pollForNetBIOSPacket(timeout) | |
355 | finally: | |
356 | self.is_busy = False | |
357 | ||
358 | return results[0] | |
359 | ||
360 | # | |
361 | # Protected Methods | |
362 | # | |
363 | ||
364 | def _pollForNetBIOSPacket(self, timeout): | |
365 | read_len = 4 | |
366 | data = '' | |
367 | ||
368 | while read_len > 0: | |
369 | try: | |
370 | ready, _, _ = select.select([ self.sock.fileno() ], [ ], [ ], timeout) | |
371 | if not ready: | |
372 | raise SMBTimeout | |
373 | ||
374 | d = self.sock.recv(read_len) | |
375 | data = data + d | |
376 | read_len -= len(d) | |
377 | except select.error, ex: | |
378 | if type(ex) is types.TupleType: | |
379 | if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN: | |
380 | raise ex | |
381 | else: | |
382 | raise ex | |
383 | ||
384 | type, flags, length = struct.unpack('>BBH', data) | |
385 | if flags & 0x01: | |
386 | length = length | 0x10000 | |
387 | ||
388 | read_len = length | |
389 | while read_len > 0: | |
390 | try: | |
391 | ready, _, _ = select.select([ self.sock.fileno() ], [ ], [ ], timeout) | |
392 | if not ready: | |
393 | raise SMBTimeout | |
394 | ||
395 | d = self.sock.recv(read_len) | |
396 | data = data + d | |
397 | read_len -= len(d) | |
398 | except select.error, ex: | |
399 | if type(ex) is types.TupleType: | |
400 | if ex[0] != errno.EINTR and ex[0] != errno.EAGAIN: | |
401 | raise ex | |
402 | else: | |
403 | raise ex | |
404 | ||
405 | self.feedData(data) |
0 | ||
1 | import os, logging, time | |
2 | from twisted.internet import reactor, defer | |
3 | from twisted.internet.protocol import ClientFactory, Protocol | |
4 | from smb_constants import * | |
5 | from smb_structs import * | |
6 | from base import SMB, NotConnectedError, NotReadyError, SMBTimeout | |
7 | ||
8 | ||
9 | __all__ = [ 'SMBProtocolFactory', 'NotConnectedError', 'NotReadyError' ] | |
10 | ||
11 | ||
12 | class SMBProtocol(Protocol, SMB): | |
13 | ||
14 | log = logging.getLogger('SMB.SMBProtocol') | |
15 | ||
16 | # | |
17 | # Protocol Methods | |
18 | # | |
19 | ||
20 | def connectionMade(self): | |
21 | self.factory.instance = self | |
22 | self.requestNMBSession() | |
23 | ||
24 | def connectionLost(self, reason): | |
25 | if self.factory.instance == self: | |
26 | self.instance = None | |
27 | ||
28 | def dataReceived(self, data): | |
29 | self.feedData(data) | |
30 | ||
31 | # | |
32 | # SMB (and its superclass) Methods | |
33 | # | |
34 | ||
35 | def write(self, data): | |
36 | self.transport.write(data) | |
37 | ||
38 | def onAuthOK(self): | |
39 | if self.factory.instance == self: | |
40 | self.factory.onAuthOK() | |
41 | reactor.callLater(1, self._cleanupPendingRequests) | |
42 | ||
43 | def onAuthFailed(self): | |
44 | if self.factory.instance == self: | |
45 | self.factory.onAuthFailed() | |
46 | ||
47 | def onNMBSessionFailed(self): | |
48 | self.log.error('Cannot establish NetBIOS session. You might have provided a wrong remote_name') | |
49 | ||
50 | # | |
51 | # Protected Methods | |
52 | # | |
53 | ||
54 | def _cleanupPendingRequests(self): | |
55 | if self.factory.instance == self: | |
56 | now = time.time() | |
57 | for mid, r in self.pending_requests.items(): | |
58 | if r.expiry_time < now: | |
59 | try: | |
60 | r.errback(SMBTimeout()) | |
61 | except Exception: pass | |
62 | del self.pending_requests[mid] | |
63 | ||
64 | reactor.callLater(1, self._cleanupPendingRequests) | |
65 | ||
66 | ||
67 | class SMBProtocolFactory(ClientFactory): | |
68 | ||
69 | protocol = SMBProtocol | |
70 | log = logging.getLogger('SMB.SMBFactory') | |
71 | ||
72 | def __init__(self, username, password, my_name, remote_name, domain = '', use_ntlm_v2 = True): | |
73 | """ | |
74 | Create a new SMBProtocolFactory instance. | |
75 | ||
76 | *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server. | |
77 | File operations can only be proceeded after the connection has been authenticated successfully. | |
78 | ||
79 | :param string my_name: The local NetBIOS machine name that will identify where this connection is originating from. | |
80 | You can freely choose a name as long as it contains a maximum of 15 alphanumeric characters and does not contain spaces and any of ``\/:*?";|+`` | |
81 | :param string remote_name: The NetBIOS machine name of the remote server. | |
82 | On windows, you can find out the machine name by right-clicking on the "My Computer" and selecting "Properties". | |
83 | This parameter must be the same as what has been configured on the remote server, or else the connection will be rejected. | |
84 | :param string domain: The network domain. On windows, it is known as the workgroup. Usually, it is safe to leave this parameter as an empty string. | |
85 | :param boolean use_ntlm_v2: Indicates whether pysmb should be NTLMv1 or NTLMv2 authentication algorithm for authentication. | |
86 | The choice of NTLMv1 and NTLMv2 is configured on the remote server, and there is no mechanism to auto-detect which algorithm has been configured. | |
87 | Hence, we can only "guess" or try both algorithms. | |
88 | On Sambda, Windows Vista and Windows 7, NTLMv2 is enabled by default. On Windows XP, we can use NTLMv1 before NTLMv2. | |
89 | """ | |
90 | self.username = username | |
91 | self.password = password | |
92 | self.my_name = my_name | |
93 | self.remote_name = remote_name | |
94 | self.domain = domain | |
95 | self.use_ntlm_v2 = use_ntlm_v2 | |
96 | self.instance = None #: The single SMBProtocol instance for each SMBProtocolFactory instance. Usually, you should not need to touch this attribute directly. | |
97 | ||
98 | # | |
99 | # Public Property | |
100 | # | |
101 | ||
102 | @property | |
103 | def isReady(self): | |
104 | """A convenient property to return True if the underlying SMB connection has connected to remote server, has successfully authenticated itself and is ready for file operations.""" | |
105 | return bool(self.instance and self.instance.has_authenticated) | |
106 | ||
107 | # | |
108 | # Public Methods for Callbacks | |
109 | # | |
110 | ||
111 | def onAuthOK(self): | |
112 | """ | |
113 | Override this method in your *SMBProtocolFactory* subclass to add in post-authentication handling. | |
114 | This method will be called when the server has replied that the SMB connection has been successfully authenticated. | |
115 | File operations can proceed when this method has been called. | |
116 | """ | |
117 | pass | |
118 | ||
119 | def onAuthFailed(self): | |
120 | """ | |
121 | Override this method in your *SMBProtocolFactory* subclass to add in post-authentication handling. | |
122 | This method will be called when the server has replied that the SMB connection has been successfully authenticated. | |
123 | ||
124 | If you want to retry authenticating from this method, | |
125 | 1. Disconnect the underlying SMB connection (call ``self.instance.transport.loseConnection()``) | |
126 | 2. Create a new SMBProtocolFactory subclass instance with different user credientials or different NTLM algorithm flag. | |
127 | 3. Call ``reactor.connectTCP`` with the new instance to re-establish the SMB connection | |
128 | """ | |
129 | pass | |
130 | ||
131 | # | |
132 | # Public Methods | |
133 | # | |
134 | ||
135 | def listShares(self, timeout = 30): | |
136 | """ | |
137 | Retrieve a list of shared resources on remote server. | |
138 | ||
139 | :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method. | |
140 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of :doc:`smb.base.SharedDevice<smb_SharedDevice>` instances. | |
141 | """ | |
142 | if not self.instance: | |
143 | raise NotConnectedError('Not connected to server') | |
144 | ||
145 | d = defer.Deferred() | |
146 | self.instance._listShares(d.callback, d.errback, timeout) | |
147 | return d | |
148 | ||
149 | def listPath(self, service_name, path, | |
150 | search = SMB_FILE_ATTRIBUTE_READONLY | SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_ARCHIVE, | |
151 | pattern = '\\*', timeout = 30): | |
152 | """ | |
153 | Retrieve a directory listing of files/folders at *path* | |
154 | ||
155 | :param string/unicode service_name: the name of the shared folder for the *path* | |
156 | :param string/unicode path: path relative to the *service_name* where we are interested to learn about its files/sub-folders. | |
157 | :param integer search: integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py). | |
158 | The default *search* value will query for all read-only, hidden, system, archive files and directories. | |
159 | :param string/unicode pattern: the filter to apply to the results before returning to the client. | |
160 | :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method. | |
161 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a list of :doc:`smb.base.SharedFile<smb_SharedFile>` instances. | |
162 | """ | |
163 | if not self.instance: | |
164 | raise NotConnectedError('Not connected to server') | |
165 | ||
166 | d = defer.Deferred() | |
167 | self.instance._listPath(service_name, path, d.callback, d.errback, search = search, pattern = pattern, timeout = timeout) | |
168 | return d | |
169 | ||
170 | def retrieveFile(self, service_name, path, file_obj, timeout = 30): | |
171 | """ | |
172 | Retrieve the contents of the file at *path* on the *service_name* and write these contents to the provided *file_obj*. | |
173 | ||
174 | The meaning of the *timeout* parameter will be different from other file operation methods. As the downloaded file usually exceeeds the maximum size | |
175 | of each SMB/CIFS data message, it will be packetized into a series of request messages (each message will request about about 60kBytes). | |
176 | The *timeout* parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and downloaded from the remote SMB/CIFS server. | |
177 | ||
178 | :param string/unicode service_name: the name of the shared folder for the *path* | |
179 | :param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback. | |
180 | :param file_obj: A file-like object that has a *write* method. Data will be written continuously to *file_obj* until EOF is received from the remote service. | |
181 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 3-element tuple of ( *file_obj*, file attributes of the file on server, number of bytes retrieved ). | |
182 | The file attributes is an integer value made up from a bitwise-OR of *SMB_FILE_ATTRIBUTE_xxx* bits (see smb_constants.py) | |
183 | """ | |
184 | if not self.instance: | |
185 | raise NotConnectedError('Not connected to server') | |
186 | ||
187 | d = defer.Deferred() | |
188 | self.instance._retrieveFile(service_name, path, file_obj, d.callback, d.errback, timeout = timeout) | |
189 | return d | |
190 | ||
191 | def storeFile(self, service_name, path, file_obj, timeout = 30): | |
192 | """ | |
193 | Store the contents of the *file_obj* at *path* on the *service_name*. | |
194 | ||
195 | The meaning of the *timeout* parameter will be different from other file operation methods. As the uploaded file usually exceeeds the maximum size | |
196 | of each SMB/CIFS data message, it will be packetized into a series of messages (usually about 60kBytes). | |
197 | The *timeout* parameter is an integer/float value that specifies the timeout interval for these individual SMB/CIFS message to be transmitted and acknowledged | |
198 | by the remote SMB/CIFS server. | |
199 | ||
200 | :param string/unicode service_name: the name of the shared folder for the *path* | |
201 | :param string/unicode path: Path of the file on the remote server. If the file at *path* does not exist, it will be created. Otherwise, it will be overwritten. | |
202 | If the *path* refers to a folder or the file cannot be opened for writing, an :doc:`OperationFailure<smb_exceptions>` will be called in the returned *Deferred* errback. | |
203 | :param file_obj: A file-like object that has a *read* method. Data will read continuously from *file_obj* until EOF. | |
204 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 2-element tuple of ( *file_obj*, number of bytes uploaded ). | |
205 | """ | |
206 | if not self.instance: | |
207 | raise NotConnectedError('Not connected to server') | |
208 | ||
209 | d = defer.Deferred() | |
210 | self.instance._storeFile(service_name, path, file_obj, d.callback, d.errback, timeout = timeout) | |
211 | return d | |
212 | ||
213 | def deleteFiles(self, service_name, path_file_pattern, timeout = 30): | |
214 | """ | |
215 | Delete one or more regular files. It supports the use of wildcards in file names, allowing for deletion of multiple files in a single request. | |
216 | ||
217 | :param string/unicode service_name: Contains the name of the shared folder. | |
218 | :param string/unicode path_file_pattern: The pathname of the file(s) to be deleted, relative to the service_name. | |
219 | Wildcards may be used in th filename component of the path. | |
220 | If your path/filename contains non-English characters, you must pass in an unicode string. | |
221 | :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method. | |
222 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *path_file_pattern* parameter. | |
223 | """ | |
224 | if not self.instance: | |
225 | raise NotConnectedError('Not connected to server') | |
226 | ||
227 | d = defer.Deferred() | |
228 | self.instance._deleteFiles(service_name, path_file_pattern, d.callback, d.errback, timeout = timeout) | |
229 | return d | |
230 | ||
231 | def createDirectory(self, service_name, path): | |
232 | """ | |
233 | Creates a new directory *path* on the *service_name*. | |
234 | ||
235 | :param string/unicode service_name: Contains the name of the shared folder. | |
236 | :param string/unicode path: The path of the new folder (relative to) the shared folder. | |
237 | If the path contains non-English characters, an unicode string must be used to pass in the path. | |
238 | :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method. | |
239 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *path* parameter. | |
240 | """ | |
241 | if not self.instance: | |
242 | raise NotConnectedError('Not connected to server') | |
243 | ||
244 | d = defer.Deferred() | |
245 | self.instance._createDirectory(service_name, path, d.callback, d.errback) | |
246 | return d | |
247 | ||
248 | def deleteDirectory(self, service_name, path): | |
249 | """ | |
250 | Delete the empty folder at *path* on *service_name* | |
251 | ||
252 | :param string/unicode service_name: Contains the name of the shared folder. | |
253 | :param string/unicode path: The path of the to-be-deleted folder (relative to) the shared folder. | |
254 | If the path contains non-English characters, an unicode string must be used to pass in the path. | |
255 | :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method. | |
256 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *path* parameter. | |
257 | """ | |
258 | if not self.instance: | |
259 | raise NotConnectedError('Not connected to server') | |
260 | ||
261 | d = defer.Deferred() | |
262 | self.instance._deleteDirectory(service_name, path, d.callback, d.errback) | |
263 | return d | |
264 | ||
265 | def rename(self, service_name, old_path, new_path): | |
266 | """ | |
267 | Rename a file or folder at *old_path* to *new_path* shared at *service_name*. Note that this method cannot be used to rename file/folder across different shared folders | |
268 | ||
269 | *old_path* and *new_path* are string/unicode referring to the old and new path of the renamed resources (relative to) the shared folder. | |
270 | If the path contains non-English characters, an unicode string must be used to pass in the path. | |
271 | ||
272 | :param string/unicode service_name: Contains the name of the shared folder. | |
273 | :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method. | |
274 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with a 2-element tuple of ( *old_path*, *new_path* ). | |
275 | """ | |
276 | if not self.instance: | |
277 | raise NotConnectedError('Not connected to server') | |
278 | ||
279 | d = defer.Deferred() | |
280 | self.instance._rename(service_name, old_path, new_path, d.callback, d.errback) | |
281 | return d | |
282 | ||
283 | def echo(self, data, timeout = 10): | |
284 | """ | |
285 | Send an echo command containing *data* to the remote SMB/CIFS server. The remote SMB/CIFS will reply with the same *data*. | |
286 | ||
287 | :param string data: Data to send to the remote server. | |
288 | :param integer/float timeout: Number of seconds that pysmb will wait before raising *SMBTimeout* via the returned *Deferred* instance's *errback* method. | |
289 | :return: A *twisted.internet.defer.Deferred* instance. The callback function will be called with the *data* parameter. | |
290 | """ | |
291 | if not self.instance: | |
292 | raise NotConnectedError('Not connected to server') | |
293 | ||
294 | d = defer.Deferred() | |
295 | self.instance._echo(data, d.callback, d.errback, timeout) | |
296 | return d | |
297 | ||
298 | def closeConnection(self): | |
299 | """ | |
300 | Disconnect from the remote SMB/CIFS server. The TCP connection will be closed at the earliest opportunity after this method returns. | |
301 | ||
302 | :return: None | |
303 | """ | |
304 | if not self.instance: | |
305 | raise NotConnectedError('Not connected to server') | |
306 | ||
307 | self.instance.transport.loseConnection() | |
308 | ||
309 | # | |
310 | # ClientFactory methods | |
311 | # (Do not touch these unless you know what you are doing) | |
312 | # | |
313 | ||
314 | def buildProtocol(self, addr): | |
315 | p = self.protocol(self.username, self.password, self.my_name, self.remote_name, self.domain, self.use_ntlm_v2) | |
316 | p.factory = self | |
317 | return p |
0 | ||
1 | import logging, binascii, time | |
2 | from smb_constants import * | |
3 | from smb_structs import * | |
4 | from nmb.base import NMBSession | |
5 | from utils import convertFILETIMEtoEpoch | |
6 | import ntlm, securityblob | |
7 | ||
8 | class NotReadyError(Exception): | |
9 | """Raised when SMB connection is not ready (i.e. not authenticated or authentication failed)""" | |
10 | pass | |
11 | ||
12 | class NotConnectedError(Exception): | |
13 | """Raised when underlying SMB connection has been disconnected or not connected yet""" | |
14 | pass | |
15 | ||
16 | class SMBTimeout(Exception): | |
17 | """Raised when a timeout has occurred while waiting for a response or for a SMB/CIFS operation to complete.""" | |
18 | pass | |
19 | ||
20 | ||
21 | class SMB(NMBSession): | |
22 | """ | |
23 | This class represents a "connection" to the remote SMB/CIFS server. | |
24 | It is not meant to be used directly in an application as it does not have any network transport implementations. | |
25 | ||
26 | For application use, please refer to | |
27 | - L{SMBProtocol.SMBProtocolFactory<smb.SMBProtocol>} if you are using Twisted framework | |
28 | ||
29 | In [MS-CIFS], this class will contain attributes of Client, Client.Connection and Client.Session abstract data models. | |
30 | ||
31 | References: | |
32 | =========== | |
33 | - [MS-CIFS]: 3.2.1 | |
34 | """ | |
35 | ||
36 | log = logging.getLogger('SMB.SMB') | |
37 | ||
38 | def __init__(self, username, password, my_name, remote_name, domain = '', use_ntlm_v2 = True): | |
39 | NMBSession.__init__(self, my_name, remote_name) | |
40 | self.username = username | |
41 | self.password = password | |
42 | self.domain = domain | |
43 | self.use_ntlm_v2 = use_ntlm_v2 #: Similar to LMAuthenticationPolicy and NTAuthenticationPolicy as described in [MS-CIFS] 3.2.1.1 | |
44 | self.smb_message = SMBMessage() | |
45 | self.pending_requests = { } #: MID mapped to _PendingRequest instance | |
46 | self.connected_trees = { } #: Share name mapped to TID | |
47 | self.next_rpc_call_id = 0 #: Next RPC callID value. Not used directly in SMB message. Usually encapsulated in sub-commands under SMB_COM_TRANSACTION or SMB_COM_TRANSACTION2 messages | |
48 | ||
49 | self.has_negotiated = False | |
50 | self.has_authenticated = False | |
51 | self.mid = 0 | |
52 | self.uid = 0 | |
53 | ||
54 | # Most of the following attributes will be initialized upon receipt of SMB_COM_NEGOTIATE message from server (via self._updateServerInfo method) | |
55 | self.use_plaintext_authentication = False #: Similar to PlaintextAuthenticationPolicy in in [MS-CIFS] 3.2.1.1 | |
56 | self.max_raw_size = 0 | |
57 | self.max_buffer_size = 0 #: Similar to MaxBufferSize as described in [MS-CIFS] 3.2.1.1 | |
58 | self.max_mpx_count = 0 #: Similar to MaxMpxCount as described in [MS-CIFS] 3.2.1.1 | |
59 | self.capabilities = 0 | |
60 | ||
61 | self.log.info('Authetication with remote machine "%s" for user "%s" will be using NTLM %s authentication (%s extended security)', | |
62 | self.remote_name, self.username, | |
63 | (self.use_ntlm_v2 and 'v2') or 'v1', | |
64 | (SUPPORT_EXTENDED_SECURITY and 'with') or 'without') | |
65 | ||
66 | ||
67 | # | |
68 | # NMBSession Methods | |
69 | # | |
70 | ||
71 | def onNMBSessionOK(self): | |
72 | self._sendSMBMessage(SMBMessage(ComNegotiateRequest())) | |
73 | ||
74 | def onNMBSessionFailed(self): | |
75 | pass | |
76 | ||
77 | def onNMBSessionMessage(self, flags, data): | |
78 | i = self.smb_message.decode(data) | |
79 | if i > 0: | |
80 | self.log.debug('Received SMB message "%s" (command:0x%2X flags:0x%02X flags2:0x%04X TID:%d UID:%d)', | |
81 | SMB_COMMAND_NAMES.get(self.smb_message.command, '<unknown>'), | |
82 | self.smb_message.command, self.smb_message.flags, self.smb_message.flags2, self.smb_message.tid, self.smb_message.uid) | |
83 | if self._updateState(self.smb_message): | |
84 | self.smb_message = SMBMessage() | |
85 | ||
86 | # | |
87 | # Public Methods for Overriding in Subclasses | |
88 | # | |
89 | ||
90 | def onAuthOK(self): | |
91 | pass | |
92 | ||
93 | def onAuthFailed(self): | |
94 | pass | |
95 | ||
96 | # | |
97 | # Protected Methods | |
98 | # | |
99 | ||
100 | def _sendSMBMessage(self, smb_message): | |
101 | if smb_message.mid == 0: | |
102 | smb_message.mid = self._getNextMID() | |
103 | smb_message.uid = self.uid | |
104 | smb_message.raw_data = smb_message.encode() | |
105 | self.sendNMBMessage(smb_message.raw_data) | |
106 | ||
107 | def _getNextMID(self): | |
108 | self.mid += 1 | |
109 | if self.mid >= 0xFFFF: # MID cannot be 0xFFFF. [MS-CIFS]: 2.2.1.6.2 | |
110 | # We don't use MID of 0 as MID can be reused for SMB_COM_TRANSACTION2_SECONDARY messages | |
111 | # where if mid=0, _sendSMBMessage will re-assign new MID values again | |
112 | self.mid = 1 | |
113 | return self.mid | |
114 | ||
115 | def _getNextRPCCallID(self): | |
116 | self.next_rpc_call_id += 1 | |
117 | return self.next_rpc_call_id | |
118 | ||
119 | def _updateState(self, message): | |
120 | if message.isReply: | |
121 | if message.command == SMB_COM_NEGOTIATE: | |
122 | self.has_negotiated = True | |
123 | self.log.info('SMB dialect negotiation successful (ExtendedSecurity:%s)', message.hasExtendedSecurity) | |
124 | self._updateServerInfo(message.payload) | |
125 | self._handleNegotiateResponse(message) | |
126 | elif message.command == SMB_COM_SESSION_SETUP_ANDX: | |
127 | if message.hasExtendedSecurity: | |
128 | if not message.status.hasError: | |
129 | try: | |
130 | result = securityblob.decodeAuthResponseSecurityBlob(message.payload.security_blob) | |
131 | if result == securityblob.RESULT_ACCEPT_COMPLETED: | |
132 | self.has_authenticated = True | |
133 | self.log.info('Authentication (with extended security) successful!') | |
134 | self.onAuthOK() | |
135 | else: | |
136 | raise ProtocolError('SMB_COM_SESSION_SETUP_ANDX status is 0 but security blob negResult value is %d' % result, message.raw_data, message) | |
137 | except securityblob.BadSecurityBlobError, ex: | |
138 | raise ProtocolError(str(ex), message.raw_data, message) | |
139 | elif message.status.internal_value == 0xc0000016: # STATUS_MORE_PROCESSING_REQUIRED | |
140 | try: | |
141 | result, ntlm_token = securityblob.decodeChallengeSecurityBlob(message.payload.security_blob) | |
142 | if result == securityblob.RESULT_ACCEPT_INCOMPLETE: | |
143 | self._handleSessionChallenge(message, ntlm_token) | |
144 | except ( securityblob.BadSecurityBlobError, securityblob.UnsupportedSecurityProvider ), ex: | |
145 | raise ProtocolError(str(ex), message.raw_data, message) | |
146 | elif message.status.internal_value == 0xc000006d: # STATUS_LOGON_FAILURE | |
147 | self.has_authenticated = False | |
148 | self.log.info('Authentication (with extended security) failed. Please check username and password. You may need to enable/disable NTLMv2 authentication.') | |
149 | self.onAuthFailed() | |
150 | else: | |
151 | raise ProtocolError('Unknown status value (0x%08X) in SMB_COM_SESSION_SETUP_ANDX (with extended security)' % message.status.internal_value, | |
152 | message.raw_data, message) | |
153 | else: | |
154 | if message.status.internal_value == 0: | |
155 | self.has_authenticated = True | |
156 | self.log.info('Authentication (without extended security) successful!') | |
157 | self.onAuthOK() | |
158 | else: | |
159 | self.has_authenticated = False | |
160 | self.log.info('Authentication (without extended security) failed. Please check username and password') | |
161 | self.onAuthFailed() | |
162 | elif message.command == SMB_COM_TREE_CONNECT_ANDX: | |
163 | try: | |
164 | req = self.pending_requests[message.mid] | |
165 | except KeyError: | |
166 | pass | |
167 | else: | |
168 | if not message.status.hasError: | |
169 | self.connected_trees[req.kwargs['path']] = message.tid | |
170 | ||
171 | req = self.pending_requests.pop(message.mid, None) | |
172 | if req: | |
173 | req.callback(message, **req.kwargs) | |
174 | return True | |
175 | ||
176 | ||
177 | def _updateServerInfo(self, payload): | |
178 | self.capabilities = payload.capabilities | |
179 | self.max_raw_size = payload.max_raw_size | |
180 | self.max_buffer_size = payload.max_buffer_size | |
181 | self.max_mpx_count = payload.max_mpx_count | |
182 | self.use_plaintext_authentication = not bool(payload.security_mode & NEGOTIATE_ENCRYPT_PASSWORDS) | |
183 | ||
184 | if self.use_plaintext_authentication: | |
185 | self.log.warning('Remote server only supports plaintext authentication. Your password can be stolen easily over the network.') | |
186 | ||
187 | if payload.security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRE: | |
188 | raise UnsupportedFeature('Remote server requires secure SMB message signing but current version pysmb does not support this yet.') | |
189 | ||
190 | ||
191 | def _handleSessionChallenge(self, message, ntlm_token): | |
192 | assert message.hasExtendedSecurity | |
193 | ||
194 | if message.uid and not self.uid: | |
195 | self.log.debug('SMB uid is now %d', message.uid) | |
196 | self.uid = message.uid | |
197 | ||
198 | server_challenge, server_flags, server_info = ntlm.decodeChallengeMessage(ntlm_token) | |
199 | if self.use_ntlm_v2: | |
200 | self.log.info('Performing NTLMv2 authentication (with extended security) with server challenge "%s"', binascii.hexlify(server_challenge)) | |
201 | nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV2(self.password, | |
202 | self.username, | |
203 | server_challenge, | |
204 | server_info, | |
205 | self.domain) | |
206 | ||
207 | else: | |
208 | self.log.info('Performing NTLMv1 authentication (with extended security) with server challenge "%s"', binascii.hexlify(server_challenge)) | |
209 | nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(self.password, server_challenge, True) | |
210 | ||
211 | ntlm_data = ntlm.generateAuthenticateMessage(server_flags, | |
212 | nt_challenge_response, | |
213 | lm_challenge_response, | |
214 | session_key, | |
215 | self.username) | |
216 | ||
217 | if self.log.isEnabledFor(logging.DEBUG): | |
218 | self.log.debug('NT challenge response is "%s" (%d bytes)', binascii.hexlify(nt_challenge_response), len(nt_challenge_response)) | |
219 | self.log.debug('LM challenge response is "%s" (%d bytes)', binascii.hexlify(lm_challenge_response), len(lm_challenge_response)) | |
220 | ||
221 | blob = securityblob.generateAuthSecurityBlob(ntlm_data) | |
222 | self._sendSMBMessage(SMBMessage(ComSessionSetupAndxRequest__WithSecurityExtension(0, blob))) | |
223 | ||
224 | ||
225 | def _handleNegotiateResponse(self, message): | |
226 | if message.uid and not self.uid: | |
227 | self.log.debug('SMB uid is now %d', message.uid) | |
228 | self.uid = message.uid | |
229 | ||
230 | if message.hasExtendedSecurity: | |
231 | ntlm_data = ntlm.generateNegotiateMessage() | |
232 | blob = securityblob.generateNegotiateSecurityBlob(ntlm_data) | |
233 | self._sendSMBMessage(SMBMessage(ComSessionSetupAndxRequest__WithSecurityExtension(message.payload.session_key, blob))) | |
234 | else: | |
235 | nt_password, _, _ = ntlm.generateChallengeResponseV1(self.password, message.payload.challenge, False) | |
236 | self.log.info('Performing NTLMv1 authentication (without extended security) with challenge "%s" and hashed password of "%s"', | |
237 | binascii.hexlify(message.payload.challenge), | |
238 | binascii.hexlify(nt_password)) | |
239 | self._sendSMBMessage(SMBMessage(ComSessionSetupAndxRequest__NoSecurityExtension(message.payload.session_key, | |
240 | self.username, | |
241 | nt_password, | |
242 | True, | |
243 | message.payload.domain))) | |
244 | ||
245 | def _listShares(self, callback, errback, timeout = 30): | |
246 | if not self.has_authenticated: | |
247 | raise NotReadyError('SMB connection not authenticated') | |
248 | ||
249 | expiry_time = time.time() + timeout | |
250 | path = 'IPC$' | |
251 | messages_history = [ ] | |
252 | ||
253 | def connectSrvSvc(tid): | |
254 | m = SMBMessage(ComNTCreateAndxRequest('\\srvsvc', | |
255 | flags = NT_CREATE_REQUEST_EXTENDED_RESPONSE, | |
256 | access_mask = READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | FILE_WRITE_EA | FILE_READ_EA | FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA, | |
257 | share_access = FILE_SHARE_READ | FILE_SHARE_WRITE, | |
258 | create_disp = FILE_OPEN, | |
259 | create_options = FILE_OPEN_NO_RECALL | FILE_NON_DIRECTORY_FILE, | |
260 | impersonation = SEC_IMPERSONATE, | |
261 | security_flags = 0)) | |
262 | m.tid = tid | |
263 | self._sendSMBMessage(m) | |
264 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectSrvSvcCB, errback) | |
265 | messages_history.append(m) | |
266 | ||
267 | def connectSrvSvcCB(create_message, **kwargs): | |
268 | messages_history.append(create_message) | |
269 | if not create_message.status.hasError: | |
270 | call_id = self._getNextRPCCallID() | |
271 | # See [MS-CIFS]: 2.2.5.6.1 for more information on TRANS_TRANSACT_NMPIPE (0x0026) parameters | |
272 | setup_bytes = struct.pack('<HH', 0x0026, create_message.payload.fid) | |
273 | # The data_bytes are binding call to Server Service RPC using DCE v1.1 RPC over SMB. See [MS-SRVS] and [C706] | |
274 | # If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream | |
275 | data_bytes = \ | |
276 | binascii.unhexlify("""05 00 0b 03 10 00 00 00 48 00 00 00""".replace(' ', '')) + \ | |
277 | struct.pack('<I', call_id) + \ | |
278 | binascii.unhexlify(""" | |
279 | b8 10 b8 10 00 00 00 00 01 00 00 00 00 00 01 00 | |
280 | c8 4f 32 4b 70 16 d3 01 12 78 5a 47 bf 6e e1 88 | |
281 | 03 00 00 00 04 5d 88 8a eb 1c c9 11 9f e8 08 00 | |
282 | 2b 10 48 60 02 00 00 00""".replace(' ', '').replace('\n', '')) | |
283 | m = SMBMessage(ComTransactionRequest(max_params_count = 0, | |
284 | max_data_count = 4280, | |
285 | max_setup_count = 0, | |
286 | data_bytes = data_bytes, | |
287 | setup_bytes = setup_bytes)) | |
288 | m.tid = create_message.tid | |
289 | self._sendSMBMessage(m) | |
290 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, rpcBindCB, errback, fid = create_message.payload.fid) | |
291 | messages_history.append(m) | |
292 | else: | |
293 | errback(OperationFailure('Failed to list shares: Unable to locate Server Service RPC endpoint', messages_history)) | |
294 | ||
295 | def rpcBindCB(trans_message, **kwargs): | |
296 | messages_history.append(trans_message) | |
297 | if not trans_message.status.hasError: | |
298 | call_id = self._getNextRPCCallID() | |
299 | ||
300 | padding = '' | |
301 | server_len = len(self.remote_name) + 1 | |
302 | server_bytes_len = server_len * 2 | |
303 | if server_len % 2 != 0: | |
304 | padding = '\0\0' | |
305 | server_bytes_len += 2 | |
306 | ||
307 | # See [MS-CIFS]: 2.2.5.6.1 for more information on TRANS_TRANSACT_NMPIPE (0x0026) parameters | |
308 | setup_bytes = struct.pack('<HH', 0x0026, kwargs['fid']) | |
309 | # The data bytes are the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC. | |
310 | # If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream | |
311 | data_bytes = \ | |
312 | binascii.unhexlify("""05 00 00 03 10 00 00 00""".replace(' ', '')) + \ | |
313 | struct.pack('<HHI', 72+server_bytes_len, 0, call_id) + \ | |
314 | binascii.unhexlify("""4c 00 00 00 00 00 0f 00 00 00 02 00""".replace(' ', '')) + \ | |
315 | struct.pack('<III', server_len, 0, server_len) + \ | |
316 | (self.remote_name + '\0').encode('UTF-16LE') + padding + \ | |
317 | binascii.unhexlify(""" | |
318 | 01 00 00 00 01 00 00 00 04 00 02 00 00 00 00 00 | |
319 | 00 00 00 00 ff ff ff ff 08 00 02 00 00 00 00 00 | |
320 | """.replace(' ', '').replace('\n', '')) | |
321 | m = SMBMessage(ComTransactionRequest(max_params_count = 0, | |
322 | max_data_count = 4280, | |
323 | max_setup_count = 0, | |
324 | data_bytes = data_bytes, | |
325 | setup_bytes = setup_bytes)) | |
326 | m.tid = trans_message.tid | |
327 | self._sendSMBMessage(m) | |
328 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, listShareResultsCB, errback, fid = kwargs['fid']) | |
329 | messages_history.append(m) | |
330 | else: | |
331 | closeFid(trans_message.tid, kwargs['fid']) | |
332 | errback(OperationFailure('Failed to list shares: Unable to bind to Server Service RPC endpoint', messages_history)) | |
333 | ||
334 | def listShareResultsCB(result_message, **kwargs): | |
335 | messages_history.append(result_message) | |
336 | if not result_message.status.hasError: | |
337 | # The payload.data_bytes will contain the results of the RPC call to NetrShareEnum (Opnum 15) at Server Service RPC. | |
338 | data_bytes = result_message.payload.data_bytes | |
339 | shares_count = struct.unpack('<I', data_bytes[36:40])[0] | |
340 | ||
341 | results = [ ] # A list of SharedDevice instances | |
342 | offset = 36 + 12 # You need to study the byte stream to understand the meaning of these constants | |
343 | for i in range(0, shares_count): | |
344 | results.append(SharedDevice(struct.unpack('<I', data_bytes[offset+4:offset+8])[0], None, None)) | |
345 | offset += 12 | |
346 | ||
347 | for i in range(0, shares_count): | |
348 | max_length, _, length = struct.unpack('<III', data_bytes[offset:offset+12]) | |
349 | offset += 12 | |
350 | results[i].name = unicode(data_bytes[offset:offset+length*2-2], 'UTF-16LE') | |
351 | ||
352 | if length % 2 != 0: | |
353 | offset += (length * 2 + 2) | |
354 | else: | |
355 | offset += (length * 2) | |
356 | ||
357 | max_length, _, length = struct.unpack('<III', data_bytes[offset:offset+12]) | |
358 | offset += 12 | |
359 | results[i].comments = unicode(data_bytes[offset:offset+length*2-2], 'UTF-16LE') | |
360 | ||
361 | if length % 2 != 0: | |
362 | offset += (length * 2 + 2) | |
363 | else: | |
364 | offset += (length * 2) | |
365 | ||
366 | closeFid(result_message.tid, kwargs['fid']) | |
367 | callback(results) | |
368 | else: | |
369 | closeFid(result_message.tid, kwargs['fid']) | |
370 | errback(OperationFailure('Failed to list shares: Unable to retrieve shared device list', messages_history)) | |
371 | ||
372 | def closeFid(tid, fid): | |
373 | m = SMBMessage(ComCloseRequest(fid)) | |
374 | m.tid = tid | |
375 | self._sendSMBMessage(m) | |
376 | messages_history.append(m) | |
377 | ||
378 | if not self.connected_trees.has_key(path): | |
379 | def connectCB(connect_message, **kwargs): | |
380 | messages_history.append(connect_message) | |
381 | if not connect_message.status.hasError: | |
382 | connectSrvSvc(connect_message.tid) | |
383 | else: | |
384 | errback(OperationFailure('Failed to list shares: Unable to connect to IPC$', messages_history)) | |
385 | ||
386 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), path ), SERVICE_ANY, '')) | |
387 | self._sendSMBMessage(m) | |
388 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = path) | |
389 | messages_history.append(m) | |
390 | else: | |
391 | connectSrvSvc(self.connected_trees[path]) | |
392 | ||
393 | def _listPath(self, service_name, path, callback, errback, search, pattern, timeout = 30): | |
394 | if not self.has_authenticated: | |
395 | raise NotReadyError('SMB connection not authenticated') | |
396 | ||
397 | expiry_time = time.time() + timeout | |
398 | path = path.replace('/', '\\') | |
399 | messages_history = [ ] | |
400 | results = [ ] | |
401 | ||
402 | def sendFindFirst(tid): | |
403 | setup_bytes = struct.pack('<H', 0x0001) # TRANS2_FIND_FIRST2 sub-command. See [MS-CIFS]: 2.2.6.2.1 | |
404 | params_bytes = \ | |
405 | struct.pack('<HHHHI', | |
406 | search, # SearchAttributes | |
407 | 100, # SearchCount | |
408 | 0x0006, # Flags: SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS | |
409 | 0x0104, # InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO | |
410 | 0x0000) # SearchStorageType | |
411 | params_bytes += pattern.encode('UTF-16LE') | |
412 | ||
413 | m = SMBMessage(ComTransaction2Request(max_params_count = 10, | |
414 | max_data_count = 16644, | |
415 | max_setup_count = 0, | |
416 | params_bytes = params_bytes, | |
417 | setup_bytes = setup_bytes)) | |
418 | m.tid = tid | |
419 | self._sendSMBMessage(m) | |
420 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, findFirstCB, errback) | |
421 | messages_history.append(m) | |
422 | ||
423 | def decodeFindStruct(data_bytes): | |
424 | # SMB_FIND_FILE_BOTH_DIRECTORY_INFO structure. See [MS-CIFS]: 2.2.8.1.7 and [MS-SMB]: 2.2.8.1.1 | |
425 | info_format = '<IIQQQQQQIIIBB24s' | |
426 | info_size = struct.calcsize(info_format) | |
427 | ||
428 | data_length = len(data_bytes) | |
429 | offset = 0 | |
430 | while offset < data_length: | |
431 | next_offset, _, \ | |
432 | create_time, last_access_time, last_write_time, last_attr_change_time, \ | |
433 | file_size, alloc_size, file_attributes, filename_length, ea_size, \ | |
434 | short_name_length, _, short_name = struct.unpack(info_format, data_bytes[offset:offset+info_size]) | |
435 | ||
436 | offset2 = offset + info_size | |
437 | ||
438 | filename = data_bytes[offset2:offset2+filename_length].decode('UTF-16LE') | |
439 | short_name = short_name.decode('UTF-16LE') | |
440 | results.append(SharedFile(create_time, last_access_time, last_write_time, last_attr_change_time, | |
441 | file_size, alloc_size, file_attributes, short_name, filename)) | |
442 | ||
443 | if next_offset: | |
444 | offset += next_offset | |
445 | else: | |
446 | break | |
447 | ||
448 | def findFirstCB(find_message, **kwargs): | |
449 | messages_history.append(find_message) | |
450 | if not find_message.status.hasError: | |
451 | # TRANS2_FIND_FIRST2 response. [MS-CIFS]: 2.2.6.2.2 | |
452 | sid, search_count, end_of_search, _, last_name_offset = struct.unpack('<HHHHH', find_message.payload.params_bytes[:10]) | |
453 | if find_message.payload.data_bytes: | |
454 | decodeFindStruct(find_message.payload.data_bytes) | |
455 | ||
456 | if end_of_search: | |
457 | callback(results) | |
458 | else: | |
459 | sendFindNext(find_message.tid, sid, last_name_offset) | |
460 | else: | |
461 | errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history)) | |
462 | ||
463 | def sendFindNext(tid, sid, resume_key): | |
464 | setup_bytes = struct.pack('<H', 0x0002) # TRANS2_FIND_NEXT2 sub-command. See [MS-CIFS]: 2.2.6.3.1 | |
465 | params_bytes = \ | |
466 | struct.pack('<HHHIH', | |
467 | sid, # SID | |
468 | 100, # SearchCount | |
469 | 0x0104, # InfoLevel: SMB_FIND_FILE_BOTH_DIRECTORY_INFO | |
470 | resume_key, # ResumeKey | |
471 | 0x000a) # Flags: SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS | SMB_FIND_RETURN_RESUME_KEYS | |
472 | params_bytes += pattern.encode('UTF-16LE') | |
473 | ||
474 | m = SMBMessage(ComTransaction2Request(max_params_count = 10, | |
475 | max_data_count = 16644, | |
476 | max_setup_count = 0, | |
477 | params_bytes = params_bytes, | |
478 | setup_bytes = setup_bytes)) | |
479 | m.tid = tid | |
480 | self._sendSMBMessage(m) | |
481 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, findNextCB, errback, sid = sid) | |
482 | messages_history.append(m) | |
483 | ||
484 | def findNextCB(find_message, **kwargs): | |
485 | messages_history.append(find_message) | |
486 | if not find_message.status.hasError: | |
487 | # TRANS2_FIND_NEXT2 response. [MS-CIFS]: 2.2.6.3.2 | |
488 | search_count, end_of_search, _, last_name_offset = struct.unpack('<HHHH', find_message.payload.params_bytes[:8]) | |
489 | if find_message.payload.data_bytes: | |
490 | decodeFindStruct(find_message.payload.data_bytes) | |
491 | ||
492 | if end_of_search: | |
493 | callback(results) | |
494 | else: | |
495 | sendFindNext(find_message.tid, kwargs['sid'], last_name_offset) | |
496 | else: | |
497 | errback(OperationFailure('Failed to list %s on %s: Unable to retrieve file list' % ( path, service_name ), messages_history)) | |
498 | ||
499 | if not self.connected_trees.has_key(service_name): | |
500 | def connectCB(connect_message, **kwargs): | |
501 | messages_history.append(connect_message) | |
502 | if not connect_message.status.hasError: | |
503 | sendFindFirst(connect_message.tid) | |
504 | else: | |
505 | errback(OperationFailure('Failed to list %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history)) | |
506 | ||
507 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) | |
508 | self._sendSMBMessage(m) | |
509 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectCB, errback, path = service_name) | |
510 | messages_history.append(m) | |
511 | else: | |
512 | sendFindFirst(self.connected_trees[service_name]) | |
513 | ||
514 | def _retrieveFile(self, service_name, path, file_obj, callback, errback, timeout = 30): | |
515 | if not self.has_authenticated: | |
516 | raise NotReadyError('SMB connection not authenticated') | |
517 | ||
518 | path = path.replace('/', '\\') | |
519 | messages_history = [ ] | |
520 | ||
521 | def sendOpen(tid): | |
522 | m = SMBMessage(ComOpenAndxRequest(filename = path, | |
523 | access_mode = 0x0040, # Sharing mode: Deny nothing to others | |
524 | open_mode = 0x0001, # Failed if file does not exist | |
525 | search_attributes = SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM, | |
526 | timeout = timeout * 1000)) | |
527 | m.tid = tid | |
528 | self._sendSMBMessage(m) | |
529 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, openCB, errback) | |
530 | messages_history.append(m) | |
531 | ||
532 | def openCB(open_message, **kwargs): | |
533 | messages_history.append(open_message) | |
534 | if not open_message.status.hasError: | |
535 | sendRead(open_message.tid, open_message.payload.fid, 0L, open_message.payload.file_attributes) | |
536 | else: | |
537 | errback(OperationFailure('Failed to retrieve %s on %s: Unable to open file' % ( path, service_name ), messages_history)) | |
538 | ||
539 | def sendRead(tid, fid, offset, file_attributes): | |
540 | read_count = self.max_raw_size - 2 | |
541 | m = SMBMessage(ComReadAndxRequest(fid = fid, | |
542 | offset = offset, | |
543 | max_return_bytes_count = read_count, | |
544 | min_return_bytes_count = min(0xFFFF, read_count))) | |
545 | m.tid = tid | |
546 | self._sendSMBMessage(m) | |
547 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, readCB, errback, fid = fid, offset = offset, file_attributes = file_attributes) | |
548 | ||
549 | def readCB(read_message, **kwargs): | |
550 | # To avoid crazy memory usage when retrieving large files, we do not save every read_message in messages_history. | |
551 | if not read_message.status.hasError: | |
552 | file_obj.write(read_message.payload.data) | |
553 | if read_message.payload.data_length < (self.max_raw_size - 2): | |
554 | closeFid(read_message.tid, kwargs['fid']) | |
555 | callback(( file_obj, kwargs['file_attributes'], kwargs['offset']+read_message.payload.data_length )) # Note that this is a tuple of 3-elements | |
556 | else: | |
557 | sendRead(read_message.tid, kwargs['fid'], kwargs['offset']+read_message.payload.data_length, kwargs['file_attributes']) | |
558 | else: | |
559 | messages_history.append(read_message) | |
560 | closeFid(read_message.tid, kwargs['fid']) | |
561 | errback(OperationFailure('Failed to retrieve %s on %s: Read failed' % ( path, service_name ), messages_history)) | |
562 | ||
563 | def closeFid(tid, fid): | |
564 | m = SMBMessage(ComCloseRequest(fid)) | |
565 | m.tid = tid | |
566 | self._sendSMBMessage(m) | |
567 | messages_history.append(m) | |
568 | ||
569 | if not self.connected_trees.has_key(service_name): | |
570 | def connectCB(connect_message, **kwargs): | |
571 | messages_history.append(connect_message) | |
572 | if not connect_message.status.hasError: | |
573 | sendOpen(connect_message.tid) | |
574 | else: | |
575 | errback(OperationFailure('Failed to retrieve %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history)) | |
576 | ||
577 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) | |
578 | self._sendSMBMessage(m) | |
579 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name) | |
580 | messages_history.append(m) | |
581 | else: | |
582 | sendOpen(self.connected_trees[service_name]) | |
583 | ||
584 | def _storeFile(self, service_name, path, file_obj, callback, errback, timeout = 30): | |
585 | if not self.has_authenticated: | |
586 | raise NotReadyError('SMB connection not authenticated') | |
587 | ||
588 | path = path.replace('/', '\\') | |
589 | messages_history = [ ] | |
590 | ||
591 | def sendOpen(tid): | |
592 | m = SMBMessage(ComOpenAndxRequest(filename = path, | |
593 | access_mode = 0x0041, # Sharing mode: Deny nothing to others + Open for writing | |
594 | open_mode = 0x0010, # Create file if file does not exist | |
595 | search_attributes = SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM, | |
596 | timeout = timeout * 1000)) | |
597 | m.tid = tid | |
598 | self._sendSMBMessage(m) | |
599 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, openCB, errback) | |
600 | messages_history.append(m) | |
601 | ||
602 | def openCB(open_message, **kwargs): | |
603 | messages_history.append(open_message) | |
604 | if not open_message.status.hasError: | |
605 | sendWrite(open_message.tid, open_message.payload.fid, 0L) | |
606 | else: | |
607 | errback(OperationFailure('Failed to store %s on %s: Unable to open file' % ( path, service_name ), messages_history)) | |
608 | ||
609 | def sendWrite(tid, fid, offset): | |
610 | write_count = min(self.max_raw_size, 0xFFFF) | |
611 | data_bytes = file_obj.read(write_count) | |
612 | if data_bytes: | |
613 | m = SMBMessage(ComWriteAndxRequest(fid = fid, offset = offset, data_bytes = data_bytes)) | |
614 | m.tid = tid | |
615 | self._sendSMBMessage(m) | |
616 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, writeCB, errback, fid = fid, offset = offset+len(data_bytes)) | |
617 | else: | |
618 | closeFid(tid, fid) | |
619 | callback(( file_obj, offset )) # Note that this is a tuple of 2-elements | |
620 | ||
621 | def writeCB(write_message, **kwargs): | |
622 | # To avoid crazy memory usage when saving large files, we do not save every write_message in messages_history. | |
623 | if not write_message.status.hasError: | |
624 | sendWrite(write_message.tid, kwargs['fid'], kwargs['offset']) | |
625 | else: | |
626 | messages_history.append(write_message) | |
627 | closeFid(write_message.tid, kwargs['fid']) | |
628 | errback(OperationFailure('Failed to store %s on %s: Write failed' % ( path, service_name ), messages_history)) | |
629 | ||
630 | def closeFid(tid, fid): | |
631 | m = SMBMessage(ComCloseRequest(fid)) | |
632 | m.tid = tid | |
633 | self._sendSMBMessage(m) | |
634 | messages_history.append(m) | |
635 | ||
636 | if not self.connected_trees.has_key(service_name): | |
637 | def connectCB(connect_message, **kwargs): | |
638 | messages_history.append(connect_message) | |
639 | if not connect_message.status.hasError: | |
640 | sendOpen(connect_message.tid) | |
641 | else: | |
642 | errback(OperationFailure('Failed to store %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history)) | |
643 | ||
644 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) | |
645 | self._sendSMBMessage(m) | |
646 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name) | |
647 | messages_history.append(m) | |
648 | else: | |
649 | sendOpen(self.connected_trees[service_name]) | |
650 | ||
651 | def _deleteFiles(self, service_name, path_file_pattern, callback, errback, timeout = 30): | |
652 | if not self.has_authenticated: | |
653 | raise NotReadyError('SMB connection not authenticated') | |
654 | ||
655 | path = path_file_pattern.replace('/', '\\') | |
656 | messages_history = [ ] | |
657 | ||
658 | def sendDelete(tid): | |
659 | m = SMBMessage(ComDeleteRequest(filename_pattern = path, | |
660 | search_attributes = SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM)) | |
661 | m.tid = tid | |
662 | self._sendSMBMessage(m) | |
663 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback) | |
664 | messages_history.append(m) | |
665 | ||
666 | def deleteCB(delete_message, **kwargs): | |
667 | messages_history.append(delete_message) | |
668 | if not delete_message.status.hasError: | |
669 | callback(path_file_pattern) | |
670 | else: | |
671 | errback(OperationFailure('Failed to store %s on %s: Delete failed' % ( path, service_name ), messages_history)) | |
672 | ||
673 | if not self.connected_trees.has_key(service_name): | |
674 | def connectCB(connect_message, **kwargs): | |
675 | messages_history.append(connect_message) | |
676 | if not connect_message.status.hasError: | |
677 | sendDelete(connect_message.tid) | |
678 | else: | |
679 | errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history)) | |
680 | ||
681 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) | |
682 | self._sendSMBMessage(m) | |
683 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name) | |
684 | messages_history.append(m) | |
685 | else: | |
686 | sendDelete(self.connected_trees[service_name]) | |
687 | ||
688 | def _createDirectory(self, service_name, path, callback, errback, timeout = 30): | |
689 | if not self.has_authenticated: | |
690 | raise NotReadyError('SMB connection not authenticated') | |
691 | ||
692 | path = path.replace('/', '\\') | |
693 | messages_history = [ ] | |
694 | ||
695 | def sendCreate(tid): | |
696 | m = SMBMessage(ComCreateDirectoryRequest(path)) | |
697 | m.tid = tid | |
698 | self._sendSMBMessage(m) | |
699 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, createCB, errback) | |
700 | messages_history.append(m) | |
701 | ||
702 | def createCB(create_message, **kwargs): | |
703 | messages_history.append(create_message) | |
704 | if not create_message.status.hasError: | |
705 | callback(path) | |
706 | else: | |
707 | errback(OperationFailure('Failed to create directory %s on %s: Create failed' % ( path, service_name ), messages_history)) | |
708 | ||
709 | if not self.connected_trees.has_key(service_name): | |
710 | def connectCB(connect_message, **kwargs): | |
711 | messages_history.append(connect_message) | |
712 | if not connect_message.status.hasError: | |
713 | sendCreate(connect_message.tid) | |
714 | else: | |
715 | errback(OperationFailure('Failed to create directory %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history)) | |
716 | ||
717 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) | |
718 | self._sendSMBMessage(m) | |
719 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name) | |
720 | messages_history.append(m) | |
721 | else: | |
722 | sendCreate(self.connected_trees[service_name]) | |
723 | ||
724 | def _deleteDirectory(self, service_name, path, callback, errback, timeout = 30): | |
725 | if not self.has_authenticated: | |
726 | raise NotReadyError('SMB connection not authenticated') | |
727 | ||
728 | path = path.replace('/', '\\') | |
729 | messages_history = [ ] | |
730 | ||
731 | def sendDelete(tid): | |
732 | m = SMBMessage(ComDeleteDirectoryRequest(path)) | |
733 | m.tid = tid | |
734 | self._sendSMBMessage(m) | |
735 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, deleteCB, errback) | |
736 | messages_history.append(m) | |
737 | ||
738 | def deleteCB(delete_message, **kwargs): | |
739 | messages_history.append(delete_message) | |
740 | if not delete_message.status.hasError: | |
741 | callback(path) | |
742 | else: | |
743 | errback(OperationFailure('Failed to delete directory %s on %s: Delete failed' % ( path, service_name ), messages_history)) | |
744 | ||
745 | if not self.connected_trees.has_key(service_name): | |
746 | def connectCB(connect_message, **kwargs): | |
747 | messages_history.append(connect_message) | |
748 | if not connect_message.status.hasError: | |
749 | sendDelete(connect_message.tid) | |
750 | else: | |
751 | errback(OperationFailure('Failed to delete %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history)) | |
752 | ||
753 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) | |
754 | self._sendSMBMessage(m) | |
755 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name) | |
756 | messages_history.append(m) | |
757 | else: | |
758 | sendDelete(self.connected_trees[service_name]) | |
759 | ||
760 | def _rename(self, service_name, old_path, new_path, callback, errback, timeout = 30): | |
761 | if not self.has_authenticated: | |
762 | raise NotReadyError('SMB connection not authenticated') | |
763 | ||
764 | new_path = new_path.replace('/', '\\') | |
765 | old_path = old_path.replace('/', '\\') | |
766 | messages_history = [ ] | |
767 | ||
768 | def sendRename(tid): | |
769 | m = SMBMessage(ComRenameRequest(old_path = old_path, | |
770 | new_path = new_path, | |
771 | search_attributes = SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM)) | |
772 | m.tid = tid | |
773 | self._sendSMBMessage(m) | |
774 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, renameCB, errback) | |
775 | messages_history.append(m) | |
776 | ||
777 | def renameCB(rename_message, **kwargs): | |
778 | messages_history.append(rename_message) | |
779 | if not rename_message.status.hasError: | |
780 | callback(( old_path, new_path )) # Note that this is a tuple of 2-elements | |
781 | else: | |
782 | errback(OperationFailure('Failed to rename %s on %s: Rename failed' % ( old_path, service_name ), messages_history)) | |
783 | ||
784 | if not self.connected_trees.has_key(service_name): | |
785 | def connectCB(connect_message, **kwargs): | |
786 | messages_history.append(connect_message) | |
787 | if not connect_message.status.hasError: | |
788 | sendRename(connect_message.tid) | |
789 | else: | |
790 | errback(OperationFailure('Failed to rename %s on %s: Unable to connect to shared device' % ( old_path, service_name ), messages_history)) | |
791 | ||
792 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) | |
793 | self._sendSMBMessage(m) | |
794 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name) | |
795 | messages_history.append(m) | |
796 | else: | |
797 | sendRename(self.connected_trees[service_name]) | |
798 | ||
799 | def _echo(self, data, callback, errback, timeout = 30): | |
800 | messages_history = [ ] | |
801 | ||
802 | def echoCB(echo_message, **kwargs): | |
803 | messages_history.append(echo_message) | |
804 | if not echo_message.status.hasError: | |
805 | callback(echo_message.payload.data) | |
806 | else: | |
807 | errback(OperationFailure('Echo failed', messages_history)) | |
808 | ||
809 | m = SMBMessage(ComEchoRequest(echo_data = data)) | |
810 | self._sendSMBMessage(m) | |
811 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, echoCB, errback) | |
812 | messages_history.append(m) | |
813 | ||
814 | ||
815 | class SharedDevice: | |
816 | """ | |
817 | Contains information about a single shared device on the remote server. | |
818 | """ | |
819 | ||
820 | # The following constants are taken from [MS-SRVS]: 2.2.2.4 | |
821 | # They are used to identify the type of shared resource from the results from the NetrShareEnum in Server Service RPC | |
822 | DISK_TREE = 0x00 | |
823 | PRINT_QUEUE = 0x01 | |
824 | COMM_DEVICE = 0x02 | |
825 | IPC = 0x03 | |
826 | ||
827 | def __init__(self, type, name, comments): | |
828 | self._type = type | |
829 | self.name = name #: An unicode string containing the name of the shared device | |
830 | self.comments = comments #: An unicode string containing the user description of the shared device | |
831 | ||
832 | @property | |
833 | def type(self): | |
834 | """ | |
835 | Returns one of the following integral constants. | |
836 | - SharedDevice.DISK_TREE | |
837 | - SharedDevice.PRINT_QUEUE | |
838 | - SharedDevice.COMM_DEVICE | |
839 | - SharedDevice.IPC | |
840 | """ | |
841 | return self._type & 0xFFFF | |
842 | ||
843 | @property | |
844 | def isSpecial(self): | |
845 | """ | |
846 | Returns True if this shared device is a special share reserved for interprocess communication (IPC$) | |
847 | or remote administration of the server (ADMIN$). Can also refer to administrative shares such as | |
848 | C$, D$, E$, and so forth | |
849 | """ | |
850 | return bool(self._type & 0x80000000) | |
851 | ||
852 | @property | |
853 | def isTemporary(self): | |
854 | """ | |
855 | Returns True if this is a temporary share that is not persisted for creation each time the file server initializes. | |
856 | """ | |
857 | return bool(self._type & 0x40000000) | |
858 | ||
859 | def __unicode__(self): | |
860 | return u'Shared device: %s (type:0x%02x comments:%s)' % (self.name, self.type, self.comments ) | |
861 | ||
862 | ||
863 | class SharedFile: | |
864 | """ | |
865 | Contain information about a file/folder entry that is shared on the shared device. | |
866 | ||
867 | As an application developer, you should not need to instantiate a *SharedFile* instance directly in your application. | |
868 | These *SharedFile* instances are usually returned via a call to *listPath* method in :doc:`smb.SMBProtocol.SMBProtocolFactory<smb_SMBProtocolFactory>`. | |
869 | ||
870 | If you encounter *SharedFile* instance where its short_name attribute is empty but the filename attribute contains a short name which does not correspond | |
871 | to any files/folders on your remote shared device, it could be that the original filename on the file/folder entry on the shared device contains | |
872 | one of these prohibited characters: "\/[]:+|<>=;?,* (see [MS-CIFS]: 2.2.1.1.1 for more details). | |
873 | """ | |
874 | ||
875 | def __init__(self, create_time, last_access_time, last_write_time, last_attr_change_time, file_size, alloc_size, file_attributes, short_name, filename): | |
876 | self.create_time = create_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of creation of this file resource on the remote server | |
877 | self.last_access_time = last_access_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last access of this file resource on the remote server | |
878 | self.last_write_time = last_write_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last modification of this file resource on the remote server | |
879 | self.last_attr_change_time = last_attr_change_time #: Float value in number of seconds since 1970-01-01 00:00:00 to the time of last attribute change of this file resource on the remote server | |
880 | self.file_size = file_size #: File size in number of bytes | |
881 | self.alloc_size = alloc_size #: Total number of bytes allocated to store this file | |
882 | self.file_attributes = file_attributes #: A SMB_EXT_FILE_ATTR integer value. See [MS-CIFS]: 2.2.1.2.3 | |
883 | self.short_name = short_name #: Unicode string containing the short name of this file (usually in 8.3 notation) | |
884 | self.filename = filename #: Unicode string containing the long filename of this file. Each OS has a limit to the length of this file name. On Windows, it is 256 characters. | |
885 | ||
886 | @property | |
887 | def isDirectory(self): | |
888 | """A convenience property to return True if this file resource is a directory on the remote server""" | |
889 | return bool(self.file_attributes & ATTR_DIRECTORY) | |
890 | ||
891 | def __unicode__(self): | |
892 | return u'Shared file: %s (FileSize:%d bytes, isDirectory:%s)' % ( self.filename, self.file_size, self.isDirectory ) | |
893 | ||
894 | ||
895 | class _PendingRequest: | |
896 | ||
897 | def __init__(self, mid, expiry_time, callback, errback, **kwargs): | |
898 | self.mid = mid | |
899 | self.expiry_time = expiry_time | |
900 | self.callback = callback | |
901 | self.errback = errback | |
902 | self.kwargs = kwargs |
0 | ||
1 | import types, hmac, binascii, struct, random | |
2 | from utils.pyDes import des | |
3 | ||
4 | try: | |
5 | import hashlib | |
6 | hashlib.new('md4') | |
7 | ||
8 | def MD4(): return hashlib.new('md4') | |
9 | except ( ImportError, ValueError ): | |
10 | from utils.md4 import MD4 | |
11 | ||
12 | try: | |
13 | import hashlib | |
14 | def MD5(s): return hashlib.md5(s) | |
15 | except ImportError: | |
16 | import md5 | |
17 | def MD5(s): return md5.new(s) | |
18 | ||
19 | ################ | |
20 | # NTLMv2 Methods | |
21 | ################ | |
22 | ||
23 | # The following constants are defined in accordance to [MS-NLMP]: 2.2.2.5 | |
24 | ||
25 | NTLM_NegotiateUnicode = 0x00000001 | |
26 | NTLM_NegotiateOEM = 0x00000002 | |
27 | NTLM_RequestTarget = 0x00000004 | |
28 | NTLM_Unknown9 = 0x00000008 | |
29 | NTLM_NegotiateSign = 0x00000010 | |
30 | NTLM_NegotiateSeal = 0x00000020 | |
31 | NTLM_NegotiateDatagram = 0x00000040 | |
32 | NTLM_NegotiateLanManagerKey = 0x00000080 | |
33 | NTLM_Unknown8 = 0x00000100 | |
34 | NTLM_NegotiateNTLM = 0x00000200 | |
35 | NTLM_NegotiateNTOnly = 0x00000400 | |
36 | NTLM_Anonymous = 0x00000800 | |
37 | NTLM_NegotiateOemDomainSupplied = 0x00001000 | |
38 | NTLM_NegotiateOemWorkstationSupplied = 0x00002000 | |
39 | NTLM_Unknown6 = 0x00004000 | |
40 | NTLM_NegotiateAlwaysSign = 0x00008000 | |
41 | NTLM_TargetTypeDomain = 0x00010000 | |
42 | NTLM_TargetTypeServer = 0x00020000 | |
43 | NTLM_TargetTypeShare = 0x00040000 | |
44 | NTLM_NegotiateExtendedSecurity = 0x00080000 | |
45 | NTLM_NegotiateIdentify = 0x00100000 | |
46 | NTLM_Unknown5 = 0x00200000 | |
47 | NTLM_RequestNonNTSessionKey = 0x00400000 | |
48 | NTLM_NegotiateTargetInfo = 0x00800000 | |
49 | NTLM_Unknown4 = 0x01000000 | |
50 | NTLM_NegotiateVersion = 0x02000000 | |
51 | NTLM_Unknown3 = 0x04000000 | |
52 | NTLM_Unknown2 = 0x08000000 | |
53 | NTLM_Unknown1 = 0x10000000 | |
54 | NTLM_Negotiate128 = 0x20000000 | |
55 | NTLM_NegotiateKeyExchange = 0x40000000 | |
56 | NTLM_Negotiate56 = 0x80000000 | |
57 | ||
58 | NTLM_FLAGS = NTLM_NegotiateUnicode | \ | |
59 | NTLM_RequestTarget | \ | |
60 | NTLM_NegotiateNTLM | \ | |
61 | NTLM_NegotiateAlwaysSign | \ | |
62 | NTLM_NegotiateExtendedSecurity | \ | |
63 | NTLM_NegotiateTargetInfo | \ | |
64 | NTLM_NegotiateVersion | \ | |
65 | NTLM_Negotiate128 | \ | |
66 | NTLM_NegotiateKeyExchange | \ | |
67 | NTLM_Negotiate56 | |
68 | ||
69 | def generateNegotiateMessage(): | |
70 | """ | |
71 | References: | |
72 | =========== | |
73 | - [MS-NLMP]: 2.2.1.1 | |
74 | """ | |
75 | s = struct.pack('<8sII8s8s8s', | |
76 | 'NTLMSSP\0', 0x01, NTLM_FLAGS, | |
77 | '\0' * 8, # Domain | |
78 | '\0' * 8, # Workstation | |
79 | '\x06\x00\x72\x17\x00\x00\x00\x0F') # Version [MS-NLMP]: 2.2.2.10 | |
80 | return s | |
81 | ||
82 | ||
83 | def generateAuthenticateMessage(challenge_flags, nt_response, lm_response, session_key, user, domain = 'WORKGROUP', workstation = 'LOCALHOST'): | |
84 | """ | |
85 | References: | |
86 | =========== | |
87 | - [MS-NLMP]: 2.2.1.3 | |
88 | """ | |
89 | FORMAT = '<8sIHHIHHIHHIHHIHHIHHII' | |
90 | FORMAT_SIZE = struct.calcsize(FORMAT) | |
91 | ||
92 | lm_response_length = len(lm_response) | |
93 | lm_response_offset = FORMAT_SIZE | |
94 | nt_response_length = len(nt_response) | |
95 | nt_response_offset = lm_response_offset + lm_response_length | |
96 | domain_unicode = domain.encode('UTF-16LE') | |
97 | domain_length = len(domain_unicode) | |
98 | domain_offset = nt_response_offset + nt_response_length | |
99 | ||
100 | padding = '' | |
101 | if domain_offset % 2 != 0: | |
102 | padding = '\0' | |
103 | domain_offset += 1 | |
104 | ||
105 | user_unicode = user.encode('UTF-16LE') | |
106 | user_length = len(user_unicode) | |
107 | user_offset = domain_offset + domain_length | |
108 | workstation_unicode = workstation.encode('UTF-16LE') | |
109 | workstation_length = len(workstation_unicode) | |
110 | workstation_offset = user_offset + user_length | |
111 | session_key_length = len(session_key) | |
112 | session_key_offset = workstation_offset + workstation_length | |
113 | ||
114 | auth_flags = challenge_flags | |
115 | auth_flags &= ~NTLM_NegotiateVersion | |
116 | ||
117 | s = struct.pack(FORMAT, | |
118 | 'NTLMSSP\0', 0x03, | |
119 | lm_response_length, lm_response_length, lm_response_offset, | |
120 | nt_response_length, nt_response_length, nt_response_offset, | |
121 | domain_length, domain_length, domain_offset, | |
122 | user_length, user_length, user_offset, | |
123 | workstation_length, workstation_length, workstation_offset, | |
124 | session_key_length, session_key_length, session_key_offset, | |
125 | auth_flags) | |
126 | ||
127 | return s + lm_response + nt_response + padding + domain_unicode + user_unicode + workstation_unicode + session_key | |
128 | ||
129 | ||
130 | def decodeChallengeMessage(ntlm_data): | |
131 | """ | |
132 | References: | |
133 | =========== | |
134 | - [MS-NLMP]: 2.2.1.2 | |
135 | - [MS-NLMP]: 2.2.2.1 (AV_PAIR) | |
136 | """ | |
137 | FORMAT = '<8sIHHII8s8sHHI' | |
138 | FORMAT_SIZE = struct.calcsize(FORMAT) | |
139 | ||
140 | signature, message_type, \ | |
141 | targetname_len, targetname_maxlen, targetname_offset, \ | |
142 | flags, challenge, _, \ | |
143 | targetinfo_len, targetinfo_maxlen, targetinfo_offset, \ | |
144 | = struct.unpack(FORMAT, ntlm_data[:FORMAT_SIZE]) | |
145 | ||
146 | assert signature == 'NTLMSSP\0' | |
147 | assert message_type == 0x02 | |
148 | ||
149 | return challenge, flags, ntlm_data[targetinfo_offset:targetinfo_offset+targetinfo_len] | |
150 | ||
151 | ||
152 | def generateChallengeResponseV2(password, user, server_challenge, server_info, domain = '', client_challenge = None): | |
153 | client_timestamp = '\0' * 8 | |
154 | ||
155 | if not client_challenge: | |
156 | client_challenge = '' | |
157 | for i in range(0, 8): | |
158 | client_challenge += chr(random.getrandbits(8)) | |
159 | assert len(client_challenge) == 8 | |
160 | ||
161 | d = MD4() | |
162 | d.update(password.encode('UTF-16LE')) | |
163 | ntlm_hash = d.digest() # The NT password hash | |
164 | response_key = hmac.new(ntlm_hash, (user.upper() + domain).encode('UTF-16LE')).digest() # The NTLMv2 password hash. In [MS-NLMP], this is the result of NTOWFv2 and LMOWFv2 functions | |
165 | temp = '\x01\x01' + '\0'*6 + client_timestamp + client_challenge + '\0'*4 + server_info | |
166 | ntproofstr = hmac.new(response_key, server_challenge + temp).digest() | |
167 | ||
168 | nt_challenge_response = ntproofstr + temp | |
169 | lm_challenge_response = hmac.new(response_key, server_challenge + client_challenge).digest() + client_challenge | |
170 | session_key = hmac.new(response_key, ntproofstr).digest() | |
171 | ||
172 | return nt_challenge_response, lm_challenge_response, session_key | |
173 | ||
174 | ||
175 | ################ | |
176 | # NTLMv1 Methods | |
177 | ################ | |
178 | ||
179 | def expandDesKey(key): | |
180 | """Expand the key from a 7-byte password key into a 8-byte DES key""" | |
181 | s = chr(((ord(key[0]) >> 1) & 0x7f) << 1) | |
182 | s = s + chr(((ord(key[0]) & 0x01) << 6 | ((ord(key[1]) >> 2) & 0x3f)) << 1) | |
183 | s = s + chr(((ord(key[1]) & 0x03) << 5 | ((ord(key[2]) >> 3) & 0x1f)) << 1) | |
184 | s = s + chr(((ord(key[2]) & 0x07) << 4 | ((ord(key[3]) >> 4) & 0x0f)) << 1) | |
185 | s = s + chr(((ord(key[3]) & 0x0f) << 3 | ((ord(key[4]) >> 5) & 0x07)) << 1) | |
186 | s = s + chr(((ord(key[4]) & 0x1f) << 2 | ((ord(key[5]) >> 6) & 0x03)) << 1) | |
187 | s = s + chr(((ord(key[5]) & 0x3f) << 1 | ((ord(key[6]) >> 7) & 0x01)) << 1) | |
188 | s = s + chr((ord(key[6]) & 0x7f) << 1) | |
189 | return s | |
190 | ||
191 | ||
192 | def DESL(K, D): | |
193 | """ | |
194 | References: | |
195 | =========== | |
196 | - http://ubiqx.org/cifs/SMB.html (2.8.3.4) | |
197 | - [MS-NLMP]: Section 6 | |
198 | """ | |
199 | d1 = des(expandDesKey(K[0:7])) | |
200 | d2 = des(expandDesKey(K[7:14])) | |
201 | d3 = des(expandDesKey(K[14:16] + '\0' * 5)) | |
202 | return d1.encrypt(D) + d2.encrypt(D) + d3.encrypt(D) | |
203 | ||
204 | ||
205 | def generateChallengeResponseV1(password, server_challenge, has_extended_security = False, client_challenge = None): | |
206 | """ | |
207 | Generate a NTLMv1 response | |
208 | ||
209 | @param password: User password string | |
210 | @param server_challange: A 8-byte challenge string sent from the server | |
211 | @param has_extended_security: A boolean value indicating whether NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag is enabled in the NTLM negFlag | |
212 | @param client_challenge: A 8-byte string representing client challenge. If None, it will be generated randomly if needed by the response generation | |
213 | @return: a tuple of ( NT challenge response string, LM challenge response string ) | |
214 | ||
215 | References: | |
216 | =========== | |
217 | - http://ubiqx.org/cifs/SMB.html (2.8.3.3 and 2.8.3.4) | |
218 | - [MS-NLMP]: 3.3.1 | |
219 | """ | |
220 | _password = (password.upper() + '\0' * 14)[:14] | |
221 | d1 = des(expandDesKey(_password[:7])) | |
222 | d2 = des(expandDesKey(_password[7:])) | |
223 | lm_response_key = d1.encrypt("KGS!@#$%") + d2.encrypt("KGS!@#$%") # LM password hash. In [MS-NLMP], this is the result of LMOWFv1 function | |
224 | ||
225 | d = MD4() | |
226 | d.update(password.encode('UTF-16LE')) | |
227 | nt_response_key = d.digest() # In [MS-NLMP], this is the result of NTOWFv1 function | |
228 | ||
229 | if has_extended_security: | |
230 | if not client_challenge: | |
231 | client_challenge = '' | |
232 | for i in range(0, 8): | |
233 | client_challenge += chr(random.getrandbits(8)) | |
234 | ||
235 | assert len(client_challenge) == 8 | |
236 | ||
237 | lm_challenge_response = client_challenge + '\0'*16 | |
238 | nt_challenge_response = DESL(nt_response_key, MD5(server_challenge + client_challenge).digest()[0:8]) | |
239 | else: | |
240 | nt_challenge_response = DESL(nt_response_key, server_challenge) # The result after DESL is the NT response | |
241 | lm_challenge_response = DESL(lm_response_key, server_challenge) # The result after DESL is the LM response | |
242 | ||
243 | d = MD4() | |
244 | d.update(nt_response_key) | |
245 | session_key = d.digest() | |
246 | ||
247 | return nt_challenge_response, lm_challenge_response, session_key |
0 | ||
1 | from pyasn1.type import tag, univ, namedtype, namedval, constraint | |
2 | from pyasn1.codec.der import encoder, decoder | |
3 | ||
4 | __all__ = [ 'generateNegotiateSecurityBlob', 'generateAuthSecurityBlob', 'decodeChallengeSecurityBlob', 'decodeAuthResponseSecurityBlob' ] | |
5 | ||
6 | ||
7 | class UnsupportedSecurityProvider(Exception): pass | |
8 | class BadSecurityBlobError(Exception): pass | |
9 | ||
10 | ||
11 | def generateNegotiateSecurityBlob(ntlm_data): | |
12 | mech_token = univ.OctetString(ntlm_data).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)) | |
13 | mech_types = MechTypeList().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)) | |
14 | mech_types.setComponentByPosition(0, univ.ObjectIdentifier('1.3.6.1.4.1.311.2.2.10')) | |
15 | ||
16 | n = NegTokenInit().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)) | |
17 | n.setComponentByName('mechTypes', mech_types) | |
18 | n.setComponentByName('mechToken', mech_token) | |
19 | ||
20 | nt = NegotiationToken() | |
21 | nt.setComponentByName('negTokenInit', n) | |
22 | ||
23 | ct = ContextToken() | |
24 | ct.setComponentByName('thisMech', univ.ObjectIdentifier('1.3.6.1.5.5.2')) | |
25 | ct.setComponentByName('innerContextToken', nt) | |
26 | ||
27 | return encoder.encode(ct) | |
28 | ||
29 | ||
30 | def generateAuthSecurityBlob(ntlm_data): | |
31 | response_token = univ.OctetString(ntlm_data).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)) | |
32 | ||
33 | n = NegTokenTarg().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)) | |
34 | n.setComponentByName('responseToken', response_token) | |
35 | ||
36 | nt = NegotiationToken() | |
37 | nt.setComponentByName('negTokenTarg', n) | |
38 | ||
39 | return encoder.encode(nt) | |
40 | ||
41 | ||
42 | def decodeChallengeSecurityBlob(data): | |
43 | try: | |
44 | d, _ = decoder.decode(data, asn1Spec = NegotiationToken()) | |
45 | nt = d.getComponentByName('negTokenTarg') | |
46 | ||
47 | token = nt.getComponentByName('responseToken') | |
48 | if not token: | |
49 | raise BadSecurityBlobError('NTLMSSP_CHALLENGE security blob does not contain responseToken field') | |
50 | ||
51 | provider_oid = nt.getComponentByName('mechListMIC') | |
52 | if provider_oid and str(provider_oid) != '1.3.6.1.4.1.311.2.2.10': # This OID is defined in [MS-NLMP]: 1.9 | |
53 | raise UnsupportedSecurityProvider('Security provider "%s" is not supported by pysmb' % str(provider_oid)) | |
54 | ||
55 | result = nt.getComponentByName('negResult') | |
56 | return int(result), str(token) | |
57 | except Exception, ex: | |
58 | raise BadSecurityBlobError(str(ex)) | |
59 | ||
60 | ||
61 | def decodeAuthResponseSecurityBlob(data): | |
62 | try: | |
63 | d, _ = decoder.decode(data, asn1Spec = NegotiationToken()) | |
64 | nt = d.getComponentByName('negTokenTarg') | |
65 | ||
66 | result = nt.getComponentByName('negResult') | |
67 | return int(result) | |
68 | except Exception, ex: | |
69 | raise BadSecurityBlobError(str(ex)) | |
70 | ||
71 | ||
72 | # | |
73 | # GSS-API ASN.1 (RFC2478 section 3.2.1) | |
74 | # | |
75 | ||
76 | RESULT_ACCEPT_COMPLETED = 0 | |
77 | RESULT_ACCEPT_INCOMPLETE = 1 | |
78 | RESULT_REJECT = 2 | |
79 | ||
80 | class NegResultEnumerated(univ.Enumerated): | |
81 | namedValues = namedval.NamedValues( | |
82 | ( 'accept_completed', 0 ), | |
83 | ( 'accept_incomplete', 1 ), | |
84 | ( 'reject', 2 ) | |
85 | ) | |
86 | subtypeSpec = univ.Enumerated.subtypeSpec + constraint.SingleValueConstraint(0, 1, 2) | |
87 | ||
88 | ||
89 | class MechTypeList(univ.SequenceOf): | |
90 | componentType = univ.ObjectIdentifier() | |
91 | ||
92 | ||
93 | class ContextFlags(univ.BitString): | |
94 | namedValues = namedval.NamedValues( | |
95 | ( 'delegFlag', 0 ), | |
96 | ( 'mutualFlag', 1 ), | |
97 | ( 'replayFlag', 2 ), | |
98 | ( 'sequenceFlag', 3 ), | |
99 | ( 'anonFlag', 4 ), | |
100 | ( 'confFlag', 5 ), | |
101 | ( 'integFlag', 6 ) | |
102 | ) | |
103 | ||
104 | ||
105 | class NegTokenInit(univ.Sequence): | |
106 | componentType = namedtype.NamedTypes( | |
107 | namedtype.OptionalNamedType('mechTypes', MechTypeList().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), | |
108 | namedtype.OptionalNamedType('reqFlags', ContextFlags().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), | |
109 | namedtype.OptionalNamedType('mechToken', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), | |
110 | namedtype.OptionalNamedType('mechListMIC', univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) | |
111 | ) | |
112 | ||
113 | ||
114 | class NegTokenTarg(univ.Sequence): | |
115 | componentType = namedtype.NamedTypes( | |
116 | namedtype.OptionalNamedType('negResult', NegResultEnumerated().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), | |
117 | namedtype.OptionalNamedType('supportedMech', univ.ObjectIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), | |
118 | namedtype.OptionalNamedType('responseToken', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), | |
119 | namedtype.OptionalNamedType('mechListMIC', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) | |
120 | ) | |
121 | ||
122 | ||
123 | class NegotiationToken(univ.Choice): | |
124 | componentType = namedtype.NamedTypes( | |
125 | namedtype.NamedType('negTokenInit', NegTokenInit().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), | |
126 | namedtype.NamedType('negTokenTarg', NegTokenTarg().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) | |
127 | ) | |
128 | ||
129 | ||
130 | class ContextToken(univ.Sequence): | |
131 | tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 0)) | |
132 | componentType = namedtype.NamedTypes( | |
133 | namedtype.NamedType('thisMech', univ.ObjectIdentifier()), | |
134 | namedtype.NamedType('innerContextToken', NegotiationToken()) | |
135 | ) |
0 | ||
1 | # Values for Command field in SMB message header | |
2 | SMB_COM_CREATE_DIRECTORY = 0x00 | |
3 | SMB_COM_DELETE_DIRECTORY = 0x01 | |
4 | SMB_COM_CLOSE = 0x04 | |
5 | SMB_COM_DELETE = 0x06 | |
6 | SMB_COM_RENAME = 0x07 | |
7 | SMB_COM_TRANSACTION = 0x25 | |
8 | SMB_COM_ECHO = 0x2B | |
9 | SMB_COM_OPEN_ANDX = 0x2D | |
10 | SMB_COM_READ_ANDX = 0x2E | |
11 | SMB_COM_WRITE_ANDX = 0x2F | |
12 | SMB_COM_TRANSACTION2 = 0x32 | |
13 | SMB_COM_NEGOTIATE = 0x72 | |
14 | SMB_COM_SESSION_SETUP_ANDX = 0x73 | |
15 | SMB_COM_TREE_CONNECT_ANDX = 0x75 | |
16 | SMB_COM_NT_CREATE_ANDX = 0xA2 | |
17 | ||
18 | SMB_COMMAND_NAMES = { | |
19 | 0x00: 'SMB_COM_CREATE_DIRECTORY', | |
20 | 0x01: 'SMB_COM_DELETE_DIRECTORY', | |
21 | 0x04: 'SMB_COM_CLOSE', | |
22 | 0x06: 'SMB_COM_DELETE', | |
23 | 0x25: 'SMB_COM_TRANSACTION', | |
24 | 0x2B: 'SMB_COM_ECHO', | |
25 | 0x2D: 'SMB_COM_OPEN_ANDX', | |
26 | 0x2E: 'SMB_COM_READ_ANDX', | |
27 | 0x2F: 'SMB_COM_WRITE_ANDX', | |
28 | 0x32: 'SMB_COM_TRANSACTION2', | |
29 | 0x72: 'SMB_COM_NEGOTIATE', | |
30 | 0x73: 'SMB_COM_SESSION_SETUP_ANDX', | |
31 | 0x75: 'SMB_COM_TREE_CONNECT_ANDX', | |
32 | 0xA2: 'SMB_COM_NT_CREATE_ANDX', | |
33 | } | |
34 | ||
35 | # Bitmask for Flags field in SMB message header | |
36 | SMB_FLAGS_LOCK_AND_READ_OK = 0x01 # LANMAN1.0 | |
37 | SMB_FLAGS_BUF_AVAIL = 0x02 # LANMAN1.0, Obsolete | |
38 | SMB_FLAGS_CASE_INSENSITIVE = 0x08 # LANMAN1.0, Obsolete | |
39 | SMB_FLAGS_CANONICALIZED_PATHS = 0x10 # LANMAN1.0, Obsolete | |
40 | SMB_FLAGS_OPLOCK = 0x20 # LANMAN1.0, Obsolete | |
41 | SMB_FLAGS_OPBATCH = 0x40 # LANMAN1.0, Obsolete | |
42 | SMB_FLAGS_REPLY = 0x80 # LANMAN1.0 | |
43 | ||
44 | # Bitmask for Flags2 field in SMB message header | |
45 | SMB_FLAGS2_LONG_NAMES = 0x0001 # LANMAN2.0 | |
46 | SMB_FLAGS2_EAS = 0x0002 # LANMAN1.2 | |
47 | SMB_FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004 # NT LANMAN | |
48 | SMB_FLAGS2_IS_LONG_NAME = 0x0040 # NT LANMAN | |
49 | SMB_FLAGS2_DFS = 0x1000 # NT LANMAN | |
50 | SMB_FLAGS2_REPARSE_PATH = 0x0400 # | |
51 | SMB_FLAGS2_EXTENDED_SECURITY = 0x0800 # | |
52 | SMB_FLAGS2_PAGING_IO = 0x2000 # NT LANMAN | |
53 | SMB_FLAGS2_NT_STATUS = 0x4000 # NT LANMAN | |
54 | SMB_FLAGS2_UNICODE = 0x8000 # NT LANMAN | |
55 | ||
56 | # Bitmask for Capabilities field in SMB_COM_SESSION_SETUP_ANDX response | |
57 | # [MS-SMB]: 2.2.4.5.2.1 (Capabilities field) | |
58 | CAP_RAW_MODE = 0x01 | |
59 | CAP_MPX_MODE = 0x02 | |
60 | CAP_UNICODE = 0x04 | |
61 | CAP_LARGE_FILES = 0x08 | |
62 | CAP_NT_SMBS = 0x10 | |
63 | CAP_RPC_REMOTE_APIS = 0x20 | |
64 | CAP_STATUS32 = 0x40 | |
65 | CAP_LEVEL_II_OPLOCKS = 0x80 | |
66 | CAP_LOCK_AND_READ = 0x0100 | |
67 | CAP_NT_FIND = 0x0200 | |
68 | CAP_DFS = 0x1000 | |
69 | CAP_INFOLEVEL_PASSTHRU = 0x2000 | |
70 | CAP_LARGE_READX = 0x4000 | |
71 | CAP_LARGE_WRITEX = 0x8000 | |
72 | CAP_LWIO = 0x010000 | |
73 | CAP_UNIX = 0x800000 | |
74 | CAP_COMPRESSED = 0x02000000 | |
75 | CAP_DYNAMIC_REAUTH = 0x20000000 | |
76 | CAP_PERSISTENT_HANDLES = 0x40000000 | |
77 | CAP_EXTENDED_SECURITY = 0x80000000 | |
78 | ||
79 | # Value for Action field in SMB_COM_SESSION_SETUP_ANDX response | |
80 | SMB_SETUP_GUEST = 0x0001 | |
81 | SMB_SETUP_USE_LANMAN_KEY = 0X0002 | |
82 | ||
83 | # Bitmask for SecurityMode field in SMB_COM_NEGOTIATE response | |
84 | NEGOTIATE_USER_SECURITY = 0x01 | |
85 | NEGOTIATE_ENCRYPT_PASSWORDS = 0x02 | |
86 | NEGOTIATE_SECURITY_SIGNATURES_ENABLE = 0x04 | |
87 | NEGOTIATE_SECURITY_SIGNATURES_REQUIRE = 0x08 | |
88 | ||
89 | # Available constants for Service field in SMB_COM_TREE_CONNECT_ANDX request | |
90 | # [MS-CIFS]: 2.2.4.55.1 (Service field) | |
91 | SERVICE_PRINTER = 'LPT1:' | |
92 | SERVICE_NAMED_PIPE = 'IPC' | |
93 | SERVICE_COMM = 'COMM' | |
94 | SERVICE_ANY = '?????' | |
95 | ||
96 | # Bitmask for Flags field in SMB_COM_NT_CREATE_ANDX request | |
97 | # [MS-CIFS]: 2.2.4.64.1 | |
98 | # [MS-SMB]: 2.2.4.9.1 | |
99 | NT_CREATE_REQUEST_OPLOCK = 0x02 | |
100 | NT_CREATE_REQUEST_OPBATCH = 0x04 | |
101 | NT_CREATE_OPEN_TARGET_DIR = 0x08 | |
102 | NT_CREATE_REQUEST_EXTENDED_RESPONSE = 0x10 # Defined in [MS-SMB]: 2.2.4.9.1 | |
103 | ||
104 | # Bitmask for DesiredAccess field in SMB_COM_NT_CREATE_ANDX request | |
105 | # [MS-CIFS]: 2.2.4.64.1 | |
106 | FILE_READ_DATA = 0x01 | |
107 | FILE_WRITE_DATA = 0X02 | |
108 | FILE_APPEND_DATA = 0x04 | |
109 | FILE_READ_EA = 0x08 | |
110 | FILE_WRITE_EA = 0x10 | |
111 | FILE_EXECUTE = 0x20 | |
112 | FILE_READ_ATTRIBUTES = 0x80 | |
113 | FILE_WRITE_ATTRIBUTES = 0x0100 | |
114 | DELETE = 0x010000 | |
115 | READ_CONTROL = 0x020000 | |
116 | WRITE_DAC = 0x040000 | |
117 | WRITE_OWNER = 0x080000 | |
118 | SYNCHRONIZE = 0x100000 | |
119 | ACCESS_SYSTEM_SECURITY = 0x01000000 | |
120 | MAXIMUM_ALLOWED = 0x02000000 | |
121 | GENERIC_ALL = 0x10000000 | |
122 | GENERIC_EXECUTE = 0x20000000 | |
123 | GENERIC_WRITE = 0x40000000 | |
124 | GENERIC_READ = 0x80000000L | |
125 | ||
126 | # SMB_EXT_FILE_ATTR bitmask ([MS-CIFS]: 2.2.1.2.3) | |
127 | # Bitmask for FileAttributes field in SMB_COM_NT_CREATE_ANDX request ([MS-CIFS]: 2.2.4.64.1) | |
128 | ATTR_READONLY = 0x01 | |
129 | ATTR_HIDDEN = 0x02 | |
130 | ATTR_SYSTEM = 0x04 | |
131 | ATTR_DIRECTORY = 0x10 | |
132 | ATTR_ARCHIVE = 0x20 | |
133 | ATTR_NORMAL = 0x80 | |
134 | ATTR_TEMPORARY = 0x0100 | |
135 | ATTR_COMPRESSED = 0x0800 | |
136 | POSIX_SEMANTICS = 0x01000000 | |
137 | BACKUP_SEMANTICS = 0x02000000 | |
138 | DELETE_ON_CLOSE = 0x04000000 | |
139 | SEQUENTIAL_SCAN = 0x08000000 | |
140 | RANDOM_ACCESS = 0x10000000 | |
141 | NO_BUFFERING = 0x20000000 | |
142 | WRITE_THROUGH = 0x80000000 | |
143 | ||
144 | # Bitmask for ShareAccess field in SMB_COM_NT_CREATE_ANDX request | |
145 | # [MS-CIFS]: 2.2.4.64.1 | |
146 | FILE_SHARE_NONE = 0x00 | |
147 | FILE_SHARE_READ = 0x01 | |
148 | FILE_SHARE_WRITE = 0x02 | |
149 | FILE_SHARE_DELETE = 0x04 | |
150 | ||
151 | # Values for CreateDisposition field in SMB_COM_NT_CREATE_ANDX request | |
152 | # [MS-CIFS]: 2.2.4.64.1 | |
153 | FILE_SUPERSEDE = 0x00 | |
154 | FILE_OPEN = 0x01 | |
155 | FILE_CREATE = 0x02 | |
156 | FILE_OPEN_IF = 0x03 | |
157 | FILE_OVERWRITE = 0x04 | |
158 | FILE_OVERWRITE_IF = 0x05 | |
159 | ||
160 | # Bitmask for CreateOptions field in SMB_COM_NT_CREATE_ANDX request | |
161 | # [MS-CIFS]: 2.2.4.64.1 | |
162 | FILE_DIRECTORY_FILE = 0x01 | |
163 | FILE_WRITE_THROUGH = 0x02 | |
164 | FILE_SEQUENTIAL_ONLY = 0x04 | |
165 | FILE_NO_INTERMEDIATE_BUFFERING = 0x08 | |
166 | FILE_SYNCHRONOUS_IO_ALERT = 0x10 | |
167 | FILE_SYNCHRONOUS_IO_NONALERT = 0x20 | |
168 | FILE_NON_DIRECTORY_FILE = 0x40 | |
169 | FILE_CREATE_TREE_CONNECTION = 0x80 | |
170 | FILE_COMPLETE_IF_OPLOCKED = 0x0100 | |
171 | FILE_NO_EA_KNOWLEDGE = 0x0200 | |
172 | FILE_OPEN_FOR_RECOVERY = 0x0400 | |
173 | FILE_RANDOM_ACCESS = 0x0800 | |
174 | FILE_DELETE_ON_CLOSE = 0x1000 | |
175 | FILE_OPEN_BY_FILE_ID = 0x2000 | |
176 | FILE_OPEN_FOR_BACKUP_INTENT = 0x4000 | |
177 | FILE_NO_COMPRESSION = 0x8000 | |
178 | FILE_RESERVE_OPFILTER = 0x100000 | |
179 | FILE_OPEN_NO_RECALL = 0x400000 | |
180 | FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x800000 | |
181 | ||
182 | # Values for ImpersonationLevel field in SMB_COM_NT_CREATE_ANDX request | |
183 | # [MS-CIFS]: 2.2.4.64.1 | |
184 | # [MS-SMB]: 2.2.4.9.1 | |
185 | SEC_ANONYMOUS = 0x00 | |
186 | SEC_IDENTIFY = 0x01 | |
187 | SEC_IMPERSONATE = 0x02 | |
188 | SEC_DELEGATION = 0x03 # Defined in [MS-SMB]: 2.2.4.9.1 | |
189 | ||
190 | # Values for SecurityFlags field in SMB_COM_NT_CREATE_ANDX request | |
191 | # [MS-CIFS]: 2.2.4.64.1 | |
192 | SMB_SECURITY_CONTEXT_TRACKING = 0x01 | |
193 | SMB_SECURITY_EFFECTIVE_ONLY = 0x02 | |
194 | ||
195 | # Bitmask for Flags field in SMB_COM_TRANSACTION2 request | |
196 | # [MS-CIFS]: 2.2.4.46.1 | |
197 | DISCONNECT_TID = 0x01 | |
198 | NO_RESPONSE = 0x02 | |
199 | ||
200 | # Bitmask for basic file attributes | |
201 | # [MS-CIFS]: 2.2.1.2.4 | |
202 | SMB_FILE_ATTRIBUTE_NORMAL = 0x00 | |
203 | SMB_FILE_ATTRIBUTE_READONLY = 0x01 | |
204 | SMB_FILE_ATTRIBUTE_HIDDEN = 0x02 | |
205 | SMB_FILE_ATTRIBUTE_SYSTEM = 0x04 | |
206 | SMB_FILE_ATTRIBUTE_VOLUME = 0x08 | |
207 | SMB_FILE_ATTRIBUTE_DIRECTORY = 0x10 | |
208 | SMB_FILE_ATTRIBUTE_ARCHIVE = 0x20 | |
209 | SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100 | |
210 | SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200 | |
211 | SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400 | |
212 | SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000 | |
213 | SMB_SEARCH_ATTRIBUTE_ARCHIVE = 0x2000 |
0 | ||
1 | import os, sys, struct, types, logging, binascii, time | |
2 | from StringIO import StringIO | |
3 | from smb_constants import * | |
4 | ||
5 | ||
6 | # Set to True if you want to enable support for extended security. Required for Windows Vista and later | |
7 | SUPPORT_EXTENDED_SECURITY = True | |
8 | ||
9 | # Supported dialects | |
10 | DIALECTS = [ ] | |
11 | for i, ( name, dialect ) in enumerate([ ( 'NT_LAN_MANAGER_DIALECT', 'NT LM 0.12' ), ]): | |
12 | DIALECTS.append(dialect) | |
13 | globals()[name] = i | |
14 | ||
15 | ||
16 | class UnsupportedFeature(Exception): | |
17 | """ | |
18 | Raised when an supported feature is present/required in the protocol but is not | |
19 | currently supported by pysmb | |
20 | """ | |
21 | pass | |
22 | ||
23 | ||
24 | class ProtocolError(Exception): | |
25 | ||
26 | def __init__(self, message, data_buf = None, smb_message = None): | |
27 | self.message = message | |
28 | self.data_buf = data_buf | |
29 | self.smb_message = smb_message | |
30 | ||
31 | def __str__(self): | |
32 | b = StringIO() | |
33 | b.write(self.message + os.linesep) | |
34 | if self.smb_message: | |
35 | b.write('=' * 20 + ' SMB Message ' + '=' * 20 + os.linesep) | |
36 | b.write(str(self.smb_message)) | |
37 | ||
38 | if self.data_buf: | |
39 | b.write('=' * 20 + ' SMB Data Packet (hex) ' + '=' * 20 + os.linesep) | |
40 | b.write(binascii.hexlify(self.data_buf)) | |
41 | b.write(os.linesep) | |
42 | ||
43 | return b.getvalue() | |
44 | ||
45 | ||
46 | class OperationFailure(Exception): | |
47 | ||
48 | def __init__(self, message, smb_messages): | |
49 | self.message = message | |
50 | self.smb_messages = smb_messages | |
51 | ||
52 | def __str__(self): | |
53 | b = StringIO() | |
54 | b.write(self.message + os.linesep) | |
55 | ||
56 | for idx, m in enumerate(self.smb_messages): | |
57 | b.write('=' * 20 + ' SMB Message %d ' % idx + '=' * 20 + os.linesep) | |
58 | b.write('SMB Header:' + os.linesep) | |
59 | b.write('-----------' + os.linesep) | |
60 | b.write(str(m)) | |
61 | b.write('SMB Data Packet (hex):' + os.linesep) | |
62 | b.write('----------------------' + os.linesep) | |
63 | b.write(binascii.hexlify(m.raw_data)) | |
64 | b.write(os.linesep) | |
65 | ||
66 | return b.getvalue() | |
67 | ||
68 | ||
69 | class SMBError: | |
70 | ||
71 | def __init__(self): | |
72 | self.reset() | |
73 | ||
74 | def reset(self): | |
75 | self.internal_value = 0L | |
76 | self.is_ntstatus = True | |
77 | ||
78 | def __str__(self): | |
79 | if self.is_ntstatus: | |
80 | return 'NTSTATUS=0x%08X' % self.internal_value | |
81 | else: | |
82 | return 'ErrorClass=0x%02X ErrorCode=0x%04X' % ( self.internal_value >> 24, self.internal_value & 0xFFFF ) | |
83 | ||
84 | @property | |
85 | def hasError(self): | |
86 | return self.internal_value != 0 | |
87 | ||
88 | ||
89 | class SMBMessage: | |
90 | ||
91 | HEADER_STRUCT_FORMAT = "<4sBIBHHQxxHHHHB" | |
92 | HEADER_STRUCT_SIZE = struct.calcsize(HEADER_STRUCT_FORMAT) | |
93 | ||
94 | log = logging.getLogger('SMB.SMBMessage') | |
95 | ||
96 | def __init__(self, payload = None): | |
97 | self.reset() | |
98 | if payload: | |
99 | self.payload = payload | |
100 | self.payload.initMessage(self) | |
101 | ||
102 | def __str__(self): | |
103 | b = StringIO() | |
104 | b.write('Command: 0x%02X (%s) %s' % ( self.command, SMB_COMMAND_NAMES.get(self.command, '<unknown>'), os.linesep )) | |
105 | b.write('Status: %s %s' % ( str(self.status), os.linesep )) | |
106 | b.write('Flags: 0x%02X %s' % ( self.flags, os.linesep )) | |
107 | b.write('Flags2: 0x%04X %s' % ( self.flags2, os.linesep )) | |
108 | b.write('PID: %d %s' % ( self.pid, os.linesep )) | |
109 | b.write('UID: %d %s' % ( self.uid, os.linesep )) | |
110 | b.write('MID: %d %s' % ( self.mid, os.linesep )) | |
111 | b.write('TID: %d %s' % ( self.tid, os.linesep )) | |
112 | b.write('Security: 0x%016X %s' % ( self.security, os.linesep )) | |
113 | b.write('Parameters: %d bytes %s%s %s' % ( len(self.parameters_data), os.linesep, binascii.hexlify(self.parameters_data), os.linesep )) | |
114 | b.write('Data: %d bytes %s%s %s' % ( len(self.data), os.linesep, binascii.hexlify(self.data), os.linesep )) | |
115 | return b.getvalue() | |
116 | ||
117 | def reset(self): | |
118 | self.raw_data = '' | |
119 | self.command = 0 | |
120 | self.status = SMBError() | |
121 | self.flags = 0 | |
122 | self.flags2 = 0 | |
123 | self.pid = 0 | |
124 | self.tid = 0 | |
125 | self.uid = 0 | |
126 | self.mid = 0 | |
127 | self.security = 0L | |
128 | self.parameters_data = '' | |
129 | self.data = '' | |
130 | self.payload = None | |
131 | ||
132 | @property | |
133 | def isReply(self): | |
134 | return bool(self.flags & SMB_FLAGS_REPLY) | |
135 | ||
136 | @property | |
137 | def hasExtendedSecurity(self): | |
138 | return bool(self.flags2 & SMB_FLAGS2_EXTENDED_SECURITY) | |
139 | ||
140 | def encode(self): | |
141 | """ | |
142 | Encode this SMB message into a series of bytes suitable to be embedded with a NetBIOS session message. | |
143 | AssertionError will be raised if this SMB message has not been initialized with a Payload instance | |
144 | ||
145 | @return: a string containing the encoded SMB message | |
146 | """ | |
147 | assert self.payload | |
148 | ||
149 | self.pid = os.getpid() | |
150 | self.payload.prepare(self) | |
151 | ||
152 | parameters_len = len(self.parameters_data) | |
153 | assert parameters_len % 2 == 0 | |
154 | ||
155 | headers_data = struct.pack(self.HEADER_STRUCT_FORMAT, | |
156 | '\xFFSMB', self.command, self.status.internal_value, self.flags, | |
157 | self.flags2, (self.pid >> 16) & 0xFFFF, self.security, self.tid, | |
158 | self.pid & 0xFFFF, self.uid, self.mid, int(parameters_len / 2)) | |
159 | return headers_data + self.parameters_data + struct.pack('<H', len(self.data)) + self.data | |
160 | ||
161 | def decode(self, buf): | |
162 | """ | |
163 | Decodes the SMB message in buf. | |
164 | All fields of the SMBMessage object will be reset to default values before decoding. | |
165 | On errors, do not assume that the fields will be reinstated back to what they are before | |
166 | this method is invoked. | |
167 | ||
168 | @param buf: data containing one complete SMB message | |
169 | @type buf: string | |
170 | @return: a positive integer indicating the number of bytes used in buf to decode this SMB message | |
171 | @raise ProtocolError: raised when decoding fails | |
172 | """ | |
173 | buf_len = len(buf) | |
174 | if buf_len < self.HEADER_STRUCT_SIZE: | |
175 | # We need at least 32 bytes (header) + 1 byte (parameter count) | |
176 | raise ProtocolError('Not enough data to decode SMB header', buf) | |
177 | ||
178 | self.reset() | |
179 | ||
180 | protocol, self.command, status, self.flags, \ | |
181 | self.flags2, pid_high, self.security, self.tid, \ | |
182 | pid_low, self.uid, self.mid, params_count = struct.unpack(self.HEADER_STRUCT_FORMAT, buf[:self.HEADER_STRUCT_SIZE]) | |
183 | ||
184 | if protocol != '\xFFSMB': | |
185 | raise ProtocolError('Invalid 4-byte protocol field', buf) | |
186 | ||
187 | self.pid = (pid_high << 16) | pid_low | |
188 | self.status.internal_value = status | |
189 | self.status.is_ntstatus = bool(self.flags2 & SMB_FLAGS2_NT_STATUS) | |
190 | ||
191 | offset = self.HEADER_STRUCT_SIZE | |
192 | if buf_len < params_count * 2 + 2: | |
193 | # Not enough data in buf to decode up to body length | |
194 | raise ProtocolError('Not enough data. Parameters list decoding failed', buf) | |
195 | ||
196 | datalen_offset = offset + params_count*2 | |
197 | body_len = struct.unpack('<H', buf[datalen_offset:datalen_offset+2])[0] | |
198 | if body_len > 0 and buf_len < (datalen_offset + 2 + body_len): | |
199 | # Not enough data in buf to decode body | |
200 | raise ProtocolError('Not enough data. Body decoding failed', buf) | |
201 | ||
202 | self.parameters_data = buf[offset:datalen_offset] | |
203 | ||
204 | if body_len > 0: | |
205 | self.data = buf[datalen_offset+2:datalen_offset+2+body_len] | |
206 | ||
207 | self.raw_data = buf | |
208 | self._decodePayload() | |
209 | ||
210 | return self.HEADER_STRUCT_SIZE + params_count * 2 + 2 + body_len | |
211 | ||
212 | def _decodePayload(self): | |
213 | if self.command == SMB_COM_READ_ANDX: | |
214 | self.payload = ComReadAndxResponse() | |
215 | elif self.command == SMB_COM_WRITE_ANDX: | |
216 | self.payload = ComWriteAndxResponse() | |
217 | elif self.command == SMB_COM_TRANSACTION: | |
218 | self.payload = ComTransactionResponse() | |
219 | elif self.command == SMB_COM_TRANSACTION2: | |
220 | self.payload = ComTransaction2Response() | |
221 | elif self.command == SMB_COM_OPEN_ANDX: | |
222 | self.payload = ComOpenAndxResponse() | |
223 | elif self.command == SMB_COM_NT_CREATE_ANDX: | |
224 | self.payload = ComNTCreateAndxResponse() | |
225 | elif self.command == SMB_COM_TREE_CONNECT_ANDX: | |
226 | self.payload = ComTreeConnectAndxResponse() | |
227 | elif self.command == SMB_COM_ECHO: | |
228 | self.payload = ComEchoResponse() | |
229 | elif self.command == SMB_COM_SESSION_SETUP_ANDX: | |
230 | self.payload = ComSessionSetupAndxResponse() | |
231 | elif self.command == SMB_COM_NEGOTIATE: | |
232 | self.payload = ComNegotiateResponse() | |
233 | ||
234 | if self.payload: | |
235 | self.payload.decode(self) | |
236 | ||
237 | ||
238 | class Payload: | |
239 | ||
240 | DEFAULT_ANDX_PARAM_HEADER = '\xFF\x00\x00\x00' | |
241 | DEFAULT_ANDX_PARAM_SIZE = 4 | |
242 | ||
243 | def initMessage(self, message): | |
244 | # SMB_FLAGS2_UNICODE must always be enabled. Without this, almost all the Payload subclasses will need to be | |
245 | # rewritten to check for OEM/Unicode strings which will be tedious. Fortunately, almost all tested CIFS services | |
246 | # support SMB_FLAGS2_UNICODE by default. | |
247 | assert message.payload == self | |
248 | message.flags = SMB_FLAGS_CASE_INSENSITIVE | |
249 | message.flags2 = SMB_FLAGS2_UNICODE | SMB_FLAGS2_NT_STATUS | SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_LONG_NAMES | |
250 | ||
251 | if SUPPORT_EXTENDED_SECURITY: | |
252 | message.flags2 |= SMB_FLAGS2_EXTENDED_SECURITY | |
253 | ||
254 | def prepare(self, message): | |
255 | raise NotImplementedError | |
256 | ||
257 | def decode(self, message): | |
258 | raise NotImplementedError | |
259 | ||
260 | ||
261 | class ComNegotiateRequest(Payload): | |
262 | """ | |
263 | References: | |
264 | =========== | |
265 | - [MS-CIFS]: 2.2.4.52.1 | |
266 | - [MS-SMB]: 2.2.4.5.1 | |
267 | """ | |
268 | ||
269 | def initMessage(self, message): | |
270 | Payload.initMessage(self, message) | |
271 | message.command = SMB_COM_NEGOTIATE | |
272 | ||
273 | def prepare(self, message): | |
274 | assert message.payload == self | |
275 | message.parameters_data = '' | |
276 | message.data = ''.join(map(lambda s: '\x02'+s+'\x00', DIALECTS)) | |
277 | ||
278 | ||
279 | class ComNegotiateResponse(Payload): | |
280 | """ | |
281 | Contains information on the SMB_COM_NEGOTIATE response from server | |
282 | ||
283 | After calling the decode method, each instance will contain the following attributes, | |
284 | - security_mode (integer) | |
285 | - max_mpx_count (integer) | |
286 | - max_number_vcs (integer) | |
287 | - max_buffer_size (long) | |
288 | - max_raw_size (long) | |
289 | - session_key (long) | |
290 | - capabilities (long) | |
291 | - system_time (long) | |
292 | - server_time_zone (integer) | |
293 | - challenge_length (integer) | |
294 | ||
295 | If the underlying SMB message's flag2 does not have SMB_FLAGS2_EXTENDED_SECURITY bit enabled, | |
296 | then the instance will have the following additional attributes, | |
297 | - challenge (string) | |
298 | - domain (unicode) | |
299 | ||
300 | If the underlying SMB message's flags2 has SMB_FLAGS2_EXTENDED_SECURITY bit enabled, | |
301 | then the instance will have the following additional attributes, | |
302 | - server_guid (string) | |
303 | - security_blob (string) | |
304 | ||
305 | References: | |
306 | =========== | |
307 | - [MS-SMB]: 2.2.4.5.2.1 | |
308 | - [MS-CIFS]: 2.2.4.52.2 | |
309 | """ | |
310 | ||
311 | PAYLOAD_STRUCT_FORMAT = '<HBHHIIIIQHB' | |
312 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
313 | ||
314 | def decode(self, message): | |
315 | assert message.command == SMB_COM_NEGOTIATE | |
316 | ||
317 | if not message.isReply: | |
318 | raise ProtocolError('Not a SMB_COM_NEGOTIATE reply', message.raw_data, message) | |
319 | ||
320 | self.security_mode, self.max_mpx_count, self.max_number_vcs, self.max_buffer_size, \ | |
321 | self.max_raw_size, self.session_key, self.capabilities, self.system_time, self.server_time_zone, \ | |
322 | self.challenge_length = ( 0, ) * 10 | |
323 | ||
324 | data_len = len(message.parameters_data) | |
325 | if data_len < 2: | |
326 | raise ProtocolError('Not enough data to decode SMB_COM_NEGOTIATE dialect_index field', message.raw_data, message) | |
327 | ||
328 | self.dialect_index = struct.unpack('<H', message.parameters_data[:2])[0] | |
329 | if self.dialect_index == NT_LAN_MANAGER_DIALECT: | |
330 | if data_len != (0x11 * 2): | |
331 | raise ProtocolError('NT LAN Manager dialect selected in SMB_COM_NEGOTIATE but parameters bytes count (%d) does not meet specs' % data_len, | |
332 | message.raw_data, message) | |
333 | else: | |
334 | _, self.security_mode, self.max_mpx_count, self.max_number_vcs, self.max_buffer_size, \ | |
335 | self.max_raw_size, self.session_key, self.capabilities, self.system_time, self.server_time_zone, \ | |
336 | self.challenge_length = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
337 | elif self.dialect_index == 0xFFFF: | |
338 | raise ProtocolError('Server does not support any of the pysmb dialects. Please email pysmb to add in support for your OS', | |
339 | message.raw_data, message) | |
340 | else: | |
341 | raise ProtocolError('Unknown dialect index (0x%04X)' % self.dialect_index, message.raw_data, message) | |
342 | ||
343 | data_len = len(message.data) | |
344 | if not message.hasExtendedSecurity: | |
345 | self.challenge, self.domain = '', '' | |
346 | if self.challenge_length > 0: | |
347 | if data_len >= self.challenge_length: | |
348 | self.challenge = message.data[:self.challenge_length] | |
349 | ||
350 | s = '' | |
351 | offset = self.challenge_length | |
352 | while offset < data_len: | |
353 | _s = message.data[offset:offset+2] | |
354 | if _s == '\0\0': | |
355 | self.domain = s.decode('UTF-16LE') | |
356 | break | |
357 | else: | |
358 | s += _s | |
359 | offset += 2 | |
360 | else: | |
361 | raise ProtocolError('Not enough data to decode SMB_COM_NEGOTIATE (without security extensions) Challenge field', message.raw_data, message) | |
362 | else: | |
363 | if data_len < 16: | |
364 | raise ProtocolError('Not enough data to decode SMB_COM_NEGOTIATE (with security extensions) ServerGUID field', message.raw_data, message) | |
365 | ||
366 | self.server_guid = message.data[:16] | |
367 | self.security_blob = message.data[16:] | |
368 | ||
369 | ||
370 | class ComSessionSetupAndxRequest__WithSecurityExtension(Payload): | |
371 | """ | |
372 | References: | |
373 | =========== | |
374 | - [MS-SMB]: 2.2.4.6.1 | |
375 | """ | |
376 | ||
377 | PAYLOAD_STRUCT_FORMAT = '<HHHIHII' | |
378 | ||
379 | def __init__(self, session_key, security_blob): | |
380 | self.session_key = session_key | |
381 | self.security_blob = security_blob | |
382 | ||
383 | def initMessage(self, message): | |
384 | Payload.initMessage(self, message) | |
385 | message.command = SMB_COM_SESSION_SETUP_ANDX | |
386 | ||
387 | def prepare(self, message): | |
388 | assert message.hasExtendedSecurity | |
389 | ||
390 | message.flags2 |= SMB_FLAGS2_UNICODE | |
391 | ||
392 | cap = CAP_UNICODE | CAP_STATUS32 | CAP_EXTENDED_SECURITY | |
393 | ||
394 | message.parameters_data = \ | |
395 | self.DEFAULT_ANDX_PARAM_HEADER + \ | |
396 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
397 | 16644, 10, 1, self.session_key, len(self.security_blob), 0, cap) | |
398 | ||
399 | message.data = self.security_blob | |
400 | if (SMBMessage.HEADER_STRUCT_SIZE + len(message.parameters_data) + len(message.data)) % 2 != 0: | |
401 | message.data = message.data + '\0' | |
402 | message.data = message.data + '\0' * 4 | |
403 | ||
404 | ||
405 | class ComSessionSetupAndxRequest__NoSecurityExtension(Payload): | |
406 | """ | |
407 | References: | |
408 | =========== | |
409 | - [MS-CIFS]: 2.2.4.53.1 | |
410 | """ | |
411 | ||
412 | PAYLOAD_STRUCT_FORMAT = '<HHHIHHII' | |
413 | ||
414 | def __init__(self, session_key, username, password, is_unicode, domain): | |
415 | self.username = username | |
416 | self.session_key = session_key | |
417 | self.password = password | |
418 | self.is_unicode = is_unicode | |
419 | self.domain = domain | |
420 | ||
421 | def initMessage(self, message): | |
422 | Payload.initMessage(self, message) | |
423 | message.command = SMB_COM_SESSION_SETUP_ANDX | |
424 | ||
425 | def prepare(self, message): | |
426 | if self.is_unicode: | |
427 | message.flags2 |= SMB_FLAGS2_UNICODE | |
428 | else: | |
429 | message.flags2 &= (~SMB_FLAGS2_UNICODE & 0xFFFF) | |
430 | ||
431 | password_len = len(self.password) | |
432 | message.parameters_data = \ | |
433 | self.DEFAULT_ANDX_PARAM_HEADER + \ | |
434 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
435 | 16644, 10, 0, self.session_key, | |
436 | (not self.is_unicode and password_len) or 0, | |
437 | (self.is_unicode and password_len) or 0, | |
438 | 0, | |
439 | CAP_UNICODE | CAP_LARGE_FILES | CAP_STATUS32) | |
440 | ||
441 | est_offset = SMBMessage.HEADER_STRUCT_SIZE + len(message.parameters_data) # To check if data until SMB paramaters are aligned to a 16-bit boundary | |
442 | ||
443 | message.data = self.password | |
444 | if (est_offset + len(message.data)) % 2 != 0 and message.flags2 & SMB_FLAGS2_UNICODE: | |
445 | message.data = message.data + '\0' | |
446 | ||
447 | if message.flags2 & SMB_FLAGS2_UNICODE: | |
448 | message.data = message.data + self.username.encode('UTF-16LE') + '\0' | |
449 | else: | |
450 | message.data = message.data + str(self.username) + '\0' | |
451 | ||
452 | if (est_offset + len(message.data)) % 2 != 0 and message.flags2 & SMB_FLAGS2_UNICODE: | |
453 | message.data = message.data + '\0' | |
454 | ||
455 | if message.flags2 & SMB_FLAGS2_UNICODE: | |
456 | message.data = message.data + self.domain.encode('UTF-16LE') + '\0\0' + 'pysmb'.encode('UTF-16LE') + '\0\0' | |
457 | else: | |
458 | message.data = message.data + self.domain + '\0pysmb\0' | |
459 | ||
460 | ||
461 | class ComSessionSetupAndxResponse(Payload): | |
462 | """ | |
463 | Contains information on the SMB_COM_SESSION_SETUP_ANDX response from server | |
464 | ||
465 | If the underlying SMB message's flags2 does not have SMB_FLAGS2_EXTENDED_SECURITY bit enabled, | |
466 | then the instance will have the following attributes, | |
467 | - action | |
468 | ||
469 | If the underlying SMB message's flags2 has SMB_FLAGS2_EXTENDED_SECURITY bit enabled | |
470 | and the message status is STATUS_MORE_PROCESSING_REQUIRED or equals to 0x00 (no error), | |
471 | then the instance will have the following attributes, | |
472 | - action | |
473 | - securityblob | |
474 | ||
475 | If the underlying SMB message's flags2 has SMB_FLAGS2_EXTENDED_SECURITY bit enabled but | |
476 | the message status is not STATUS_MORE_PROCESSING_REQUIRED | |
477 | ||
478 | References: | |
479 | =========== | |
480 | - [MS-SMB]: 2.2.4.6.2 | |
481 | - [MS-CIFS]: 2.2.4.53.2 | |
482 | """ | |
483 | ||
484 | NOSECURE_PARAMETER_STRUCT_FORMAT = '<BBHH' | |
485 | NOSECURE_PARAMETER_STRUCT_SIZE = struct.calcsize(NOSECURE_PARAMETER_STRUCT_FORMAT) | |
486 | ||
487 | SECURE_PARAMETER_STRUCT_FORMAT = '<BBHHH' | |
488 | SECURE_PARAMETER_STRUCT_SIZE = struct.calcsize(SECURE_PARAMETER_STRUCT_FORMAT) | |
489 | ||
490 | def decode(self, message): | |
491 | assert message.command == SMB_COM_SESSION_SETUP_ANDX | |
492 | if not message.hasExtendedSecurity: | |
493 | if not message.status.hasError: | |
494 | if len(message.parameters_data) < self.NOSECURE_PARAMETER_STRUCT_SIZE: | |
495 | raise ProtocolError('Not enough data to decode SMB_COM_SESSION_SETUP_ANDX (no security extensions) parameters', message.raw_data, message) | |
496 | ||
497 | _, _, _, self.action = struct.unpack(self.NOSECURE_PARAMETER_STRUCT_FORMAT, message.parameters_data[:self.NOSECURE_PARAMETER_STRUCT_SIZE]) | |
498 | else: | |
499 | if not message.status.hasError or message.status.internal_value == 0xc0000016: # STATUS_MORE_PROCESSING_REQUIRED | |
500 | if len(message.parameters_data) < self.SECURE_PARAMETER_STRUCT_SIZE: | |
501 | raise ProtocolError('Not enough data to decode SMB_COM_SESSION_SETUP_ANDX (with security extensions) parameters', message.raw_data, message) | |
502 | ||
503 | _, _, _, self.action, blob_length = struct.unpack(self.SECURE_PARAMETER_STRUCT_FORMAT, message.parameters_data[:self.SECURE_PARAMETER_STRUCT_SIZE]) | |
504 | if len(message.data) < blob_length: | |
505 | raise ProtocolError('Not enough data to decode SMB_COM_SESSION_SETUP_ANDX (with security extensions) security blob', message.raw_data, message) | |
506 | ||
507 | self.security_blob = message.data[:blob_length] | |
508 | ||
509 | ||
510 | class ComTreeConnectAndxRequest(Payload): | |
511 | """ | |
512 | References: | |
513 | =========== | |
514 | - [MS-CIFS]: 2.2.4.55.1 | |
515 | """ | |
516 | ||
517 | PAYLOAD_STRUCT_FORMAT = '<HH' | |
518 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
519 | ||
520 | def __init__(self, path, service, password = ''): | |
521 | self.path = path | |
522 | self.service = service | |
523 | self.password = password + '\0' | |
524 | ||
525 | def initMessage(self, message): | |
526 | Payload.initMessage(self, message) | |
527 | message.command = SMB_COM_TREE_CONNECT_ANDX | |
528 | ||
529 | def prepare(self, message): | |
530 | password_len = len(self.password) | |
531 | message.parameters_data = \ | |
532 | self.DEFAULT_ANDX_PARAM_HEADER + \ | |
533 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
534 | 0x08 | (message.tid and 0x0001) or 0x00, # Disconnect tid, if message.tid must be non-zero | |
535 | password_len) | |
536 | ||
537 | padding = '' | |
538 | if password_len % 2 == 0: | |
539 | padding = '\0' | |
540 | ||
541 | # Note that service field is never encoded in UTF-16LE. [MS-CIFS]: 2.2.1.1 | |
542 | message.data = self.password + padding + self.path.encode('UTF-16LE') + '\0\0' + self.service + '\0' | |
543 | ||
544 | ||
545 | class ComTreeConnectAndxResponse(Payload): | |
546 | """ | |
547 | Contains information about the SMB_COM_TREE_CONNECT_ANDX response from the server. | |
548 | ||
549 | If the message has no errors, each instance contains the following attributes: | |
550 | - optional_support | |
551 | ||
552 | References: | |
553 | =========== | |
554 | - [MS-CIFS]: 2.2.4.55.2 | |
555 | """ | |
556 | ||
557 | PAYLOAD_STRUCT_FORMAT = '<BBHH' | |
558 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
559 | ||
560 | def decode(self, message): | |
561 | assert message.command == SMB_COM_TREE_CONNECT_ANDX | |
562 | ||
563 | if not message.status.hasError: | |
564 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE: | |
565 | raise ProtocolError('Not enough data to decode SMB_COM_TREE_CONNECT_ANDX parameters', message.raw_data, message) | |
566 | ||
567 | _, _, _, self.optional_support = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
568 | ||
569 | ||
570 | class ComNTCreateAndxRequest(Payload): | |
571 | """ | |
572 | References: | |
573 | =========== | |
574 | - [MS-CIFS]: 2.2.4.64.1 | |
575 | - [MS-SMB]: 2.2.4.9.1 | |
576 | """ | |
577 | ||
578 | PAYLOAD_STRUCT_FORMAT = '<BHIIIQIIIIIB' | |
579 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
580 | ||
581 | def __init__(self, filename, flags = 0, root_fid = 0, access_mask = 0, allocation_size = 0L, ext_attr = 0, | |
582 | share_access = 0, create_disp = 0, create_options = 0, impersonation = 0, security_flags = 0): | |
583 | self.filename = (filename + '\0').encode('UTF-16LE') | |
584 | self.flags = flags | |
585 | self.root_fid = root_fid | |
586 | self.access_mask = access_mask | |
587 | self.allocation_size = allocation_size | |
588 | self.ext_attr = ext_attr | |
589 | self.share_access = share_access | |
590 | self.create_disp = create_disp | |
591 | self.create_options = create_options | |
592 | self.impersonation = impersonation | |
593 | self.security_flags = security_flags | |
594 | ||
595 | def initMessage(self, message): | |
596 | Payload.initMessage(self, message) | |
597 | message.command = SMB_COM_NT_CREATE_ANDX | |
598 | ||
599 | def prepare(self, message): | |
600 | filename_len = len(self.filename) | |
601 | ||
602 | message.parameters_data = \ | |
603 | self.DEFAULT_ANDX_PARAM_HEADER + \ | |
604 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
605 | 0x00, # reserved | |
606 | filename_len, # NameLength | |
607 | self.flags, # Flags | |
608 | self.root_fid, # RootDirectoryFID | |
609 | self.access_mask, # DesiredAccess | |
610 | self.allocation_size, # AllocationSize | |
611 | self.ext_attr, # ExtFileAttributes | |
612 | self.share_access, # ShareAccess | |
613 | self.create_disp, # CreateDisposition | |
614 | self.create_options, # CreateOptions | |
615 | self.impersonation, # ImpersonationLevel | |
616 | self.security_flags) # SecurityFlags | |
617 | ||
618 | padding = '' | |
619 | if (message.HEADER_STRUCT_SIZE + len(message.parameters_data)) % 2 != 0: | |
620 | padding = '\0' | |
621 | ||
622 | message.data = padding + self.filename | |
623 | ||
624 | ||
625 | class ComNTCreateAndxResponse(Payload): | |
626 | """ | |
627 | Contains (partial) information about the SMB_COM_NT_CREATE_ANDX response from the server. | |
628 | ||
629 | Each instance contains the following attributes after decoding: | |
630 | - oplock_level | |
631 | - fid | |
632 | ||
633 | References: | |
634 | =========== | |
635 | - [MS-CIFS]: 2.2.4.64.2 | |
636 | """ | |
637 | PAYLOAD_STRUCT_FORMAT = '<BBHBH' | |
638 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
639 | ||
640 | def decode(self, message): | |
641 | assert message.command == SMB_COM_NT_CREATE_ANDX | |
642 | ||
643 | if not message.status.hasError: | |
644 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE: | |
645 | raise ProtocolError('Not enough data to decode SMB_COM_NT_CREATE_ANDX parameters', message.raw_data, message) | |
646 | ||
647 | _, _, _, self.oplock_level, self.fid = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
648 | ||
649 | ||
650 | class ComTransactionRequest(Payload): | |
651 | """ | |
652 | References: | |
653 | =========== | |
654 | - [MS-CIFS]: 2.2.4.33.1 | |
655 | """ | |
656 | ||
657 | PAYLOAD_STRUCT_FORMAT = '<HHHHBBHIHHHHHH' | |
658 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
659 | ||
660 | def __init__(self, max_params_count, max_data_count, max_setup_count, | |
661 | total_params_count = 0, total_data_count = 0, | |
662 | params_bytes = '', data_bytes = '', setup_bytes = '', | |
663 | flags = 0, timeout = 0, name = "\\PIPE\\"): | |
664 | self.total_params_count = total_params_count or len(params_bytes) | |
665 | self.total_data_count = total_data_count or len(data_bytes) | |
666 | self.max_params_count = max_params_count | |
667 | self.max_data_count = max_data_count | |
668 | self.max_setup_count = max_setup_count | |
669 | self.flags = flags | |
670 | self.timeout = timeout | |
671 | self.params_bytes = params_bytes | |
672 | self.data_bytes = data_bytes | |
673 | self.setup_bytes = setup_bytes | |
674 | self.name = name | |
675 | ||
676 | def initMessage(self, message): | |
677 | Payload.initMessage(self, message) | |
678 | message.command = SMB_COM_TRANSACTION | |
679 | ||
680 | def prepare(self, message): | |
681 | name = (self.name + '\0').encode('UTF-16LE') | |
682 | name_len = len(name) | |
683 | setup_bytes_len = len(self.setup_bytes) | |
684 | params_bytes_len = len(self.params_bytes) | |
685 | data_bytes_len = len(self.data_bytes) | |
686 | ||
687 | padding0 = '' | |
688 | offset = message.HEADER_STRUCT_SIZE + self.PAYLOAD_STRUCT_SIZE + setup_bytes_len + 2 # constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters) | |
689 | if offset % 2 != 0: | |
690 | padding0 = '\0' | |
691 | offset += 1 | |
692 | ||
693 | offset += name_len # For the name field | |
694 | padding1 = '' | |
695 | if offset % 4 != 0: | |
696 | padding1 = '\0'*(4-offset%4) | |
697 | offset += (4-offset%4) | |
698 | ||
699 | if params_bytes_len > 0: | |
700 | params_bytes_offset = offset | |
701 | offset += params_bytes_len | |
702 | else: | |
703 | params_bytes_offset = 0 | |
704 | ||
705 | padding2 = '' | |
706 | if offset % 4 != 0: | |
707 | padding2 = '\0'*(4-offset%4) | |
708 | offset += (4-offset%4) | |
709 | ||
710 | if data_bytes_len > 0: | |
711 | data_bytes_offset = offset | |
712 | else: | |
713 | data_bytes_offset = 0 | |
714 | ||
715 | message.parameters_data = \ | |
716 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
717 | self.total_params_count, | |
718 | self.total_data_count, | |
719 | self.max_params_count, | |
720 | self.max_data_count, | |
721 | self.max_setup_count, | |
722 | 0x00, # Reserved1. Must be 0x00 | |
723 | self.flags, | |
724 | self.timeout, | |
725 | 0x0000, # Reserved2. Must be 0x0000 | |
726 | params_bytes_len, | |
727 | params_bytes_offset, | |
728 | data_bytes_len, | |
729 | data_bytes_offset, | |
730 | int(setup_bytes_len / 2)) + \ | |
731 | self.setup_bytes | |
732 | ||
733 | message.data = padding0 + name + padding1 + self.params_bytes + padding2 + self.data_bytes | |
734 | ||
735 | ||
736 | class ComTransactionResponse(Payload): | |
737 | """ | |
738 | Contains information about a SMB_COM_TRANSACTION response from the server | |
739 | ||
740 | After decoding, each instance contains the following attributes: | |
741 | - total_params_count (integer) | |
742 | - total_data_count (integer) | |
743 | - setup_bytes (string) | |
744 | - data_bytes (string) | |
745 | - params_bytes (string) | |
746 | ||
747 | References: | |
748 | =========== | |
749 | - [MS-CIFS]: 2.2.4.33.2 | |
750 | """ | |
751 | ||
752 | PAYLOAD_STRUCT_FORMAT = '<HHHHHHHHHH' | |
753 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
754 | ||
755 | def decode(self, message): | |
756 | assert message.command == SMB_COM_TRANSACTION | |
757 | ||
758 | if not message.status.hasError: | |
759 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE: | |
760 | raise ProtocolError('Not enough data to decode SMB_COM_TRANSACTION parameters', message.raw_data, message) | |
761 | ||
762 | self.total_params_count, self.total_data_count, _, \ | |
763 | params_bytes_len, params_bytes_offset, params_bytes_displ, \ | |
764 | data_bytes_len, data_bytes_offset, data_bytes_displ, \ | |
765 | setup_count = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
766 | ||
767 | if setup_count > 0: | |
768 | setup_bytes_len = setup_count * 2 | |
769 | ||
770 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE + setup_bytes_len: | |
771 | raise ProtocolError('Not enough data to decode SMB_COM_TRANSACTION parameters', message.raw_data, message) | |
772 | ||
773 | self.setup_bytes = message.parameters_data[self.PAYLOAD_STRUCT_SIZE:self.PAYLOAD_STRUCT_SIZE+setup_bytes_len] | |
774 | else: | |
775 | self.setup_bytes = '' | |
776 | ||
777 | offset = message.HEADER_STRUCT_SIZE + self.PAYLOAD_STRUCT_SIZE + setup_count * 2 + 2 # constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters) | |
778 | ||
779 | if params_bytes_len > 0: | |
780 | self.params_bytes = message.data[params_bytes_offset-offset:params_bytes_offset-offset+params_bytes_len] | |
781 | else: | |
782 | self.params_bytes = '' | |
783 | ||
784 | if data_bytes_len > 0: | |
785 | self.data_bytes = message.data[data_bytes_offset-offset:data_bytes_offset-offset+data_bytes_len] | |
786 | else: | |
787 | self.data_bytes = '' | |
788 | ||
789 | ||
790 | class ComTransaction2Request(Payload): | |
791 | """ | |
792 | References: | |
793 | =========== | |
794 | - [MS-CIFS]: 2.2.4.46.1 | |
795 | """ | |
796 | ||
797 | PAYLOAD_STRUCT_FORMAT = 'HHHHBBHIHHHHHH' | |
798 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
799 | ||
800 | def __init__(self, max_params_count, max_data_count, max_setup_count, | |
801 | total_params_count = 0, total_data_count = 0, | |
802 | params_bytes = '', data_bytes = '', setup_bytes = '', | |
803 | flags = 0, timeout = 0): | |
804 | self.total_params_count = total_params_count or len(params_bytes) | |
805 | self.total_data_count = total_data_count or len(data_bytes) | |
806 | self.max_params_count = max_params_count | |
807 | self.max_data_count = max_data_count | |
808 | self.max_setup_count = max_setup_count | |
809 | self.flags = flags | |
810 | self.timeout = timeout | |
811 | self.params_bytes = params_bytes | |
812 | self.data_bytes = data_bytes | |
813 | self.setup_bytes = setup_bytes | |
814 | ||
815 | def initMessage(self, message): | |
816 | Payload.initMessage(self, message) | |
817 | message.command = SMB_COM_TRANSACTION2 | |
818 | ||
819 | def prepare(self, message): | |
820 | setup_bytes_len = len(self.setup_bytes) | |
821 | params_bytes_len = len(self.params_bytes) | |
822 | data_bytes_len = len(self.data_bytes) | |
823 | name = '\0\0' | |
824 | ||
825 | padding0 = '' | |
826 | offset = message.HEADER_STRUCT_SIZE + self.PAYLOAD_STRUCT_SIZE + setup_bytes_len + 2 # constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters) | |
827 | if offset % 2 != 0: | |
828 | padding0 = '\0' | |
829 | offset += 1 | |
830 | ||
831 | offset += 2 # For the name field | |
832 | padding1 = '' | |
833 | if offset % 4 != 0: | |
834 | padding1 = '\0'*(4-offset%4) | |
835 | ||
836 | if params_bytes_len > 0: | |
837 | params_bytes_offset = offset | |
838 | offset += params_bytes_len | |
839 | else: | |
840 | params_bytes_offset = 0 | |
841 | ||
842 | padding2 = '' | |
843 | if offset % 4 != 0: | |
844 | padding2 = '\0'*(4-offset%4) | |
845 | ||
846 | if data_bytes_len > 0: | |
847 | data_bytes_offset = offset | |
848 | else: | |
849 | data_bytes_offset = 0 | |
850 | ||
851 | message.parameters_data = \ | |
852 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
853 | self.total_params_count, | |
854 | self.total_data_count, | |
855 | self.max_params_count, | |
856 | self.max_data_count, | |
857 | self.max_setup_count, | |
858 | 0x00, # Reserved1. Must be 0x00 | |
859 | self.flags, | |
860 | self.timeout, | |
861 | 0x0000, # Reserved2. Must be 0x0000 | |
862 | params_bytes_len, | |
863 | params_bytes_offset, | |
864 | data_bytes_len, | |
865 | data_bytes_offset, | |
866 | int(setup_bytes_len / 2)) + \ | |
867 | self.setup_bytes | |
868 | ||
869 | message.data = padding0 + name + padding1 + self.params_bytes + padding2 + self.data_bytes | |
870 | ||
871 | ||
872 | class ComTransaction2Response(Payload): | |
873 | """ | |
874 | Contains information about a SMB_COM_TRANSACTION2 response from the server | |
875 | ||
876 | After decoding, each instance contains the following attributes: | |
877 | - total_params_count (integer) | |
878 | - total_data_count (integer) | |
879 | - setup_bytes (string) | |
880 | - data_bytes (string) | |
881 | - params_bytes (string) | |
882 | ||
883 | References: | |
884 | =========== | |
885 | - [MS-CIFS]: 2.2.4.46.2 | |
886 | """ | |
887 | ||
888 | PAYLOAD_STRUCT_FORMAT = '<HHHHHHHHHBB' | |
889 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
890 | ||
891 | def decode(self, message): | |
892 | assert message.command == SMB_COM_TRANSACTION2 | |
893 | ||
894 | if not message.status.hasError: | |
895 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE: | |
896 | raise ProtocolError('Not enough data to decode SMB_COM_TRANSACTION2 parameters', message.raw_data, message) | |
897 | ||
898 | self.total_params_count, self.total_data_count, _, \ | |
899 | params_bytes_len, params_bytes_offset, params_bytes_displ, \ | |
900 | data_bytes_len, data_bytes_offset, data_bytes_displ, \ | |
901 | setup_count, _ = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
902 | ||
903 | if setup_count > 0: | |
904 | setup_bytes_len = setup_count * 2 | |
905 | ||
906 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE + setup_bytes_len: | |
907 | raise ProtocolError('Not enough data to decode SMB_COM_TRANSACTION parameters', message.raw_data, message) | |
908 | ||
909 | self.setup_bytes = message.parameters_data[self.PAYLOAD_STRUCT_SIZE:self.PAYLOAD_STRUCT_SIZE+setup_bytes_len] | |
910 | else: | |
911 | self.setup_bytes = '' | |
912 | ||
913 | offset = message.HEADER_STRUCT_SIZE + self.PAYLOAD_STRUCT_SIZE + setup_count * 2 + 2 # constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters) | |
914 | ||
915 | if params_bytes_len > 0: | |
916 | self.params_bytes = message.data[params_bytes_offset-offset:params_bytes_offset-offset+params_bytes_len] | |
917 | else: | |
918 | self.params_bytes = '' | |
919 | ||
920 | if data_bytes_len > 0: | |
921 | self.data_bytes = message.data[data_bytes_offset-offset:data_bytes_offset-offset+data_bytes_len] | |
922 | else: | |
923 | self.data_bytes = '' | |
924 | ||
925 | ||
926 | class ComCloseRequest(Payload): | |
927 | """ | |
928 | References: | |
929 | =========== | |
930 | - [MS-CIFS]: 2.2.4.5.1 | |
931 | """ | |
932 | ||
933 | PAYLOAD_STRUCT_FORMAT = '<HI' | |
934 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
935 | ||
936 | def __init__(self, fid, last_modified_time = 0xFFFFFFFF): | |
937 | self.fid = fid | |
938 | self.last_modified_time = last_modified_time | |
939 | ||
940 | def initMessage(self, message): | |
941 | Payload.initMessage(self, message) | |
942 | message.command = SMB_COM_CLOSE | |
943 | ||
944 | def prepare(self, message): | |
945 | message.parameters_data = struct.pack(self.PAYLOAD_STRUCT_FORMAT, self.fid, self.last_modified_time) | |
946 | message.data = '' | |
947 | ||
948 | ||
949 | class ComOpenAndxRequest(Payload): | |
950 | """ | |
951 | References: | |
952 | =========== | |
953 | - [MS-CIFS]: 2.2.4.41.1 | |
954 | """ | |
955 | ||
956 | PAYLOAD_STRUCT_FORMAT = '<HHHHIHIII' | |
957 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
958 | ||
959 | def __init__(self, filename, access_mode, open_mode, flags = 0x0000, search_attributes = 0, file_attributes = 0, create_time = 0, timeout = 0): | |
960 | """ | |
961 | @param create_time: Epoch time value to indicate the time of creation for this file. If zero, we will automatically assign the current time | |
962 | @type create_time: int | |
963 | @param timeout: Number of milliseconds to wait for blocked open request before failing | |
964 | @type timeout: int | |
965 | """ | |
966 | self.filename = filename | |
967 | self.access_mode = access_mode | |
968 | self.open_mode = open_mode | |
969 | self.flags = flags | |
970 | self.search_attributes = search_attributes | |
971 | self.file_attributes = file_attributes | |
972 | self.create_time = create_time or int(time.time()) | |
973 | self.timeout = timeout | |
974 | ||
975 | def initMessage(self, message): | |
976 | Payload.initMessage(self, message) | |
977 | message.command = SMB_COM_OPEN_ANDX | |
978 | ||
979 | def prepare(self, message): | |
980 | message.parameters_data = \ | |
981 | self.DEFAULT_ANDX_PARAM_HEADER + \ | |
982 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
983 | self.flags, | |
984 | self.access_mode, | |
985 | self.search_attributes, | |
986 | self.file_attributes, | |
987 | self.create_time, | |
988 | self.open_mode, | |
989 | 0, # AllocationSize | |
990 | 0, # Timeout (in milli-secs) | |
991 | 0) # Reserved | |
992 | ||
993 | message.data = '\0' + self.filename.encode('UTF-16LE') + '\0\0' | |
994 | ||
995 | ||
996 | class ComOpenAndxResponse(Payload): | |
997 | """ | |
998 | Contains information about a SMB_COM_OPEN_ANDX response from the server | |
999 | ||
1000 | After decoding, each instance will contain the following attributes: | |
1001 | - fid (integer) | |
1002 | - file_attributes (integer) | |
1003 | - last_write_time (long) | |
1004 | - access_rights (integer) | |
1005 | - resource_type (integer) | |
1006 | - open_results (integer) | |
1007 | ||
1008 | References: | |
1009 | =========== | |
1010 | - [MS-CIFS]: 2.2.4.41.2 | |
1011 | - [MS-SMB]: 2.2.4.1.2 | |
1012 | """ | |
1013 | ||
1014 | PAYLOAD_STRUCT_FORMAT = '<BBHHHIIHHHHHHH' | |
1015 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
1016 | ||
1017 | def decode(self, message): | |
1018 | assert message.command == SMB_COM_OPEN_ANDX | |
1019 | ||
1020 | if not message.status.hasError: | |
1021 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE: | |
1022 | raise ProtocolError('Not enough data to decode SMB_COM_OPEN_ANDX parameters', message.raw_data, message) | |
1023 | ||
1024 | _, _, _, self.fid, self.file_attributes, self.last_write_time, _, \ | |
1025 | self.access_rights, self.resource_type, _, self.open_results, _, _, _ = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, | |
1026 | message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
1027 | ||
1028 | ||
1029 | class ComWriteAndxRequest(Payload): | |
1030 | """ | |
1031 | References: | |
1032 | =========== | |
1033 | - [MS-CIFS]: 2.2.4.43.1 | |
1034 | - [MS-SMB]: 2.2.4.3.1 | |
1035 | """ | |
1036 | ||
1037 | PAYLOAD_STRUCT_FORMAT = '<HIIHHHHHI' | |
1038 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
1039 | ||
1040 | def __init__(self, fid, data_bytes, offset, write_mode = 0, timeout = 0): | |
1041 | """ | |
1042 | @param timeout: Number of milliseconds to wait for blocked write request before failing. Must be zero for writing to regular file | |
1043 | @type timeout: int | |
1044 | """ | |
1045 | self.fid = fid | |
1046 | self.offset = offset | |
1047 | self.data_bytes = data_bytes | |
1048 | self.timeout = timeout | |
1049 | self.write_mode = write_mode | |
1050 | ||
1051 | def initMessage(self, message): | |
1052 | Payload.initMessage(self, message) | |
1053 | message.command = SMB_COM_WRITE_ANDX | |
1054 | ||
1055 | def prepare(self, message): | |
1056 | # constant 1 is to account for the pad byte in the message.data | |
1057 | # constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters) | |
1058 | data_offset = message.HEADER_STRUCT_SIZE + self.DEFAULT_ANDX_PARAM_SIZE + self.PAYLOAD_STRUCT_SIZE + 1 + 2 | |
1059 | data_len = len(self.data_bytes) | |
1060 | ||
1061 | message.parameters_data = \ | |
1062 | self.DEFAULT_ANDX_PARAM_HEADER + \ | |
1063 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
1064 | self.fid, | |
1065 | self.offset & 0xFFFFFFFF, | |
1066 | self.timeout, | |
1067 | self.write_mode, | |
1068 | data_len, # Remaining | |
1069 | 0x0000, # Reserved | |
1070 | len(self.data_bytes), # DataLength | |
1071 | data_offset, # DataOffset | |
1072 | self.offset >> 32) # OffsetHigh field defined in [MS-SMB]: 2.2.4.3.1 | |
1073 | ||
1074 | message.data = '\0' + self.data_bytes | |
1075 | ||
1076 | ||
1077 | class ComWriteAndxResponse(Payload): | |
1078 | """ | |
1079 | References: | |
1080 | =========== | |
1081 | - [MS-CIFS]: 2.2.4.43.2 | |
1082 | - [MS-SMB]: 2.2.4.3.2 | |
1083 | """ | |
1084 | ||
1085 | PAYLOAD_STRUCT_FORMAT = '<BBHHHHH' # We follow the SMB_COM_WRITEX_ANDX server extensions in [MS-SMB]: 2.2.4.3.2 | |
1086 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
1087 | ||
1088 | def decode(self, message): | |
1089 | assert message.command == SMB_COM_WRITE_ANDX | |
1090 | ||
1091 | if not message.status.hasError: | |
1092 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE: | |
1093 | raise ProtocolError('Not enough data to decode SMB_COM_WRITE_ANDX parameters', message.raw_data, message) | |
1094 | ||
1095 | _, _, _, count, self.available, high_count, _ = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
1096 | self.count = (count & 0xFFFF) | (high_count << 16) | |
1097 | ||
1098 | ||
1099 | class ComReadAndxRequest(Payload): | |
1100 | """ | |
1101 | References: | |
1102 | =========== | |
1103 | - [MS-CIFS]: 2.2.4.42.1 | |
1104 | - [MS-SMB]: 2.2.4.2.1 | |
1105 | """ | |
1106 | ||
1107 | PAYLOAD_STRUCT_FORMAT = '<HIHHIHI' | |
1108 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
1109 | ||
1110 | def __init__(self, fid, offset, max_return_bytes_count, min_return_bytes_count, timeout = 0, remaining = 0): | |
1111 | """ | |
1112 | @param timeout: If reading from a regular file, this parameter must be 0. | |
1113 | @type timeout: int | |
1114 | """ | |
1115 | self.fid = fid | |
1116 | self.remaining = remaining | |
1117 | self.max_return_bytes_count = max_return_bytes_count | |
1118 | self.min_return_bytes_count = min_return_bytes_count | |
1119 | self.offset = offset | |
1120 | self.timeout = timeout | |
1121 | ||
1122 | def initMessage(self, message): | |
1123 | Payload.initMessage(self, message) | |
1124 | message.command = SMB_COM_READ_ANDX | |
1125 | ||
1126 | def prepare(self, message): | |
1127 | message.parameters_data = \ | |
1128 | self.DEFAULT_ANDX_PARAM_HEADER + \ | |
1129 | struct.pack(self.PAYLOAD_STRUCT_FORMAT, | |
1130 | self.fid, | |
1131 | self.offset & 0xFFFFFFFF, | |
1132 | self.max_return_bytes_count, | |
1133 | self.min_return_bytes_count, | |
1134 | self.timeout or (self.max_return_bytes_count >> 32), # Note that in [MS-SMB]: 2.2.4.2.1, this field can also act as MaxCountHigh field | |
1135 | self.remaining, # In [MS-CIFS]: 2.2.4.42.1, this field must be set to 0x0000 | |
1136 | self.offset >> 32) | |
1137 | ||
1138 | message.data = '' | |
1139 | ||
1140 | ||
1141 | class ComReadAndxResponse(Payload): | |
1142 | """ | |
1143 | References: | |
1144 | =========== | |
1145 | - [MS-CIFS]: 2.2.4.42.2 | |
1146 | - [MS-SMB]: 2.2.4.2.2 | |
1147 | """ | |
1148 | ||
1149 | PAYLOAD_STRUCT_FORMAT = '<BBHHHHHHHHHHH' | |
1150 | PAYLOAD_STRUCT_SIZE = struct.calcsize(PAYLOAD_STRUCT_FORMAT) | |
1151 | ||
1152 | def decode(self, message): | |
1153 | assert message.command == SMB_COM_READ_ANDX | |
1154 | ||
1155 | if not message.status.hasError: | |
1156 | if len(message.parameters_data) < self.PAYLOAD_STRUCT_SIZE: | |
1157 | raise ProtocolError('Not enough data to decode SMB_COM_READ_ANDX parameters', message.raw_data, message) | |
1158 | ||
1159 | _, _, _, _, _, _, self.data_length, data_offset, _, _, _, _, _ = struct.unpack(self.PAYLOAD_STRUCT_FORMAT, | |
1160 | message.parameters_data[:self.PAYLOAD_STRUCT_SIZE]) | |
1161 | ||
1162 | offset = data_offset - message.HEADER_STRUCT_SIZE - self.PAYLOAD_STRUCT_SIZE - 2 # constant 2 is for the ByteCount field in the SMB header (i.e. field which indicates number of data bytes after the SMB parameters) | |
1163 | self.data = message.data[offset:offset+self.data_length] | |
1164 | assert len(self.data) == self.data_length | |
1165 | ||
1166 | ||
1167 | class ComDeleteRequest(Payload): | |
1168 | """ | |
1169 | References: | |
1170 | =========== | |
1171 | - [MS-CIFS]: 2.2.4.7.1 | |
1172 | """ | |
1173 | ||
1174 | def __init__(self, filename_pattern, search_attributes = 0): | |
1175 | self.filename_pattern = filename_pattern | |
1176 | self.search_attributes = search_attributes | |
1177 | ||
1178 | def initMessage(self, message): | |
1179 | Payload.initMessage(self, message) | |
1180 | message.command = SMB_COM_DELETE | |
1181 | ||
1182 | def prepare(self, message): | |
1183 | message.parameters_data = struct.pack('<H', self.search_attributes) | |
1184 | message.data = '\x04' + self.filename_pattern.encode('UTF-16LE') + '\0\0' | |
1185 | ||
1186 | ||
1187 | class ComCreateDirectoryRequest(Payload): | |
1188 | """ | |
1189 | Although this command has been marked deprecated in [MS-CIFS], we continue to use it for its simplicity | |
1190 | as compared to its replacement TRANS2_CREATE_DIRECTORY sub-command [MS-CIFS]: 2.2.6.14 | |
1191 | ||
1192 | References: | |
1193 | =========== | |
1194 | - [MS-CIFS]: 2.2.4.1.1 | |
1195 | """ | |
1196 | ||
1197 | def __init__(self, path): | |
1198 | self.path = path | |
1199 | ||
1200 | def initMessage(self, message): | |
1201 | Payload.initMessage(self, message) | |
1202 | message.command = SMB_COM_CREATE_DIRECTORY | |
1203 | ||
1204 | def prepare(self, message): | |
1205 | message.parameters_data = '' | |
1206 | message.data = '\x04' + self.path.encode('UTF-16LE') + '\0\0' | |
1207 | ||
1208 | ||
1209 | class ComDeleteDirectoryRequest(Payload): | |
1210 | """ | |
1211 | References: | |
1212 | =========== | |
1213 | - [MS-CIFS]: 2.2.4.2.1 | |
1214 | """ | |
1215 | ||
1216 | def __init__(self, path): | |
1217 | self.path = path | |
1218 | ||
1219 | def initMessage(self, message): | |
1220 | Payload.initMessage(self, message) | |
1221 | message.command = SMB_COM_DELETE_DIRECTORY | |
1222 | ||
1223 | def prepare(self, message): | |
1224 | message.parameters_data = '' | |
1225 | message.data = '\x04' + self.path.encode('UTF-16LE') + '\0\0' | |
1226 | ||
1227 | ||
1228 | class ComRenameRequest(Payload): | |
1229 | """ | |
1230 | References: | |
1231 | =========== | |
1232 | - [MS-CIFS]: 2.2.4.8.1 | |
1233 | """ | |
1234 | ||
1235 | def __init__(self, old_path, new_path, search_attributes = 0): | |
1236 | self.old_path = old_path | |
1237 | self.new_path = new_path | |
1238 | self.search_attributes = search_attributes | |
1239 | ||
1240 | def initMessage(self, message): | |
1241 | Payload.initMessage(self, message) | |
1242 | message.command = SMB_COM_RENAME | |
1243 | ||
1244 | def prepare(self, message): | |
1245 | message.parameters_data = struct.pack('<H', self.search_attributes) | |
1246 | message.data = '\x04' + self.old_path.encode('UTF-16LE') + '\x00\x00\x04\x00' + self.new_path.encode('UTF-16LE') + '\x00\x00' | |
1247 | ||
1248 | ||
1249 | class ComEchoRequest(Payload): | |
1250 | """ | |
1251 | References: | |
1252 | =========== | |
1253 | - [MS-CIFS]: 2.2.4.39.1 | |
1254 | """ | |
1255 | ||
1256 | def __init__(self, echo_data = '', echo_count = 1): | |
1257 | self.echo_count = echo_count | |
1258 | self.echo_data = echo_data | |
1259 | ||
1260 | def initMessage(self, message): | |
1261 | Payload.initMessage(self, message) | |
1262 | message.command = SMB_COM_ECHO | |
1263 | message.tid = 0xFFFF | |
1264 | ||
1265 | def prepare(self, message): | |
1266 | message.parameters_data = struct.pack('<H', self.echo_count) | |
1267 | message.data = self.echo_data | |
1268 | ||
1269 | ||
1270 | class ComEchoResponse(Payload): | |
1271 | """ | |
1272 | References: | |
1273 | =========== | |
1274 | - [MS-CIFS]: 2.2.4.39.2 | |
1275 | """ | |
1276 | ||
1277 | def decode(self, message): | |
1278 | self.sequence_number = struct.unpack('<H', message.parameters_data[:2])[0] | |
1279 | self.data = message.data |
0 | ||
1 | md4.py and U32.py | |
2 | Both modules downloaded from http://www.oocities.org/rozmanov/python/md4.html. | |
3 | Licensed under LGPL | |
4 | ||
5 | pyDes.py 2.0.0 | |
6 | Downloaded from http://twhiteman.netfirms.com/des.html | |
7 | Licensed under public domain |
0 | # U32.py implements 32-bit unsigned int class for Python | |
1 | # Version 1.0 | |
2 | # Copyright (C) 2001-2002 Dmitry Rozmanov | |
3 | # | |
4 | # This library is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU Lesser General Public | |
6 | # License as published by the Free Software Foundation; either | |
7 | # version 2.1 of the License, or (at your option) any later version. | |
8 | # | |
9 | # This library is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | # Lesser General Public License for more details. | |
13 | # | |
14 | # You should have received a copy of the GNU Lesser General Public | |
15 | # License along with this library; if not, write to the Free Software | |
16 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 | # | |
18 | # e-mail: [email protected] | |
19 | # | |
20 | #==================================================================== | |
21 | ||
22 | C = 0x1000000000L | |
23 | ||
24 | #-------------------------------------------------------------------- | |
25 | def norm(n): | |
26 | return n & 0xFFFFFFFFL | |
27 | ||
28 | #==================================================================== | |
29 | class U32: | |
30 | v = 0L | |
31 | ||
32 | #-------------------------------------------------------------------- | |
33 | def __init__(self, value = 0): | |
34 | self.v = C + norm(abs(long(value))) | |
35 | ||
36 | #-------------------------------------------------------------------- | |
37 | def set(self, value = 0): | |
38 | self.v = C + norm(abs(long(value))) | |
39 | ||
40 | #-------------------------------------------------------------------- | |
41 | def __repr__(self): | |
42 | return hex(norm(self.v)) | |
43 | ||
44 | #-------------------------------------------------------------------- | |
45 | def __long__(self): return long(norm(self.v)) | |
46 | ||
47 | #-------------------------------------------------------------------- | |
48 | def __int__(self): return int(norm(self.v)) | |
49 | ||
50 | #-------------------------------------------------------------------- | |
51 | def __chr__(self): return chr(norm(self.v)) | |
52 | ||
53 | #-------------------------------------------------------------------- | |
54 | def __add__(self, b): | |
55 | r = U32() | |
56 | r.v = C + norm(self.v + b.v) | |
57 | return r | |
58 | ||
59 | #-------------------------------------------------------------------- | |
60 | def __sub__(self, b): | |
61 | r = U32() | |
62 | if self.v < b.v: | |
63 | r.v = C + norm(0x100000000L - (b.v - self.v)) | |
64 | else: r.v = C + norm(self.v - b.v) | |
65 | return r | |
66 | ||
67 | #-------------------------------------------------------------------- | |
68 | def __mul__(self, b): | |
69 | r = U32() | |
70 | r.v = C + norm(self.v * b.v) | |
71 | return r | |
72 | ||
73 | #-------------------------------------------------------------------- | |
74 | def __div__(self, b): | |
75 | r = U32() | |
76 | r.v = C + (norm(self.v) / norm(b.v)) | |
77 | return r | |
78 | ||
79 | #-------------------------------------------------------------------- | |
80 | def __mod__(self, b): | |
81 | r = U32() | |
82 | r.v = C + (norm(self.v) % norm(b.v)) | |
83 | return r | |
84 | ||
85 | #-------------------------------------------------------------------- | |
86 | def __neg__(self): return U32(self.v) | |
87 | ||
88 | #-------------------------------------------------------------------- | |
89 | def __pos__(self): return U32(self.v) | |
90 | ||
91 | #-------------------------------------------------------------------- | |
92 | def __abs__(self): return U32(self.v) | |
93 | ||
94 | #-------------------------------------------------------------------- | |
95 | def __invert__(self): | |
96 | r = U32() | |
97 | r.v = C + norm(~self.v) | |
98 | return r | |
99 | ||
100 | #-------------------------------------------------------------------- | |
101 | def __lshift__(self, b): | |
102 | r = U32() | |
103 | r.v = C + norm(self.v << b) | |
104 | return r | |
105 | ||
106 | #-------------------------------------------------------------------- | |
107 | def __rshift__(self, b): | |
108 | r = U32() | |
109 | r.v = C + (norm(self.v) >> b) | |
110 | return r | |
111 | ||
112 | #-------------------------------------------------------------------- | |
113 | def __and__(self, b): | |
114 | r = U32() | |
115 | r.v = C + norm(self.v & b.v) | |
116 | return r | |
117 | ||
118 | #-------------------------------------------------------------------- | |
119 | def __or__(self, b): | |
120 | r = U32() | |
121 | r.v = C + norm(self.v | b.v) | |
122 | return r | |
123 | ||
124 | #-------------------------------------------------------------------- | |
125 | def __xor__(self, b): | |
126 | r = U32() | |
127 | r.v = C + norm(self.v ^ b.v) | |
128 | return r | |
129 | ||
130 | #-------------------------------------------------------------------- | |
131 | def __not__(self): | |
132 | return U32(not norm(self.v)) | |
133 | ||
134 | #-------------------------------------------------------------------- | |
135 | def truth(self): | |
136 | return norm(self.v) | |
137 | ||
138 | #-------------------------------------------------------------------- | |
139 | def __cmp__(self, b): | |
140 | if norm(self.v) > norm(b.v): return 1 | |
141 | elif norm(self.v) < norm(b.v): return -1 | |
142 | else: return 0 | |
143 | ||
144 | #-------------------------------------------------------------------- | |
145 | def __nonzero__(self): | |
146 | return norm(self.v) | |
147 |
0 | # md4.py implements md4 hash class for Python | |
1 | # Version 1.0 | |
2 | # Copyright (C) 2001-2002 Dmitry Rozmanov | |
3 | # | |
4 | # based on md4.c from "the Python Cryptography Toolkit, version 1.0.0 | |
5 | # Copyright (C) 1995, A.M. Kuchling" | |
6 | # | |
7 | # This library is free software; you can redistribute it and/or | |
8 | # modify it under the terms of the GNU Lesser General Public | |
9 | # License as published by the Free Software Foundation; either | |
10 | # version 2.1 of the License, or (at your option) any later version. | |
11 | # | |
12 | # This library is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | # Lesser General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU Lesser General Public | |
18 | # License along with this library; if not, write to the Free Software | |
19 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | # | |
21 | # e-mail: [email protected] | |
22 | # | |
23 | #==================================================================== | |
24 | ||
25 | # MD4 validation data | |
26 | ||
27 | md4_test= [ | |
28 | ('', 0x31d6cfe0d16ae931b73c59d7e0c089c0L), | |
29 | ("a", 0xbde52cb31de33e46245e05fbdbd6fb24L), | |
30 | ("abc", 0xa448017aaf21d8525fc10ae87aa6729dL), | |
31 | ("message digest", 0xd9130a8164549fe818874806e1c7014bL), | |
32 | ("abcdefghijklmnopqrstuvwxyz", 0xd79e1c308aa5bbcdeea8ed63df412da9L), | |
33 | ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", | |
34 | 0x043f8582f241db351ce627e153e7f0e4L), | |
35 | ("12345678901234567890123456789012345678901234567890123456789012345678901234567890", | |
36 | 0xe33b4ddc9c38f2199c3e7b164fcc0536L), | |
37 | ] | |
38 | ||
39 | #==================================================================== | |
40 | from U32 import U32 | |
41 | ||
42 | #-------------------------------------------------------------------- | |
43 | class MD4: | |
44 | A = None | |
45 | B = None | |
46 | C = None | |
47 | D = None | |
48 | count, len1, len2 = None, None, None | |
49 | buf = [] | |
50 | ||
51 | #----------------------------------------------------- | |
52 | def __init__(self): | |
53 | ||
54 | ||
55 | self.A = U32(0x67452301L) | |
56 | self.B = U32(0xefcdab89L) | |
57 | self.C = U32(0x98badcfeL) | |
58 | self.D = U32(0x10325476L) | |
59 | self.count, self.len1, self.len2 = U32(0L), U32(0L), U32(0L) | |
60 | self.buf = [0x00] * 64 | |
61 | ||
62 | #----------------------------------------------------- | |
63 | def __repr__(self): | |
64 | r = 'A = %s, \nB = %s, \nC = %s, \nD = %s.\n' % (self.A.__repr__(), self.B.__repr__(), self.C.__repr__(), self.D.__repr__()) | |
65 | r = r + 'count = %s, \nlen1 = %s, \nlen2 = %s.\n' % (self.count.__repr__(), self.len1.__repr__(), self.len2.__repr__()) | |
66 | for i in range(4): | |
67 | for j in range(16): | |
68 | r = r + '%4s ' % hex(self.buf[i+j]) | |
69 | r = r + '\n' | |
70 | ||
71 | return r | |
72 | #----------------------------------------------------- | |
73 | def make_copy(self): | |
74 | ||
75 | dest = new() | |
76 | ||
77 | dest.len1 = self.len1 | |
78 | dest.len2 = self.len2 | |
79 | dest.A = self.A | |
80 | dest.B = self.B | |
81 | dest.C = self.C | |
82 | dest.D = self.D | |
83 | dest.count = self.count | |
84 | for i in range(self.count): | |
85 | dest.buf[i] = self.buf[i] | |
86 | ||
87 | return dest | |
88 | ||
89 | #----------------------------------------------------- | |
90 | def update(self, str): | |
91 | ||
92 | buf = [] | |
93 | for i in str: buf.append(ord(i)) | |
94 | ilen = U32(len(buf)) | |
95 | ||
96 | # check if the first length is out of range | |
97 | # as the length is measured in bits then multiplay it by 8 | |
98 | if (long(self.len1 + (ilen << 3)) < long(self.len1)): | |
99 | self.len2 = self.len2 + U32(1) | |
100 | ||
101 | self.len1 = self.len1 + (ilen << 3) | |
102 | self.len2 = self.len2 + (ilen >> 29) | |
103 | ||
104 | L = U32(0) | |
105 | bufpos = 0 | |
106 | while (long(ilen) > 0): | |
107 | if (64 - long(self.count)) < long(ilen): L = U32(64 - long(self.count)) | |
108 | else: L = ilen | |
109 | for i in range(int(L)): self.buf[i + int(self.count)] = buf[i + bufpos] | |
110 | self.count = self.count + L | |
111 | ilen = ilen - L | |
112 | bufpos = bufpos + int(L) | |
113 | ||
114 | if (long(self.count) == 64L): | |
115 | self.count = U32(0L) | |
116 | X = [] | |
117 | i = 0 | |
118 | for j in range(16): | |
119 | X.append(U32(self.buf[i]) + (U32(self.buf[i+1]) << 8) + \ | |
120 | (U32(self.buf[i+2]) << 16) + (U32(self.buf[i+3]) << 24)) | |
121 | i = i + 4 | |
122 | ||
123 | A = self.A | |
124 | B = self.B | |
125 | C = self.C | |
126 | D = self.D | |
127 | ||
128 | A = f1(A,B,C,D, 0, 3, X) | |
129 | D = f1(D,A,B,C, 1, 7, X) | |
130 | C = f1(C,D,A,B, 2,11, X) | |
131 | B = f1(B,C,D,A, 3,19, X) | |
132 | A = f1(A,B,C,D, 4, 3, X) | |
133 | D = f1(D,A,B,C, 5, 7, X) | |
134 | C = f1(C,D,A,B, 6,11, X) | |
135 | B = f1(B,C,D,A, 7,19, X) | |
136 | A = f1(A,B,C,D, 8, 3, X) | |
137 | D = f1(D,A,B,C, 9, 7, X) | |
138 | C = f1(C,D,A,B,10,11, X) | |
139 | B = f1(B,C,D,A,11,19, X) | |
140 | A = f1(A,B,C,D,12, 3, X) | |
141 | D = f1(D,A,B,C,13, 7, X) | |
142 | C = f1(C,D,A,B,14,11, X) | |
143 | B = f1(B,C,D,A,15,19, X) | |
144 | ||
145 | A = f2(A,B,C,D, 0, 3, X) | |
146 | D = f2(D,A,B,C, 4, 5, X) | |
147 | C = f2(C,D,A,B, 8, 9, X) | |
148 | B = f2(B,C,D,A,12,13, X) | |
149 | A = f2(A,B,C,D, 1, 3, X) | |
150 | D = f2(D,A,B,C, 5, 5, X) | |
151 | C = f2(C,D,A,B, 9, 9, X) | |
152 | B = f2(B,C,D,A,13,13, X) | |
153 | A = f2(A,B,C,D, 2, 3, X) | |
154 | D = f2(D,A,B,C, 6, 5, X) | |
155 | C = f2(C,D,A,B,10, 9, X) | |
156 | B = f2(B,C,D,A,14,13, X) | |
157 | A = f2(A,B,C,D, 3, 3, X) | |
158 | D = f2(D,A,B,C, 7, 5, X) | |
159 | C = f2(C,D,A,B,11, 9, X) | |
160 | B = f2(B,C,D,A,15,13, X) | |
161 | ||
162 | A = f3(A,B,C,D, 0, 3, X) | |
163 | D = f3(D,A,B,C, 8, 9, X) | |
164 | C = f3(C,D,A,B, 4,11, X) | |
165 | B = f3(B,C,D,A,12,15, X) | |
166 | A = f3(A,B,C,D, 2, 3, X) | |
167 | D = f3(D,A,B,C,10, 9, X) | |
168 | C = f3(C,D,A,B, 6,11, X) | |
169 | B = f3(B,C,D,A,14,15, X) | |
170 | A = f3(A,B,C,D, 1, 3, X) | |
171 | D = f3(D,A,B,C, 9, 9, X) | |
172 | C = f3(C,D,A,B, 5,11, X) | |
173 | B = f3(B,C,D,A,13,15, X) | |
174 | A = f3(A,B,C,D, 3, 3, X) | |
175 | D = f3(D,A,B,C,11, 9, X) | |
176 | C = f3(C,D,A,B, 7,11, X) | |
177 | B = f3(B,C,D,A,15,15, X) | |
178 | ||
179 | self.A = self.A + A | |
180 | self.B = self.B + B | |
181 | self.C = self.C + C | |
182 | self.D = self.D + D | |
183 | ||
184 | #----------------------------------------------------- | |
185 | def digest(self): | |
186 | ||
187 | res = [0x00] * 16 | |
188 | s = [0x00] * 8 | |
189 | padding = [0x00] * 64 | |
190 | padding[0] = 0x80 | |
191 | padlen, oldlen1, oldlen2 = U32(0), U32(0), U32(0) | |
192 | ||
193 | temp = self.make_copy() | |
194 | ||
195 | oldlen1 = temp.len1 | |
196 | oldlen2 = temp.len2 | |
197 | if (56 <= long(self.count)): padlen = U32(56 - long(self.count) + 64) | |
198 | else: padlen = U32(56 - long(self.count)) | |
199 | ||
200 | temp.update(int_array2str(padding[:int(padlen)])) | |
201 | ||
202 | s[0]= (oldlen1) & U32(0xFF) | |
203 | s[1]=((oldlen1) >> 8) & U32(0xFF) | |
204 | s[2]=((oldlen1) >> 16) & U32(0xFF) | |
205 | s[3]=((oldlen1) >> 24) & U32(0xFF) | |
206 | s[4]= (oldlen2) & U32(0xFF) | |
207 | s[5]=((oldlen2) >> 8) & U32(0xFF) | |
208 | s[6]=((oldlen2) >> 16) & U32(0xFF) | |
209 | s[7]=((oldlen2) >> 24) & U32(0xFF) | |
210 | temp.update(int_array2str(s)) | |
211 | ||
212 | res[ 0]= temp.A & U32(0xFF) | |
213 | res[ 1]=(temp.A >> 8) & U32(0xFF) | |
214 | res[ 2]=(temp.A >> 16) & U32(0xFF) | |
215 | res[ 3]=(temp.A >> 24) & U32(0xFF) | |
216 | res[ 4]= temp.B & U32(0xFF) | |
217 | res[ 5]=(temp.B >> 8) & U32(0xFF) | |
218 | res[ 6]=(temp.B >> 16) & U32(0xFF) | |
219 | res[ 7]=(temp.B >> 24) & U32(0xFF) | |
220 | res[ 8]= temp.C & U32(0xFF) | |
221 | res[ 9]=(temp.C >> 8) & U32(0xFF) | |
222 | res[10]=(temp.C >> 16) & U32(0xFF) | |
223 | res[11]=(temp.C >> 24) & U32(0xFF) | |
224 | res[12]= temp.D & U32(0xFF) | |
225 | res[13]=(temp.D >> 8) & U32(0xFF) | |
226 | res[14]=(temp.D >> 16) & U32(0xFF) | |
227 | res[15]=(temp.D >> 24) & U32(0xFF) | |
228 | ||
229 | return int_array2str(res) | |
230 | ||
231 | #==================================================================== | |
232 | # helpers | |
233 | def F(x, y, z): return (((x) & (y)) | ((~x) & (z))) | |
234 | def G(x, y, z): return (((x) & (y)) | ((x) & (z)) | ((y) & (z))) | |
235 | def H(x, y, z): return ((x) ^ (y) ^ (z)) | |
236 | ||
237 | def ROL(x, n): return (((x) << n) | ((x) >> (32-n))) | |
238 | ||
239 | def f1(a, b, c, d, k, s, X): return ROL(a + F(b, c, d) + X[k], s) | |
240 | def f2(a, b, c, d, k, s, X): return ROL(a + G(b, c, d) + X[k] + U32(0x5a827999L), s) | |
241 | def f3(a, b, c, d, k, s, X): return ROL(a + H(b, c, d) + X[k] + U32(0x6ed9eba1L), s) | |
242 | ||
243 | #-------------------------------------------------------------------- | |
244 | # helper function | |
245 | def int_array2str(array): | |
246 | str = '' | |
247 | for i in array: | |
248 | str = str + chr(i) | |
249 | return str | |
250 | ||
251 | #-------------------------------------------------------------------- | |
252 | # To be able to use md4.new() instead of md4.MD4() | |
253 | new = MD4 |
0 | ############################################################################# | |
1 | # Documentation # | |
2 | ############################################################################# | |
3 | ||
4 | # Author: Todd Whiteman | |
5 | # Date: 16th March, 2009 | |
6 | # Verion: 2.0.0 | |
7 | # License: Public Domain - free to do as you wish | |
8 | # Homepage: http://twhiteman.netfirms.com/des.html | |
9 | # | |
10 | # This is a pure python implementation of the DES encryption algorithm. | |
11 | # It's pure python to avoid portability issues, since most DES | |
12 | # implementations are programmed in C (for performance reasons). | |
13 | # | |
14 | # Triple DES class is also implemented, utilising the DES base. Triple DES | |
15 | # is either DES-EDE3 with a 24 byte key, or DES-EDE2 with a 16 byte key. | |
16 | # | |
17 | # See the README.txt that should come with this python module for the | |
18 | # implementation methods used. | |
19 | # | |
20 | # Thanks to: | |
21 | # * David Broadwell for ideas, comments and suggestions. | |
22 | # * Mario Wolff for pointing out and debugging some triple des CBC errors. | |
23 | # * Santiago Palladino for providing the PKCS5 padding technique. | |
24 | # * Shaya for correcting the PAD_PKCS5 triple des CBC errors. | |
25 | # | |
26 | """A pure python implementation of the DES and TRIPLE DES encryption algorithms. | |
27 | ||
28 | Class initialization | |
29 | -------------------- | |
30 | pyDes.des(key, [mode], [IV], [pad], [padmode]) | |
31 | pyDes.triple_des(key, [mode], [IV], [pad], [padmode]) | |
32 | ||
33 | key -> Bytes containing the encryption key. 8 bytes for DES, 16 or 24 bytes | |
34 | for Triple DES | |
35 | mode -> Optional argument for encryption type, can be either | |
36 | pyDes.ECB (Electronic Code Book) or pyDes.CBC (Cypher Block Chaining) | |
37 | IV -> Optional Initial Value bytes, must be supplied if using CBC mode. | |
38 | Length must be 8 bytes. | |
39 | pad -> Optional argument, set the pad character (PAD_NORMAL) to use during | |
40 | all encrypt/decrpt operations done with this instance. | |
41 | padmode -> Optional argument, set the padding mode (PAD_NORMAL or PAD_PKCS5) | |
42 | to use during all encrypt/decrpt operations done with this instance. | |
43 | ||
44 | I recommend to use PAD_PKCS5 padding, as then you never need to worry about any | |
45 | padding issues, as the padding can be removed unambiguously upon decrypting | |
46 | data that was encrypted using PAD_PKCS5 padmode. | |
47 | ||
48 | Common methods | |
49 | -------------- | |
50 | encrypt(data, [pad], [padmode]) | |
51 | decrypt(data, [pad], [padmode]) | |
52 | ||
53 | data -> Bytes to be encrypted/decrypted | |
54 | pad -> Optional argument. Only when using padmode of PAD_NORMAL. For | |
55 | encryption, adds this characters to the end of the data block when | |
56 | data is not a multiple of 8 bytes. For decryption, will remove the | |
57 | trailing characters that match this pad character from the last 8 | |
58 | bytes of the unencrypted data block. | |
59 | padmode -> Optional argument, set the padding mode, must be one of PAD_NORMAL | |
60 | or PAD_PKCS5). Defaults to PAD_NORMAL. | |
61 | ||
62 | ||
63 | Example | |
64 | ------- | |
65 | from pyDes import * | |
66 | ||
67 | data = "Please encrypt my data" | |
68 | k = des("DESCRYPT", CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) | |
69 | # For Python3, you'll need to use bytes, i.e.: | |
70 | # data = b"Please encrypt my data" | |
71 | # k = des(b"DESCRYPT", CBC, b"\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) | |
72 | d = k.encrypt(data) | |
73 | print "Encrypted: %r" % d | |
74 | print "Decrypted: %r" % k.decrypt(d) | |
75 | assert k.decrypt(d, padmode=PAD_PKCS5) == data | |
76 | ||
77 | ||
78 | See the module source (pyDes.py) for more examples of use. | |
79 | You can also run the pyDes.py file without and arguments to see a simple test. | |
80 | ||
81 | Note: This code was not written for high-end systems needing a fast | |
82 | implementation, but rather a handy portable solution with small usage. | |
83 | ||
84 | """ | |
85 | ||
86 | import sys | |
87 | ||
88 | # _pythonMajorVersion is used to handle Python2 and Python3 differences. | |
89 | _pythonMajorVersion = sys.version_info[0] | |
90 | ||
91 | # Modes of crypting / cyphering | |
92 | ECB = 0 | |
93 | CBC = 1 | |
94 | ||
95 | # Modes of padding | |
96 | PAD_NORMAL = 1 | |
97 | PAD_PKCS5 = 2 | |
98 | ||
99 | # PAD_PKCS5: is a method that will unambiguously remove all padding | |
100 | # characters after decryption, when originally encrypted with | |
101 | # this padding mode. | |
102 | # For a good description of the PKCS5 padding technique, see: | |
103 | # http://www.faqs.org/rfcs/rfc1423.html | |
104 | ||
105 | # The base class shared by des and triple des. | |
106 | class _baseDes(object): | |
107 | def __init__(self, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL): | |
108 | if IV: | |
109 | IV = self._guardAgainstUnicode(IV) | |
110 | if pad: | |
111 | pad = self._guardAgainstUnicode(pad) | |
112 | self.block_size = 8 | |
113 | # Sanity checking of arguments. | |
114 | if pad and padmode == PAD_PKCS5: | |
115 | raise ValueError("Cannot use a pad character with PAD_PKCS5") | |
116 | if IV and len(IV) != self.block_size: | |
117 | raise ValueError("Invalid Initial Value (IV), must be a multiple of " + str(self.block_size) + " bytes") | |
118 | ||
119 | # Set the passed in variables | |
120 | self._mode = mode | |
121 | self._iv = IV | |
122 | self._padding = pad | |
123 | self._padmode = padmode | |
124 | ||
125 | def getKey(self): | |
126 | """getKey() -> bytes""" | |
127 | return self.__key | |
128 | ||
129 | def setKey(self, key): | |
130 | """Will set the crypting key for this object.""" | |
131 | key = self._guardAgainstUnicode(key) | |
132 | self.__key = key | |
133 | ||
134 | def getMode(self): | |
135 | """getMode() -> pyDes.ECB or pyDes.CBC""" | |
136 | return self._mode | |
137 | ||
138 | def setMode(self, mode): | |
139 | """Sets the type of crypting mode, pyDes.ECB or pyDes.CBC""" | |
140 | self._mode = mode | |
141 | ||
142 | def getPadding(self): | |
143 | """getPadding() -> bytes of length 1. Padding character.""" | |
144 | return self._padding | |
145 | ||
146 | def setPadding(self, pad): | |
147 | """setPadding() -> bytes of length 1. Padding character.""" | |
148 | if pad is not None: | |
149 | pad = self._guardAgainstUnicode(pad) | |
150 | self._padding = pad | |
151 | ||
152 | def getPadMode(self): | |
153 | """getPadMode() -> pyDes.PAD_NORMAL or pyDes.PAD_PKCS5""" | |
154 | return self._padmode | |
155 | ||
156 | def setPadMode(self, mode): | |
157 | """Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5""" | |
158 | self._padmode = mode | |
159 | ||
160 | def getIV(self): | |
161 | """getIV() -> bytes""" | |
162 | return self._iv | |
163 | ||
164 | def setIV(self, IV): | |
165 | """Will set the Initial Value, used in conjunction with CBC mode""" | |
166 | if not IV or len(IV) != self.block_size: | |
167 | raise ValueError("Invalid Initial Value (IV), must be a multiple of " + str(self.block_size) + " bytes") | |
168 | IV = self._guardAgainstUnicode(IV) | |
169 | self._iv = IV | |
170 | ||
171 | def _padData(self, data, pad, padmode): | |
172 | # Pad data depending on the mode | |
173 | if padmode is None: | |
174 | # Get the default padding mode. | |
175 | padmode = self.getPadMode() | |
176 | if pad and padmode == PAD_PKCS5: | |
177 | raise ValueError("Cannot use a pad character with PAD_PKCS5") | |
178 | ||
179 | if padmode == PAD_NORMAL: | |
180 | if len(data) % self.block_size == 0: | |
181 | # No padding required. | |
182 | return data | |
183 | ||
184 | if not pad: | |
185 | # Get the default padding. | |
186 | pad = self.getPadding() | |
187 | if not pad: | |
188 | raise ValueError("Data must be a multiple of " + str(self.block_size) + " bytes in length. Use padmode=PAD_PKCS5 or set the pad character.") | |
189 | data += (self.block_size - (len(data) % self.block_size)) * pad | |
190 | ||
191 | elif padmode == PAD_PKCS5: | |
192 | pad_len = 8 - (len(data) % self.block_size) | |
193 | if _pythonMajorVersion < 3: | |
194 | data += pad_len * chr(pad_len) | |
195 | else: | |
196 | data += bytes([pad_len] * pad_len) | |
197 | ||
198 | return data | |
199 | ||
200 | def _unpadData(self, data, pad, padmode): | |
201 | # Unpad data depending on the mode. | |
202 | if not data: | |
203 | return data | |
204 | if pad and padmode == PAD_PKCS5: | |
205 | raise ValueError("Cannot use a pad character with PAD_PKCS5") | |
206 | if padmode is None: | |
207 | # Get the default padding mode. | |
208 | padmode = self.getPadMode() | |
209 | ||
210 | if padmode == PAD_NORMAL: | |
211 | if not pad: | |
212 | # Get the default padding. | |
213 | pad = self.getPadding() | |
214 | if pad: | |
215 | data = data[:-self.block_size] + \ | |
216 | data[-self.block_size:].rstrip(pad) | |
217 | ||
218 | elif padmode == PAD_PKCS5: | |
219 | if _pythonMajorVersion < 3: | |
220 | pad_len = ord(data[-1]) | |
221 | else: | |
222 | pad_len = data[-1] | |
223 | data = data[:-pad_len] | |
224 | ||
225 | return data | |
226 | ||
227 | def _guardAgainstUnicode(self, data): | |
228 | # Only accept byte strings or ascii unicode values, otherwise | |
229 | # there is no way to correctly decode the data into bytes. | |
230 | if _pythonMajorVersion < 3: | |
231 | if isinstance(data, unicode): | |
232 | raise ValueError("pyDes can only work with bytes, not Unicode strings.") | |
233 | else: | |
234 | if isinstance(data, str): | |
235 | # Only accept ascii unicode values. | |
236 | try: | |
237 | return data.encode('ascii') | |
238 | except UnicodeEncodeError: | |
239 | pass | |
240 | raise ValueError("pyDes can only work with encoded strings, not Unicode.") | |
241 | return data | |
242 | ||
243 | ############################################################################# | |
244 | # DES # | |
245 | ############################################################################# | |
246 | class des(_baseDes): | |
247 | """DES encryption/decrytpion class | |
248 | ||
249 | Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes. | |
250 | ||
251 | pyDes.des(key,[mode], [IV]) | |
252 | ||
253 | key -> Bytes containing the encryption key, must be exactly 8 bytes | |
254 | mode -> Optional argument for encryption type, can be either pyDes.ECB | |
255 | (Electronic Code Book), pyDes.CBC (Cypher Block Chaining) | |
256 | IV -> Optional Initial Value bytes, must be supplied if using CBC mode. | |
257 | Must be 8 bytes in length. | |
258 | pad -> Optional argument, set the pad character (PAD_NORMAL) to use | |
259 | during all encrypt/decrpt operations done with this instance. | |
260 | padmode -> Optional argument, set the padding mode (PAD_NORMAL or | |
261 | PAD_PKCS5) to use during all encrypt/decrpt operations done | |
262 | with this instance. | |
263 | """ | |
264 | ||
265 | ||
266 | # Permutation and translation tables for DES | |
267 | __pc1 = [56, 48, 40, 32, 24, 16, 8, | |
268 | 0, 57, 49, 41, 33, 25, 17, | |
269 | 9, 1, 58, 50, 42, 34, 26, | |
270 | 18, 10, 2, 59, 51, 43, 35, | |
271 | 62, 54, 46, 38, 30, 22, 14, | |
272 | 6, 61, 53, 45, 37, 29, 21, | |
273 | 13, 5, 60, 52, 44, 36, 28, | |
274 | 20, 12, 4, 27, 19, 11, 3 | |
275 | ] | |
276 | ||
277 | # number left rotations of pc1 | |
278 | __left_rotations = [ | |
279 | 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 | |
280 | ] | |
281 | ||
282 | # permuted choice key (table 2) | |
283 | __pc2 = [ | |
284 | 13, 16, 10, 23, 0, 4, | |
285 | 2, 27, 14, 5, 20, 9, | |
286 | 22, 18, 11, 3, 25, 7, | |
287 | 15, 6, 26, 19, 12, 1, | |
288 | 40, 51, 30, 36, 46, 54, | |
289 | 29, 39, 50, 44, 32, 47, | |
290 | 43, 48, 38, 55, 33, 52, | |
291 | 45, 41, 49, 35, 28, 31 | |
292 | ] | |
293 | ||
294 | # initial permutation IP | |
295 | __ip = [57, 49, 41, 33, 25, 17, 9, 1, | |
296 | 59, 51, 43, 35, 27, 19, 11, 3, | |
297 | 61, 53, 45, 37, 29, 21, 13, 5, | |
298 | 63, 55, 47, 39, 31, 23, 15, 7, | |
299 | 56, 48, 40, 32, 24, 16, 8, 0, | |
300 | 58, 50, 42, 34, 26, 18, 10, 2, | |
301 | 60, 52, 44, 36, 28, 20, 12, 4, | |
302 | 62, 54, 46, 38, 30, 22, 14, 6 | |
303 | ] | |
304 | ||
305 | # Expansion table for turning 32 bit blocks into 48 bits | |
306 | __expansion_table = [ | |
307 | 31, 0, 1, 2, 3, 4, | |
308 | 3, 4, 5, 6, 7, 8, | |
309 | 7, 8, 9, 10, 11, 12, | |
310 | 11, 12, 13, 14, 15, 16, | |
311 | 15, 16, 17, 18, 19, 20, | |
312 | 19, 20, 21, 22, 23, 24, | |
313 | 23, 24, 25, 26, 27, 28, | |
314 | 27, 28, 29, 30, 31, 0 | |
315 | ] | |
316 | ||
317 | # The (in)famous S-boxes | |
318 | __sbox = [ | |
319 | # S1 | |
320 | [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, | |
321 | 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, | |
322 | 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, | |
323 | 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], | |
324 | ||
325 | # S2 | |
326 | [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, | |
327 | 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, | |
328 | 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, | |
329 | 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], | |
330 | ||
331 | # S3 | |
332 | [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, | |
333 | 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, | |
334 | 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, | |
335 | 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], | |
336 | ||
337 | # S4 | |
338 | [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, | |
339 | 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, | |
340 | 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, | |
341 | 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], | |
342 | ||
343 | # S5 | |
344 | [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, | |
345 | 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, | |
346 | 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, | |
347 | 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], | |
348 | ||
349 | # S6 | |
350 | [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, | |
351 | 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, | |
352 | 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, | |
353 | 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], | |
354 | ||
355 | # S7 | |
356 | [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, | |
357 | 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, | |
358 | 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, | |
359 | 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], | |
360 | ||
361 | # S8 | |
362 | [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, | |
363 | 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, | |
364 | 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, | |
365 | 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], | |
366 | ] | |
367 | ||
368 | ||
369 | # 32-bit permutation function P used on the output of the S-boxes | |
370 | __p = [ | |
371 | 15, 6, 19, 20, 28, 11, | |
372 | 27, 16, 0, 14, 22, 25, | |
373 | 4, 17, 30, 9, 1, 7, | |
374 | 23,13, 31, 26, 2, 8, | |
375 | 18, 12, 29, 5, 21, 10, | |
376 | 3, 24 | |
377 | ] | |
378 | ||
379 | # final permutation IP^-1 | |
380 | __fp = [ | |
381 | 39, 7, 47, 15, 55, 23, 63, 31, | |
382 | 38, 6, 46, 14, 54, 22, 62, 30, | |
383 | 37, 5, 45, 13, 53, 21, 61, 29, | |
384 | 36, 4, 44, 12, 52, 20, 60, 28, | |
385 | 35, 3, 43, 11, 51, 19, 59, 27, | |
386 | 34, 2, 42, 10, 50, 18, 58, 26, | |
387 | 33, 1, 41, 9, 49, 17, 57, 25, | |
388 | 32, 0, 40, 8, 48, 16, 56, 24 | |
389 | ] | |
390 | ||
391 | # Type of crypting being done | |
392 | ENCRYPT = 0x00 | |
393 | DECRYPT = 0x01 | |
394 | ||
395 | # Initialisation | |
396 | def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL): | |
397 | # Sanity checking of arguments. | |
398 | if len(key) != 8: | |
399 | raise ValueError("Invalid DES key size. Key must be exactly 8 bytes long.") | |
400 | _baseDes.__init__(self, mode, IV, pad, padmode) | |
401 | self.key_size = 8 | |
402 | ||
403 | self.L = [] | |
404 | self.R = [] | |
405 | self.Kn = [ [0] * 48 ] * 16 # 16 48-bit keys (K1 - K16) | |
406 | self.final = [] | |
407 | ||
408 | self.setKey(key) | |
409 | ||
410 | def setKey(self, key): | |
411 | """Will set the crypting key for this object. Must be 8 bytes.""" | |
412 | _baseDes.setKey(self, key) | |
413 | self.__create_sub_keys() | |
414 | ||
415 | def __String_to_BitList(self, data): | |
416 | """Turn the string data, into a list of bits (1, 0)'s""" | |
417 | if _pythonMajorVersion < 3: | |
418 | # Turn the strings into integers. Python 3 uses a bytes | |
419 | # class, which already has this behaviour. | |
420 | data = [ord(c) for c in data] | |
421 | l = len(data) * 8 | |
422 | result = [0] * l | |
423 | pos = 0 | |
424 | for ch in data: | |
425 | i = 7 | |
426 | while i >= 0: | |
427 | if ch & (1 << i) != 0: | |
428 | result[pos] = 1 | |
429 | else: | |
430 | result[pos] = 0 | |
431 | pos += 1 | |
432 | i -= 1 | |
433 | ||
434 | return result | |
435 | ||
436 | def __BitList_to_String(self, data): | |
437 | """Turn the list of bits -> data, into a string""" | |
438 | result = [] | |
439 | pos = 0 | |
440 | c = 0 | |
441 | while pos < len(data): | |
442 | c += data[pos] << (7 - (pos % 8)) | |
443 | if (pos % 8) == 7: | |
444 | result.append(c) | |
445 | c = 0 | |
446 | pos += 1 | |
447 | ||
448 | if _pythonMajorVersion < 3: | |
449 | return ''.join([ chr(c) for c in result ]) | |
450 | else: | |
451 | return bytes(result) | |
452 | ||
453 | def __permutate(self, table, block): | |
454 | """Permutate this block with the specified table""" | |
455 | return list(map(lambda x: block[x], table)) | |
456 | ||
457 | # Transform the secret key, so that it is ready for data processing | |
458 | # Create the 16 subkeys, K[1] - K[16] | |
459 | def __create_sub_keys(self): | |
460 | """Create the 16 subkeys K[1] to K[16] from the given key""" | |
461 | key = self.__permutate(des.__pc1, self.__String_to_BitList(self.getKey())) | |
462 | i = 0 | |
463 | # Split into Left and Right sections | |
464 | self.L = key[:28] | |
465 | self.R = key[28:] | |
466 | while i < 16: | |
467 | j = 0 | |
468 | # Perform circular left shifts | |
469 | while j < des.__left_rotations[i]: | |
470 | self.L.append(self.L[0]) | |
471 | del self.L[0] | |
472 | ||
473 | self.R.append(self.R[0]) | |
474 | del self.R[0] | |
475 | ||
476 | j += 1 | |
477 | ||
478 | # Create one of the 16 subkeys through pc2 permutation | |
479 | self.Kn[i] = self.__permutate(des.__pc2, self.L + self.R) | |
480 | ||
481 | i += 1 | |
482 | ||
483 | # Main part of the encryption algorithm, the number cruncher :) | |
484 | def __des_crypt(self, block, crypt_type): | |
485 | """Crypt the block of data through DES bit-manipulation""" | |
486 | block = self.__permutate(des.__ip, block) | |
487 | self.L = block[:32] | |
488 | self.R = block[32:] | |
489 | ||
490 | # Encryption starts from Kn[1] through to Kn[16] | |
491 | if crypt_type == des.ENCRYPT: | |
492 | iteration = 0 | |
493 | iteration_adjustment = 1 | |
494 | # Decryption starts from Kn[16] down to Kn[1] | |
495 | else: | |
496 | iteration = 15 | |
497 | iteration_adjustment = -1 | |
498 | ||
499 | i = 0 | |
500 | while i < 16: | |
501 | # Make a copy of R[i-1], this will later become L[i] | |
502 | tempR = self.R[:] | |
503 | ||
504 | # Permutate R[i - 1] to start creating R[i] | |
505 | self.R = self.__permutate(des.__expansion_table, self.R) | |
506 | ||
507 | # Exclusive or R[i - 1] with K[i], create B[1] to B[8] whilst here | |
508 | self.R = list(map(lambda x, y: x ^ y, self.R, self.Kn[iteration])) | |
509 | B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]] | |
510 | # Optimization: Replaced below commented code with above | |
511 | #j = 0 | |
512 | #B = [] | |
513 | #while j < len(self.R): | |
514 | # self.R[j] = self.R[j] ^ self.Kn[iteration][j] | |
515 | # j += 1 | |
516 | # if j % 6 == 0: | |
517 | # B.append(self.R[j-6:j]) | |
518 | ||
519 | # Permutate B[1] to B[8] using the S-Boxes | |
520 | j = 0 | |
521 | Bn = [0] * 32 | |
522 | pos = 0 | |
523 | while j < 8: | |
524 | # Work out the offsets | |
525 | m = (B[j][0] << 1) + B[j][5] | |
526 | n = (B[j][1] << 3) + (B[j][2] << 2) + (B[j][3] << 1) + B[j][4] | |
527 | ||
528 | # Find the permutation value | |
529 | v = des.__sbox[j][(m << 4) + n] | |
530 | ||
531 | # Turn value into bits, add it to result: Bn | |
532 | Bn[pos] = (v & 8) >> 3 | |
533 | Bn[pos + 1] = (v & 4) >> 2 | |
534 | Bn[pos + 2] = (v & 2) >> 1 | |
535 | Bn[pos + 3] = v & 1 | |
536 | ||
537 | pos += 4 | |
538 | j += 1 | |
539 | ||
540 | # Permutate the concatination of B[1] to B[8] (Bn) | |
541 | self.R = self.__permutate(des.__p, Bn) | |
542 | ||
543 | # Xor with L[i - 1] | |
544 | self.R = list(map(lambda x, y: x ^ y, self.R, self.L)) | |
545 | # Optimization: This now replaces the below commented code | |
546 | #j = 0 | |
547 | #while j < len(self.R): | |
548 | # self.R[j] = self.R[j] ^ self.L[j] | |
549 | # j += 1 | |
550 | ||
551 | # L[i] becomes R[i - 1] | |
552 | self.L = tempR | |
553 | ||
554 | i += 1 | |
555 | iteration += iteration_adjustment | |
556 | ||
557 | # Final permutation of R[16]L[16] | |
558 | self.final = self.__permutate(des.__fp, self.R + self.L) | |
559 | return self.final | |
560 | ||
561 | ||
562 | # Data to be encrypted/decrypted | |
563 | def crypt(self, data, crypt_type): | |
564 | """Crypt the data in blocks, running it through des_crypt()""" | |
565 | ||
566 | # Error check the data | |
567 | if not data: | |
568 | return '' | |
569 | if len(data) % self.block_size != 0: | |
570 | if crypt_type == des.DECRYPT: # Decryption must work on 8 byte blocks | |
571 | raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n.") | |
572 | if not self.getPadding(): | |
573 | raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n. Try setting the optional padding character") | |
574 | else: | |
575 | data += (self.block_size - (len(data) % self.block_size)) * self.getPadding() | |
576 | # print "Len of data: %f" % (len(data) / self.block_size) | |
577 | ||
578 | if self.getMode() == CBC: | |
579 | if self.getIV(): | |
580 | iv = self.__String_to_BitList(self.getIV()) | |
581 | else: | |
582 | raise ValueError("For CBC mode, you must supply the Initial Value (IV) for ciphering") | |
583 | ||
584 | # Split the data into blocks, crypting each one seperately | |
585 | i = 0 | |
586 | dict = {} | |
587 | result = [] | |
588 | #cached = 0 | |
589 | #lines = 0 | |
590 | while i < len(data): | |
591 | # Test code for caching encryption results | |
592 | #lines += 1 | |
593 | #if dict.has_key(data[i:i+8]): | |
594 | #print "Cached result for: %s" % data[i:i+8] | |
595 | # cached += 1 | |
596 | # result.append(dict[data[i:i+8]]) | |
597 | # i += 8 | |
598 | # continue | |
599 | ||
600 | block = self.__String_to_BitList(data[i:i+8]) | |
601 | ||
602 | # Xor with IV if using CBC mode | |
603 | if self.getMode() == CBC: | |
604 | if crypt_type == des.ENCRYPT: | |
605 | block = list(map(lambda x, y: x ^ y, block, iv)) | |
606 | #j = 0 | |
607 | #while j < len(block): | |
608 | # block[j] = block[j] ^ iv[j] | |
609 | # j += 1 | |
610 | ||
611 | processed_block = self.__des_crypt(block, crypt_type) | |
612 | ||
613 | if crypt_type == des.DECRYPT: | |
614 | processed_block = list(map(lambda x, y: x ^ y, processed_block, iv)) | |
615 | #j = 0 | |
616 | #while j < len(processed_block): | |
617 | # processed_block[j] = processed_block[j] ^ iv[j] | |
618 | # j += 1 | |
619 | iv = block | |
620 | else: | |
621 | iv = processed_block | |
622 | else: | |
623 | processed_block = self.__des_crypt(block, crypt_type) | |
624 | ||
625 | ||
626 | # Add the resulting crypted block to our list | |
627 | #d = self.__BitList_to_String(processed_block) | |
628 | #result.append(d) | |
629 | result.append(self.__BitList_to_String(processed_block)) | |
630 | #dict[data[i:i+8]] = d | |
631 | i += 8 | |
632 | ||
633 | # print "Lines: %d, cached: %d" % (lines, cached) | |
634 | ||
635 | # Return the full crypted string | |
636 | if _pythonMajorVersion < 3: | |
637 | return ''.join(result) | |
638 | else: | |
639 | return bytes.fromhex('').join(result) | |
640 | ||
641 | def encrypt(self, data, pad=None, padmode=None): | |
642 | """encrypt(data, [pad], [padmode]) -> bytes | |
643 | ||
644 | data : Bytes to be encrypted | |
645 | pad : Optional argument for encryption padding. Must only be one byte | |
646 | padmode : Optional argument for overriding the padding mode. | |
647 | ||
648 | The data must be a multiple of 8 bytes and will be encrypted | |
649 | with the already specified key. Data does not have to be a | |
650 | multiple of 8 bytes if the padding character is supplied, or | |
651 | the padmode is set to PAD_PKCS5, as bytes will then added to | |
652 | ensure the be padded data is a multiple of 8 bytes. | |
653 | """ | |
654 | data = self._guardAgainstUnicode(data) | |
655 | if pad is not None: | |
656 | pad = self._guardAgainstUnicode(pad) | |
657 | data = self._padData(data, pad, padmode) | |
658 | return self.crypt(data, des.ENCRYPT) | |
659 | ||
660 | def decrypt(self, data, pad=None, padmode=None): | |
661 | """decrypt(data, [pad], [padmode]) -> bytes | |
662 | ||
663 | data : Bytes to be encrypted | |
664 | pad : Optional argument for decryption padding. Must only be one byte | |
665 | padmode : Optional argument for overriding the padding mode. | |
666 | ||
667 | The data must be a multiple of 8 bytes and will be decrypted | |
668 | with the already specified key. In PAD_NORMAL mode, if the | |
669 | optional padding character is supplied, then the un-encrypted | |
670 | data will have the padding characters removed from the end of | |
671 | the bytes. This pad removal only occurs on the last 8 bytes of | |
672 | the data (last data block). In PAD_PKCS5 mode, the special | |
673 | padding end markers will be removed from the data after decrypting. | |
674 | """ | |
675 | data = self._guardAgainstUnicode(data) | |
676 | if pad is not None: | |
677 | pad = self._guardAgainstUnicode(pad) | |
678 | data = self.crypt(data, des.DECRYPT) | |
679 | return self._unpadData(data, pad, padmode) | |
680 | ||
681 | ||
682 | ||
683 | ############################################################################# | |
684 | # Triple DES # | |
685 | ############################################################################# | |
686 | class triple_des(_baseDes): | |
687 | """Triple DES encryption/decrytpion class | |
688 | ||
689 | This algorithm uses the DES-EDE3 (when a 24 byte key is supplied) or | |
690 | the DES-EDE2 (when a 16 byte key is supplied) encryption methods. | |
691 | Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes. | |
692 | ||
693 | pyDes.des(key, [mode], [IV]) | |
694 | ||
695 | key -> Bytes containing the encryption key, must be either 16 or | |
696 | 24 bytes long | |
697 | mode -> Optional argument for encryption type, can be either pyDes.ECB | |
698 | (Electronic Code Book), pyDes.CBC (Cypher Block Chaining) | |
699 | IV -> Optional Initial Value bytes, must be supplied if using CBC mode. | |
700 | Must be 8 bytes in length. | |
701 | pad -> Optional argument, set the pad character (PAD_NORMAL) to use | |
702 | during all encrypt/decrpt operations done with this instance. | |
703 | padmode -> Optional argument, set the padding mode (PAD_NORMAL or | |
704 | PAD_PKCS5) to use during all encrypt/decrpt operations done | |
705 | with this instance. | |
706 | """ | |
707 | def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL): | |
708 | _baseDes.__init__(self, mode, IV, pad, padmode) | |
709 | self.setKey(key) | |
710 | ||
711 | def setKey(self, key): | |
712 | """Will set the crypting key for this object. Either 16 or 24 bytes long.""" | |
713 | self.key_size = 24 # Use DES-EDE3 mode | |
714 | if len(key) != self.key_size: | |
715 | if len(key) == 16: # Use DES-EDE2 mode | |
716 | self.key_size = 16 | |
717 | else: | |
718 | raise ValueError("Invalid triple DES key size. Key must be either 16 or 24 bytes long") | |
719 | if self.getMode() == CBC: | |
720 | if not self.getIV(): | |
721 | # Use the first 8 bytes of the key | |
722 | self._iv = key[:self.block_size] | |
723 | if len(self.getIV()) != self.block_size: | |
724 | raise ValueError("Invalid IV, must be 8 bytes in length") | |
725 | self.__key1 = des(key[:8], self._mode, self._iv, | |
726 | self._padding, self._padmode) | |
727 | self.__key2 = des(key[8:16], self._mode, self._iv, | |
728 | self._padding, self._padmode) | |
729 | if self.key_size == 16: | |
730 | self.__key3 = self.__key1 | |
731 | else: | |
732 | self.__key3 = des(key[16:], self._mode, self._iv, | |
733 | self._padding, self._padmode) | |
734 | _baseDes.setKey(self, key) | |
735 | ||
736 | # Override setter methods to work on all 3 keys. | |
737 | ||
738 | def setMode(self, mode): | |
739 | """Sets the type of crypting mode, pyDes.ECB or pyDes.CBC""" | |
740 | _baseDes.setMode(self, mode) | |
741 | for key in (self.__key1, self.__key2, self.__key3): | |
742 | key.setMode(mode) | |
743 | ||
744 | def setPadding(self, pad): | |
745 | """setPadding() -> bytes of length 1. Padding character.""" | |
746 | _baseDes.setPadding(self, pad) | |
747 | for key in (self.__key1, self.__key2, self.__key3): | |
748 | key.setPadding(pad) | |
749 | ||
750 | def setPadMode(self, mode): | |
751 | """Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5""" | |
752 | _baseDes.setPadMode(self, mode) | |
753 | for key in (self.__key1, self.__key2, self.__key3): | |
754 | key.setPadMode(mode) | |
755 | ||
756 | def setIV(self, IV): | |
757 | """Will set the Initial Value, used in conjunction with CBC mode""" | |
758 | _baseDes.setIV(self, IV) | |
759 | for key in (self.__key1, self.__key2, self.__key3): | |
760 | key.setIV(IV) | |
761 | ||
762 | def encrypt(self, data, pad=None, padmode=None): | |
763 | """encrypt(data, [pad], [padmode]) -> bytes | |
764 | ||
765 | data : bytes to be encrypted | |
766 | pad : Optional argument for encryption padding. Must only be one byte | |
767 | padmode : Optional argument for overriding the padding mode. | |
768 | ||
769 | The data must be a multiple of 8 bytes and will be encrypted | |
770 | with the already specified key. Data does not have to be a | |
771 | multiple of 8 bytes if the padding character is supplied, or | |
772 | the padmode is set to PAD_PKCS5, as bytes will then added to | |
773 | ensure the be padded data is a multiple of 8 bytes. | |
774 | """ | |
775 | ENCRYPT = des.ENCRYPT | |
776 | DECRYPT = des.DECRYPT | |
777 | data = self._guardAgainstUnicode(data) | |
778 | if pad is not None: | |
779 | pad = self._guardAgainstUnicode(pad) | |
780 | # Pad the data accordingly. | |
781 | data = self._padData(data, pad, padmode) | |
782 | if self.getMode() == CBC: | |
783 | self.__key1.setIV(self.getIV()) | |
784 | self.__key2.setIV(self.getIV()) | |
785 | self.__key3.setIV(self.getIV()) | |
786 | i = 0 | |
787 | result = [] | |
788 | while i < len(data): | |
789 | block = self.__key1.crypt(data[i:i+8], ENCRYPT) | |
790 | block = self.__key2.crypt(block, DECRYPT) | |
791 | block = self.__key3.crypt(block, ENCRYPT) | |
792 | self.__key1.setIV(block) | |
793 | self.__key2.setIV(block) | |
794 | self.__key3.setIV(block) | |
795 | result.append(block) | |
796 | i += 8 | |
797 | if _pythonMajorVersion < 3: | |
798 | return ''.join(result) | |
799 | else: | |
800 | return bytes.fromhex('').join(result) | |
801 | else: | |
802 | data = self.__key1.crypt(data, ENCRYPT) | |
803 | data = self.__key2.crypt(data, DECRYPT) | |
804 | return self.__key3.crypt(data, ENCRYPT) | |
805 | ||
806 | def decrypt(self, data, pad=None, padmode=None): | |
807 | """decrypt(data, [pad], [padmode]) -> bytes | |
808 | ||
809 | data : bytes to be encrypted | |
810 | pad : Optional argument for decryption padding. Must only be one byte | |
811 | padmode : Optional argument for overriding the padding mode. | |
812 | ||
813 | The data must be a multiple of 8 bytes and will be decrypted | |
814 | with the already specified key. In PAD_NORMAL mode, if the | |
815 | optional padding character is supplied, then the un-encrypted | |
816 | data will have the padding characters removed from the end of | |
817 | the bytes. This pad removal only occurs on the last 8 bytes of | |
818 | the data (last data block). In PAD_PKCS5 mode, the special | |
819 | padding end markers will be removed from the data after | |
820 | decrypting, no pad character is required for PAD_PKCS5. | |
821 | """ | |
822 | ENCRYPT = des.ENCRYPT | |
823 | DECRYPT = des.DECRYPT | |
824 | data = self._guardAgainstUnicode(data) | |
825 | if pad is not None: | |
826 | pad = self._guardAgainstUnicode(pad) | |
827 | if self.getMode() == CBC: | |
828 | self.__key1.setIV(self.getIV()) | |
829 | self.__key2.setIV(self.getIV()) | |
830 | self.__key3.setIV(self.getIV()) | |
831 | i = 0 | |
832 | result = [] | |
833 | while i < len(data): | |
834 | iv = data[i:i+8] | |
835 | block = self.__key3.crypt(iv, DECRYPT) | |
836 | block = self.__key2.crypt(block, ENCRYPT) | |
837 | block = self.__key1.crypt(block, DECRYPT) | |
838 | self.__key1.setIV(iv) | |
839 | self.__key2.setIV(iv) | |
840 | self.__key3.setIV(iv) | |
841 | result.append(block) | |
842 | i += 8 | |
843 | if _pythonMajorVersion < 3: | |
844 | data = ''.join(result) | |
845 | else: | |
846 | data = bytes.fromhex('').join(result) | |
847 | else: | |
848 | data = self.__key3.crypt(data, DECRYPT) | |
849 | data = self.__key2.crypt(data, ENCRYPT) | |
850 | data = self.__key1.crypt(data, DECRYPT) | |
851 | return self._unpadData(data, pad, padmode) |
0 | # Makefile for Sphinx documentation | |
1 | # | |
2 | ||
3 | # You can set these variables from the command line. | |
4 | SPHINXOPTS = | |
5 | SPHINXBUILD = sphinx-build | |
6 | PAPER = | |
7 | BUILDDIR = ../docs | |
8 | ||
9 | # Internal variables. | |
10 | PAPEROPT_a4 = -D latex_paper_size=a4 | |
11 | PAPEROPT_letter = -D latex_paper_size=letter | |
12 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source | |
13 | # the i18n builder cannot share the environment and doctrees with the others | |
14 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source | |
15 | ||
16 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext | |
17 | ||
18 | help: | |
19 | @echo "Please use \`make <target>' where <target> is one of" | |
20 | @echo " html to make standalone HTML files" | |
21 | @echo " dirhtml to make HTML files named index.html in directories" | |
22 | @echo " singlehtml to make a single large HTML file" | |
23 | @echo " pickle to make pickle files" | |
24 | @echo " json to make JSON files" | |
25 | @echo " htmlhelp to make HTML files and a HTML help project" | |
26 | @echo " qthelp to make HTML files and a qthelp project" | |
27 | @echo " devhelp to make HTML files and a Devhelp project" | |
28 | @echo " epub to make an epub" | |
29 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" | |
30 | @echo " latexpdf to make LaTeX files and run them through pdflatex" | |
31 | @echo " text to make text files" | |
32 | @echo " man to make manual pages" | |
33 | @echo " texinfo to make Texinfo files" | |
34 | @echo " info to make Texinfo files and run them through makeinfo" | |
35 | @echo " gettext to make PO message catalogs" | |
36 | @echo " changes to make an overview of all changed/added/deprecated items" | |
37 | @echo " linkcheck to check all external links for integrity" | |
38 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" | |
39 | ||
40 | clean: | |
41 | -rm -rf $(BUILDDIR)/* | |
42 | ||
43 | html: | |
44 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html | |
45 | @echo | |
46 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." | |
47 | ||
48 | dirhtml: | |
49 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml | |
50 | @echo | |
51 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." | |
52 | ||
53 | singlehtml: | |
54 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml | |
55 | @echo | |
56 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." | |
57 | ||
58 | pickle: | |
59 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle | |
60 | @echo | |
61 | @echo "Build finished; now you can process the pickle files." | |
62 | ||
63 | json: | |
64 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json | |
65 | @echo | |
66 | @echo "Build finished; now you can process the JSON files." | |
67 | ||
68 | htmlhelp: | |
69 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp | |
70 | @echo | |
71 | @echo "Build finished; now you can run HTML Help Workshop with the" \ | |
72 | ".hhp project file in $(BUILDDIR)/htmlhelp." | |
73 | ||
74 | qthelp: | |
75 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp | |
76 | @echo | |
77 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ | |
78 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" | |
79 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pysmb.qhcp" | |
80 | @echo "To view the help file:" | |
81 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pysmb.qhc" | |
82 | ||
83 | devhelp: | |
84 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp | |
85 | @echo | |
86 | @echo "Build finished." | |
87 | @echo "To view the help file:" | |
88 | @echo "# mkdir -p $$HOME/.local/share/devhelp/pysmb" | |
89 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pysmb" | |
90 | @echo "# devhelp" | |
91 | ||
92 | epub: | |
93 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub | |
94 | @echo | |
95 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." | |
96 | ||
97 | latex: | |
98 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | |
99 | @echo | |
100 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." | |
101 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ | |
102 | "(use \`make latexpdf' here to do that automatically)." | |
103 | ||
104 | latexpdf: | |
105 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | |
106 | @echo "Running LaTeX files through pdflatex..." | |
107 | $(MAKE) -C $(BUILDDIR)/latex all-pdf | |
108 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." | |
109 | ||
110 | text: | |
111 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text | |
112 | @echo | |
113 | @echo "Build finished. The text files are in $(BUILDDIR)/text." | |
114 | ||
115 | man: | |
116 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man | |
117 | @echo | |
118 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." | |
119 | ||
120 | texinfo: | |
121 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo | |
122 | @echo | |
123 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." | |
124 | @echo "Run \`make' in that directory to run these through makeinfo" \ | |
125 | "(use \`make info' here to do that automatically)." | |
126 | ||
127 | info: | |
128 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo | |
129 | @echo "Running Texinfo files through makeinfo..." | |
130 | make -C $(BUILDDIR)/texinfo info | |
131 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." | |
132 | ||
133 | gettext: | |
134 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale | |
135 | @echo | |
136 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." | |
137 | ||
138 | changes: | |
139 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes | |
140 | @echo | |
141 | @echo "The overview file is in $(BUILDDIR)/changes." | |
142 | ||
143 | linkcheck: | |
144 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck | |
145 | @echo | |
146 | @echo "Link check complete; look for any errors in the above output " \ | |
147 | "or in $(BUILDDIR)/linkcheck/output.txt." | |
148 | ||
149 | doctest: | |
150 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest | |
151 | @echo "Testing of doctests in the sources finished, look at the " \ | |
152 | "results in $(BUILDDIR)/doctest/output.txt." |
0 | @ECHO OFF | |
1 | ||
2 | REM Command file for Sphinx documentation | |
3 | ||
4 | if "%SPHINXBUILD%" == "" ( | |
5 | set SPHINXBUILD=sphinx-build | |
6 | ) | |
7 | set BUILDDIR=build | |
8 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source | |
9 | set I18NSPHINXOPTS=%SPHINXOPTS% source | |
10 | if NOT "%PAPER%" == "" ( | |
11 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% | |
12 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% | |
13 | ) | |
14 | ||
15 | if "%1" == "" goto help | |
16 | ||
17 | if "%1" == "help" ( | |
18 | :help | |
19 | echo.Please use `make ^<target^>` where ^<target^> is one of | |
20 | echo. html to make standalone HTML files | |
21 | echo. dirhtml to make HTML files named index.html in directories | |
22 | echo. singlehtml to make a single large HTML file | |
23 | echo. pickle to make pickle files | |
24 | echo. json to make JSON files | |
25 | echo. htmlhelp to make HTML files and a HTML help project | |
26 | echo. qthelp to make HTML files and a qthelp project | |
27 | echo. devhelp to make HTML files and a Devhelp project | |
28 | echo. epub to make an epub | |
29 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter | |
30 | echo. text to make text files | |
31 | echo. man to make manual pages | |
32 | echo. texinfo to make Texinfo files | |
33 | echo. gettext to make PO message catalogs | |
34 | echo. changes to make an overview over all changed/added/deprecated items | |
35 | echo. linkcheck to check all external links for integrity | |
36 | echo. doctest to run all doctests embedded in the documentation if enabled | |
37 | goto end | |
38 | ) | |
39 | ||
40 | if "%1" == "clean" ( | |
41 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i | |
42 | del /q /s %BUILDDIR%\* | |
43 | goto end | |
44 | ) | |
45 | ||
46 | if "%1" == "html" ( | |
47 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html | |
48 | if errorlevel 1 exit /b 1 | |
49 | echo. | |
50 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. | |
51 | goto end | |
52 | ) | |
53 | ||
54 | if "%1" == "dirhtml" ( | |
55 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml | |
56 | if errorlevel 1 exit /b 1 | |
57 | echo. | |
58 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. | |
59 | goto end | |
60 | ) | |
61 | ||
62 | if "%1" == "singlehtml" ( | |
63 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml | |
64 | if errorlevel 1 exit /b 1 | |
65 | echo. | |
66 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. | |
67 | goto end | |
68 | ) | |
69 | ||
70 | if "%1" == "pickle" ( | |
71 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle | |
72 | if errorlevel 1 exit /b 1 | |
73 | echo. | |
74 | echo.Build finished; now you can process the pickle files. | |
75 | goto end | |
76 | ) | |
77 | ||
78 | if "%1" == "json" ( | |
79 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json | |
80 | if errorlevel 1 exit /b 1 | |
81 | echo. | |
82 | echo.Build finished; now you can process the JSON files. | |
83 | goto end | |
84 | ) | |
85 | ||
86 | if "%1" == "htmlhelp" ( | |
87 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp | |
88 | if errorlevel 1 exit /b 1 | |
89 | echo. | |
90 | echo.Build finished; now you can run HTML Help Workshop with the ^ | |
91 | .hhp project file in %BUILDDIR%/htmlhelp. | |
92 | goto end | |
93 | ) | |
94 | ||
95 | if "%1" == "qthelp" ( | |
96 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp | |
97 | if errorlevel 1 exit /b 1 | |
98 | echo. | |
99 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ | |
100 | .qhcp project file in %BUILDDIR%/qthelp, like this: | |
101 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pysmb.qhcp | |
102 | echo.To view the help file: | |
103 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pysmb.ghc | |
104 | goto end | |
105 | ) | |
106 | ||
107 | if "%1" == "devhelp" ( | |
108 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp | |
109 | if errorlevel 1 exit /b 1 | |
110 | echo. | |
111 | echo.Build finished. | |
112 | goto end | |
113 | ) | |
114 | ||
115 | if "%1" == "epub" ( | |
116 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub | |
117 | if errorlevel 1 exit /b 1 | |
118 | echo. | |
119 | echo.Build finished. The epub file is in %BUILDDIR%/epub. | |
120 | goto end | |
121 | ) | |
122 | ||
123 | if "%1" == "latex" ( | |
124 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex | |
125 | if errorlevel 1 exit /b 1 | |
126 | echo. | |
127 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. | |
128 | goto end | |
129 | ) | |
130 | ||
131 | if "%1" == "text" ( | |
132 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text | |
133 | if errorlevel 1 exit /b 1 | |
134 | echo. | |
135 | echo.Build finished. The text files are in %BUILDDIR%/text. | |
136 | goto end | |
137 | ) | |
138 | ||
139 | if "%1" == "man" ( | |
140 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man | |
141 | if errorlevel 1 exit /b 1 | |
142 | echo. | |
143 | echo.Build finished. The manual pages are in %BUILDDIR%/man. | |
144 | goto end | |
145 | ) | |
146 | ||
147 | if "%1" == "texinfo" ( | |
148 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo | |
149 | if errorlevel 1 exit /b 1 | |
150 | echo. | |
151 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. | |
152 | goto end | |
153 | ) | |
154 | ||
155 | if "%1" == "gettext" ( | |
156 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale | |
157 | if errorlevel 1 exit /b 1 | |
158 | echo. | |
159 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. | |
160 | goto end | |
161 | ) | |
162 | ||
163 | if "%1" == "changes" ( | |
164 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes | |
165 | if errorlevel 1 exit /b 1 | |
166 | echo. | |
167 | echo.The overview file is in %BUILDDIR%/changes. | |
168 | goto end | |
169 | ) | |
170 | ||
171 | if "%1" == "linkcheck" ( | |
172 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck | |
173 | if errorlevel 1 exit /b 1 | |
174 | echo. | |
175 | echo.Link check complete; look for any errors in the above output ^ | |
176 | or in %BUILDDIR%/linkcheck/output.txt. | |
177 | goto end | |
178 | ) | |
179 | ||
180 | if "%1" == "doctest" ( | |
181 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest | |
182 | if errorlevel 1 exit /b 1 | |
183 | echo. | |
184 | echo.Testing of doctests in the sources finished, look at the ^ | |
185 | results in %BUILDDIR%/doctest/output.txt. | |
186 | goto end | |
187 | ) | |
188 | ||
189 | :end |
0 | ||
1 | NBNSProtocol Class | |
2 | ================== | |
3 | ||
4 | pysmb has a *NBNSProtocol* implementation for Twisted framework. | |
5 | This allows you to perform name query asynchronously without having your application to block and wait for the results. | |
6 | ||
7 | In your project, | |
8 | 1. Create a NBNSProtocol instance. | |
9 | 2. Just call *queryName* method which will return a *Deferred* instance. Add your callback function to the *Deferred* instance via *addCallback* method to receive the results of the name query. | |
10 | 3. When you are done with the NBNSProtocol instance, call its <NBNSProtocol instance>.transport.stopListening method to remove this instance from the reactor. | |
11 | ||
12 | .. autoclass:: nmb.NetBIOSProtocol.NBNSProtocol | |
13 | :members: | |
14 | :special-members: | |
15 | ||
16 | .. autoclass:: nmb.NetBIOSProtocol.NetBIOSTimeout | |
17 | :members: |
0 | ||
1 | NetBIOS class | |
2 | ============= | |
3 | ||
4 | To use the NetBIOS class in your application, | |
5 | 1. Create a new NetBIOS instance | |
6 | 2. Call *queryName* method for each name you wish to query. The method will block until a reply is received from the remote SMB/CIFS service, or until timeout. | |
7 | 3. When you are done, call *close* method to release the underlying resources. | |
8 | ||
9 | .. autoclass:: nmb.NetBIOS.NetBIOS | |
10 | :members: | |
11 | :special-members: |
0 | ||
1 | SMBConnection Class | |
2 | =================== | |
3 | ||
4 | The SMBConnection is suitable for developers who wish to use pysmb to perform file operations with a remote SMB/CIFS server sequentially. | |
5 | ||
6 | Each file operation method, when invoked, will block and return after it has completed or has encountered an error. | |
7 | ||
8 | Caveats | |
9 | ------- | |
10 | ||
11 | * It is not meant to be used asynchronously. | |
12 | * A single *SMBConnection* instance should not be used to perform more than one operation concurrently at the same time. | |
13 | * Do not keep a *SMBConnection* instance "idle" for too long, i.e. keeping a *SMBConnection* instance but not using it. | |
14 | Most SMB/CIFS servers have some sort of keepalive mechanism and impose a timeout limit. | |
15 | If the clients fail to respond within the timeout limit, the SMB/CIFS server may disconnect the client. | |
16 | ||
17 | .. autoclass:: smb.SMBConnection.SMBConnection | |
18 | :members: | |
19 | :special-members: |
0 | ||
1 | SMBProtocolFactory Class | |
2 | ======================== | |
3 | ||
4 | For those who want to utilize pysmb in Twisted framework, pysmb has a *smb.SMBProtocol.SMBProtocol* implementation. | |
5 | In most cases, you do not need to touch or import the *SMBProtocol* directly. All the SMB functionalities are exposed in the *SMBProtocolFactory*. | |
6 | ||
7 | In your project, | |
8 | 1. Create a new class and subclass *SMBProtocolFactory*. | |
9 | 2. Override the *SMBProtocolFactory.onAuthOK* and *SMBProtocolFactory.onAuthFailed* instance methods to provide your own post-authenthentication handling. | |
10 | Once *SMBProtocolFactory.onAuthOK* has been called by pymsb internals, your application is ready to communicate with the remote SMB/CIFS service through | |
11 | the *SMBProtocolFactory* public methods such as *SMBProtocolFactory.storeFile*, *SMBProtocolFactory.retrieveFile*, etc. | |
12 | 3. When you want to disconnect from the remote SMB/CIFS server, just call *SMBProtocolFactory.closeConnection* method. | |
13 | ||
14 | All the *SMBProtocolFactory* public methods that provide file functionlities will return a *twisted.internet.defer.Deferred* instance. | |
15 | A :doc:`NotReadyError<smb_exceptions>` exception is raised when the underlying SMB is not authenticated. | |
16 | If the underlying SMB connection has been terminated, a :doc:`NotConnectedError<smb_exceptions>` exception is raised. | |
17 | ||
18 | All the file operation methods in *SMBProtocolFactory* class accept a *timeout* parameter. This parameter specifies the time limit where pysmb will wait for the | |
19 | entire file operation (except *storeFile* and *retrieveFile* methods) to complete. If the file operation fails to complete within the timeout period, the returned | |
20 | *Deferred* instance's *errback* method will be called with a *SMBTimeout* exception. | |
21 | ||
22 | If you are interested in learning the results of the operation or to know when the operation has completed, you should | |
23 | add a handling method to the returned *Deferred* instance via *Deferred.addCallback*. If the file operation fails, the *Deferred.errback* function will be called | |
24 | with an :doc:`OperationFailure<smb_exceptions>`; on timeout, it will be called with a :doc:`SMBTimeout<smb_exceptions>`. | |
25 | ||
26 | Caveats | |
27 | ------- | |
28 | ||
29 | * A new factory instance must be created for each SMB connection to the remote SMB/CIFS service. Avoid reusing the same factory instance for more than one SMB connection. | |
30 | * The remote SMB/CIFS server usually imposes a limit of the number of concurrent file operations for each client. For example, to transfer a thousand files, you may need to setup a queue in your application and call *storeFile* or *retrieveFile* in batches. | |
31 | * The *timeout* parameter in the file operation methods are not precise; it is accurate to within 1 second interval, i.e. with a timeout of 0.5 sec, pysmb might raise | |
32 | *SMBTimeout* exception after 1.5 sec. | |
33 | ||
34 | .. autoclass:: smb.SMBProtocol.SMBProtocolFactory | |
35 | :members: | |
36 | :special-members: |
0 | ||
1 | SMB Exceptions | |
2 | ============== | |
3 | ||
4 | .. autoclass:: smb.base.SMBTimeout | |
5 | :members: | |
6 | ||
7 | .. autoclass:: smb.base.NotReadyError | |
8 | :members: | |
9 | ||
10 | .. autoclass:: smb.base.NotConnectedError | |
11 | :members: | |
12 | ||
13 | .. autoclass:: smb.smb_structs.UnsupportedFeature | |
14 | :members: | |
15 | ||
16 | .. autoclass:: smb.smb_structs.ProtocolError | |
17 | :members: | |
18 | ||
19 | .. autoclass:: smb.smb_structs.OperationFailure | |
20 | :members: |
0 | # -*- coding: utf-8 -*- | |
1 | # | |
2 | # pysmb documentation build configuration file, created by | |
3 | # sphinx-quickstart on Sun Dec 18 15:54:40 2011. | |
4 | # | |
5 | # This file is execfile()d with the current directory set to its containing dir. | |
6 | # | |
7 | # Note that not all possible configuration values are present in this | |
8 | # autogenerated file. | |
9 | # | |
10 | # All configuration values have a default; values that are commented out | |
11 | # serve to show the default. | |
12 | ||
13 | import sys, os | |
14 | ||
15 | # If extensions (or modules to document with autodoc) are in another directory, | |
16 | # add these directories to sys.path here. If the directory is relative to the | |
17 | # documentation root, use os.path.abspath to make it absolute, like shown here. | |
18 | #sys.path.insert(0, os.path.abspath('.')) | |
19 | sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) | |
20 | ||
21 | # -- General configuration ----------------------------------------------------- | |
22 | ||
23 | # If your documentation needs a minimal Sphinx version, state it here. | |
24 | #needs_sphinx = '1.0' | |
25 | ||
26 | # Add any Sphinx extension module names here, as strings. They can be extensions | |
27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | |
28 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] | |
29 | ||
30 | # Add any paths that contain templates here, relative to this directory. | |
31 | templates_path = ['_templates'] | |
32 | ||
33 | # The suffix of source filenames. | |
34 | source_suffix = '.rst' | |
35 | ||
36 | # The encoding of source files. | |
37 | #source_encoding = 'utf-8-sig' | |
38 | ||
39 | # The master toctree document. | |
40 | master_doc = 'index' | |
41 | ||
42 | # General information about the project. | |
43 | project = u'pysmb' | |
44 | copyright = u'2011, Michael Teo' | |
45 | ||
46 | # The version info for the project you're documenting, acts as replacement for | |
47 | # |version| and |release|, also used in various other places throughout the | |
48 | # built documents. | |
49 | # | |
50 | # The short X.Y version. | |
51 | version = '1.0.0' | |
52 | # The full version, including alpha/beta/rc tags. | |
53 | release = '1.0.0' | |
54 | ||
55 | # The language for content autogenerated by Sphinx. Refer to documentation | |
56 | # for a list of supported languages. | |
57 | #language = None | |
58 | ||
59 | # There are two options for replacing |today|: either, you set today to some | |
60 | # non-false value, then it is used: | |
61 | #today = '' | |
62 | # Else, today_fmt is used as the format for a strftime call. | |
63 | #today_fmt = '%B %d, %Y' | |
64 | ||
65 | # List of patterns, relative to source directory, that match files and | |
66 | # directories to ignore when looking for source files. | |
67 | exclude_patterns = [] | |
68 | ||
69 | # The reST default role (used for this markup: `text`) to use for all documents. | |
70 | #default_role = None | |
71 | ||
72 | # If true, '()' will be appended to :func: etc. cross-reference text. | |
73 | #add_function_parentheses = True | |
74 | ||
75 | # If true, the current module name will be prepended to all description | |
76 | # unit titles (such as .. function::). | |
77 | #add_module_names = True | |
78 | ||
79 | # If true, sectionauthor and moduleauthor directives will be shown in the | |
80 | # output. They are ignored by default. | |
81 | #show_authors = False | |
82 | ||
83 | # The name of the Pygments (syntax highlighting) style to use. | |
84 | pygments_style = 'sphinx' | |
85 | ||
86 | # A list of ignored prefixes for module index sorting. | |
87 | #modindex_common_prefix = [] | |
88 | ||
89 | autodoc_member_order = 'groupwise' | |
90 | ||
91 | # -- Options for HTML output --------------------------------------------------- | |
92 | ||
93 | # The theme to use for HTML and HTML Help pages. See the documentation for | |
94 | # a list of builtin themes. | |
95 | html_theme = 'sphinxdoc' | |
96 | ||
97 | # Theme options are theme-specific and customize the look and feel of a theme | |
98 | # further. For a list of options available for each theme, see the | |
99 | # documentation. | |
100 | #html_theme_options = {} | |
101 | ||
102 | # Add any paths that contain custom themes here, relative to this directory. | |
103 | #html_theme_path = [] | |
104 | ||
105 | # The name for this set of Sphinx documents. If None, it defaults to | |
106 | # "<project> v<release> documentation". | |
107 | #html_title = None | |
108 | ||
109 | # A shorter title for the navigation bar. Default is the same as html_title. | |
110 | #html_short_title = None | |
111 | ||
112 | # The name of an image file (relative to this directory) to place at the top | |
113 | # of the sidebar. | |
114 | #html_logo = None | |
115 | ||
116 | # The name of an image file (within the static path) to use as favicon of the | |
117 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 | |
118 | # pixels large. | |
119 | #html_favicon = None | |
120 | ||
121 | # Add any paths that contain custom static files (such as style sheets) here, | |
122 | # relative to this directory. They are copied after the builtin static files, | |
123 | # so a file named "default.css" will overwrite the builtin "default.css". | |
124 | html_static_path = ['_static'] | |
125 | ||
126 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, | |
127 | # using the given strftime format. | |
128 | #html_last_updated_fmt = '%b %d, %Y' | |
129 | ||
130 | # If true, SmartyPants will be used to convert quotes and dashes to | |
131 | # typographically correct entities. | |
132 | #html_use_smartypants = True | |
133 | ||
134 | # Custom sidebar templates, maps document names to template names. | |
135 | #html_sidebars = {} | |
136 | ||
137 | # Additional templates that should be rendered to pages, maps page names to | |
138 | # template names. | |
139 | #html_additional_pages = {} | |
140 | ||
141 | # If false, no module index is generated. | |
142 | #html_domain_indices = True | |
143 | ||
144 | # If false, no index is generated. | |
145 | #html_use_index = True | |
146 | ||
147 | # If true, the index is split into individual pages for each letter. | |
148 | #html_split_index = False | |
149 | ||
150 | # If true, links to the reST sources are added to the pages. | |
151 | #html_show_sourcelink = True | |
152 | ||
153 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. | |
154 | #html_show_sphinx = True | |
155 | ||
156 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. | |
157 | #html_show_copyright = True | |
158 | ||
159 | # If true, an OpenSearch description file will be output, and all pages will | |
160 | # contain a <link> tag referring to it. The value of this option must be the | |
161 | # base URL from which the finished HTML is served. | |
162 | #html_use_opensearch = '' | |
163 | ||
164 | # This is the file name suffix for HTML files (e.g. ".xhtml"). | |
165 | #html_file_suffix = None | |
166 | ||
167 | # Output file base name for HTML help builder. | |
168 | htmlhelp_basename = 'pysmbdoc' | |
169 | ||
170 | ||
171 | # -- Options for LaTeX output -------------------------------------------------- | |
172 | ||
173 | latex_elements = { | |
174 | # The paper size ('letterpaper' or 'a4paper'). | |
175 | #'papersize': 'letterpaper', | |
176 | ||
177 | # The font size ('10pt', '11pt' or '12pt'). | |
178 | #'pointsize': '10pt', | |
179 | ||
180 | # Additional stuff for the LaTeX preamble. | |
181 | #'preamble': '', | |
182 | } | |
183 | ||
184 | # Grouping the document tree into LaTeX files. List of tuples | |
185 | # (source start file, target name, title, author, documentclass [howto/manual]). | |
186 | latex_documents = [ | |
187 | ('index', 'pysmb.tex', u'pysmb Documentation', | |
188 | u'Michael Teo', 'manual'), | |
189 | ] | |
190 | ||
191 | # The name of an image file (relative to this directory) to place at the top of | |
192 | # the title page. | |
193 | #latex_logo = None | |
194 | ||
195 | # For "manual" documents, if this is true, then toplevel headings are parts, | |
196 | # not chapters. | |
197 | #latex_use_parts = False | |
198 | ||
199 | # If true, show page references after internal links. | |
200 | #latex_show_pagerefs = False | |
201 | ||
202 | # If true, show URL addresses after external links. | |
203 | #latex_show_urls = False | |
204 | ||
205 | # Documents to append as an appendix to all manuals. | |
206 | #latex_appendices = [] | |
207 | ||
208 | # If false, no module index is generated. | |
209 | #latex_domain_indices = True | |
210 | ||
211 | ||
212 | # -- Options for manual page output -------------------------------------------- | |
213 | ||
214 | # One entry per manual page. List of tuples | |
215 | # (source start file, name, description, authors, manual section). | |
216 | man_pages = [ | |
217 | ('index', 'pysmb', u'pysmb Documentation', | |
218 | [u'Michael Teo'], 1) | |
219 | ] | |
220 | ||
221 | # If true, show URL addresses after external links. | |
222 | #man_show_urls = False | |
223 | ||
224 | ||
225 | # -- Options for Texinfo output ------------------------------------------------ | |
226 | ||
227 | # Grouping the document tree into Texinfo files. List of tuples | |
228 | # (source start file, target name, title, author, | |
229 | # dir menu entry, description, category) | |
230 | texinfo_documents = [ | |
231 | ('index', 'pysmb', u'pysmb Documentation', | |
232 | u'Michael Teo', 'pysmb', 'One line description of project.', | |
233 | 'Miscellaneous'), | |
234 | ] | |
235 | ||
236 | # Documents to append as an appendix to all manuals. | |
237 | #texinfo_appendices = [] | |
238 | ||
239 | # If false, no module index is generated. | |
240 | #texinfo_domain_indices = True | |
241 | ||
242 | # How to display URL addresses: 'footnote', 'no', or 'inline'. | |
243 | #texinfo_show_urls = 'footnote' |
0 | ||
1 | Extending pysmb For Other Frameworks | |
2 | ==================================== | |
3 | ||
4 | This page briefly describes the steps involved in extending pysmb for other frameworks. | |
5 | ||
6 | In general, you need to take care of the SMB TCP connection setup, i.e. finding the IP address of the remote server and connect to the SMB/CIFS service. | |
7 | Then you need to read/write synchronously or asynchronously from and to the SMB socket. And you need to handle post-authentication callback methods, and from these methods, | |
8 | initiate file operations with the remote SMB/CIFS server. | |
9 | ||
10 | Now the above steps in more technical details: | |
11 | 1. Create a new class which subclasses the *smb.base.SMB* class. Most often, the connection setup will be part of the *__init__* method. | |
12 | 2. Override the *write(self, data)* method to provide an implementation which will write *data* to the socket. | |
13 | 3. Write your own loop handling method to read data from the socket. Once data have been read, call *feedData* method with the parameter. | |
14 | The *feedData* method has its own internal buffer, so it can accept incomplete NetBIOS session packet data. | |
15 | 4. Override | |
16 | * *onAuthOK* method to include your own operations to perform when authentication is successful. You can initiate file operations in this method. | |
17 | * *onAuthFailed* method to include your own processing on what to do when authentication fails. You can report this as an error, or to try a different NTLM authentication algorithm (*use_ntlm_v2* parameter in the constructor). | |
18 | * *onNMBSessionFailed* method to include your own processing on what to do when pysmb fails to setup the NetBIOS session with the remote server. Usually, this is due to a wrong *remote_name* parameter in the constructor. |
0 | .. pysmb documentation master file, created by | |
1 | sphinx-quickstart on Sun Dec 18 15:54:40 2011. | |
2 | You can adapt this file completely to your liking, but it should at least | |
3 | contain the root `toctree` directive. | |
4 | ||
5 | Welcome to pysmb's documentation! | |
6 | ================================= | |
7 | ||
8 | pysmb is a pure Python implementation of the client-side SMB/CIFS protocol which is the underlying protocol that facilitates file sharing and printing between Windows machines, | |
9 | as well as with Linux machines via the Samba server application. | |
10 | pysmb is developed in Python 2.4.6 (and Python 2.7.1) and has been tested against shared folders on Windows XP SP3, Windows Vista, Windows 7 and Samba 3.x. | |
11 | ||
12 | License | |
13 | ------- | |
14 | pysmb itself is licensed under an opensource license. | |
15 | You are free to use pysmb in any applications, including for commercial purposes. | |
16 | For more details on the terms of use, please read the LICENSE file that comes with your pysmb source. | |
17 | ||
18 | pysmb depends on other 3rd-party modules whose terms of use are not covered by pysmb. | |
19 | Use of these modules could possibly conflict with your licensing needs. Please exercise your own discretion to determine their suitabilities. | |
20 | I have listed these modules in the following section. | |
21 | ||
22 | Credits | |
23 | ------- | |
24 | pysmb is not alone. It is made possible with support from other modules. | |
25 | ||
26 | * **pyasn1** : Pure Python implementation of ASN.1 parsing and encoding (not included together with pysmb; needs to be installed separately) | |
27 | * **md4** and **U32** : Pure Python implementation of MD4 hashing algorithm and 32-bit unsigned integer by Dmitry Rozmanov. Licensed under LGPL and included together with pysmb. | |
28 | * **pyDes** : Pure python implementation of the DES encryption algorithm by Todd Whiteman. Free domain and included together with pysmb. | |
29 | ||
30 | In various places, there are references to different specifications. Most of these referenced specifications | |
31 | can be downloaded from Microsoft web site under Microsoft's "Open Specification Promise". If you need to download | |
32 | a copy of these specifications, please google for it. For example, google for "MS-CIFS" to download the CIFS specification for NT LM dialect. | |
33 | ||
34 | Package Contents and Description | |
35 | ================================ | |
36 | ||
37 | pysmb is organized into 2 main packages: smb and nmb. | |
38 | The smb package contains all the functionalities related to Server Message Block (SMB) implementation. | |
39 | As an application developer, you will be importing this module into your application. | |
40 | Hence, please take some time to familiarize yourself with the smb package contents. | |
41 | ||
42 | * **nmb/base.py** : | |
43 | Contains the NetBIOSSession and NBNS abstract class which implements NetBIOS session and NetBIOS Name Service communication | |
44 | without any network transport specifics. | |
45 | * **nmb/NetBIOS.py**: | |
46 | Provides a NBNS implementation to query IP addresses for machine names. All operations are blocking I/O. | |
47 | * **nmb/NetBIOSProtocol.py** : | |
48 | Provides the NBNS protocol implementation for use in Twisted framework. | |
49 | ||
50 | * **smb/base.py** : | |
51 | Contains the SMB abstract class which implements the SMB communication without any network transport specifics. | |
52 | * **smb/ntlm.py** : | |
53 | Contains the NTLMv1 and NTLMv2 authentication routines and the decoding/encoding of NTLM authentication messages within SMB messages. | |
54 | * **smb/securityblob.py** : | |
55 | Provides routines to encode/decode the NTLMSSP security blob in the SMB messages. | |
56 | * **smb/smb_constants.py** : | |
57 | All the constants used in the smb package | |
58 | * **smb/smb_structs.py** : | |
59 | Contains the internal classes used in the SMB package. These classes are usually used to encode/decode the parameter and data blocks of specific SMB message. | |
60 | * **smb/SMBConnection.py** : | |
61 | Contains a SMB protocol implementation. All operations are blocking I/O. | |
62 | * **smb/SMBProtocol.py** : | |
63 | Contains the SMB protocol implementation for use in the Twisted framework. | |
64 | ||
65 | Using pysmb | |
66 | =========== | |
67 | ||
68 | As an application developer who is looking to use pysmb to translate NetBIOS names to IP addresses, | |
69 | * To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read | |
70 | :doc:`nmb.NetBIOS.NetBIOS<api/nmb_NetBIOS>` documentation. | |
71 | * To use pysmb in Twisted, please read :doc:`nmb.NetBIOSProtocol.NBNSProtocol<api/nmb_NBNSProtocol>` documentation. | |
72 | ||
73 | As an application developer who is looking to use pysmb to implement file transfer or authentication over SMB: | |
74 | * To use pysmb in applications where you want the file operations to return after they have completed (synchronous style), please read | |
75 | :doc:`smb.SMBConnection.SMBConnection<api/smb_SMBConnection>` documentation. | |
76 | * To use pysmb in Twisted, please read :doc:`smb.SMBProtocol.SMBProtocolFactory<api/smb_SMBProtocolFactory>` documentation. | |
77 | ||
78 | As a software developer who is looking to modify pysmb so that you can integrate it to other network frameworks: | |
79 | * Read :doc:`extending` | |
80 | ||
81 | ||
82 | ||
83 | Indices and tables | |
84 | ================== | |
85 | ||
86 | .. toctree:: | |
87 | :glob: | |
88 | :maxdepth: 1 | |
89 | ||
90 | api/* | |
91 | extending | |
92 | ||
93 | * :ref:`genindex` | |
94 | * :ref:`search` |
0 | ||
1 | from nmb.NetBIOS import NetBIOS | |
2 | from nose.tools import with_setup | |
3 | ||
4 | conn = None | |
5 | ||
6 | def teardown_func(): | |
7 | global conn | |
8 | conn.close() | |
9 | ||
10 | @with_setup(teardown = teardown_func) | |
11 | def test_broadcast(): | |
12 | global conn | |
13 | conn = NetBIOS() | |
14 | assert conn.queryName('MICHAEL-I5PC', timeout = 10) | |
15 |
0 | ||
1 | from nose.twistedtools import reactor, deferred | |
2 | from twisted.internet import defer | |
3 | from nmb.NetBIOSProtocol import NBNSProtocol | |
4 | from nose.tools import with_setup | |
5 | ||
6 | ||
7 | @deferred(timeout=15.0) | |
8 | def test_broadcast(): | |
9 | def cb(results): | |
10 | assert results | |
11 | ||
12 | def cleanup(r): | |
13 | p.transport.stopListening() | |
14 | ||
15 | p = NBNSProtocol() | |
16 | d = p.queryName('MICHAEL-I5PC', timeout = 10) | |
17 | d.addCallback(cb) | |
18 | d.addBoth(cleanup) | |
19 | ||
20 | return d |
0 | ||
1 | Steps to Follow to Run the Unit Tests | |
2 | ===================================== | |
3 | ||
4 | 1a. Install Nose Testing Framework | |
5 | All the unit tests here are designed to be conducted with the nose testing framework. | |
6 | You can install the latest nose testing framework by running: easy_install nose | |
7 | For more information on nose testing, please visit http://readthedocs.org/docs/nose/en/latest/ | |
8 | ||
9 | 1b. Install the Twisted framework | |
10 | If you need to test the SMB/NetBIOS protocol implementations for Twisted framework, | |
11 | you should install the Twisted framework from http://twistedmatrix.com/ | |
12 | or by running: easy_install Twisted | |
13 | Without the Twisted framework, the Twisted tests will fail. | |
14 | ||
15 | 2. Prepare a Shared Folder "smbtest" on a Remote Server | |
16 | To run the unit tests here, besides installing the nose testing framework, you will | |
17 | also need to prepare a shared folder on a remote server. | |
18 | pysmb has been tested against Samba 3.x, Windows XP SP3 and Windows Vista. | |
19 | The shared folder must be named "smbtest". | |
20 | ||
21 | 3. Unzip smbtest.zip in the Shared Folder | |
22 | In the same folder where you are viewing this readme file, there should be a zip file | |
23 | called "smbtest.zip". Unzip the contents of this zip file in the shared folder. | |
24 | ||
25 | 4. Update Connection Details in connection.ini | |
26 | In the same folder where you are viewing this readme file, there should be an ini file | |
27 | called "connection.ini". Edit this file's connection details to match the shared folder's | |
28 | access information. | |
29 | ||
30 | 5. Run the Unit Tests | |
31 | Just run: nosetests |
0 | ||
1 | from smb.SMBConnection import SMBConnection | |
2 | from util import getConnectionInfo | |
3 | from nose.tools import with_setup | |
4 | ||
5 | conn = None | |
6 | ||
7 | def teardown_func(): | |
8 | global conn | |
9 | conn.close() | |
10 | ||
11 | @with_setup(teardown = teardown_func) | |
12 | def test_NTLMv1_auth(): | |
13 | global conn | |
14 | info = getConnectionInfo() | |
15 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False) | |
16 | assert conn.connect(info['server_ip'], info['server_port']) | |
17 | ||
18 | @with_setup(teardown = teardown_func) | |
19 | def test_NTLMv2_auth(): | |
20 | global conn | |
21 | info = getConnectionInfo() | |
22 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
23 | assert conn.connect(info['server_ip'], info['server_port']) |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, time, random | |
3 | from smb.SMBConnection import SMBConnection | |
4 | from util import getConnectionInfo | |
5 | from nose.tools import with_setup | |
6 | ||
7 | conn = None | |
8 | ||
9 | def setup_func(): | |
10 | global conn | |
11 | info = getConnectionInfo() | |
12 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
13 | assert conn.connect(info['server_ip'], info['server_port']) | |
14 | ||
15 | def teardown_func(): | |
16 | global conn | |
17 | conn.close() | |
18 | ||
19 | @with_setup(setup_func, teardown_func) | |
20 | def test_english_directory(): | |
21 | global conn | |
22 | ||
23 | path = os.sep + 'TestDir %d-%d' % ( time.time(), random.randint(0, 1000) ) | |
24 | conn.createDirectory('smbtest', path) | |
25 | ||
26 | entries = conn.listPath('smbtest', os.path.dirname(path.replace('/', os.sep))) | |
27 | names = map(lambda e: e.filename, entries) | |
28 | assert os.path.basename(path.replace('/', os.sep)) in names | |
29 | ||
30 | conn.deleteDirectory('smbtest', path) | |
31 | ||
32 | entries = conn.listPath('smbtest', os.path.dirname(path.replace('/', os.sep))) | |
33 | names = map(lambda e: e.filename, entries) | |
34 | assert os.path.basename(path.replace('/', os.sep)) not in names | |
35 | ||
36 | @with_setup(setup_func, teardown_func) | |
37 | def test_unicode_directory(): | |
38 | global conn | |
39 | ||
40 | path = os.sep + u'文件夹创建 %d-%d' % ( time.time(), random.randint(0, 1000) ) | |
41 | conn.createDirectory('smbtest', path) | |
42 | ||
43 | entries = conn.listPath('smbtest', os.path.dirname(path.replace('/', os.sep))) | |
44 | names = map(lambda e: e.filename, entries) | |
45 | assert os.path.basename(path.replace('/', os.sep)) in names | |
46 | ||
47 | conn.deleteDirectory('smbtest', path) | |
48 | ||
49 | entries = conn.listPath('smbtest', os.path.dirname(path.replace('/', os.sep))) | |
50 | names = map(lambda e: e.filename, entries) | |
51 | assert os.path.basename(path.replace('/', os.sep)) not in names |
0 | ||
1 | import random | |
2 | from smb.SMBConnection import SMBConnection | |
3 | from util import getConnectionInfo | |
4 | from nose.tools import with_setup | |
5 | ||
6 | conn = None | |
7 | ||
8 | def setup_func(): | |
9 | global conn | |
10 | info = getConnectionInfo() | |
11 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
12 | assert conn.connect(info['server_ip'], info['server_port']) | |
13 | ||
14 | def teardown_func(): | |
15 | global conn | |
16 | conn.close() | |
17 | ||
18 | @with_setup(setup_func, teardown_func) | |
19 | def test_echo(): | |
20 | global conn | |
21 | ||
22 | data = '%d' % random.randint(1000, 9999) | |
23 | assert conn.echo(data) == data | |
24 |
0 | ||
1 | from smb.SMBConnection import SMBConnection | |
2 | from util import getConnectionInfo | |
3 | from nose.tools import with_setup | |
4 | ||
5 | conn = None | |
6 | ||
7 | def setup_func(): | |
8 | global conn | |
9 | info = getConnectionInfo() | |
10 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
11 | assert conn.connect(info['server_ip'], info['server_port']) | |
12 | ||
13 | def teardown_func(): | |
14 | global conn | |
15 | conn.close() | |
16 | ||
17 | @with_setup(setup_func, teardown_func) | |
18 | def test_listPath(): | |
19 | global conn | |
20 | results = conn.listPath('smbtest', '/') | |
21 | filenames = map(lambda r: ( r.filename, r.isDirectory ), results) | |
22 | assert ( u'\u6d4b\u8bd5\u6587\u4ef6\u5939', True ) in filenames # Test non-English folder names | |
23 | assert ( u'Test Folder with Long Name', True ) in filenames # Test long English folder names | |
24 | assert ( u'TestDir1', True ) in filenames # Test short English folder names | |
25 | assert ( u'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names | |
26 | assert ( u'rfc1001.txt', False ) in filenames # Test short English file names |
0 | ||
1 | from smb.SMBConnection import SMBConnection | |
2 | from util import getConnectionInfo | |
3 | from nose.tools import with_setup | |
4 | ||
5 | conn = None | |
6 | ||
7 | def setup_func(): | |
8 | global conn | |
9 | info = getConnectionInfo() | |
10 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
11 | assert conn.connect(info['server_ip'], info['server_port']) | |
12 | ||
13 | def teardown_func(): | |
14 | global conn | |
15 | conn.close() | |
16 | ||
17 | @with_setup(setup_func, teardown_func) | |
18 | def test_listshares(): | |
19 | global conn | |
20 | results = conn.listShares() | |
21 | assert 'smbtest' in map(lambda r: r.name.lower(), results) |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, time, random | |
3 | from StringIO import StringIO | |
4 | from smb.SMBConnection import SMBConnection | |
5 | from util import getConnectionInfo | |
6 | from nose.tools import with_setup | |
7 | ||
8 | conn = None | |
9 | ||
10 | def setup_func(): | |
11 | global conn | |
12 | info = getConnectionInfo() | |
13 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
14 | assert conn.connect(info['server_ip'], info['server_port']) | |
15 | ||
16 | def teardown_func(): | |
17 | global conn | |
18 | conn.close() | |
19 | ||
20 | @with_setup(setup_func, teardown_func) | |
21 | def test_rename_english_file(): | |
22 | global conn | |
23 | ||
24 | old_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
25 | new_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
26 | ||
27 | conn.storeFile('smbtest', old_path, StringIO('Rename file test')) | |
28 | ||
29 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
30 | filenames = map(lambda e: e.filename, entries) | |
31 | assert os.path.basename(old_path.replace('/', os.sep)) in filenames | |
32 | assert os.path.basename(new_path.replace('/', os.sep)) not in filenames | |
33 | ||
34 | conn.rename('smbtest', old_path, new_path) | |
35 | ||
36 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
37 | filenames = map(lambda e: e.filename, entries) | |
38 | assert os.path.basename(old_path.replace('/', os.sep)) not in filenames | |
39 | assert os.path.basename(new_path.replace('/', os.sep)) in filenames | |
40 | ||
41 | conn.deleteFiles('smbtest', new_path) | |
42 | ||
43 | @with_setup(setup_func, teardown_func) | |
44 | def test_rename_unicode_file(): | |
45 | global conn | |
46 | ||
47 | old_path = u'/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
48 | new_path = u'/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
49 | ||
50 | conn.storeFile('smbtest', old_path, StringIO('Rename file test')) | |
51 | ||
52 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
53 | filenames = map(lambda e: e.filename, entries) | |
54 | assert os.path.basename(old_path.replace('/', os.sep)) in filenames | |
55 | assert os.path.basename(new_path.replace('/', os.sep)) not in filenames | |
56 | ||
57 | conn.rename('smbtest', old_path, new_path) | |
58 | ||
59 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
60 | filenames = map(lambda e: e.filename, entries) | |
61 | assert os.path.basename(old_path.replace('/', os.sep)) not in filenames | |
62 | assert os.path.basename(new_path.replace('/', os.sep)) in filenames | |
63 | ||
64 | conn.deleteFiles('smbtest', new_path) | |
65 | ||
66 | @with_setup(setup_func, teardown_func) | |
67 | def test_rename_english_directory(): | |
68 | global conn | |
69 | ||
70 | old_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
71 | new_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
72 | ||
73 | conn.createDirectory('smbtest', old_path) | |
74 | ||
75 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
76 | filenames = map(lambda e: e.filename, entries) | |
77 | assert os.path.basename(old_path.replace('/', os.sep)) in filenames | |
78 | assert os.path.basename(new_path.replace('/', os.sep)) not in filenames | |
79 | ||
80 | conn.rename('smbtest', old_path, new_path) | |
81 | ||
82 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
83 | filenames = map(lambda e: e.filename, entries) | |
84 | assert os.path.basename(old_path.replace('/', os.sep)) not in filenames | |
85 | assert os.path.basename(new_path.replace('/', os.sep)) in filenames | |
86 | ||
87 | conn.deleteDirectory('smbtest', new_path) | |
88 | ||
89 | @with_setup(setup_func, teardown_func) | |
90 | def test_rename_unicode_directory(): | |
91 | global conn | |
92 | ||
93 | old_path = u'/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) ) | |
94 | new_path = u'/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) ) | |
95 | ||
96 | conn.createDirectory('smbtest', old_path) | |
97 | ||
98 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
99 | filenames = map(lambda e: e.filename, entries) | |
100 | assert os.path.basename(old_path.replace('/', os.sep)) in filenames | |
101 | assert os.path.basename(new_path.replace('/', os.sep)) not in filenames | |
102 | ||
103 | conn.rename('smbtest', old_path, new_path) | |
104 | ||
105 | entries = conn.listPath('smbtest', os.path.dirname(old_path.replace('/', os.sep))) | |
106 | filenames = map(lambda e: e.filename, entries) | |
107 | assert os.path.basename(old_path.replace('/', os.sep)) not in filenames | |
108 | assert os.path.basename(new_path.replace('/', os.sep)) in filenames | |
109 | ||
110 | conn.deleteDirectory('smbtest', new_path) |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, tempfile | |
3 | from StringIO import StringIO | |
4 | from smb.SMBConnection import SMBConnection | |
5 | from util import getConnectionInfo | |
6 | from nose.tools import with_setup | |
7 | ||
8 | try: | |
9 | import hashlib | |
10 | def MD5(): return hashlib.md5() | |
11 | except ImportError: | |
12 | import md5 | |
13 | def MD5(): return md5.new() | |
14 | ||
15 | conn = None | |
16 | ||
17 | def setup_func(): | |
18 | global conn | |
19 | info = getConnectionInfo() | |
20 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
21 | assert conn.connect(info['server_ip'], info['server_port']) | |
22 | ||
23 | def teardown_func(): | |
24 | global conn | |
25 | conn.close() | |
26 | ||
27 | @with_setup(setup_func, teardown_func) | |
28 | def test_retr_multiplereads(): | |
29 | # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes) | |
30 | global conn | |
31 | temp_fh = StringIO() | |
32 | file_attributes, filesize = conn.retrieveFile('smbtest', '/rfc1001.txt', temp_fh) | |
33 | ||
34 | md = MD5() | |
35 | md.update(temp_fh.getvalue()) | |
36 | assert md.hexdigest() == '5367c2bbf97f521059c78eab65309ad3' | |
37 | assert filesize == 158437 | |
38 | ||
39 | temp_fh.close() | |
40 | ||
41 | @with_setup(setup_func, teardown_func) | |
42 | def test_retr_longfilename(): | |
43 | # Test file retrieval that has a long English filename | |
44 | global conn | |
45 | temp_fh = StringIO() | |
46 | file_attributes, filesize = conn.retrieveFile('smbtest', '/Implementing CIFS - SMB.html', temp_fh) | |
47 | ||
48 | md = MD5() | |
49 | md.update(temp_fh.getvalue()) | |
50 | assert md.hexdigest() == '671c5700d279fcbbf958c1bba3c2639e' | |
51 | assert filesize == 421269 | |
52 | ||
53 | temp_fh.close() | |
54 | ||
55 | ||
56 | @with_setup(setup_func, teardown_func) | |
57 | def test_retr_unicodefilename(): | |
58 | # Test file retrieval that has a long non-English filename inside a folder with a non-English name | |
59 | global conn | |
60 | temp_fh = StringIO() | |
61 | file_attributes, filesize = conn.retrieveFile('smbtest', u'/测试文件夹/垃圾文件.dat', temp_fh) | |
62 | ||
63 | md = MD5() | |
64 | md.update(temp_fh.getvalue()) | |
65 | assert md.hexdigest() == '8a44c1e80d55e91c92350955cdf83442' | |
66 | assert filesize == 256000 | |
67 | ||
68 | temp_fh.close() |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, tempfile, random, time | |
3 | from StringIO import StringIO | |
4 | from smb.SMBConnection import SMBConnection | |
5 | from util import getConnectionInfo | |
6 | from nose.tools import with_setup | |
7 | ||
8 | try: | |
9 | import hashlib | |
10 | def MD5(): return hashlib.md5() | |
11 | except ImportError: | |
12 | import md5 | |
13 | def MD5(): return md5.new() | |
14 | ||
15 | conn = None | |
16 | ||
17 | TEST_FILENAME = os.path.join(os.path.dirname(__file__), os.pardir, 'SupportFiles', 'binary.dat') | |
18 | TEST_FILESIZE = 256000 | |
19 | TEST_DIGEST = 'bb6303f76e29f354b6fdf6ef58587e48' | |
20 | ||
21 | def setup_func(): | |
22 | global conn | |
23 | info = getConnectionInfo() | |
24 | conn = SMBConnection(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
25 | assert conn.connect(info['server_ip'], info['server_port']) | |
26 | ||
27 | def teardown_func(): | |
28 | global conn | |
29 | conn.close() | |
30 | ||
31 | ||
32 | @with_setup(setup_func, teardown_func) | |
33 | def test_store_long_filename(): | |
34 | filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) ) | |
35 | ||
36 | filesize = conn.storeFile('smbtest', filename, open(TEST_FILENAME, 'rb')) | |
37 | assert filesize == TEST_FILESIZE | |
38 | ||
39 | entries = conn.listPath('smbtest', os.path.dirname(filename.replace('/', os.sep))) | |
40 | filenames = map(lambda e: e.filename, entries) | |
41 | assert os.path.basename(filename.replace('/', os.sep)) in filenames | |
42 | ||
43 | buf = StringIO() | |
44 | file_attributes, file_size = conn.retrieveFile('smbtest', filename, buf) | |
45 | assert file_size == TEST_FILESIZE | |
46 | ||
47 | md = MD5() | |
48 | md.update(buf.getvalue()) | |
49 | assert md.hexdigest() == TEST_DIGEST | |
50 | buf.close() | |
51 | ||
52 | conn.deleteFiles('smbtest', filename) | |
53 | ||
54 | ||
55 | @with_setup(setup_func, teardown_func) | |
56 | def test_store_unicode_filename(): | |
57 | filename = os.sep + u'上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) ) | |
58 | ||
59 | filesize = conn.storeFile('smbtest', filename, open(TEST_FILENAME, 'rb')) | |
60 | assert filesize == TEST_FILESIZE | |
61 | ||
62 | entries = conn.listPath('smbtest', os.path.dirname(filename.replace('/', os.sep))) | |
63 | filenames = map(lambda e: e.filename, entries) | |
64 | assert os.path.basename(filename.replace('/', os.sep)) in filenames | |
65 | ||
66 | buf = StringIO() | |
67 | file_attributes, file_size = conn.retrieveFile('smbtest', filename, buf) | |
68 | assert file_size == TEST_FILESIZE | |
69 | ||
70 | md = MD5() | |
71 | md.update(buf.getvalue()) | |
72 | assert md.hexdigest() == TEST_DIGEST | |
73 | buf.close() | |
74 | ||
75 | conn.deleteFiles('smbtest', filename) |
0 | ||
1 | import os | |
2 | from ConfigParser import SafeConfigParser | |
3 | ||
4 | def getConnectionInfo(): | |
5 | config_filename = os.path.join(os.path.dirname(__file__), os.path.pardir, 'connection.ini') | |
6 | cp = SafeConfigParser() | |
7 | cp.read(config_filename) | |
8 | ||
9 | info = { | |
10 | 'server_name': cp.get('server', 'name'), | |
11 | 'server_ip': cp.get('server', 'ip'), | |
12 | 'server_port': cp.getint('server', 'port'), | |
13 | 'client_name': cp.get('client', 'name'), | |
14 | 'user': cp.get('user', 'name'), | |
15 | 'password': cp.get('user', 'password'), | |
16 | } | |
17 | return info | |
18 |
0 | ||
1 | from nose.twistedtools import reactor, deferred | |
2 | from twisted.internet import defer | |
3 | from smb.SMBProtocol import SMBProtocolFactory | |
4 | from util import getConnectionInfo | |
5 | ||
6 | ||
7 | class AuthFactory(SMBProtocolFactory): | |
8 | ||
9 | def __init__(self, *args, **kwargs): | |
10 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
11 | self.d = defer.Deferred() | |
12 | self.d.addBoth(self.testDone) | |
13 | ||
14 | def testDone(self, r): | |
15 | if self.instance: | |
16 | self.instance.transport.loseConnection() | |
17 | return r | |
18 | ||
19 | def onAuthOK(self): | |
20 | self.d.callback(True) | |
21 | ||
22 | def onAuthFailed(self): | |
23 | self.d.callback(False) | |
24 | ||
25 | ||
26 | @deferred(timeout=5.0) | |
27 | def test_NTLMv1_auth(): | |
28 | def result(auth_passed): | |
29 | assert auth_passed | |
30 | ||
31 | info = getConnectionInfo() | |
32 | factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False) | |
33 | factory.d.addCallback(result) | |
34 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
35 | return factory.d | |
36 | ||
37 | ||
38 | @deferred(timeout=5.0) | |
39 | def test_NTLMv2_auth(): | |
40 | def result(auth_passed): | |
41 | assert auth_passed | |
42 | ||
43 | info = getConnectionInfo() | |
44 | factory = AuthFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
45 | factory.d.addCallback(result) | |
46 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
47 | return factory.d |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, random, time | |
3 | from nose.twistedtools import reactor, deferred | |
4 | from twisted.internet import defer | |
5 | from smb.SMBProtocol import SMBProtocolFactory | |
6 | from util import getConnectionInfo | |
7 | ||
8 | ||
9 | class DirectoryFactory(SMBProtocolFactory): | |
10 | ||
11 | def __init__(self, *args, **kwargs): | |
12 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
13 | self.d = defer.Deferred() | |
14 | self.d.addBoth(self.testDone) | |
15 | self.service_name = '' | |
16 | self.path = '' | |
17 | ||
18 | def testDone(self, r): | |
19 | if self.instance: | |
20 | self.instance.transport.loseConnection() | |
21 | return r | |
22 | ||
23 | def createDone(self, result): | |
24 | d = self.listPath(self.service_name, os.path.dirname(self.path.replace('/', os.sep))) | |
25 | d.addCallback(self.listComplete) | |
26 | d.addErrback(self.d.errback) | |
27 | ||
28 | def listComplete(self, entries): | |
29 | names = map(lambda e: e.filename, entries) | |
30 | assert os.path.basename(self.path.replace('/', os.sep)) in names | |
31 | ||
32 | d = self.deleteDirectory(self.service_name, self.path) | |
33 | d.addCallback(self.deleteDone) | |
34 | d.addErrback(self.d.errback) | |
35 | ||
36 | def deleteDone(self, result): | |
37 | d = self.listPath(self.service_name, os.path.dirname(self.path.replace('/', os.sep))) | |
38 | d.addCallback(self.list2Complete) | |
39 | d.addErrback(self.d.errback) | |
40 | ||
41 | def list2Complete(self, entries): | |
42 | names = map(lambda e: e.filename, entries) | |
43 | assert os.path.basename(self.path.replace('/', os.sep)) not in names | |
44 | self.d.callback(True) | |
45 | ||
46 | def onAuthOK(self): | |
47 | d = self.createDirectory(self.service_name, self.path) | |
48 | d.addCallback(self.createDone) | |
49 | d.addErrback(self.d.errback) | |
50 | ||
51 | def onAuthFailed(self): | |
52 | self.d.errback('Auth failed') | |
53 | ||
54 | ||
55 | @deferred(timeout=15.0) | |
56 | def test_english_directory(): | |
57 | info = getConnectionInfo() | |
58 | factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
59 | factory.service_name = 'smbtest' | |
60 | factory.path = os.sep + 'TestDir %d-%d' % ( time.time(), random.randint(0, 1000) ) | |
61 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
62 | return factory.d | |
63 | ||
64 | @deferred(timeout=15.0) | |
65 | def test_unicode_directory(): | |
66 | info = getConnectionInfo() | |
67 | factory = DirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
68 | factory.service_name = 'smbtest' | |
69 | factory.path = os.sep + u'文件夹创建 %d-%d' % ( time.time(), random.randint(0, 1000) ) | |
70 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
71 | return factory.d |
0 | ||
1 | from nose.twistedtools import reactor, deferred | |
2 | from twisted.internet import defer | |
3 | from smb.SMBProtocol import SMBProtocolFactory | |
4 | from util import getConnectionInfo | |
5 | ||
6 | ||
7 | class EchoFactory(SMBProtocolFactory): | |
8 | ||
9 | def __init__(self, *args, **kwargs): | |
10 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
11 | self.d = defer.Deferred() | |
12 | self.d.addBoth(self.testDone) | |
13 | self.echo_data = 'This is an echo test' | |
14 | ||
15 | def testDone(self, r): | |
16 | if self.instance: | |
17 | self.instance.transport.loseConnection() | |
18 | return r | |
19 | ||
20 | def onAuthOK(self): | |
21 | def cb(data): | |
22 | assert data == self.echo_data | |
23 | self.d.callback(True) | |
24 | ||
25 | d = self.echo(self.echo_data) | |
26 | d.addCallback(cb) | |
27 | d.addErrback(self.d.errback) | |
28 | ||
29 | def onAuthFailed(self): | |
30 | self.d.errback('Auth failed') | |
31 | ||
32 | ||
33 | @deferred(timeout=15.0) | |
34 | def test_echo(): | |
35 | info = getConnectionInfo() | |
36 | factory = EchoFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
37 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
38 | return factory.d |
0 | ||
1 | from nose.twistedtools import reactor, deferred | |
2 | from twisted.internet import defer | |
3 | from smb.SMBProtocol import SMBProtocolFactory | |
4 | from util import getConnectionInfo | |
5 | ||
6 | ||
7 | class ListPathFactory(SMBProtocolFactory): | |
8 | ||
9 | def __init__(self, *args, **kwargs): | |
10 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
11 | self.d = defer.Deferred() | |
12 | self.d.addBoth(self.testDone) | |
13 | ||
14 | def testDone(self, r): | |
15 | if self.instance: | |
16 | self.instance.transport.loseConnection() | |
17 | return r | |
18 | ||
19 | def onAuthOK(self): | |
20 | def cb(results): | |
21 | filenames = map(lambda r: ( r.filename, r.isDirectory ), results) | |
22 | assert ( u'\u6d4b\u8bd5\u6587\u4ef6\u5939', True ) in filenames # Test non-English folder names | |
23 | assert ( u'Test Folder with Long Name', True ) in filenames # Test long English folder names | |
24 | assert ( u'TestDir1', True ) in filenames # Test short English folder names | |
25 | assert ( u'Implementing CIFS - SMB.html', False ) in filenames # Test long English file names | |
26 | assert ( u'rfc1001.txt', False ) in filenames # Test short English file names | |
27 | ||
28 | self.d.callback(True) | |
29 | ||
30 | d = self.listPath('smbtest', '/', timeout = 15) | |
31 | d.addCallback(cb) | |
32 | d.addErrback(self.d.errback) | |
33 | ||
34 | def onAuthFailed(self): | |
35 | self.d.errback('Auth failed') | |
36 | ||
37 | ||
38 | @deferred(timeout=15.0) | |
39 | def test_listPath(): | |
40 | info = getConnectionInfo() | |
41 | factory = ListPathFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
42 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
43 | return factory.d |
0 | ||
1 | from nose.twistedtools import reactor, deferred | |
2 | from twisted.internet import defer | |
3 | from smb.SMBProtocol import SMBProtocolFactory | |
4 | from util import getConnectionInfo | |
5 | ||
6 | ||
7 | class ListSharesFactory(SMBProtocolFactory): | |
8 | ||
9 | def __init__(self, *args, **kwargs): | |
10 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
11 | self.d = defer.Deferred() | |
12 | self.d.addBoth(self.testDone) | |
13 | ||
14 | def testDone(self, r): | |
15 | if self.instance: | |
16 | self.instance.transport.loseConnection() | |
17 | return r | |
18 | ||
19 | def onAuthOK(self): | |
20 | def cb(results): | |
21 | assert 'smbtest' in map(lambda r: r.name.lower(), results) | |
22 | self.d.callback(True) | |
23 | self.instance.transport.loseConnection() | |
24 | ||
25 | d = self.listShares(timeout = 15) | |
26 | d.addCallback(cb) | |
27 | d.addErrback(self.d.errback) | |
28 | ||
29 | def onAuthFailed(self): | |
30 | self.d.errback('Auth failed') | |
31 | ||
32 | ||
33 | @deferred(timeout=15.0) | |
34 | def test_listshares(): | |
35 | info = getConnectionInfo() | |
36 | factory = ListSharesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
37 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
38 | return factory.d |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, random, time | |
3 | from StringIO import StringIO | |
4 | from nose.twistedtools import reactor, deferred | |
5 | from twisted.internet import defer | |
6 | from smb.SMBProtocol import SMBProtocolFactory | |
7 | from util import getConnectionInfo | |
8 | ||
9 | ||
10 | class RenameFactory(SMBProtocolFactory): | |
11 | ||
12 | def __init__(self, *args, **kwargs): | |
13 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
14 | self.d = defer.Deferred() | |
15 | self.d.addBoth(self.testDone) | |
16 | self.service = '' | |
17 | self.new_path = '' | |
18 | self.old_path = '' | |
19 | ||
20 | def testDone(self, r): | |
21 | if self.instance: | |
22 | self.instance.transport.loseConnection() | |
23 | return r | |
24 | ||
25 | def pathCreated(self, result): | |
26 | d = self.listPath(self.service, os.path.dirname(self.old_path.replace('/', os.sep))) | |
27 | d.addCallback(self.listComplete) | |
28 | d.addErrback(self.d.errback) | |
29 | ||
30 | def listComplete(self, entries): | |
31 | filenames = map(lambda e: e.filename, entries) | |
32 | assert os.path.basename(self.old_path.replace('/', os.sep)) in filenames | |
33 | assert os.path.basename(self.new_path.replace('/', os.sep)) not in filenames | |
34 | ||
35 | d = self.rename(self.service, self.old_path, self.new_path) | |
36 | d.addCallback(self.renameComplete) | |
37 | d.addErrback(self.d.errback) | |
38 | ||
39 | def renameComplete(self, result): | |
40 | d = self.listPath(self.service, os.path.dirname(self.new_path.replace('/', os.sep))) | |
41 | d.addCallback(self.list2Complete) | |
42 | d.addErrback(self.d.errback) | |
43 | ||
44 | def list2Complete(self, entries): | |
45 | filenames = map(lambda e: e.filename, entries) | |
46 | assert os.path.basename(self.new_path.replace('/', os.sep)) in filenames | |
47 | assert os.path.basename(self.old_path.replace('/', os.sep)) not in filenames | |
48 | self.cleanup() | |
49 | ||
50 | def onAuthFailed(self): | |
51 | self.d.errback('Auth failed') | |
52 | ||
53 | ||
54 | class RenameFileFactory(RenameFactory): | |
55 | ||
56 | def onAuthOK(self): | |
57 | d = self.storeFile(self.service, self.old_path, StringIO('Rename file test')) | |
58 | d.addCallback(self.pathCreated) | |
59 | d.addErrback(self.d.errback) | |
60 | ||
61 | def cleanup(self): | |
62 | d = self.deleteFiles(self.service, self.new_path) | |
63 | d.chainDeferred(self.d) | |
64 | ||
65 | ||
66 | class RenameDirectoryFactory(RenameFactory): | |
67 | ||
68 | def onAuthOK(self): | |
69 | d = self.createDirectory(self.service, self.old_path) | |
70 | d.addCallback(self.pathCreated) | |
71 | d.addErrback(self.d.errback) | |
72 | ||
73 | def cleanup(self): | |
74 | d = self.deleteDirectory(self.service, self.new_path) | |
75 | d.chainDeferred(self.d) | |
76 | ||
77 | ||
78 | @deferred(timeout=30.0) | |
79 | def test_rename_english_file(): | |
80 | info = getConnectionInfo() | |
81 | factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
82 | factory.service = 'smbtest' | |
83 | factory.old_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
84 | factory.new_path = '/RenameTest %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
85 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
86 | return factory.d | |
87 | ||
88 | @deferred(timeout=30.0) | |
89 | def test_rename_unicode_file(): | |
90 | info = getConnectionInfo() | |
91 | factory = RenameFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
92 | factory.service = 'smbtest' | |
93 | factory.old_path = u'/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
94 | factory.new_path = u'/改名测试 %d-%d.txt' % ( time.time(), random.randint(1000, 9999) ) | |
95 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
96 | return factory.d | |
97 | ||
98 | @deferred(timeout=30.0) | |
99 | def test_rename_english_directory(): | |
100 | info = getConnectionInfo() | |
101 | factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
102 | factory.service = 'smbtest' | |
103 | factory.old_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) ) | |
104 | factory.new_path = '/RenameTest %d-%d' % ( time.time(), random.randint(1000, 9999) ) | |
105 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
106 | return factory.d | |
107 | ||
108 | @deferred(timeout=30.0) | |
109 | def test_rename_unicode_directory(): | |
110 | info = getConnectionInfo() | |
111 | factory = RenameDirectoryFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
112 | factory.service = 'smbtest' | |
113 | factory.old_path = u'/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) ) | |
114 | factory.new_path = u'/改名测试 %d-%d' % ( time.time(), random.randint(1000, 9999) ) | |
115 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
116 | return factory.d |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, tempfile | |
3 | from nose.twistedtools import reactor, deferred | |
4 | from twisted.internet import defer | |
5 | from smb.SMBProtocol import SMBProtocolFactory | |
6 | from util import getConnectionInfo | |
7 | ||
8 | try: | |
9 | import hashlib | |
10 | def MD5(): return hashlib.md5() | |
11 | except ImportError: | |
12 | import md5 | |
13 | def MD5(): return md5.new() | |
14 | ||
15 | ||
16 | class RetrieveFileFactory(SMBProtocolFactory): | |
17 | ||
18 | def __init__(self, *args, **kwargs): | |
19 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
20 | self.d = defer.Deferred() | |
21 | self.d.addBoth(self.testDone) | |
22 | self.temp_fh = tempfile.NamedTemporaryFile(prefix = 'pysmbtest-') | |
23 | self.service = '' | |
24 | self.path = '' | |
25 | self.digest = '' | |
26 | self.filesize = 0 | |
27 | ||
28 | def testDone(self, r): | |
29 | if self.instance: | |
30 | self.instance.transport.loseConnection() | |
31 | return r | |
32 | ||
33 | def fileRetrieved(self, write_result): | |
34 | file_obj, file_attributes, file_size = write_result | |
35 | assert file_obj == self.temp_fh | |
36 | ||
37 | md = MD5() | |
38 | filesize = 0 | |
39 | self.temp_fh.seek(0) | |
40 | while True: | |
41 | s = self.temp_fh.read(8192) | |
42 | if not s: | |
43 | break | |
44 | md.update(s) | |
45 | filesize += len(s) | |
46 | ||
47 | assert self.filesize == filesize | |
48 | assert md.hexdigest() == self.digest | |
49 | ||
50 | self.temp_fh.close() | |
51 | self.d.callback(True) | |
52 | self.instance.transport.loseConnection() | |
53 | ||
54 | def onAuthOK(self): | |
55 | assert self.service | |
56 | assert self.path | |
57 | ||
58 | d = self.retrieveFile(self.service, self.path, self.temp_fh, timeout = 15) | |
59 | d.addCallback(self.fileRetrieved) | |
60 | d.addErrback(self.d.errback) | |
61 | ||
62 | def onAuthFailed(self): | |
63 | self.d.errback('Auth failed') | |
64 | ||
65 | ||
66 | @deferred(timeout=30.0) | |
67 | def test_retr_multiplereads(): | |
68 | # Test file retrieval using multiple ReadAndx calls (assuming each call will not reach more than 65534 bytes) | |
69 | info = getConnectionInfo() | |
70 | factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
71 | factory.service = 'smbtest' | |
72 | factory.path = '/rfc1001.txt' | |
73 | factory.digest = '5367c2bbf97f521059c78eab65309ad3' | |
74 | factory.filesize = 158437 | |
75 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
76 | return factory.d | |
77 | ||
78 | @deferred(timeout=30.0) | |
79 | def test_retr_longfilename(): | |
80 | # Test file retrieval that has a long English filename | |
81 | info = getConnectionInfo() | |
82 | factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
83 | factory.service = 'smbtest' | |
84 | factory.path = '/Implementing CIFS - SMB.html' | |
85 | factory.digest = '671c5700d279fcbbf958c1bba3c2639e' | |
86 | factory.filesize = 421269 | |
87 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
88 | return factory.d | |
89 | ||
90 | @deferred(timeout=30.0) | |
91 | def test_retr_unicodefilename(): | |
92 | # Test file retrieval that has a long non-English filename inside a folder with a non-English name | |
93 | info = getConnectionInfo() | |
94 | factory = RetrieveFileFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
95 | factory.service = 'smbtest' | |
96 | factory.path = u'/测试文件夹/垃圾文件.dat' | |
97 | factory.digest = '8a44c1e80d55e91c92350955cdf83442' | |
98 | factory.filesize = 256000 | |
99 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
100 | return factory.d |
0 | # -*- coding: utf-8 -*- | |
1 | ||
2 | import os, time, random | |
3 | from StringIO import StringIO | |
4 | from nose.twistedtools import reactor, deferred | |
5 | from twisted.internet import defer | |
6 | from smb.SMBProtocol import SMBProtocolFactory | |
7 | from util import getConnectionInfo | |
8 | ||
9 | try: | |
10 | import hashlib | |
11 | def MD5(): return hashlib.md5() | |
12 | except ImportError: | |
13 | import md5 | |
14 | def MD5(): return md5.new() | |
15 | ||
16 | class StoreFilesFactory(SMBProtocolFactory): | |
17 | """ | |
18 | A super test factory that tests store file, list files, retrieve file and delete file functionlities in sequence. | |
19 | """ | |
20 | ||
21 | TEST_FILENAME = os.path.join(os.path.dirname(__file__), os.pardir, 'SupportFiles', 'binary.dat') | |
22 | TEST_FILESIZE = 256000 | |
23 | TEST_DIGEST = 'bb6303f76e29f354b6fdf6ef58587e48' | |
24 | ||
25 | def __init__(self, *args, **kwargs): | |
26 | SMBProtocolFactory.__init__(self, *args, **kwargs) | |
27 | self.d = defer.Deferred() | |
28 | self.d.addBoth(self.testDone) | |
29 | self.service_name = '' | |
30 | self.filename = '' | |
31 | ||
32 | def testDone(self, r): | |
33 | if self.instance: | |
34 | self.instance.transport.loseConnection() | |
35 | return r | |
36 | ||
37 | def storeComplete(self, result): | |
38 | file_obj, filesize = result | |
39 | file_obj.close() | |
40 | assert filesize == self.TEST_FILESIZE | |
41 | ||
42 | d = self.listPath(self.service_name, os.path.dirname(self.filename.replace('/', os.sep))) | |
43 | d.addCallback(self.listComplete) | |
44 | d.addErrback(self.d.errback) | |
45 | ||
46 | def listComplete(self, entries): | |
47 | filenames = map(lambda e: e.filename, entries) | |
48 | assert os.path.basename(self.filename.replace('/', os.sep)) in filenames | |
49 | ||
50 | d = self.retrieveFile(self.service_name, self.filename, StringIO()) | |
51 | d.addCallback(self.retrieveComplete) | |
52 | d.addErrback(self.d.errback) | |
53 | ||
54 | def retrieveComplete(self, result): | |
55 | file_obj, file_attributes, file_size = result | |
56 | ||
57 | md = MD5() | |
58 | md.update(file_obj.getvalue()) | |
59 | file_obj.close() | |
60 | ||
61 | assert file_size == self.TEST_FILESIZE | |
62 | assert md.hexdigest() == self.TEST_DIGEST | |
63 | ||
64 | d = self.deleteFiles(self.service_name, self.filename) | |
65 | d.addCallback(self.deleteComplete) | |
66 | d.addErrback(self.d.errback) | |
67 | ||
68 | def deleteComplete(self, result): | |
69 | d = self.listPath(self.service_name, os.path.dirname(self.filename.replace('/', os.sep))) | |
70 | d.addCallback(self.list2Complete) | |
71 | d.addErrback(self.d.errback) | |
72 | ||
73 | def list2Complete(self, entries): | |
74 | filenames = map(lambda e: e.filename, entries) | |
75 | assert os.path.basename(self.filename.replace('/', os.sep)) not in filenames | |
76 | self.d.callback(True) | |
77 | self.instance.transport.loseConnection() | |
78 | ||
79 | def onAuthOK(self): | |
80 | d = self.storeFile(self.service_name, self.filename, open(self.TEST_FILENAME, 'rb')) | |
81 | d.addCallback(self.storeComplete) | |
82 | d.addErrback(self.d.errback) | |
83 | ||
84 | def onAuthFailed(self): | |
85 | self.d.errback('Auth failed') | |
86 | ||
87 | ||
88 | @deferred(timeout=30.0) | |
89 | def test_store_long_filename(): | |
90 | info = getConnectionInfo() | |
91 | factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
92 | factory.service_name = 'smbtest' | |
93 | factory.filename = os.sep + 'StoreTest %d-%d.dat' % ( time.time(), random.randint(0, 10000) ) | |
94 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
95 | return factory.d | |
96 | ||
97 | @deferred(timeout=30.0) | |
98 | def test_store_unicode_filename(): | |
99 | info = getConnectionInfo() | |
100 | factory = StoreFilesFactory(info['user'], info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = True) | |
101 | factory.service_name = 'smbtest' | |
102 | factory.filename = os.sep + u'上载测试 %d-%d.dat' % ( time.time(), random.randint(0, 10000) ) | |
103 | reactor.connectTCP(info['server_ip'], info['server_port'], factory) | |
104 | return factory.d |
0 | ||
1 | import os | |
2 | from ConfigParser import SafeConfigParser | |
3 | ||
4 | def getConnectionInfo(): | |
5 | config_filename = os.path.join(os.path.dirname(__file__), os.path.pardir, 'connection.ini') | |
6 | cp = SafeConfigParser() | |
7 | cp.read(config_filename) | |
8 | ||
9 | info = { | |
10 | 'server_name': cp.get('server', 'name'), | |
11 | 'server_ip': cp.get('server', 'ip'), | |
12 | 'server_port': cp.getint('server', 'port'), | |
13 | 'client_name': cp.get('client', 'name'), | |
14 | 'user': cp.get('user', 'name'), | |
15 | 'password': cp.get('user', 'password'), | |
16 | } | |
17 | return info | |
18 |
Binary diff not shown
0 | ||
1 | [server] | |
2 | name = SERVER | |
3 | ip = 192.168.1.1 | |
4 | port = 139 | |
5 | ||
6 | [client] | |
7 | name = TESTCLIENT | |
8 | ||
9 | [user] | |
10 | name = myuser | |
11 | password = mypassword |
Binary diff not shown
0 | ||
1 | import binascii | |
2 | from smb import ntlm | |
3 | ||
4 | def test_NTLMv1_without_extended_security(): | |
5 | password = 'Password' | |
6 | server_challenge = '\x01\x23\x45\x67\x89\xab\xcd\xef' | |
7 | ||
8 | nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(password, | |
9 | server_challenge, | |
10 | has_extended_security = False, | |
11 | client_challenge = '\xAA'*8) | |
12 | ||
13 | assert binascii.hexlify(nt_challenge_response).lower() == '67 c4 30 11 f3 02 98 a2 ad 35 ec e6 4f 16 33 1c 44 bd be d9 27 84 1f 94'.replace(' ', '') # [MS-NLMP]: 4.2.2.2.1 | |
14 | assert binascii.hexlify(lm_challenge_response).lower() == '98 de f7 b8 7f 88 aa 5d af e2 df 77 96 88 a1 72 de f1 1c 7d 5c cd ef 13'.replace(' ', '') # [MS-NLMP]: 4.2.2.2.2 | |
15 | ||
16 | ||
17 | def test_NTLMv1_with_extended_security(): | |
18 | password = 'Password' | |
19 | server_challenge = '\x01\x23\x45\x67\x89\xab\xcd\xef' | |
20 | ||
21 | nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV1(password, | |
22 | server_challenge, | |
23 | has_extended_security = True, | |
24 | client_challenge = '\xAA'*8) | |
25 | ||
26 | assert binascii.hexlify(nt_challenge_response).lower() == '75 37 f8 03 ae 36 71 28 ca 45 82 04 bd e7 ca f8 1e 97 ed 26 83 26 72 32'.replace(' ', '') # [MS-NLMP]: 4.2.3.2.2 | |
27 | assert binascii.hexlify(lm_challenge_response).lower() == 'aa aa aa aa aa aa aa aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'.replace(' ', '') # [MS-NLMP]: 4.2.3.2.1 | |
28 | ||
29 | ||
30 | def test_NTLMv2(): | |
31 | user = 'User' | |
32 | password = 'Password' | |
33 | domain = 'Domain' | |
34 | server_challenge = '\x01\x23\x45\x67\x89\xab\xcd\xef' | |
35 | ||
36 | server_avpair = binascii.unhexlify('01 00 0c 00 53 00 65 00 72 00 76 00 65 00 72 00'.replace(' ', '')) | |
37 | domain_avpair = binascii.unhexlify('02 00 0c 00 44 00 6f 00 6d 00 61 00 69 00 6e 00'.replace(' ', '')) | |
38 | ||
39 | nt_challenge_response, lm_challenge_response, session_key = ntlm.generateChallengeResponseV2(password, | |
40 | user, | |
41 | server_challenge, | |
42 | server_avpair + domain_avpair + '\0'*4, | |
43 | domain, | |
44 | client_challenge = '\xAA'*8) | |
45 | ||
46 | assert binascii.hexlify(lm_challenge_response).lower() == '86 c3 50 97 ac 9c ec 10 25 54 76 4a 57 cc cc 19 aa aa aa aa aa aa aa aa'.replace(' ', '') # [MS-NLMP]: 4.2.4.2.1 |
0 | ||
1 | import binascii | |
2 | from smb import securityblob | |
3 | ||
4 | ||
5 | def test_NTLMSSP_NEGOTIATE_encoding(): | |
6 | ntlm_data = binascii.unhexlify('4e544c4d5353500001000000978208e200000000000000000000000000000000060072170000000f') # The NTLM negotiate message | |
7 | blob = securityblob.generateNegotiateSecurityBlob(ntlm_data) | |
8 | ||
9 | TARGET = binascii.unhexlify(""" | |
10 | 60 48 06 06 2b 06 01 05 05 02 a0 3e 30 3c a0 0e | |
11 | 30 0c 06 0a 2b 06 01 04 01 82 37 02 02 0a a2 2a | |
12 | 04 28 4e 54 4c 4d 53 53 50 00 01 00 00 00 97 82 | |
13 | 08 e2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
14 | 00 00 06 00 72 17 00 00 00 0f | |
15 | """.replace(' ', '').replace('\n', '')) | |
16 | ||
17 | assert blob == TARGET | |
18 | ||
19 | ||
20 | def test_NTLMSSP_CHALLENGE_decoding(): | |
21 | blob = binascii.unhexlify(""" | |
22 | a1 81 be 30 81 bb a0 03 0a 01 01 a1 0c 06 0a 2b | |
23 | 06 01 04 01 82 37 02 02 0a a2 81 a5 04 81 a2 4e | |
24 | 54 4c 4d 53 53 50 00 02 00 00 00 0a 00 0a 00 38 | |
25 | 00 00 00 15 82 8a e2 32 81 ce 29 7f de 3f 80 00 | |
26 | 00 00 00 00 00 00 00 60 00 60 00 42 00 00 00 06 | |
27 | 01 00 00 00 00 00 0f 43 00 45 00 54 00 55 00 53 | |
28 | 00 02 00 0a 00 43 00 45 00 54 00 55 00 53 00 01 | |
29 | 00 0a 00 43 00 45 00 54 00 55 00 53 00 04 00 16 | |
30 | 00 6c 00 6f 00 63 00 61 00 6c 00 64 00 6f 00 6d | |
31 | 00 61 00 69 00 6e 00 03 00 22 00 63 00 65 00 74 | |
32 | 00 75 00 73 00 2e 00 6c 00 6f 00 63 00 61 00 6c | |
33 | 00 64 00 6f 00 6d 00 61 00 69 00 6e 00 00 00 00 | |
34 | 00""".replace(' ', '').replace('\n', '')) | |
35 | ||
36 | RESPONSE_TOKENS = binascii.unhexlify(""" | |
37 | 4e 54 4c 4d 53 53 50 00 02 00 00 00 0a 00 0a 00 | |
38 | 38 00 00 00 15 82 8a e2 32 81 ce 29 7f de 3f 80 | |
39 | 00 00 00 00 00 00 00 00 60 00 60 00 42 00 00 00 | |
40 | 06 01 00 00 00 00 00 0f 43 00 45 00 54 00 55 00 | |
41 | 53 00 02 00 0a 00 43 00 45 00 54 00 55 00 53 00 | |
42 | 01 00 0a 00 43 00 45 00 54 00 55 00 53 00 04 00 | |
43 | 16 00 6c 00 6f 00 63 00 61 00 6c 00 64 00 6f 00 | |
44 | 6d 00 61 00 69 00 6e 00 03 00 22 00 63 00 65 00 | |
45 | 74 00 75 00 73 00 2e 00 6c 00 6f 00 63 00 61 00 | |
46 | 6c 00 64 00 6f 00 6d 00 61 00 69 00 6e 00 00 00 | |
47 | 00 00 | |
48 | """.replace(' ', '').replace('\n', '')) | |
49 | ||
50 | result, response_tokens = securityblob.decodeChallengeSecurityBlob(blob) | |
51 | ||
52 | assert result == securityblob.RESULT_ACCEPT_INCOMPLETE | |
53 | assert response_tokens == RESPONSE_TOKENS | |
54 | ||
55 | ||
56 | def test_NTLMSSP_AUTH_encoding(): | |
57 | ntlm_data = binascii.unhexlify(""" | |
58 | 4e 54 4c 4d 53 53 50 00 03 00 00 00 01 00 01 00 | |
59 | 70 00 00 00 00 00 00 00 71 00 00 00 00 00 00 00 | |
60 | 58 00 00 00 00 00 00 00 58 00 00 00 18 00 18 00 | |
61 | 58 00 00 00 10 00 10 00 71 00 00 00 15 8a 88 e2 | |
62 | 06 00 72 17 00 00 00 0f 06 49 3b c4 f6 2a 2b be | |
63 | 61 a6 81 e7 cc 58 37 b4 4d 00 49 00 43 00 48 00 | |
64 | 41 00 45 00 4c 00 2d 00 49 00 35 00 50 00 43 00 | |
65 | 00 a7 0d b4 74 c3 d8 14 c9 df 3d 80 6d 87 94 42 | |
66 | bc | |
67 | """.replace(' ', '').replace('\n', '')) | |
68 | ||
69 | TARGET = binascii.unhexlify(""" | |
70 | a1 81 8a 30 81 87 a2 81 84 04 81 81 4e 54 4c 4d | |
71 | 53 53 50 00 03 00 00 00 01 00 01 00 70 00 00 00 | |
72 | 00 00 00 00 71 00 00 00 00 00 00 00 58 00 00 00 | |
73 | 00 00 00 00 58 00 00 00 18 00 18 00 58 00 00 00 | |
74 | 10 00 10 00 71 00 00 00 15 8a 88 e2 06 00 72 17 | |
75 | 00 00 00 0f 06 49 3b c4 f6 2a 2b be 61 a6 81 e7 | |
76 | cc 58 37 b4 4d 00 49 00 43 00 48 00 41 00 45 00 | |
77 | 4c 00 2d 00 49 00 35 00 50 00 43 00 00 a7 0d b4 | |
78 | 74 c3 d8 14 c9 df 3d 80 6d 87 94 42 bc | |
79 | """.replace(' ', '').replace('\n', '')) | |
80 | ||
81 | blob = securityblob.generateAuthSecurityBlob(ntlm_data) | |
82 | ||
83 | assert blob == TARGET | |
84 | ||
85 | ||
86 | def test_auth_response_decoding(): | |
87 | blob = binascii.unhexlify("a1 07 30 05 a0 03 0a 01 00".replace(' ', '')) | |
88 | ||
89 | result = securityblob.decodeAuthResponseSecurityBlob(blob) | |
90 | assert result == securityblob.RESULT_ACCEPT_COMPLETED | |
91 |