Import from old repository

This commit is contained in:
Stefan 2020-04-06 18:48:34 +02:00
commit 0da6783a45
762 changed files with 103065 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# Ignore back-up files.
*~
# Ignore compiled Python files.
*.pyc
*.pyo
# Don't include build related files.
/dependencies/
/dist/
/build/
# And don't care about the 'egg'.
/plaso.egg-info
# Test files
.coverage
tests-coverage.txt
# And don't care about the temporary code review file if it exists.
._code_review_number

14
.travis.yml Normal file
View File

@ -0,0 +1,14 @@
language: python
python:
- "2.7"
before_install:
- sudo add-apt-repository ppa:kristinn-l/plaso-dev -y
- sudo apt-get update -q
- sudo apt-get install binplist libbde-python libesedb-python libevt-python libevtx-python libewf-python libfwsi-python liblnk-python libmsiecf-python libolecf-python libqcow-python libregf-python libsmdev-python libsmraw-python libvhdi-python libvmdk-python libvshadow-python ipython python-bencode python-construct python-dateutil python-dfvfs python-dpkt python-hachoir-core python-hachoir-metadata python-hachoir-parser python-protobuf python-psutil python-pyparsing python-six python-yaml python-tz pytsk3
- sudo pip install coveralls
- sudo pip install ipython --upgrade
script:
- ./run_tests.py
- coverage run --source=plaso --omit="*_test*,*__init__*,*test_lib*" ./run_tests.py
after_success:
- coveralls

138
ACKNOWLEDGEMENTS Normal file
View File

@ -0,0 +1,138 @@
Acknowledgements: plaso
Copyright 2012 The Plaso Project Authors.
Please see the AUTHORS file for details on individual authors.
Plaso is a Python rewrite of the log2timeline Perl version.
Plaso is developed and maintained by:
* Kristinn Gudjonsson
* Eric Mak
* Joachim Metz
Plaso depends on various other projects. So thanks to the authors
and others involved with these projects:
* Python and modules
* libyaml
* iPython
* PyInstaller
* the SleuthKit
* pytsk
* Hachoir (not included in binary release)
Thanks to contributors (alphabetically based on last name):
* Brian Baskin
* Parsers
* BEncode
* Java IDX parser
* Johan Berggren
* SQLite plugins
* Zeitgeist activity database
* Petter Bjelland
* Parsers
* Firefox Cache
* Ashley Holtz
* Parsers
* IIS
* Adobe ColdFusion
* Dominique Kilman
* Parsers
* PCAP
* Marc Leavitt
* Parsers
* PL-SQL recall (PLSRecall.dat)
* Preston Miller
*Windows Registry Plugins
* SAM Users
* Shutdown
* USB
* Joaquin Moreno Garijo
* Parsers
* ASL
* BSM
* Cups IPP
* Mac AppFirewall
* Mac KeyChain
* Mac Securityd
* mac_wifi.log
* utmp
* utmpx
* SQLite plugins
* Skype
* Plist plugins
* Airport
* Apple Account
* Install History
* Mac User
* Software Update
* Spotlight
* TimeMachine
* David Nides (@davnads)
* Output modules
* 4n6time SQLite, with thanks to Eric Wong for assistance
* 4n6time MySQL
* Parsers
* Hachoir (meta data)
* OLECF
* OMXL
* Symantec AV Log
* timelib StringToDatetime function
* SQLite plugins
* Google Drive
* Windows Registry plugins
* Office MRU
* Outlook
* Terminal Server Client (RDP)
* Typed Paths
* Typed URLs
* USBStor
* Win7 UserAssist
* WinRar
* Patrik Nisen
* For providing input for parsing the DestList stream for the automatic
destinations OLECF plugin
* Francesco Picasso
* Parsers
* PopContest
* SELinux
* SkyDriveLog
* SkyDriveLogErr
* XChatLog
* XChatScrollBack
* Jordi Sanchez
* For providing:
* binplist
* object filter
* Elizabeth Schweinsberg
* Parsers
* McAfee AV Access Protection Log
* Windows Registry plugins
* MSIE zones
* Marc Séguin
* Windows Registry plugins
* CCleaner
* Keith Wall
* SQLite plugins
* Android calls database
* Android sms database
* updates to the timezone transformation
Test data:
Copied with permission from the GRR project: https://github.com/google/grr
* History
* index.dat
* places.sqlite
Copied with permission granted by Jerome Marty.
* WUAUCLT.EXE-830BCC14.pf
Copied with permission granted by Rob Lee.
Copyright SANS Institute - Digital Forensics and Incident Response.
* 1b4dd67f29cb1962.automaticDestinations-ms
* 5afe4de1b92fc382.customDestinations-ms
* example.lnk
* SysEvent.Evt
* System.evtx
* Ntuser.dat (multiple instances)
* Windows.edb

27
AUTHORS Normal file
View File

@ -0,0 +1,27 @@
# Names should be added to this file with this pattern:
#
# For individuals:
# Name (email address)
#
# For organizations:
# Organization (fnmatch pattern)
#
# See python fnmatch module documentation for more information.
Google Inc. (*@google.com)
Kristinn Gudjonsson (kiddi@kiddaland.net)
Joachim Metz (joachim.metz@gmail.com)
Brian Baskin (brian@thebaskins.com)
David Nides (david.nides@gmail.com)
Dominique Kilman (lexistar97@gmail.com)
Elizabeth Schweinsberg (beth@bethlogic.net)
Eric Mak (ericmak@gmail.com)
Francesco Picasso (francesco.picasso@gmail.com)
Joaquin Moreno Garijo (Joaquin.MorenoGarijo.2013@live.rhul.ac.uk)
Keith Wall (kwallster@gmail.com)
Marc Seguin (segumarc@gmail.com)
Oliver Jensen (ojensen5115@gmail.com)
Petter Bjelland (petter.bjelland@gmail.com)
Ashley Holtz (ashley.a.holtz@gmail.com)
Stefan Swerk (stefan_rubanetra@swerk.priv.at)
Preston Miller (preston.miller@dpmforensics.com)

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

10
MANIFEST.in Normal file
View File

@ -0,0 +1,10 @@
include ACKNOWLEDGEMENTS AUTHORS LICENSE README
include run_tests.py
include utils/check_dependencies.py
exclude .gitignore
exclude *.pyc
recursive-include config *
recursive-include extra *
recursive-include plaso *.proto
recursive-exclude plaso *.pyc
recursive-include test_data *

31
README Normal file
View File

@ -0,0 +1,31 @@
plaso (Plaso Langar Að Safna Öllu) - super timeline all the things
In short, plaso is a Python-based backend engine for the tool log2timeline.
A longer version:
log2timeline is a tool designed to extract timestamps from various files found
on a typical computer system(s) and aggregate them.
The initial purpose of plaso was to collect all timestamped events of interest
on a computer system and have them aggregated in a single place for computer
forensic analysis (aka Super Timeline).
However plaso has become a framework that supports:
* adding new parsers or parsing plug-ins;
* adding new analysis plug-ins;
* writing one-off scripts to automate repetitive tasks in computer forensic
analysis or equivalent.
And is moving to support:
* adding new general purpose parses/plugins that may not have timestamps
associated to them;
* adding more analysis context;
* tagging events;
* allowing more targeted approach to the collection/parsing.
Also see:
* log2timeline: http://plaso.kiddaland.net/usage/log2timeline/
* Project documentation: http://plaso.kiddaland.net/
* Downloads: https://googledrive.com/host/0B30H7z4S52FleW5vUHBnblJfcjg/

35
README.md Normal file
View File

@ -0,0 +1,35 @@
# plaso (Plaso Langar Að Safna Öllu) #
*super timeline all the things*
Various statistics for the tool:
Code Coverage: [![Coverage
Status](https://img.shields.io/coveralls/log2timeline/plaso.svg)](https://coveralls.io/r/log2timeline/plaso?branch=master)
Build Status: [![Build
Status](https://travis-ci.org/log2timeline/plaso.svg?branch=master)](https://travis-ci.org/log2timeline/plaso)
In short, plaso is a Python-based backend engine for the tool [log2timeline] (http://plaso.kiddaland.net "Plaso home of the super timeline").
## A longer version ##
log2timeline is a tool designed to extract timestamps from various files found on a typical computer system(s) and aggregate them.
The initial purpose of plaso was to collect all timestamped events of interest on a computer system and have them aggregated in a single place for computer forensic analysis (aka Super Timeline).
However plaso has become a framework that supports:
* adding new parsers or parsing plug-ins;
* adding new analysis plug-ins;
* writing one-off scripts to automate repetitive tasks in computer forensic analysis or equivalent.
And is moving to support:
* adding new general purpose parses/plugins that may not have timestamps associated to them;
* adding more analysis context;
* tagging events;
* allowing more targeted approach to the collection/parsing.
Also see:
* [log2timeline] (http://plaso.kiddaland.net/usage/log2timeline/ "Usage for log2timeline")
* [Project documentation] (http://plaso.kiddaland.net/ "Tool's main documentation site")
* [Downloads] (https://googledrive.com/host/0B30H7z4S52FleW5vUHBnblJfcjg/ "Download the latest version")

View File

@ -0,0 +1,23 @@
python-plaso (1.1.0-1) unstable; urgency=low
* Version 1.1.0 development release.
-- Log2Timeline <log2timeline-dev@googlegroups.com> Sat, 14 Dec 2013 12:15:00 +0100
python-plaso (1.0.2-2) unstable; urgency=low
* Version 1.0.2 alpha release.
-- Log2Timeline <log2timeline-dev@googlegroups.com> Mon, 28 Oct 2013 12:20:23 -0700
python-plaso (1.0.2-1) unstable; urgency=low
* Version 1.0.2 RC1 release.
-- Log2Timeline <log2timeline-dev@googlegroups.com> Sat, 19 Oct 2013 09:15:00 +0200
python-plaso (1.0-1) unstable; urgency=low
* Initial release.
-- Log2Timeline <log2timeline-dev@googlegroups.com> Sat, 8 Dec 2012 09:15:00 +0200

View File

@ -0,0 +1 @@
7

View File

@ -0,0 +1,16 @@
Source: python-plaso
Section: unknown
Priority: extra
Maintainer: Log2Timeline <log2timeline-dev@googlegroups.com>
Build-Depends: debhelper (>= 7.0.0), python, python-setuptools
Standards-Version: 3.9.2
Homepage: https://github.com/log2timeline/plaso/
Package: python-plaso
Architecture: all
Depends: binplist, libprotobuf7 | libprotobuf8, libyaml-0-2, libbde-python, libesedb-python, libevt-python, libevtx-python, libewf-python, libfwsi-python, liblnk-python, libmsiecf-python, libolecf-python, libqcow-python, libregf-python, libtsk, libsmdev-python, libsmraw-python, libvhdi-python, libvmdk-python, libvshadow-python, ipython, python-bencode, python-construct, python-dateutil, python-dfvfs, python-dpkt, python-hachoir-core, python-hachoir-metadata, python-hachoir-parser, python-protobuf, python-psutil, python-pyparsing, python-six, python-yaml, python-tz, pytsk3, ${shlibs:Depends}, ${misc:Depends}
Recommends: elasticsearch, libesedb-tools, libbde-tools, libevt-tools, libevtx-tools, libewf-tools, liblnk-tools, libmsiecf-tools, libolecf-tools, libqcow-tools, libregf-tools, libsmdev-tools, libsmraw-tools, libvhdi-tools, libvmdk-tools, libvshadow-tools, libtsk-dev, pyelasticsearch, sleuthkit
Description: Plaso Log2Timeline
Log2Timeline is a framework to create super timelines.
It is a framework to parse various files and collect time-based
digital artifacts that can be used in computer forensics.

View File

@ -0,0 +1,27 @@
Format: http://dep.debian.net/deps/dep5
Upstream-Name: plaso
Source: https://github.com/log2timeline/plaso/
Files: *
Copyright: 2012 The Plaso Project Authors.
License: Apache-2.0
Files: debian/*
Copyright: 2012 The Plaso Project Authors.
License: Apache-2.0
License: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
.
http://www.apache.org/licenses/LICENSE-2.0
.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
.
On Debian systems, the complete text of the Apache version 2.0 license
can be found in "/usr/share/common-licenses/Apache-2.0".

View File

@ -0,0 +1,4 @@
ACKNOWLEDGEMENTS
AUTHORS
LICENSE
README

45
config/dpkg/debian/rules Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/make -f
# debian/rules that uses debhelper >= 7.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# This has to be exported to make some magic below work.
export DH_OPTIONS
%:
dh $@
override_dh_auto_clean:
override_dh_auto_test:
override_dh_installmenu:
override_dh_installmime:
override_dh_installmodules:
override_dh_installlogcheck:
override_dh_installlogrotate:
override_dh_installpam:
override_dh_installppp:
override_dh_installudev:
override_dh_installwm:
override_dh_installxfonts:
override_dh_gconf:
override_dh_icons:
override_dh_perl:
override_dh_pysupport:

View File

@ -0,0 +1,20 @@
Copyright (c) 2006 Kirill Simonov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,143 @@
BitTorrent Open Source License
Version 1.1
This BitTorrent Open Source License (the "License") applies to the BitTorrent client and related software products as well as any updates or maintenance releases of that software ("BitTorrent Products") that are distributed by BitTorrent, Inc. ("Licensor"). Any BitTorrent Product licensed pursuant to this License is a Licensed Product. Licensed Product, in its entirety, is protected by U.S. copyright law. This License identifies the terms under which you may use, copy, distribute or modify Licensed Product.
Preamble
This Preamble is intended to describe, in plain English, the nature and scope of this License. However, this Preamble is not a part of this license. The legal effect of this License is dependent only upon the terms of the License and not this Preamble.
This License complies with the Open Source Definition and is derived from the Jabber Open Source License 1.0 (the "JOSL"), which has been approved by Open Source Initiative. Sections 4(c) and 4(f)(iii) from the JOSL have been deleted.
This License provides that:
1. You may use or give away the Licensed Product, alone or as a component of an aggregate software distribution containing programs from several different sources. No royalty or other fee is required.
2. Both Source Code and executable versions of the Licensed Product, including Modifications made by previous Contributors, are available for your use. (The terms "Licensed Product," "Modifications," "Contributors" and "Source Code" are defined in the License.)
3. You are allowed to make Modifications to the Licensed Product, and you can create Derivative Works from it. (The term "Derivative Works" is defined in the License.)
4. By accepting the Licensed Product under the provisions of this License, you agree that any Modifications you make to the Licensed Product and then distribute are governed by the provisions of this License. In particular, you must make the Source Code of your Modifications available to others free of charge and without a royalty.
5. You may sell, accept donations or otherwise receive compensation for executable versions of a Licensed Product, without paying a royalty or other fee to the Licensor or any Contributor, provided that such executable versions contain your or another Contributor?s material Modifications. For the avoidance of doubt, to the extent your executable version of a Licensed Product does not contain your or another Contributor?s material Modifications, you may not sell, accept donations or otherwise receive compensation for such executable.
You may use the Licensed Product for any purpose, but the Licensor is not providing you any warranty whatsoever, nor is the Licensor accepting any liability in the event that the Licensed Product doesn't work properly or causes you any injury or damages.
6. If you sublicense the Licensed Product or Derivative Works, you may charge fees for warranty or support, or for accepting indemnity or liability obligations to your customers. You cannot charge for, sell, accept donations or otherwise receive compensation for the Source Code.
7. If you assert any patent claims against the Licensor relating to the Licensed Product, or if you breach any terms of the License, your rights to the Licensed Product under this License automatically terminate.
You may use this License to distribute your own Derivative Works, in which case the provisions of this License will apply to your Derivative Works just as they do to the original Licensed Product.
Alternatively, you may distribute your Derivative Works under any other OSI-approved Open Source license, or under a proprietary license of your choice. If you use any license other than this License, however, you must continue to fulfill the requirements of this License (including the provisions relating to publishing the Source Code) for those portions of your Derivative Works that consist of the Licensed Product, including the files containing Modifications.
New versions of this License may be published from time to time in connection with new versions of a Licensed Product or otherwise. You may choose to continue to use the license terms in this version of the License for the Licensed Product that was originally licensed hereunder, however, the new versions of this License will at all times apply to new versions of the Licensed Product released by Licensor after the release of the new version of this License. Only the Licensor has the right to change the License terms as they apply to the Licensed Product.
This License relies on precise definitions for certain terms. Those terms are defined when they are first used, and the definitions are repeated for your convenience in a Glossary at the end of the License.
License Terms
1. Grant of License From Licensor. Subject to the terms and conditions of this License, Licensor hereby grants you a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims, to do the following:
a. Use, reproduce, modify, display, perform, sublicense and distribute any Modifications created by a Contributor or portions thereof, in both Source Code or as an executable program, either on an unmodified basis or as part of Derivative Works.
b. Under claims of patents now or hereafter owned or controlled by Contributor, to make, use, sell, offer for sale, have made, and/or otherwise dispose of Modifications or portions thereof, but solely to the extent that any such claim is necessary to enable you to make, use, sell, offer for sale, have made, and/or otherwise dispose of Modifications or portions thereof or Derivative Works thereof.
2. Grant of License to Modifications From Contributor. "Modifications" means any additions to or deletions from the substance or structure of (i) a file containing a Licensed Product, or (ii) any new file that contains any part of a Licensed Product. Hereinafter in this License, the term "Licensed Product" shall include all previous Modifications that you receive from any Contributor. Subject to the terms and conditions of this License, By application of the provisions in Section 4(a) below, each person or entity who created or contributed to the creation of, and distributed, a Modification (a "Contributor") hereby grants you a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims, to do the following:
a. Use, reproduce, modify, display, perform, sublicense and distribute any Modifications created by such Contributor or portions thereof, in both Source Code or as an executable program, either on an unmodified basis or as part of Derivative Works.
b. Under claims of patents now or hereafter owned or controlled by Contributor, to make, use, sell, offer for sale, have made, and/or otherwise dispose of Modifications or portions thereof, but solely to the extent that any such claim is necessary to enable you to make, use, sell, offer for sale, have made, and/or otherwise dispose of Modifications or portions thereof or Derivative Works thereof.
3. Exclusions From License Grant. Nothing in this License shall be deemed to grant any rights to trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor or any Contributor except as expressly stated herein. No patent license is granted separate from the Licensed Product, for code that you delete from the Licensed Product, or for combinations of the Licensed Product with other software or hardware. No right is granted to the trademarks of Licensor or any Contributor even if such marks are included in the Licensed Product. Nothing in this License shall be interpreted to prohibit Licensor from licensing under different terms from this License any code that Licensor otherwise would have a right to license. As an express condition for your use of the Licensed Product, you hereby agree that you will not, without the prior written consent of Licensor, use any trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor or any Contributor except as expressly stated herein. For the avoidance of doubt and without limiting the foregoing, you hereby agree that you will not use or display any trademark of Licensor or any Contributor in any domain name, directory filepath, advertisement, link or other reference to you in any manner or in any media.
4. Your Obligations Regarding Distribution.
a. Application of This License to Your Modifications. As an express condition for your use of the Licensed Product, you hereby agree that any Modifications that you create or to which you contribute, and which you distribute, are governed by the terms of this License including, without limitation, Section 2. Any Modifications that you create or to which you contribute may be distributed only under the terms of this License or a future version of this License released under Section 7. You must include a copy of this License with every copy of the Modifications you distribute. You agree not to offer or impose any terms on any Source Code or executable version of the Licensed Product or Modifications that alter or restrict the applicable version of this License or the recipients' rights hereunder. However, you may include an additional document offering the additional rights described in Section 4(d).
b. Availability of Source Code. You must make available, without charge, under the terms of this License, the Source Code of the Licensed Product and any Modifications that you distribute, either on the same media as you distribute any executable or other form of the Licensed Product, or via a mechanism generally accepted in the software development community for the electronic transfer of data (an "Electronic Distribution Mechanism"). The Source Code for any version of Licensed Product or Modifications that you distribute must remain available for as long as any executable or other form of the Licensed Product is distributed by you. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party.
c. Intellectual Property Matters.
i. Third Party Claims. If you have knowledge that a license to a third party's intellectual property right is required to exercise the rights granted by this License, you must include a text file with the Source Code distribution titled "LEGAL" that describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If you obtain such knowledge after you make any Modifications available as described in Section 4(b), you shall promptly modify the LEGAL file in all copies you make available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Licensed Product from you that new knowledge has been obtained.
ii. Contributor APIs. If your Modifications include an application programming interface ("API") and you have knowledge of patent licenses that are reasonably necessary to implement that API, you must also include this information in the LEGAL file.
iii. Representations. You represent that, except as disclosed pursuant to 4(c)(i) above, you believe that any Modifications you distribute are your original creations and that you have sufficient rights to grant the rights conveyed by this License.
d. Required Notices. You must duplicate this License in any documentation you provide along with the Source Code of any Modifications you create or to which you contribute, and which you distribute, wherever you describe recipients' rights relating to Licensed Product. You must duplicate the notice contained in Exhibit A (the "Notice") in each file of the Source Code of any copy you distribute of the Licensed Product. If you created a Modification, you may add your name as a Contributor to the Notice. If it is not possible to put the Notice in a particular Source Code file due to its structure, then you must include such Notice in a location (such as a relevant directory file) where a user would be likely to look for such a notice. You may choose to offer, and charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Licensed Product. However, you may do so only on your own behalf, and not on behalf of the Licensor or any Contributor. You must make it clear that any such warranty, support, indemnity or liability obligation is offered by you alone, and you hereby agree to indemnify the Licensor and every Contributor for any liability incurred by the Licensor or such Contributor as a result of warranty, support, indemnity or liability terms you offer.
e. Distribution of Executable Versions. You may distribute Licensed Product as an executable program under a license of your choice that may contain terms different from this License provided (i) you have satisfied the requirements of Sections 4(a) through 4(d) for that distribution, (ii) you include a conspicuous notice in the executable version, related documentation and collateral materials stating that the Source Code version of the
Licensed Product is available under the terms of this License, including a description of how and where you have fulfilled the obligations of Section 4(b), and (iii) you make it clear that any terms that differ from this License are offered by you alone, not by Licensor or any Contributor. You hereby agree to indemnify the Licensor and every Contributor for any liability incurred by Licensor or such Contributor as a result of any terms you offer.
f. Distribution of Derivative Works. You may create Derivative Works (e.g., combinations of some or all of the Licensed Product with other code) and distribute the Derivative Works as products under any other license you select, with the proviso that the requirements of this License are fulfilled for those portions of the Derivative Works that consist of the Licensed Product or any Modifications thereto.
g. Compensation for Distribution of Executable Versions of Licensed Products, Modifications or Derivative Works. Notwithstanding any provision of this License to the contrary, by distributing, selling, licensing, sublicensing or otherwise making available any Licensed Product, or Modification or Derivative Work thereof, you and Licensor hereby acknowledge and agree that you may sell, license or sublicense for a fee, accept donations or otherwise receive compensation for executable versions of a Licensed Product, without paying a royalty or other fee to the Licensor or any other Contributor, provided that such executable versions (i) contain your or another Contributor?s material Modifications, or (ii) are otherwise material Derivative Works. For purposes of this License, an executable version of the Licensed Product will be deemed to contain a material Modification, or will otherwise be deemed a material Derivative Work, if (a) the Licensed Product is modified with your own or a third party?s software programs or other code, and/or the Licensed Product is combined with a number of your own or a third party?s software programs or code, respectively, and (b) such software programs or code add or contribute material value, functionality or features to the License Product. For the avoidance of doubt, to the extent your executable version of a Licensed Product does not contain your or another Contributor?s material Modifications or is otherwise not a material Derivative Work, in each case as contemplated herein, you may not sell, license or sublicense for a fee, accept donations or otherwise receive compensation for such executable. Additionally, without limitation of the foregoing and notwithstanding any provision of this License to the contrary, you cannot charge for, sell, license or sublicense for a fee, accept donations or otherwise receive compensation for the Source Code.
5. Inability to Comply Due to Statute or Regulation. If it is impossible for you to comply with any of the terms of this License with respect to some or all of the Licensed Product due to statute, judicial order, or regulation, then you must (i) comply with the terms of this License to the maximum extent possible, (ii) cite the statute or regulation that prohibits you from adhering to the License, and (iii) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 4(d), and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill at computer programming to be able to understand it.
6. Application of This License. This License applies to code to which Licensor or Contributor has attached the Notice in Exhibit A, which is incorporated herein by this reference.
7. Versions of This License.
a. New Versions. Licensor may publish from time to time revised and/or new versions of the License.
b. Effect of New Versions. Once Licensed Product has been published under a particular version of the License, you may always continue to use it under the terms of that version, provided that any such license be in full force and effect at the time, and has not been revoked or otherwise terminated. You may also choose to use such Licensed Product under the terms of any subsequent version (but not any prior version) of the License published by Licensor. No one other than Licensor has the right to modify the terms applicable to Licensed Product created under this License.
c. Derivative Works of this License. If you create or use a modified version of this License, which you may do only in order to apply it to software that is not already a Licensed Product under this License, you must rename your license so that it is not confusingly similar to this License, and must make it clear that your license contains terms that differ from this License. In so naming your license, you may not use any trademark of Licensor or any Contributor.
8. Disclaimer of Warranty. LICENSED PRODUCT IS PROVIDED UNDER THIS LICENSE ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE LICENSED PRODUCT IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LICENSED PRODUCT IS WITH YOU. SHOULD LICENSED PRODUCT PROVE DEFECTIVE IN ANY RESPECT, YOU (AND NOT THE LICENSOR OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS
DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF LICENSED PRODUCT IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
9. Termination.
a. Automatic Termination Upon Breach. This license and the rights granted hereunder will terminate automatically if you fail to comply with the terms herein and fail to cure such breach within ten (10) days of being notified of the breach by the Licensor. For purposes of this provision, proof of delivery via email to the address listed in the ?WHOIS? database of the registrar for any website through which you distribute or market any Licensed Product, or to any alternate email address which you designate in writing to the Licensor, shall constitute sufficient notification. All sublicenses to the Licensed Product that are properly granted shall survive any termination of this license so long as they continue to complye with the terms of this License. Provisions that, by their nature, must remain in effect beyond the termination of this License, shall survive.
b. Termination Upon Assertion of Patent Infringement. If you initiate litigation by asserting a patent infringement claim (excluding declaratory judgment actions) against Licensor or a Contributor (Licensor or Contributor against whom you file such an action is referred to herein as Respondent) alleging that Licensed Product directly or indirectly infringes any patent, then any and all rights granted by such Respondent to you under Sections 1 or 2 of this License shall terminate prospectively upon sixty (60) days notice from Respondent (the "Notice Period") unless within that Notice Period you either agree in writing (i) to pay Respondent a mutually agreeable reasonably royalty for your past or future use of Licensed Product made by such Respondent, or (ii) withdraw your litigation claim with respect to Licensed Product against such Respondent. If within said Notice Period a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Licensor to you under Sections 1 and 2 automatically terminate at the expiration of said Notice Period.
c. Reasonable Value of This License. If you assert a patent infringement claim against Respondent alleging that Licensed Product directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by said Respondent under Sections 1 and 2 shall be taken into account in determining the amount or value of any payment or license.
d. No Retroactive Effect of Termination. In the event of termination under Sections 9(a) or 9(b) above, all end user license agreements (excluding licenses to distributors and resellers) that have been validly granted by you or any distributor hereunder prior to termination shall survive termination.
10. Limitation of Liability. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE LICENSOR, ANY CONTRIBUTOR, OR ANY DISTRIBUTOR OF LICENSED PRODUCT, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
11. Responsibility for Claims. As between Licensor and Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License. You agree to work with Licensor and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
12. U.S. Government End Users. The Licensed Product is a commercial item, as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of commercial computer software and commercial computer software documentation, as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Licensed Product with only those rights set forth herein.
13. Miscellaneous. This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. You expressly agree that in any litigation relating to this license the losing party shall be responsible for costs including, without limitation, court costs and reasonable attorneys fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation that provides that the language of a contract shall be construed against the drafter shall not apply to this License.
14. Definition of You in This License. You throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 7. For legal entities, you includes any entity that controls, is controlled by, is under common control with, or affiliated with, you. For purposes of this definition, control means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. You are responsible for advising any affiliated entity of the terms of this License, and that any rights or privileges derived from or obtained by way of this License are subject to the restrictions outlined herein.
15. Glossary. All defined terms in this License that are used in more than one Section of this License are repeated here, in alphabetical order, for the convenience of the reader. The Section of this License in which each defined term is first used is shown in parentheses.
Contributor: Each person or entity who created or contributed to the creation of, and distributed, a Modification. (See Section 2)
Derivative Works: That term as used in this License is defined under U.S. copyright law. (See Section 1(b))
License: This BitTorrent Open Source License. (See first paragraph of License)
Licensed Product: Any BitTorrent Product licensed pursuant to this License. The term "Licensed Product" includes all previous Modifications from any Contributor that you receive. (See first paragraph of License and Section 2)
Licensor: BitTorrent, Inc. (See first paragraph of License)
Modifications: Any additions to or deletions from the substance or structure of (i) a file containing Licensed Product, or (ii) any new file that contains any part of Licensed Product. (See Section 2)
Notice: The notice contained in Exhibit A. (See Section 4(e))
Source Code: The preferred form for making modifications to the Licensed Product, including all modules contained therein, plus any associated interface definition files, scripts used to control compilation and installation of an executable program, or a list of differential comparisons against the Source Code of the Licensed Product. (See Section 1(a))
You: This term is defined in Section 14 of this License.
EXHIBIT A
The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product or any hereto. Contributors to any Modifications may add their own copyright notices to identify their own contributions.
License:
The contents of this file are subject to the BitTorrent Open Source License Version 1.0 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License at http://www.bittorrent.com/license/.
Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License.

View File

@ -0,0 +1,13 @@
Copyright 2013 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,21 @@
Copyright (C) 2006-2013
Tomer Filiba (tomerfiliba@gmail.com)
Corbin Simpson (MostAwesomeDude@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,29 @@
dateutil - Extensions to the standard python 2.3+ datetime module.
Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,28 @@
Copyright (c) 2004 Dug Song <dugsong@monkey.org>
All rights reserved, all wrongs reversed.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors and copyright holders may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,85 @@
=============================
The IPython licensing terms
=============================
IPython is licensed under the terms of the Modified BSD License (also known as
New or Revised BSD), as follows:
Copyright (c) 2008-2010, IPython Development Team
Copyright (c) 2001-2007, Fernando Perez. <fernando.perez@colorado.edu>
Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the IPython Development Team nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
About the IPython Development Team
----------------------------------
Fernando Perez began IPython in 2001 based on code from Janko Hauser
<jhauser@zscout.de> and Nathaniel Gray <n8gray@caltech.edu>. Fernando is still
the project lead.
The IPython Development Team is the set of all contributors to the IPython
project. This includes all of the IPython subprojects. A full list with
details is kept in the documentation directory, in the file
``about/credits.txt``.
The core team that coordinates development on GitHub can be found here:
http://github.com/ipython. As of late 2010, it consists of:
* Brian E. Granger
* Jonathan March
* Evan Patterson
* Fernando Perez
* Min Ragan-Kelley
* Robert Kern
Our Copyright Policy
--------------------
IPython uses a shared copyright model. Each contributor maintains copyright
over their contributions to IPython. But, it is important to note that these
contributions are typically only changes to the repositories. Thus, the IPython
source code, in its entirety is not the copyright of any single person or
institution. Instead, it is the collective copyright of the entire IPython
Development Team. If individual contributors want to maintain a record of what
changes/contributions they have specific copyright on, they should indicate
their copyright in the commit message of the change, when they commit the
change to one of the IPython repositories.
With this in mind, the following banner should be used in any source code file
to indicate the copyright and license terms:
#-----------------------------------------------------------------------------
# Copyright (c) 2010, IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,19 @@
Copyright (c) 2006 Kirill Simonov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,33 @@
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Code generated by the Protocol Buffer compiler is owned by the owner
of the input file used when generating it. This code is not
standalone and requires a support library to be linked with it. This
support library is itself covered by the above license.

View File

@ -0,0 +1,27 @@
psutil is distributed under BSD license reproduced below.
Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola'
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the psutil authors nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

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

View File

@ -0,0 +1,364 @@
================================
The PyInstaller licensing terms
================================
Copyright (c) 2010-2013, PyInstaller Development Team
Copyright (c) 2005-2009, Giovanni Bajo
Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
PyInstaller is licensed under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Bootloader Exception
--------------------
In addition to the permissions in the GNU General Public License, the
authors give you unlimited permission to link or embed compiled bootloader
and related files into combinations with other programs, and to distribute
those combinations without any restriction coming from the use of those
files. (The General Public License restrictions do apply in other respects;
for example, they cover modification of the files, and distribution when
not linked into a combine executable.)
Bootloader and Related Files
----------------------------
Bootloader and related files are files which are embedded within the
final executable. This includes files in directories:
./bootloader/
./PyInstaller/loader
About the PyInstaller Development Team
--------------------------------------
The PyInstaller Development Team is the set of contributors
to the PyInstaller project. A full list with details is kept
in the documentation directory, in the file
``doc/credits.txt``.
The core team that coordinates development on GitHub can be found here:
https://github.com/pyinstaller/pyinstaller. As of 2013, it consists of:
* Giovanni Bajo
* Hartmut Goebel
* Martin Zibricky
Our Copyright Policy
--------------------
PyInstaller uses a shared copyright model. Each contributor maintains copyright
over their contributions to PyInstaller. But, it is important to note that these
contributions are typically only changes to the repositories. Thus,
the PyInstaller source code, in its entirety is not the copyright of any single
person or institution. Instead, it is the collective copyright of the entire
PyInstaller Development Team. If individual contributors want to maintain
a record of what changes/contributions they have specific copyright on, they
should indicate their copyright in the commit message of the change, when they
commit the change to the PyInstaller repository.
With this in mind, the following banner should be used in any source code file
to indicate the copyright and license terms:
#-----------------------------------------------------------------------------
# Copyright (c) 2013, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License with exception
# for distributing bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
GNU General Public License
--------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View File

@ -0,0 +1,18 @@
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,19 @@
Copyright (c) 2004-2013 Gerhard Häring
This software is provided 'as-is', without any express or implied warranty. In
no event will the authors be held liable for any damages arising from the use
of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software in
a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@ -0,0 +1,945 @@
.. highlightlang:: none
.. _history-and-license:
*******************
History and License
*******************
History of the software
=======================
Python was created in the early 1990s by Guido van Rossum at Stichting
Mathematisch Centrum (CWI, see http://www.cwi.nl/) in the Netherlands as a
successor of a language called ABC. Guido remains Python's principal author,
although it includes many contributions from others.
In 1995, Guido continued his work on Python at the Corporation for National
Research Initiatives (CNRI, see http://www.cnri.reston.va.us/) in Reston,
Virginia where he released several versions of the software.
In May 2000, Guido and the Python core development team moved to BeOpen.com to
form the BeOpen PythonLabs team. In October of the same year, the PythonLabs
team moved to Digital Creations (now Zope Corporation; see
http://www.zope.com/). In 2001, the Python Software Foundation (PSF, see
http://www.python.org/psf/) was formed, a non-profit organization created
specifically to own Python-related Intellectual Property. Zope Corporation is a
sponsoring member of the PSF.
All Python releases are Open Source (see http://www.opensource.org/ for the Open
Source Definition). Historically, most, but not all, Python releases have also
been GPL-compatible; the table below summarizes the various releases.
+----------------+--------------+-----------+------------+-----------------+
| Release | Derived from | Year | Owner | GPL compatible? |
+================+==============+===========+============+=================+
| 0.9.0 thru 1.2 | n/a | 1991-1995 | CWI | yes |
+----------------+--------------+-----------+------------+-----------------+
| 1.3 thru 1.5.2 | 1.2 | 1995-1999 | CNRI | yes |
+----------------+--------------+-----------+------------+-----------------+
| 1.6 | 1.5.2 | 2000 | CNRI | no |
+----------------+--------------+-----------+------------+-----------------+
| 2.0 | 1.6 | 2000 | BeOpen.com | no |
+----------------+--------------+-----------+------------+-----------------+
| 1.6.1 | 1.6 | 2001 | CNRI | no |
+----------------+--------------+-----------+------------+-----------------+
| 2.1 | 2.0+1.6.1 | 2001 | PSF | no |
+----------------+--------------+-----------+------------+-----------------+
| 2.0.1 | 2.0+1.6.1 | 2001 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.1.1 | 2.1+2.0.1 | 2001 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.2 | 2.1.1 | 2001 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.1.2 | 2.1.1 | 2002 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.1.3 | 2.1.2 | 2002 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.2.1 | 2.2 | 2002 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.2.2 | 2.2.1 | 2002 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.2.3 | 2.2.2 | 2002-2003 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.3 | 2.2.2 | 2002-2003 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.3.1 | 2.3 | 2002-2003 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.3.2 | 2.3.1 | 2003 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.3.3 | 2.3.2 | 2003 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.3.4 | 2.3.3 | 2004 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.3.5 | 2.3.4 | 2005 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.4 | 2.3 | 2004 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.4.1 | 2.4 | 2005 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.4.2 | 2.4.1 | 2005 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.4.3 | 2.4.2 | 2006 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.4.4 | 2.4.3 | 2006 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.5 | 2.4 | 2006 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.5.1 | 2.5 | 2007 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.5.2 | 2.5.1 | 2008 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.5.3 | 2.5.2 | 2008 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.6 | 2.5 | 2008 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.6.1 | 2.6 | 2008 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.6.2 | 2.6.1 | 2009 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.6.3 | 2.6.2 | 2009 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.6.4 | 2.6.3 | 2010 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
| 2.7 | 2.6 | 2010 | PSF | yes |
+----------------+--------------+-----------+------------+-----------------+
.. note::
GPL-compatible doesn't mean that we're distributing Python under the GPL. All
Python licenses, unlike the GPL, let you distribute a modified version without
making your changes open source. The GPL-compatible licenses make it possible to
combine Python with other software that is released under the GPL; the others
don't.
Thanks to the many outside volunteers who have worked under Guido's direction to
make these releases possible.
Terms and conditions for accessing or otherwise using Python
============================================================
.. centered:: PSF LICENSE AGREEMENT FOR PYTHON |release|
#. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
the Individual or Organization ("Licensee") accessing and otherwise using Python
|release| software in source or binary form and its associated documentation.
#. Subject to the terms and conditions of this License Agreement, PSF hereby
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
analyze, test, perform and/or display publicly, prepare derivative works,
distribute, and otherwise use Python |release| alone or in any derivative
version, provided, however, that PSF's License Agreement and PSF's notice of
copyright, i.e., "Copyright © 2001-2013 Python Software Foundation; All Rights
Reserved" are retained in Python |release| alone or in any derivative version
prepared by Licensee.
#. In the event Licensee prepares a derivative work that is based on or
incorporates Python |release| or any part thereof, and wants to make the
derivative work available to others as provided herein, then Licensee hereby
agrees to include in any such work a brief summary of the changes made to Python
|release|.
#. PSF is making Python |release| available to Licensee on an "AS IS" basis.
PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
USE OF PYTHON |release| WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
#. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON |release|
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON |release|, OR ANY DERIVATIVE
THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
#. This License Agreement will automatically terminate upon a material breach of
its terms and conditions.
#. Nothing in this License Agreement shall be deemed to create any relationship
of agency, partnership, or joint venture between PSF and Licensee. This License
Agreement does not grant permission to use PSF trademarks or trade name in a
trademark sense to endorse or promote products or services of Licensee, or any
third party.
#. By copying, installing or otherwise using Python |release|, Licensee agrees
to be bound by the terms and conditions of this License Agreement.
.. centered:: BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
.. centered:: BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
#. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at
160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization
("Licensee") accessing and otherwise using this software in source or binary
form and its associated documentation ("the Software").
#. Subject to the terms and conditions of this BeOpen Python License Agreement,
BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license
to reproduce, analyze, test, perform and/or display publicly, prepare derivative
works, distribute, and otherwise use the Software alone or in any derivative
version, provided, however, that the BeOpen Python License is retained in the
Software, alone or in any derivative version prepared by Licensee.
#. BeOpen is making the Software available to Licensee on an "AS IS" basis.
BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
#. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR
ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING,
MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF
ADVISED OF THE POSSIBILITY THEREOF.
#. This License Agreement will automatically terminate upon a material breach of
its terms and conditions.
#. This License Agreement shall be governed by and interpreted in all respects
by the law of the State of California, excluding conflict of law provisions.
Nothing in this License Agreement shall be deemed to create any relationship of
agency, partnership, or joint venture between BeOpen and Licensee. This License
Agreement does not grant permission to use BeOpen trademarks or trade names in a
trademark sense to endorse or promote products or services of Licensee, or any
third party. As an exception, the "BeOpen Python" logos available at
http://www.pythonlabs.com/logos.html may be used according to the permissions
granted on that web page.
#. By copying, installing or otherwise using the software, Licensee agrees to be
bound by the terms and conditions of this License Agreement.
.. centered:: CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
#. This LICENSE AGREEMENT is between the Corporation for National Research
Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191
("CNRI"), and the Individual or Organization ("Licensee") accessing and
otherwise using Python 1.6.1 software in source or binary form and its
associated documentation.
#. Subject to the terms and conditions of this License Agreement, CNRI hereby
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
analyze, test, perform and/or display publicly, prepare derivative works,
distribute, and otherwise use Python 1.6.1 alone or in any derivative version,
provided, however, that CNRI's License Agreement and CNRI's notice of copyright,
i.e., "Copyright © 1995-2001 Corporation for National Research Initiatives; All
Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version
prepared by Licensee. Alternately, in lieu of CNRI's License Agreement,
Licensee may substitute the following text (omitting the quotes): "Python 1.6.1
is made available subject to the terms and conditions in CNRI's License
Agreement. This Agreement together with Python 1.6.1 may be located on the
Internet using the following unique, persistent identifier (known as a handle):
1895.22/1013. This Agreement may also be obtained from a proxy server on the
Internet using the following URL: http://hdl.handle.net/1895.22/1013."
#. In the event Licensee prepares a derivative work that is based on or
incorporates Python 1.6.1 or any part thereof, and wants to make the derivative
work available to others as provided herein, then Licensee hereby agrees to
include in any such work a brief summary of the changes made to Python 1.6.1.
#. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI
MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE,
BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY
OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
#. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR
ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE
THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
#. This License Agreement will automatically terminate upon a material breach of
its terms and conditions.
#. This License Agreement shall be governed by the federal intellectual property
law of the United States, including without limitation the federal copyright
law, and, to the extent such U.S. federal law does not apply, by the law of the
Commonwealth of Virginia, excluding Virginia's conflict of law provisions.
Notwithstanding the foregoing, with regard to derivative works based on Python
1.6.1 that incorporate non-separable material that was previously distributed
under the GNU General Public License (GPL), the law of the Commonwealth of
Virginia shall govern this License Agreement only as to issues arising under or
with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in
this License Agreement shall be deemed to create any relationship of agency,
partnership, or joint venture between CNRI and Licensee. This License Agreement
does not grant permission to use CNRI trademarks or trade name in a trademark
sense to endorse or promote products or services of Licensee, or any third
party.
#. By clicking on the "ACCEPT" button where indicated, or by copying, installing
or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and
conditions of this License Agreement.
.. centered:: ACCEPT
.. centered:: CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
Copyright © 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The
Netherlands. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that
the above copyright notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting documentation, and that
the name of Stichting Mathematisch Centrum or CWI not be used in advertising or
publicity pertaining to distribution of the software without specific, written
prior permission.
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
Licenses and Acknowledgements for Incorporated Software
=======================================================
This section is an incomplete, but growing list of licenses and acknowledgements
for third-party software incorporated in the Python distribution.
Mersenne Twister
----------------
The :mod:`_random` module includes code based on a download from
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html. The following are
the verbatim comments from the original code::
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
Sockets
-------
The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and
:func:`getnameinfo`, which are coded in separate source files from the WIDE
Project, http://www.wide.ad.jp/. ::
Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Floating point exception control
--------------------------------
The source for the :mod:`fpectl` module includes the following notice::
---------------------------------------------------------------------
/ Copyright (c) 1996. \
| The Regents of the University of California. |
| All rights reserved. |
| |
| Permission to use, copy, modify, and distribute this software for |
| any purpose without fee is hereby granted, provided that this en- |
| tire notice is included in all copies of any software which is or |
| includes a copy or modification of this software and in all |
| copies of the supporting documentation for such software. |
| |
| This work was produced at the University of California, Lawrence |
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
| between the U.S. Department of Energy and The Regents of the |
| University of California for the operation of UC LLNL. |
| |
| DISCLAIMER |
| |
| This software was prepared as an account of work sponsored by an |
| agency of the United States Government. Neither the United States |
| Government nor the University of California nor any of their em- |
| ployees, makes any warranty, express or implied, or assumes any |
| liability or responsibility for the accuracy, completeness, or |
| usefulness of any information, apparatus, product, or process |
| disclosed, or represents that its use would not infringe |
| privately-owned rights. Reference herein to any specific commer- |
| cial products, process, or service by trade name, trademark, |
| manufacturer, or otherwise, does not necessarily constitute or |
| imply its endorsement, recommendation, or favoring by the United |
| States Government or the University of California. The views and |
| opinions of authors expressed herein do not necessarily state or |
| reflect those of the United States Government or the University |
| of California, and shall not be used for advertising or product |
\ endorsement purposes. /
---------------------------------------------------------------------
MD5 message digest algorithm
----------------------------
The source code for the :mod:`md5` module contains the following notice::
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
Asynchronous socket services
----------------------------
The :mod:`asynchat` and :mod:`asyncore` modules contain the following notice::
Copyright 1996 by Sam Rushing
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of Sam
Rushing not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Cookie management
-----------------
The :mod:`Cookie` module contains the following notice::
Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu>
All Rights Reserved
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
Timothy O'Malley not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
Execution tracing
-----------------
The :mod:`trace` module contains the following notice::
portions copyright 2001, Autonomous Zones Industries, Inc., all rights...
err... reserved and offered to the public under the terms of the
Python 2.2 license.
Author: Zooko O'Whielacronx
http://zooko.com/
mailto:zooko@zooko.com
Copyright 2000, Mojam Media, Inc., all rights reserved.
Author: Skip Montanaro
Copyright 1999, Bioreason, Inc., all rights reserved.
Author: Andrew Dalke
Copyright 1995-1997, Automatrix, Inc., all rights reserved.
Author: Skip Montanaro
Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved.
Permission to use, copy, modify, and distribute this Python software and
its associated documentation for any purpose without fee is hereby
granted, provided that the above copyright notice appears in all copies,
and that both that copyright notice and this permission notice appear in
supporting documentation, and that the name of neither Automatrix,
Bioreason or Mojam Media be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
UUencode and UUdecode functions
-------------------------------
The :mod:`uu` module contains the following notice::
Copyright 1994 by Lance Ellinghouse
Cathedral City, California Republic, United States of America.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Lance Ellinghouse
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Modified by Jack Jansen, CWI, July 1995:
- Use binascii module to do the actual line-by-line conversion
between ascii and binary. This results in a 1000-fold speedup. The C
version is still 5 times faster, though.
- Arguments more compliant with Python standard
XML Remote Procedure Calls
--------------------------
The :mod:`xmlrpclib` module contains the following notice::
The XML-RPC client interface is
Copyright (c) 1999-2002 by Secret Labs AB
Copyright (c) 1999-2002 by Fredrik Lundh
By obtaining, using, and/or copying this software and/or its
associated documentation, you agree that you have read, understood,
and will comply with the following terms and conditions:
Permission to use, copy, modify, and distribute this software and
its associated documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice appears in
all copies, and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
Secret Labs AB or the author not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
test_epoll
----------
The :mod:`test_epoll` contains the following notice::
Copyright (c) 2001-2006 Twisted Matrix Laboratories.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Select kqueue
-------------
The :mod:`select` and contains the following notice for the kqueue interface::
Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
strtod and dtoa
---------------
The file :file:`Python/dtoa.c`, which supplies C functions dtoa and
strtod for conversion of C doubles to and from strings, is derived
from the file of the same name by David M. Gay, currently available
from http://www.netlib.org/fp/. The original file, as retrieved on
March 16, 2009, contains the following copyright and licensing
notice::
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
OpenSSL
-------
The modules :mod:`hashlib`, :mod:`posix`, :mod:`ssl`, :mod:`crypt` use
the OpenSSL library for added performance if made available by the
operating system. Additionally, the Windows installers for Python
include a copy of the OpenSSL libraries, so we include a copy of the
OpenSSL license here::
LICENSE ISSUES
==============
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit.
See below for the actual license texts. Actually both licenses are BSD-style
Open Source licenses. In case of any license issues related to OpenSSL
please contact openssl-core@openssl.org.
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
expat
-----
The :mod:`pyexpat` extension is built using an included copy of the expat
sources unless the build is configured ``--with-system-expat``::
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
and Clark Cooper
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
libffi
------
The :mod:`_ctypes` extension is built using an included copy of the libffi
sources unless the build is configured ``--with-system-libffi``::
Copyright (c) 1996-2008 Red Hat, Inc and others.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
zlib
----
The :mod:`zlib` extension is built using an included copy of the zlib
sources if the zlib version found on the system is too old to be
used for the build::
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu

View File

@ -0,0 +1,13 @@
Copyright 2010 Michael Cohen
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,19 @@
Copyright (c) 2003-2009 Stuart Bishop <stuart@stuartbishop.net>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,30 @@
Unless stated in the specfic source file, this work is
Copyright (c) 1994-2008, Mark Hammond
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
Neither name of Mark Hammond nor the name of contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,18 @@
Copyright (c) 2010-2014 Benjamin Peterson
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,221 @@
IBM PUBLIC LICENSE VERSION 1.0 - CORONER TOOLKIT UTILITIES
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS IBM PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of International Business Machines Corporation ("IBM"),
the Original Program, and
b) in the case of each Contributor,
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate
from and are distributed by that particular Contributor.
A Contribution 'originates' from a Contributor if it was added
to the Program by such Contributor itself or anyone acting on
such Contributor's behalf.
Contributions do not include additions to the Program which:
(i) are separate modules of software distributed in conjunction
with the Program under their own license agreement, and
(ii) are not derivative works of the Program.
"Contributor" means IBM and any other entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which
are necessarily infringed by the use or sale of its Contribution alone
or when combined with the Program.
"Original Program" means the original version of the software accompanying
this Agreement as released by IBM, including source code, object code
and documentation, if any.
"Program" means the Original Program and Contributions.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby
grants Recipient a non-exclusive, worldwide, royalty-free copyright
license to reproduce, prepare derivative works of, publicly display,
publicly perform, distribute and sublicense the Contribution of such
Contributor, if any, and such derivative works, in source code and
object code form.
b) Subject to the terms of this Agreement, each Contributor hereby
grants Recipient a non-exclusive, worldwide, royalty-free patent
license under Licensed Patents to make, use, sell, offer to sell,
import and otherwise transfer the Contribution of such Contributor,
if any, in source code and object code form. This patent license
shall apply to the combination of the Contribution and the Program
if, at the time the Contribution is added by the Contributor, such
addition of the Contribution causes such combination to be covered
by the Licensed Patents. The patent license shall not apply to any
other combinations which include the Contribution. No hardware per
se is licensed hereunder.
c) Recipient understands that although each Contributor grants the
licenses to its Contributions set forth herein, no assurances are
provided by any Contributor that the Program does not infringe the
patent or other intellectual property rights of any other entity.
Each Contributor disclaims any liability to Recipient for claims
brought by any other entity based on infringement of intellectual
property rights or otherwise. As a condition to exercising the rights
and licenses granted hereunder, each Recipient hereby assumes sole
responsibility to secure any other intellectual property rights
needed, if any. For example, if a third party patent license
is required to allow Recipient to distribute the Program, it is
Recipient's responsibility to acquire that license before distributing
the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright
license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form
under its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all
warranties and conditions, express and implied, including
warranties or conditions of title and non-infringement, and
implied warranties or conditions of merchantability and fitness
for a particular purpose;
ii) effectively excludes on behalf of all Contributors all
liability for damages, including direct, indirect, special,
incidental and consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement
are offered by that Contributor alone and not by any other
party; and
iv) states that source code for the Program is available from
such Contributor, and informs licensees how to obtain it in a
reasonable manner on or through a medium customarily used for
software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the
Program.
Each Contributor must include the following in a conspicuous location
in the Program:
Copyright (c) 1997,1998,1999, International Business Machines
Corporation and others. All Rights Reserved.
In addition, each Contributor must identify itself as the originator of
its Contribution, if any, in a manner that reasonably allows subsequent
Recipients to identify the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities
with respect to end users, business partners and the like. While this
license is intended to facilitate the commercial use of the Program, the
Contributor who includes the Program in a commercial product offering
should do so in a manner which does not create potential liability for
other Contributors. Therefore, if a Contributor includes the Program in
a commercial product offering, such Contributor ("Commercial Contributor")
hereby agrees to defend and indemnify every other Contributor
("Indemnified Contributor") against any losses, damages and costs
(collectively "Losses") arising from claims, lawsuits and other legal
actions brought by a third party against the Indemnified Contributor to
the extent caused by the acts or omissions of such Commercial Contributor
in connection with its distribution of the Program in a commercial
product offering. The obligations in this section do not apply to any
claims or Losses relating to any actual or alleged intellectual property
infringement. In order to qualify, an Indemnified Contributor must:
a) promptly notify the Commercial Contributor in writing of such claim,
and
b) allow the Commercial Contributor to control, and cooperate with
the Commercial Contributor in, the defense and any related
settlement negotiations. The Indemnified Contributor may
participate in any such claim at its own expense.
For example, a Contributor might include the Program in a commercial
product offering, Product X. That Contributor is then a Commercial
Contributor. If that Commercial Contributor then makes performance
claims, or offers warranties related to Product X, those performance
claims and warranties are such Commercial Contributor's responsibility
alone. Under this section, the Commercial Contributor would have to
defend claims against the other Contributors related to those performance
claims and warranties, and if a court requires any other Contributor to
pay any damages as a result, the Commercial Contributor must pay those
damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE. Each Recipient is solely responsible for determining
the appropriateness of using and distributing the Program and assumes
all risks associated with its exercise of rights under this Agreement,
including but not limited to the risks and costs of program errors,
compliance with applicable laws, damage to or loss of data, programs or
equipment, and unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION
OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this Agreement, and without further action
by the parties hereto, such provision shall be reformed to the minimum
extent necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against a Contributor with
respect to a patent applicable to software (including a cross-claim or
counterclaim in a lawsuit), then any patent licenses granted by that
Contributor to such Recipient under this Agreement shall terminate
as of the date such litigation is filed. In addition, If Recipient
institutes patent litigation against any entity (including a cross-claim
or counterclaim in a lawsuit) alleging that the Program itself (excluding
combinations of the Program with other software or hardware) infringes
such Recipient's patent(s), then such Recipient's rights granted under
Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails
to comply with any of the material terms or conditions of this Agreement
and does not cure such failure in a reasonable period of time after
becoming aware of such noncompliance. If all Recipient's rights under
this Agreement terminate, Recipient agrees to cease use and distribution
of the Program as soon as reasonably practicable. However, Recipient's
obligations under this Agreement and any licenses granted by Recipient
relating to the Program shall continue and survive.
IBM may publish new versions (including revisions) of this Agreement
from time to time. Each new version of the Agreement will be given a
distinguishing version number. The Program (including Contributions)
may always be distributed subject to the version of the Agreement under
which it was received. In addition, after a new version of the Agreement
is published, Contributor may elect to distribute the Program (including
its Contributions) under the new version. No one other than IBM has the
right to modify this Agreement. Except as expressly stated in Sections
2(a) and 2(b) above, Recipient receives no rights or licenses to the
intellectual property of any Contributor under this Agreement, whether
expressly, by implication, estoppel or otherwise. All rights in the
Program not expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to
this Agreement will bring a legal action under this Agreement more than
one year after the cause of action arose. Each party waives its rights
to a jury trial in any resulting litigation.

View File

@ -0,0 +1,213 @@
Common Public License Version 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and
documentation distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates' from a
Contributor if it was added to the Program by such Contributor itself or anyone
acting on such Contributor's behalf. Contributions do not include additions to
the Program which: (i) are separate modules of software distributed in
conjunction with the Program under their own license agreement, and (ii) are not
derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly perform,
distribute and sublicense the Contribution of such Contributor, if any, and such
derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed
Patents to make, use, sell, offer to sell, import and otherwise transfer the
Contribution of such Contributor, if any, in source code and object code form.
This patent license shall apply to the combination of the Contribution and the
Program if, at the time the Contribution is added by the Contributor, such
addition of the Contribution causes such combination to be covered by the
Licensed Patents. The patent license shall not apply to any other combinations
which include the Contribution. No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses
to its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other intellectual
property rights of any other entity. Each Contributor disclaims any liability to
Recipient for claims brought by any other entity based on infringement of
intellectual property rights or otherwise. As a condition to exercising the
rights and licenses granted hereunder, each Recipient hereby assumes sole
responsibility to secure any other intellectual property rights needed, if any.
For example, if a third party patent license is required to allow Recipient to
distribute the Program, it is Recipient's responsibility to acquire that license
before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright license set
forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under its
own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of title and
non-infringement, and implied warranties or conditions of merchantability and
fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and consequential
damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are offered
by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable manner on or
through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained within the
Program.
Each Contributor must identify itself as the originator of its Contribution, if
any, in a manner that reasonably allows subsequent Recipients to identify the
originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor who
includes the Program in a commercial product offering should do so in a manner
which does not create potential liability for other Contributors. Therefore, if
a Contributor includes the Program in a commercial product offering, such
Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
every other Contributor ("Indemnified Contributor") against any losses, damages
and costs (collectively "Losses") arising from claims, lawsuits and other legal
actions brought by a third party against the Indemnified Contributor to the
extent caused by the acts or omissions of such Commercial Contributor in
connection with its distribution of the Program in a commercial product
offering. The obligations in this section do not apply to any claims or Losses
relating to any actual or alleged intellectual property infringement. In order
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
Contributor in writing of such claim, and b) allow the Commercial Contributor to
control, and cooperate with the Commercial Contributor in, the defense and any
related settlement negotiations. The Indemnified Contributor may participate in
any such claim at its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If that
Commercial Contributor then makes performance claims, or offers warranties
related to Product X, those performance claims and warranties are such
Commercial Contributor's responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a court
requires any other Contributor to pay any damages as a result, the Commercial
Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
Recipient is solely responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its exercise of
rights under this Agreement, including but not limited to the risks and costs of
program errors, compliance with applicable laws, damage to or loss of data,
programs or equipment, and unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under applicable
law, it shall not affect the validity or enforceability of the remainder of the
terms of this Agreement, and without further action by the parties hereto, such
provision shall be reformed to the minimum extent necessary to make such
provision valid and enforceable.
If Recipient institutes patent litigation against a Contributor with respect to
a patent applicable to software (including a cross-claim or counterclaim in a
lawsuit), then any patent licenses granted by that Contributor to such Recipient
under this Agreement shall terminate as of the date such litigation is filed. In
addition, if Recipient institutes patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that the Program
itself (excluding combinations of the Program with other software or hardware)
infringes such Recipient's patent(s), then such Recipient's rights granted under
Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and does
not cure such failure in a reasonable period of time after becoming aware of
such noncompliance. If all Recipient's rights under this Agreement terminate,
Recipient agrees to cease use and distribution of the Program as soon as
reasonably practicable. However, Recipient's obligations under this Agreement
and any licenses granted by Recipient relating to the Program shall continue and
survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be
modified in the following manner. The Agreement Steward reserves the right to
publish new versions (including revisions) of this Agreement from time to time.
No one other than the Agreement Steward has the right to modify this Agreement.
IBM is the initial Agreement Steward. IBM may assign the responsibility to serve
as the Agreement Steward to a suitable separate entity. Each new version of the
Agreement will be given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the Agreement
under which it was received. In addition, after a new version of the Agreement
is published, Contributor may elect to distribute the Program (including its
Contributions) under the new version. Except as expressly stated in Sections
2(a) and 2(b) above, Recipient receives no rights or licenses to the
intellectual property of any Contributor under this Agreement, whether
expressly, by implication, estoppel or otherwise. All rights in the Program not
expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury trial in
any resulting litigation.

View File

@ -0,0 +1,166 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

BIN
config/logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

14
config/macosx/Readme.txt Normal file
View File

@ -0,0 +1,14 @@
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
| PLASO INSTALLER README
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
This is a simple installer for plaso.
Simply run the install.sh script as root (sudo ./install.sh) and all shall
be installed and work as it should.
What the installer does is to install all dependencies to plaso as well as
plaso and dfvfs as separate packages.
More documentation: http://plaso.kiddaland.net
Questions/comments/thoughts? send them to log2timeline-discuss@googlegroups.com

56
config/macosx/install.sh.in Executable file
View File

@ -0,0 +1,56 @@
#!/bin/bash
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This is a simple installer script for the Mac OS X platform.
EXIT_SUCCESS=0;
EXIT_FAILURE=1;
echo "==============================================================="
echo " PLASO INSTALLER"
echo "==============================================================="
if test "$USER" != "root";
then
echo "This script requires root privileges. Running: sudo.";
sudo ls > /dev/null
if test $? -ne 0;
then
echo "Do you have root privileges?";
exit ${EXIT_FAILURE};
fi
fi
VOLUME_NAME="/Volumes/@VOLUMENAME@";
if ! test -d ${VOLUME_NAME};
then
echo "Unable to find installation directory: ${VOLUME_NAME}";
exit ${EXIT_FAILURE};
fi
echo "Installing packages.";
find ${VOLUME_NAME} -name "*.pkg" -exec sudo installer -target / -pkg {} \;
echo "Done.";
exit ${EXIT_SUCCESS};

74
config/macosx/make_dist.sh Executable file
View File

@ -0,0 +1,74 @@
#!/bin/bash
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Script to make a plaso Mac OS X distribution package.
EXIT_SUCCESS=0;
EXIT_FAILURE=1;
if ! test -d dependencies;
then
echo "Missing dependencies directory.";
exit ${EXIT_FAILURE};
fi
if ! test -d config;
then
echo "Missing config directory.";
exit ${EXIT_FAILURE};
fi
MACOSX_VERSION=`sw_vers -productVersion | awk -F '.' '{print $1 "." $2}'`;
PLASO_VERSION=`grep -e '^__version' plaso/__init__.py | sed -e "s/^[^=]*= '\([^']*\)'/\1/g"`;
if ! test -z $1;
then
PLASO_VERSION="${PLASO_VERSION}-$1";
fi
if ! test -f ../python-plaso-${PLASO_VERSION}.pkg;
then
echo "Missing plaso package: ../python-plaso-${PLASO_VERSION}.pkg file.";
exit ${EXIT_FAILURE};
fi
DISTDIR="plaso-${PLASO_VERSION}";
if test -d "${DISTDIR}";
then
echo "Distribution directory: ${DISTDIR} already exists.";
exit ${EXIT_FAILURE};
fi
mkdir "${DISTDIR}";
cp -r config/licenses "${DISTDIR}";
cp config/macosx/Readme.txt "${DISTDIR}";
sed "s/@VOLUMENAME@/${DISTDIR}/" config/macosx/install.sh.in > "${DISTDIR}/install.sh";
mkdir "${DISTDIR}/packages";
cp dependencies/*.pkg "${DISTDIR}/packages";
cp ../python-plaso-${PLASO_VERSION}.pkg "${DISTDIR}/packages";
hdiutil create ../plaso-${PLASO_VERSION}_macosx-${MACOSX_VERSION}.dmg -srcfolder "${DISTDIR}/" -fs HFS+;
exit ${EXIT_SUCCESS};

16
config/windows/make.bat Normal file
View File

@ -0,0 +1,16 @@
@echo off
del /q /s build dist 2> NUL
rmdir /q /s build dist 2> NUL
set PYTHONPATH=.
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\image_export.py
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\log2timeline.py
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\pinfo.py
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\plasm.py
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\pprof.py
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\preg.py
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\pshell.py
C:\Python27\python.exe ..\pyinstaller\pyinstaller.py --onedir plaso\frontend\psort.py
set PYTHONPATH=

View File

@ -0,0 +1,12 @@
@echo off
@rem Script to make sure the executables run after make_dist.bat.
dist\plaso\image_export.exe -h
dist\plaso\log2timeline.exe --info
dist\plaso\pinfo.exe -v test_data\psort_test.out
dist\plaso\plasm.exe -h
dist\plaso\pprof.exe
dist\plaso\preg.exe -h
dist\plaso\psort.exe
dist\plaso\pshell.exe

View File

@ -0,0 +1,22 @@
@echo off
del /q /s dist\plaso 2> NUL
rmdir /q /s dist\plaso 2> NUL
mkdir dist\plaso
mkdir dist\plaso\licenses
xcopy /q /y ACKNOWLEDGEMENTS dist\plaso
xcopy /q /y AUTHORS dist\plaso
xcopy /q /y LICENSE dist\plaso
xcopy /q /y README dist\plaso
xcopy /q /y config\licenses\* dist\plaso\licenses
xcopy /q /y /s dist\image_export\* dist\plaso
xcopy /q /y /s dist\log2timeline\* dist\plaso
xcopy /q /y /s dist\pinfo\* dist\plaso
xcopy /q /y /s dist\plasm\* dist\plaso
xcopy /q /y /s dist\pprof\* dist\plaso
xcopy /q /y /s dist\preg\* dist\plaso
xcopy /q /y /s dist\pshell\* dist\plaso
xcopy /q /y /s dist\psort\* dist\plaso

1
extra/README Normal file
View File

@ -0,0 +1 @@
This folder will contain additional files that contain filter criteria, tagging files, etc.

View File

@ -0,0 +1,329 @@
{
"title": "Plaso",
"services": {
"query": {
"idQueue": [
1,
2,
3,
4
],
"list": {
"0": {
"query": "*",
"alias": "",
"color": "#7EB26D",
"id": 0,
"pin": false,
"type": "lucene"
}
},
"ids": [
0
]
},
"filter": {
"idQueue": [
0,
1,
2
],
"list": {},
"ids": []
}
},
"rows": [
{
"title": "Histogram",
"height": "200px",
"editable": true,
"collapse": false,
"collapsable": true,
"panels": [
{
"span": 12,
"editable": true,
"type": "histogram",
"loadingEditor": false,
"mode": "count",
"time_field": "datetime",
"queries": {
"mode": "all",
"ids": [
0
]
},
"value_field": null,
"auto_int": true,
"resolution": 100,
"interval": "1y",
"intervals": [
"auto",
"1s",
"1m",
"5m",
"10m",
"30m",
"1h",
"3h",
"12h",
"1d",
"1w",
"1M",
"1y"
],
"fill": 0,
"linewidth": 3,
"timezone": "browser",
"spyable": true,
"zoomlinks": true,
"bars": true,
"stack": true,
"points": false,
"lines": false,
"legend": true,
"x-axis": true,
"y-axis": true,
"percentage": false,
"interactive": true,
"options": true,
"tooltip": {
"value_type": "cumulative",
"query_as_alias": false
},
"title": "Histogram"
}
],
"notice": false
},
{
"title": "Graph",
"height": "250px",
"editable": true,
"collapse": false,
"collapsable": true,
"panels": [
{
"error": false,
"span": 4,
"editable": true,
"type": "terms",
"loadingEditor": false,
"queries": {
"mode": "selected",
"ids": [
0
]
},
"field": "source_short",
"exclude": [],
"missing": true,
"other": true,
"size": 10,
"order": "count",
"style": {
"font-size": "10pt"
},
"donut": false,
"tilt": false,
"labels": true,
"arrangement": "horizontal",
"chart": "bar",
"counter_pos": "below",
"spyable": true,
"title": "Source Distribution"
},
{
"error": false,
"span": 4,
"editable": true,
"type": "terms",
"loadingEditor": false,
"queries": {
"mode": "selected",
"ids": []
},
"field": "parser",
"exclude": [],
"missing": true,
"other": true,
"size": 10,
"order": "count",
"style": {
"font-size": "10pt"
},
"donut": false,
"tilt": false,
"labels": true,
"arrangement": "horizontal",
"chart": "table",
"counter_pos": "above",
"spyable": true,
"title": "Parser Count"
},
{
"error": false,
"span": 4,
"editable": true,
"type": "terms",
"loadingEditor": false,
"queries": {
"mode": "selected",
"ids": []
},
"field": "hostname",
"exclude": [],
"missing": true,
"other": true,
"size": 10,
"order": "count",
"style": {
"font-size": "10pt"
},
"donut": false,
"tilt": false,
"labels": true,
"arrangement": "horizontal",
"chart": "bar",
"counter_pos": "above",
"spyable": true,
"title": "Hosts"
}
],
"notice": false
},
{
"title": "Events",
"height": "650px",
"editable": true,
"collapse": false,
"collapsable": true,
"panels": [
{
"error": false,
"span": 12,
"editable": true,
"group": [
"default"
],
"type": "table",
"size": 100,
"pages": 5,
"offset": 0,
"sort": [
"datetime",
"desc"
],
"style": {
"font-size": "9pt"
},
"overflow": "min-height",
"fields": [
"datetime",
"timestamp_desc",
"hostname",
"username",
"source_short",
"source_long",
"message",
"tag",
"display_name"
],
"highlight": [],
"sortable": true,
"header": true,
"paging": true,
"spyable": true,
"queries": {
"mode": "all",
"ids": [
0
]
},
"field_list": true,
"status": "Stable",
"trimFactor": 300,
"normTimes": true,
"title": "Documents",
"all_fields": false
}
],
"notice": false
}
],
"editable": true,
"index": {
"interval": "none",
"pattern": "[logstash-]YYYY.MM.DD",
"default": "_all"
},
"style": "light",
"failover": false,
"panel_hints": true,
"loader": {
"save_gist": false,
"save_elasticsearch": true,
"save_local": true,
"save_default": true,
"save_temp": true,
"save_temp_ttl_enable": true,
"save_temp_ttl": "30d",
"load_gist": true,
"load_elasticsearch": true,
"load_elasticsearch_size": 20,
"load_local": true,
"hide": false
},
"pulldowns": [
{
"type": "query",
"collapse": false,
"notice": false,
"query": "*",
"pinned": true,
"history": [],
"remember": 10,
"enable": true
},
{
"type": "filtering",
"collapse": true,
"notice": false,
"enable": true
}
],
"nav": [
{
"type": "timepicker",
"collapse": false,
"notice": false,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"timefield": "@timestamp",
"enable": true
}
],
"refresh": false
}

21
extra/tag_macosx.txt Executable file
View File

@ -0,0 +1,21 @@
Application Execution
data_type is 'macosx:application_usage'
data_type is 'syslog:line' AND body contains 'COMMAND=/bin/launchctl'
Application Install
data_type is 'plist:key' AND plugin is 'plist_install_history'
AutoRun
data_type is 'fs:stat' AND filename contains 'LaunchAgents/' AND timestamp_desc is 'HFS_DETECT crtime' AND filename contains '.plist'
File Downloaded
data_type is 'chrome:history:file_downloaded'
timestamp_desc is 'File Downloaded'
data_type is 'macosx:lsquarantine'
Device Connected
data_type is 'ipod:device:entry'
data_type is 'plist:key' and plugin is 'plist_airport'
Document Printed
(data_type is 'metadata:hachoir' OR data_type is 'metadata:OLECF') AND timestamp_desc contains 'Printed'

94
extra/tag_windows.txt Executable file
View File

@ -0,0 +1,94 @@
Application Execution
data_type is 'windows:prefetch'
data_type is 'windows:lnk:link' and filename contains 'Recent' and (local_path contains '.exe' or network_path contains '.exe' or relative_path contains '.exe')
data_type is 'windows:registry:key_value' AND (plugin contains 'userassist' or plugin contains 'mru') AND regvalue.__all__ contains '.exe'
data_type is 'windows:evtx:record' and strings contains 'user mode service' and strings contains 'demand start'
data_type is 'fs:stat' and filename contains 'Windows/Tasks/At'
data_type is 'windows:tasks:job'
data_type is 'windows:evt:record' and source_name is 'Security' and event_identifier is 592
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Security-Auditing' and event_identifier is 4688
data_type is 'windows:registry:appcompatcache'
Application Installed
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Application-Experience' and event_identifier is 903
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Application-Experience' and event_identifier is 904
Application Updated
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Application-Experience' and event_identifier is 905
Application Removed
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Application-Experience' and event_identifier is 907
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Application-Experience' and event_identifier is 908
Document Opened
data_type is 'windows:registry:key_value' AND plugin contains 'mru' AND regvalue.__all__ not contains '.exe' AND timestamp > 0
Failed Login
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Security-Auditing' and event_identifier is 4625
Logon
data_type is 'windows:evt:record' and source_name is 'Security' and event_identifier is 540
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Security-Auditing' and event_identifier is 4624
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 21
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 1101
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Winlogon' and event_identifier is 7001
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-RemoteConnectionManager' and event_identifier is 1147
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-RemoteConnectionManager' and event_identifier is 1149
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-User Profiles Service' and event_identifier is 2
Logoff
data_type is 'windows:evt:record' and source_name is 'Security' and event_identifier is 538
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Security-Auditing' and event_identifier is 4634
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Winlogon' and event_identifier is 7002
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 23
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 1103
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-User Profiles Service' and event_identifier is 4
Disconnect
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 24
Reconnect
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 25
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 1105
Shell Start
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 22
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TerminalServices-LocalSessionManager' and event_identifer is 1102
Task Scheduled
data_type is 'windows:evt:record' and source_name is 'Security' and event_identifier is 602
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Security-Auditing' and event_identifier is 4698
Job Success
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TaskScheduler' and event_identifier is 102
Action Success
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-TaskScheduler' and event_identifier is 201
Name Resolution Timeout
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-DNS-Client' and event_identifier is 1014
Time Change
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Kernel-General' and event_identifier is 1
Shutdown
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Kernel-General' and event_identifier is 13
System Start
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Kernel-General' and event_identifier is 13
System Sleep
data_type is 'windows:evtx:record' and source_name is 'Microsoft-Windows-Kernel-Power' and event_identifier is 42
AutoRun
data_type is 'windows:registry:key_value' and plugin contains 'Run'
File Downloaded
data_type is 'chrome:history:file_downloaded'
timestamp_desc is 'File Downloaded'
Document Printed
(data_type is 'metadata:hachoir' OR data_type is 'olecf:summary_info') AND timestamp_desc contains 'Printed'
Startup Application
data_type is 'windows:registry:key_value' AND (plugin contains 'run' or plugin contains 'lfu') AND (regvalue.__all__ contains '.exe' OR regvalue.__all__ contains '.dll')

30
plaso/__init__.py Normal file
View File

@ -0,0 +1,30 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2012 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
__version__ = '1.2.0'
VERSION_DEV = False
VERSION_DATE = '20141220'
def GetVersion():
"""Returns version information for plaso."""
if not VERSION_DEV:
return __version__
return u'{0:s}_{1:s}'.format(__version__, VERSION_DATE)

View File

@ -0,0 +1,83 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Import statements for analysis plugins and common methods."""
from plaso.analysis import interface
from plaso.lib import errors
# Import statements of analysis plugins.
from plaso.analysis import browser_search
from plaso.analysis import chrome_extension
from plaso.analysis import windows_services
# TODO: move these functions to a manager class. And add a test for this
# function.
def ListAllPluginNames(show_all=True):
"""Return a list of all available plugin names and it's doc string."""
results = []
for cls_obj in interface.AnalysisPlugin.classes.itervalues():
doc_string, _, _ = cls_obj.__doc__.partition('\n')
obj = cls_obj(None)
if not show_all and cls_obj.ENABLE_IN_EXTRACTION:
results.append((obj.plugin_name, doc_string, obj.plugin_type))
elif show_all:
results.append((obj.plugin_name, doc_string, obj.plugin_type))
return sorted(results)
def LoadPlugins(plugin_names, incoming_queues, options=None):
"""Yield analysis plugins for a given list of plugin names.
Given a list of plugin names this method finds the analysis
plugins, initializes them and returns a generator.
Args:
plugin_names: A list of plugin names that should be loaded up. This
should be a list of strings.
incoming_queues: A list of queues (QueueInterface object) that the plugin
uses to read in incoming events to analyse.
options: Optional command line arguments (instance of
argparse.Namespace). The default is None.
Yields:
Analysis plugin objects (instances of AnalysisPlugin).
Raises:
errors.BadConfigOption: If plugins_names does not contain a list of
strings.
"""
try:
plugin_names_lower = [word.lower() for word in plugin_names]
except AttributeError:
raise errors.BadConfigOption(u'Plugin names should be a list of strings.')
for plugin_object in interface.AnalysisPlugin.classes.itervalues():
plugin_name = plugin_object.NAME.lower()
if plugin_name in plugin_names_lower:
queue_index = plugin_names_lower.index(plugin_name)
try:
incoming_queue = incoming_queues[queue_index]
except (TypeError, IndexError):
incoming_queue = None
yield plugin_object(incoming_queue, options)

View File

@ -0,0 +1,257 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A plugin that extracts browser history from events."""
import collections
import logging
import urllib
from plaso import filters
from plaso.analysis import interface
from plaso.formatters import manager as formatters_manager
from plaso.lib import event
# Create a lightweight object that is used to store timeline based information
# about each search term.
SEARCH_OBJECT = collections.namedtuple(
'SEARCH_OBJECT', 'time source engine search_term')
def ScrubLine(line):
"""Scrub the line of most obvious HTML codes.
An attempt at taking a line and swapping all instances
of %XX which represent a character in hex with it's
unicode character.
Args:
line: The string that we are about to "fix".
Returns:
String that has it's %XX hex codes swapped for text.
"""
if not line:
return ''
try:
return unicode(urllib.unquote(str(line)), 'utf-8')
except UnicodeDecodeError:
logging.warning(u'Unable to decode line: {0:s}'.format(line))
return line
class FilterClass(object):
"""A class that contains all the parser functions."""
@classmethod
def _GetBetweenQEqualsAndAmbersand(cls, string):
"""Return back string that is defined 'q=' and '&'."""
if 'q=' not in string:
return string
_, _, line = string.partition('q=')
before_and, _, _ = line.partition('&')
if not before_and:
return line
return before_and.split()[0]
@classmethod
def _SearchAndQInLine(cls, string):
"""Return a bool indicating if the words q= and search appear in string."""
return 'search' in string and 'q=' in string
@classmethod
def GoogleSearch(cls, url):
"""Return back the extracted string."""
if not cls._SearchAndQInLine(url):
return
line = cls._GetBetweenQEqualsAndAmbersand(url)
if not line:
return
return line.replace('+', ' ')
@classmethod
def YouTube(cls, url):
"""Return back the extracted string."""
return cls.GenericSearch(url)
@classmethod
def BingSearch(cls, url):
"""Return back the extracted string."""
return cls.GenericSearch(url)
@classmethod
def GenericSearch(cls, url):
"""Return back the extracted string from a generic search engine."""
if not cls._SearchAndQInLine(url):
return
return cls._GetBetweenQEqualsAndAmbersand(url).replace('+', ' ')
@classmethod
def Yandex(cls, url):
"""Return back the results from Yandex search engine."""
if 'text=' not in url:
return
_, _, line = url.partition('text=')
before_and, _, _ = line.partition('&')
if not before_and:
return
yandex_search_url = before_and.split()[0]
return yandex_search_url.replace('+', ' ')
@classmethod
def DuckDuckGo(cls, url):
"""Return back the extracted string."""
if not 'q=' in url:
return
return cls._GetBetweenQEqualsAndAmbersand(url).replace('+', ' ')
@classmethod
def Gmail(cls, url):
"""Return back the extracted string."""
if 'search/' not in url:
return
_, _, line = url.partition('search/')
first, _, _ = line.partition('/')
second, _, _ = first.partition('?compose')
return second.replace('+', ' ')
class AnalyzeBrowserSearchPlugin(interface.AnalysisPlugin):
"""Analyze browser search entries from events."""
NAME = 'browser_search'
# Indicate that we do not want to run this plugin during regular extraction.
ENABLE_IN_EXTRACTION = False
# Here we define filters and callback methods for all hits on each filter.
FILTERS = (
(('url iregexp "(www.|encrypted.|/)google." and url contains "search"'),
'GoogleSearch'),
('url contains "youtube.com"', 'YouTube'),
(('source is "WEBHIST" and url contains "bing.com" and url contains '
'"search"'), 'BingSearch'),
('url contains "mail.google.com"', 'Gmail'),
(('source is "WEBHIST" and url contains "yandex.com" and url contains '
'"yandsearch"'), 'Yandex'),
('url contains "duckduckgo.com"', 'DuckDuckGo')
)
# We need to implement the interface for analysis plugins, but we don't use
# command line options here, so disable checking for unused args.
# pylint: disable=unused-argument
def __init__(self, incoming_queue, options=None):
"""Initializes the browser search analysis plugin.
Args:
incoming_queue: A queue that is used to listen to incoming events.
options: Optional command line arguments (instance of
argparse.Namespace). The default is None.
"""
super(AnalyzeBrowserSearchPlugin, self).__init__(incoming_queue)
self._filter_dict = {}
self._counter = collections.Counter()
# Store a list of search terms in a timeline format.
# The format is key = timestamp, value = (source, engine, search term).
self._search_term_timeline = []
for filter_str, call_back in self.FILTERS:
filter_obj = filters.GetFilter(filter_str)
call_back_obj = getattr(FilterClass, call_back, None)
if filter_obj and call_back_obj:
self._filter_dict[filter_obj] = (call_back, call_back_obj)
# pylint: enable=unused-argument
def CompileReport(self):
"""Compiles a report of the analysis.
Returns:
The analysis report (instance of AnalysisReport).
"""
report = event.AnalysisReport()
results = {}
for key, count in self._counter.iteritems():
search_engine, _, search_term = key.partition(':')
results.setdefault(search_engine, {})
results[search_engine][search_term] = count
report.report_dict = results
report.report_array = self._search_term_timeline
lines_of_text = []
for search_engine, terms in sorted(results.items()):
lines_of_text.append(u' == ENGINE: {0:s} =='.format(search_engine))
for search_term, count in sorted(
terms.iteritems(), key=lambda x: (x[1], x[0]), reverse=True):
lines_of_text.append(u'{0:d} {1:s}'.format(count, search_term))
# An empty string is added to have SetText create an empty line.
lines_of_text.append(u'')
report.SetText(lines_of_text)
return report
def ExamineEvent(
self, unused_analysis_context, event_object, **unused_kwargs):
"""Analyzes an event object.
Args:
analysis_context: An analysis context object
(instance of AnalysisContext).
event_object: An event object (instance of EventObject).
"""
# This event requires an URL attribute.
url_attribute = getattr(event_object, 'url', None)
if not url_attribute:
return
# TODO: refactor this the source should be used in formatting only.
# Check if we are dealing with a web history event.
source, _ = formatters_manager.EventFormatterManager.GetSourceStrings(
event_object)
if source != 'WEBHIST':
return
for filter_obj, call_backs in self._filter_dict.items():
call_back_name, call_back_object = call_backs
if filter_obj.Match(event_object):
returned_line = ScrubLine(call_back_object(url_attribute))
if not returned_line:
continue
self._counter[u'{0:s}:{1:s}'.format(call_back_name, returned_line)] += 1
# Add the timeline format for each search term.
self._search_term_timeline.append(SEARCH_OBJECT(
getattr(event_object, 'timestamp', 0),
getattr(event_object, 'plugin', getattr(
event_object, 'parser', u'N/A')),
call_back_name, returned_line))

View File

@ -0,0 +1,74 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the browser search analysis plugin."""
import unittest
from plaso.analysis import browser_search
from plaso.analysis import test_lib
# pylint: disable=unused-import
from plaso.formatters import chrome as chrome_formatter
from plaso.lib import event
from plaso.parsers import sqlite
from plaso.parsers.sqlite_plugins import chrome
class BrowserSearchAnalysisTest(test_lib.AnalysisPluginTestCase):
"""Tests for the browser search analysis plugin."""
def setUp(self):
"""Sets up the needed objects used throughout the test."""
self._parser = sqlite.SQLiteParser()
def testAnalyzeFile(self):
"""Read a storage file that contains URL data and analyze it."""
knowledge_base = self._SetUpKnowledgeBase()
test_file = self._GetTestFilePath(['History'])
event_queue = self._ParseFile(self._parser, test_file, knowledge_base)
analysis_plugin = browser_search.AnalyzeBrowserSearchPlugin(event_queue)
analysis_report_queue_consumer = self._RunAnalysisPlugin(
analysis_plugin, knowledge_base)
analysis_reports = self._GetAnalysisReportsFromQueue(
analysis_report_queue_consumer)
self.assertEquals(len(analysis_reports), 1)
analysis_report = analysis_reports[0]
# Due to the behavior of the join one additional empty string at the end
# is needed to create the last empty line.
expected_text = u'\n'.join([
u' == ENGINE: GoogleSearch ==',
u'1 really really funny cats',
u'1 java plugin',
u'1 funnycats.exe',
u'1 funny cats',
u'',
u''])
self.assertEquals(analysis_report.text, expected_text)
self.assertEquals(analysis_report.plugin_name, 'browser_search')
expected_keys = set([u'GoogleSearch'])
self.assertEquals(set(analysis_report.report_dict.keys()), expected_keys)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,201 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A plugin that gather extension ID's from Chrome history browser."""
import logging
import re
import urllib2
from plaso.analysis import interface
from plaso.lib import event
class AnalyzeChromeExtensionPlugin(interface.AnalysisPlugin):
"""Convert Chrome extension ID's into names, requires Internet connection."""
NAME = 'chrome_extension'
# Indicate that we can run this plugin during regular extraction.
ENABLE_IN_EXTRACTION = True
_TITLE_RE = re.compile('<title>([^<]+)</title>')
_WEB_STORE_URL = u'https://chrome.google.com/webstore/detail/{xid}?hl=en-US'
# We need to implement the interface for analysis plugins, but we don't use
# command line options here, so disable checking for unused args.
# pylint: disable=unused-argument
def __init__(self, incoming_queue, options=None):
"""Initializes the Chrome extension analysis plugin.
Args:
incoming_queue: A queue that is used to listen to incoming events.
options: Optional command line arguments (instance of
argparse.Namespace). The default is None.
"""
super(AnalyzeChromeExtensionPlugin, self).__init__(incoming_queue)
self._results = {}
self.plugin_type = self.TYPE_REPORT
# TODO: see if these can be moved to arguments passed to ExamineEvent
# or some kind of state object.
self._sep = None
self._user_paths = None
# Saved list of already looked up extensions.
self._extensions = {}
# pylint: enable=unused-argument
def _GetChromeWebStorePage(self, extension_id):
"""Retrieves the page for the extension from the Chrome store website.
Args:
extension_id: string containing the extension identifier.
"""
web_store_url = self._WEB_STORE_URL.format(xid=extension_id)
try:
response = urllib2.urlopen(web_store_url)
except urllib2.HTTPError as exception:
logging.warning((
u'[{0:s}] unable to retrieve URL: {1:s} with error: {2:s}').format(
self.NAME, web_store_url, exception))
return
except urllib2.URLError as exception:
logging.warning((
u'[{0:s}] invalid URL: {1:s} with error: {2:s}').format(
self.NAME, web_store_url, exception))
return
return response
def _GetTitleFromChromeWebStore(self, extension_id):
"""Retrieves the name of the extension from the Chrome store website.
Args:
extension_id: string containing the extension identifier.
"""
# Check if we have already looked this extension up.
if extension_id in self._extensions:
return self._extensions.get(extension_id)
response = self._GetChromeWebStorePage(extension_id)
if not response:
logging.warning(
u'[{0:s}] no data returned for extension identifier: {1:s}'.format(
self.NAME, extension_id))
return
first_line = response.readline()
match = self._TITLE_RE.search(first_line)
if match:
title = match.group(1)
if title.startswith(u'Chrome Web Store - '):
name = title[19:]
elif title.endswith(u'- Chrome Web Store'):
name = title[:-19]
self._extensions[extension_id] = name
return name
self._extensions[extension_id] = u'Not Found'
def CompileReport(self):
"""Compiles a report of the analysis.
Returns:
The analysis report (instance of AnalysisReport).
"""
report = event.AnalysisReport()
report.report_dict = self._results
lines_of_text = []
for user, extensions in sorted(self._results.iteritems()):
lines_of_text.append(u' == USER: {0:s} =='.format(user))
for extension, extension_id in sorted(extensions):
lines_of_text.append(u' {0:s} [{1:s}]'.format(extension, extension_id))
# An empty string is added to have SetText create an empty line.
lines_of_text.append(u'')
report.SetText(lines_of_text)
return report
def ExamineEvent(self, analysis_context, event_object, **unused_kwargs):
"""Analyzes an event object.
Args:
analysis_context: An analysis context object
(instance of AnalysisContext).
event_object: An event object (instance of EventObject).
"""
# Only interested in filesystem events.
if event_object.data_type != 'fs:stat':
return
filename = getattr(event_object, 'filename', None)
if not filename:
return
# Determine if we have a Chrome extension ID.
if u'chrome' not in filename.lower():
return
if not self._sep:
self._sep = analysis_context.GetPathSegmentSeparator(filename)
if not self._user_paths:
self._user_paths = analysis_context.GetUserPaths(analysis_context.users)
if u'{0:s}Extensions{0:s}'.format(self._sep) not in filename:
return
# Now we have extension ID's, let's check if we've got the
# folder, nothing else.
paths = filename.split(self._sep)
if paths[-2] != u'Extensions':
return
extension_id = paths[-1]
if extension_id == u'Temp':
return
# Get the user and ID.
user = analysis_context.GetUsernameFromPath(
self._user_paths, filename, self._sep)
# We still want this information in here, so that we can
# manually deduce the username.
if not user:
if len(filename) > 25:
user = u'Not found ({0:s}...)'.format(filename[0:25])
else:
user = u'Not found ({0:s})'.format(filename)
extension = self._GetTitleFromChromeWebStore(extension_id)
if not extension:
extension = extension_id
self._results.setdefault(user, [])
extension_string = extension.decode('utf-8', 'ignore')
if (extension_string, extension_id) not in self._results[user]:
self._results[user].append((extension_string, extension_id))

View File

@ -0,0 +1,196 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the chrome extension analysis plugin."""
import os
import unittest
from plaso.analysis import chrome_extension
from plaso.analysis import test_lib
from plaso.engine import queue
from plaso.engine import single_process
from plaso.lib import event
# We are accessing quite a lot of protected members in this test file.
# Suppressing that message test file wide.
# pylint: disable=protected-access
class AnalyzeChromeExtensionTestPlugin(
chrome_extension.AnalyzeChromeExtensionPlugin):
"""Chrome extension analysis plugin used for testing."""
NAME = 'chrome_extension_test'
_TEST_DATA_PATH = os.path.join(
os.getcwd(), u'test_data', u'chrome_extensions')
def _GetChromeWebStorePage(self, extension_id):
"""Retrieves the page for the extension from the Chrome store test data.
Args:
extension_id: string containing the extension identifier.
"""
chrome_web_store_file = os.path.join(self._TEST_DATA_PATH, extension_id)
if not os.path.exists(chrome_web_store_file):
return
return open(chrome_web_store_file, 'rb')
class ChromeExtensionTest(test_lib.AnalysisPluginTestCase):
"""Tests for the chrome extension analysis plugin."""
# Few config options here.
MAC_PATHS = [
'/Users/dude/Libary/Application Data/Google/Chrome/Default/Extensions',
('/Users/dude/Libary/Application Data/Google/Chrome/Default/Extensions/'
'apdfllckaahabafndbhieahigkjlhalf'),
'/private/var/log/system.log',
'/Users/frank/Library/Application Data/Google/Chrome/Default',
'/Users/hans/Library/Application Data/Google/Chrome/Default',
('/Users/frank/Library/Application Data/Google/Chrome/Default/'
'Extensions/pjkljhegncpnkpknbcohdijeoejaedia'),
'/Users/frank/Library/Application Data/Google/Chrome/Default/Extensions',]
WIN_PATHS = [
'C:\\Users\\Dude\\SomeFolder\\Chrome\\Default\\Extensions',
('C:\\Users\\Dude\\SomeNoneStandardFolder\\Chrome\\Default\\Extensions\\'
'hmjkmjkepdijhoojdojkdfohbdgmmhki'),
('\\Users\\frank\\AppData\\Local\\Google\\Chrome\\Extensions\\'
'blpcfgokakmgnkcojhhkbfbldkacnbeo'),
'\\Users\\frank\\AppData\\Local\\Google\\Chrome\\Extensions',
('\\Users\\frank\\AppData\\Local\\Google\\Chrome\\Extensions\\'
'icppfcnhkcmnfdhfhphakoifcfokfdhg'),
'C:\\Windows\\System32',
'\\Stuff/with path separator\\Folder']
MAC_USERS = [
{u'name': u'root', u'path': u'/var/root', u'sid': u'0'},
{u'name': u'frank', u'path': u'/Users/frank', u'sid': u'4052'},
{u'name': u'hans', u'path': u'/Users/hans', u'sid': u'4352'},
{u'name': u'dude', u'path': u'/Users/dude', u'sid': u'1123'}]
WIN_USERS = [
{u'name': u'dude', u'path': u'C:\\Users\\dude', u'sid': u'S-1'},
{u'name': u'frank', u'path': u'C:\\Users\\frank', u'sid': u'S-2'}]
def _CreateTestEventObject(self, path):
"""Create a test event object with a particular path."""
event_object = event.EventObject()
event_object.data_type = 'fs:stat'
event_object.timestamp = 12345
event_object.timestamp_desc = u'Some stuff'
event_object.filename = path
return event_object
def testMacAnalyzerPlugin(self):
"""Test the plugin against mock events."""
knowledge_base = self._SetUpKnowledgeBase(knowledge_base_values={
'users': self.MAC_USERS})
event_queue = single_process.SingleProcessQueue()
# Fill the incoming queue with events.
test_queue_producer = queue.ItemQueueProducer(event_queue)
test_queue_producer.ProduceItems([
self._CreateTestEventObject(path) for path in self.MAC_PATHS])
test_queue_producer.SignalEndOfInput()
# Initialize plugin.
analysis_plugin = AnalyzeChromeExtensionTestPlugin(event_queue)
# Run the analysis plugin.
analysis_report_queue_consumer = self._RunAnalysisPlugin(
analysis_plugin, knowledge_base)
analysis_reports = self._GetAnalysisReportsFromQueue(
analysis_report_queue_consumer)
self.assertEquals(len(analysis_reports), 1)
analysis_report = analysis_reports[0]
self.assertEquals(analysis_plugin._sep, u'/')
# Due to the behavior of the join one additional empty string at the end
# is needed to create the last empty line.
expected_text = u'\n'.join([
u' == USER: dude ==',
u' Google Drive [apdfllckaahabafndbhieahigkjlhalf]',
u'',
u' == USER: frank ==',
u' Gmail [pjkljhegncpnkpknbcohdijeoejaedia]',
u'',
u''])
self.assertEquals(analysis_report.text, expected_text)
self.assertEquals(analysis_report.plugin_name, 'chrome_extension_test')
expected_keys = set([u'frank', u'dude'])
self.assertEquals(set(analysis_report.report_dict.keys()), expected_keys)
def testWinAnalyzePlugin(self):
"""Test the plugin against mock events."""
knowledge_base = self._SetUpKnowledgeBase(knowledge_base_values={
'users': self.WIN_USERS})
event_queue = single_process.SingleProcessQueue()
# Fill the incoming queue with events.
test_queue_producer = queue.ItemQueueProducer(event_queue)
test_queue_producer.ProduceItems([
self._CreateTestEventObject(path) for path in self.WIN_PATHS])
test_queue_producer.SignalEndOfInput()
# Initialize plugin.
analysis_plugin = AnalyzeChromeExtensionTestPlugin(event_queue)
# Run the analysis plugin.
analysis_report_queue_consumer = self._RunAnalysisPlugin(
analysis_plugin, knowledge_base)
analysis_reports = self._GetAnalysisReportsFromQueue(
analysis_report_queue_consumer)
self.assertEquals(len(analysis_reports), 1)
analysis_report = analysis_reports[0]
self.assertEquals(analysis_plugin._sep, u'\\')
# Due to the behavior of the join one additional empty string at the end
# is needed to create the last empty line.
expected_text = u'\n'.join([
u' == USER: dude ==',
u' Google Keep - notes and lists [hmjkmjkepdijhoojdojkdfohbdgmmhki]',
u'',
u' == USER: frank ==',
u' Google Play Music [icppfcnhkcmnfdhfhphakoifcfokfdhg]',
u' YouTube [blpcfgokakmgnkcojhhkbfbldkacnbeo]',
u'',
u''])
self.assertEquals(analysis_report.text, expected_text)
self.assertEquals(analysis_report.plugin_name, 'chrome_extension_test')
expected_keys = set([u'frank', u'dude'])
self.assertEquals(set(analysis_report.report_dict.keys()), expected_keys)
if __name__ == '__main__':
unittest.main()

168
plaso/analysis/context.py Normal file
View File

@ -0,0 +1,168 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The analysis context object."""
class AnalysisContext(object):
"""Class that implements the analysis context."""
def __init__(self, analysis_report_queue_producer, knowledge_base):
"""Initializes a analysis plugin context object.
Args:
analysis_report_queue_producer: the analysis report queue producer
(instance of ItemQueueProducer).
knowledge_base: A knowledge base object (instance of KnowledgeBase),
which contains information from the source data needed
for analysis.
"""
super(AnalysisContext, self).__init__()
self._analysis_report_queue_producer = analysis_report_queue_producer
self._knowledge_base = knowledge_base
self.number_of_produced_analysis_reports = 0
@property
def users(self):
"""The list of users."""
return self._knowledge_base.users
def GetPathSegmentSeparator(self, path):
"""Given a path give back the path separator as a best guess.
Args:
path: the path.
Returns:
The path segment separator.
"""
if path.startswith(u'\\') or path[1:].startswith(u':\\'):
return u'\\'
if path.startswith(u'/'):
return u'/'
if u'/' and u'\\' in path:
# Let's count slashes and guess which one is the right one.
forward_count = len(path.split(u'/'))
backward_count = len(path.split(u'\\'))
if forward_count > backward_count:
return u'/'
else:
return u'\\'
# Now we are sure there is only one type of separators yet
# the path does not start with one.
if u'/' in path:
return u'/'
else:
return u'\\'
def GetUsernameFromPath(self, user_paths, file_path, path_segment_separator):
"""Return a username based on preprocessing and the path.
During preprocessing the tool will gather file paths to where each user
profile is stored, and which user it belongs to. This function takes in
a path to a file and compares it to a list of all discovered usernames
and paths to their profiles in the system. If it finds that the file path
belongs to a user profile it will return the username that the profile
belongs to.
Args:
user_paths: A dictionary object containing the paths per username.
file_path: The full path to the file being analyzed.
path_segment_separator: String containing the path segment separator.
Returns:
If possible the responsible username behind the file. Otherwise None.
"""
if not user_paths:
return
if path_segment_separator != u'/':
use_path = file_path.replace(path_segment_separator, u'/')
else:
use_path = file_path
if use_path[1:].startswith(u':/'):
use_path = use_path[2:]
use_path = use_path.lower()
for user, path in user_paths.iteritems():
if use_path.startswith(path):
return user
def GetUserPaths(self, users):
"""Retrieves the user paths.
Args:
users: a list of users.
Returns:
A dictionary object containing the paths per username or None if no users.
"""
if not users:
return
user_paths = {}
user_separator = None
for user in users:
name = user.get('name')
path = user.get('path')
if not path or not name:
continue
if not user_separator:
user_separator = self.GetPathSegmentSeparator(path)
if user_separator != u'/':
path = path.replace(user_separator, u'/').replace(u'//', u'/')
if path[1:].startswith(u':/'):
path = path[2:]
name = name.lower()
user_paths[name] = path.lower()
return user_paths
def ProcessAnalysisReport(self, analysis_report, plugin_name=None):
"""Processes an analysis report before it is emitted to the queue.
Args:
analysis_report: the analysis report object (instance of AnalysisReport).
plugin_name: Optional name of the plugin. The default is None.
"""
if not getattr(analysis_report, 'plugin_name', None) and plugin_name:
analysis_report.plugin_name = plugin_name
def ProduceAnalysisReport(self, analysis_report, plugin_name=None):
"""Produces an analysis report onto the queue.
Args:
analysis_report: the analysis report object (instance of AnalysisReport).
plugin_name: Optional name of the plugin. The default is None.
"""
self.ProcessAnalysisReport(analysis_report, plugin_name=plugin_name)
self._analysis_report_queue_producer.ProduceItem(analysis_report)
self.number_of_produced_analysis_reports += 1

View File

@ -0,0 +1,134 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the analysis context."""
import unittest
from plaso.analysis import context
from plaso.analysis import test_lib
from plaso.engine import queue
from plaso.engine import single_process
class AnalysisContextTest(test_lib.AnalysisPluginTestCase):
"""Tests for the analysis context."""
MAC_PATHS = [
'/Users/dude/Library/Application Data/Google/Chrome/Default/Extensions',
('/Users/dude/Library/Application Data/Google/Chrome/Default/Extensions/'
'apdfllckaahabafndbhieahigkjlhalf'),
'/private/var/log/system.log',
'/Users/frank/Library/Application Data/Google/Chrome/Default',
'/Users/hans/Library/Application Data/Google/Chrome/Default',
('/Users/frank/Library/Application Data/Google/Chrome/Default/'
'Extensions/pjkljhegncpnkpknbcohdijeoejaedia'),
'/Users/frank/Library/Application Data/Google/Chrome/Default/Extensions',]
WIN_PATHS = [
'C:\\Users\\Dude\\SomeFolder\\Chrome\\Default\\Extensions',
('C:\\Users\\Dude\\SomeNoneStandardFolder\\Chrome\\Default\\Extensions\\'
'hmjkmjkepdijhoojdojkdfohbdgmmhki'),
('\\Users\\frank\\AppData\\Local\\Google\\Chrome\\Extensions\\'
'blpcfgokakmgnkcojhhkbfbldkacnbeo'),
'\\Users\\frank\\AppData\\Local\\Google\\Chrome\\Extensions',
('\\Users\\frank\\AppData\\Local\\Google\\Chrome\\Extensions\\'
'icppfcnhkcmnfdhfhphakoifcfokfdhg'),
'C:\\Windows\\System32',
'\\Stuff/with path separator\\Folder']
MAC_USERS = [
{u'name': u'root', u'path': u'/var/root', u'sid': u'0'},
{u'name': u'frank', u'path': u'/Users/frank', u'sid': u'4052'},
{u'name': u'hans', u'path': u'/Users/hans', u'sid': u'4352'},
{u'name': u'dude', u'path': u'/Users/dude', u'sid': u'1123'}]
WIN_USERS = [
{u'name': u'dude', u'path': u'C:\\Users\\dude', u'sid': u'S-1'},
{u'name': u'frank', u'path': u'C:\\Users\\frank', u'sid': u'S-2'}]
def setUp(self):
"""Sets up the needed objects used throughout the test."""
knowledge_base = self._SetUpKnowledgeBase()
analysis_report_queue = single_process.SingleProcessQueue()
analysis_report_queue_producer = queue.ItemQueueProducer(
analysis_report_queue)
self._analysis_context = context.AnalysisContext(
analysis_report_queue_producer, knowledge_base)
def testGetPathSegmentSeparator(self):
"""Tests the GetPathSegmentSeparator function."""
for path in self.MAC_PATHS:
path_segment_separator = self._analysis_context.GetPathSegmentSeparator(
path)
self.assertEquals(path_segment_separator, u'/')
for path in self.WIN_PATHS:
path_segment_separator = self._analysis_context.GetPathSegmentSeparator(
path)
self.assertEquals(path_segment_separator, u'\\')
def testGetUserPaths(self):
"""Tests the GetUserPaths function."""
user_paths = self._analysis_context.GetUserPaths(self.MAC_USERS)
self.assertEquals(
set(user_paths.keys()), set([u'frank', u'dude', u'hans', u'root']))
self.assertEquals(user_paths[u'frank'], u'/users/frank')
self.assertEquals(user_paths[u'dude'], u'/users/dude')
self.assertEquals(user_paths[u'hans'], u'/users/hans')
self.assertEquals(user_paths[u'root'], u'/var/root')
user_paths = self._analysis_context.GetUserPaths(self.WIN_USERS)
self.assertEquals(set(user_paths.keys()), set([u'frank', u'dude']))
self.assertEquals(user_paths[u'frank'], u'/users/frank')
self.assertEquals(user_paths[u'dude'], u'/users/dude')
def testGetUsernameFromPath(self):
"""Tests the GetUsernameFromPath function."""
user_paths = self._analysis_context.GetUserPaths(self.MAC_USERS)
username = self._analysis_context.GetUsernameFromPath(
user_paths, self.MAC_PATHS[0], u'/')
self.assertEquals(username, u'dude')
username = self._analysis_context.GetUsernameFromPath(
user_paths, self.MAC_PATHS[4], u'/')
self.assertEquals(username, u'hans')
username = self._analysis_context.GetUsernameFromPath(
user_paths, self.WIN_PATHS[0], u'/')
self.assertEquals(username, None)
user_paths = self._analysis_context.GetUserPaths(self.WIN_USERS)
username = self._analysis_context.GetUsernameFromPath(
user_paths, self.WIN_PATHS[0], u'\\')
self.assertEquals(username, u'dude')
username = self._analysis_context.GetUsernameFromPath(
user_paths, self.WIN_PATHS[2], u'\\')
self.assertEquals(username, u'frank')
username = self._analysis_context.GetUsernameFromPath(
user_paths, self.MAC_PATHS[2], u'\\')
self.assertEquals(username, None)
if __name__ == '__main__':
unittest.main()

139
plaso/analysis/interface.py Normal file
View File

@ -0,0 +1,139 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains basic interface for analysis plugins."""
import abc
from plaso.engine import queue
from plaso.lib import registry
from plaso.lib import timelib
class AnalysisPlugin(queue.EventObjectQueueConsumer):
"""Analysis plugin gets a copy of each read event for analysis."""
__metaclass__ = registry.MetaclassRegistry
__abstract = True
# The URLS should contain a list of URLs with additional information about
# this analysis plugin.
URLS = []
# The name of the plugin. This is the name that is matched against when
# loading plugins, so it is important that this name is short, concise and
# explains the nature of the plugin easily. It also needs to be unique.
NAME = 'Plugin'
# A flag indicating whether or not this plugin should be run during extraction
# phase or reserved entirely for post processing stage.
# Typically this would mean that the plugin is perhaps too computationally
# heavy to be run during event extraction and should rather be run during
# post-processing.
# Since most plugins should perhaps rather be run during post-processing
# this is set to False by default and needs to be overwritten if the plugin
# should be able to run during the extraction phase.
ENABLE_IN_EXTRACTION = False
# All the possible report types.
TYPE_ANOMALY = 1 # Plugin that is inspecting events for anomalies.
TYPE_STATISTICS = 2 # Statistical calculations.
TYPE_ANNOTATION = 3 # Inspecting events with the primary purpose of
# annotating or tagging them.
TYPE_REPORT = 4 # Inspecting events to provide a summary information.
# Optional arguments to be added to the argument parser.
# An example would be:
# ARGUMENTS = [('--myparameter', {
# 'action': 'store',
# 'help': 'This is my parameter help',
# 'dest': 'myparameter',
# 'default': '',
# 'type': 'unicode'})]
#
# Where all arguments into the dict object have a direct translation
# into the argparse parser.
ARGUMENTS = []
# We need to implement the interface for analysis plugins, but we don't use
# command line options here, so disable checking for unused args.
# pylint: disable=unused-argument
def __init__(self, incoming_queue, options=None):
"""Initializes an analysis plugin.
Args:
incoming_queue: A queue that is used to listen to incoming events.
options: Optional command line arguments (instance of
argparse.Namespace). The default is None.
"""
super(AnalysisPlugin, self).__init__(incoming_queue)
self.plugin_type = self.TYPE_REPORT
# pylint: enable=unused-argument
def _ConsumeEventObject(self, event_object, analysis_context=None, **kwargs):
"""Consumes an event object callback for ConsumeEventObjects.
Args:
event_object: An event object (instance of EventObject).
analysis_context: Optional analysis context object (instance of
AnalysisContext). The default is None.
"""
self.ExamineEvent(analysis_context, event_object, **kwargs)
@property
def plugin_name(self):
"""Return the name of the plugin."""
return self.NAME
@abc.abstractmethod
def CompileReport(self):
"""Compiles a report of the analysis.
After the plugin has received every copy of an event to
analyze this function will be called so that the report
can be assembled.
Returns:
The analysis report (instance of AnalysisReport).
"""
@abc.abstractmethod
def ExamineEvent(self, analysis_context, event_object, **kwargs):
"""Analyzes an event object.
Args:
analysis_context: An analysis context object (instance of
AnalysisContext).
event_object: An event object (instance of EventObject).
"""
def RunPlugin(self, analysis_context):
"""For each item in the queue send the read event to analysis.
Args:
analysis_context: An analysis context object (instance of
AnalysisContext).
"""
self.ConsumeEventObjects(analysis_context=analysis_context)
analysis_report = self.CompileReport()
if analysis_report:
# TODO: move this into the plugins?
analysis_report.time_compiled = timelib.Timestamp.GetNow()
analysis_context.ProduceAnalysisReport(
analysis_report, plugin_name=self.plugin_name)

171
plaso/analysis/test_lib.py Normal file
View File

@ -0,0 +1,171 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Analysis plugin related functions and classes for testing."""
import os
import unittest
from dfvfs.lib import definitions
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import resolver as path_spec_resolver
from plaso.analysis import context
from plaso.artifacts import knowledge_base
from plaso.engine import queue
from plaso.engine import single_process
from plaso.lib import event
from plaso.parsers import context as parsers_context
class TestAnalysisReportQueueConsumer(queue.ItemQueueConsumer):
"""Class that implements a test analysis report queue consumer."""
def __init__(self, queue_object):
"""Initializes the queue consumer.
Args:
queue_object: the queue object (instance of Queue).
"""
super(TestAnalysisReportQueueConsumer, self).__init__(queue_object)
self.analysis_reports = []
def _ConsumeItem(self, analysis_report):
"""Consumes an item callback for ConsumeItems.
Args:
analysis_report: the analysis report (instance of AnalysisReport).
"""
self.analysis_reports.append(analysis_report)
@property
def number_of_analysis_reports(self):
"""The number of analysis reports."""
return len(self.analysis_reports)
class AnalysisPluginTestCase(unittest.TestCase):
"""The unit test case for an analysis plugin."""
_TEST_DATA_PATH = os.path.join(os.getcwd(), 'test_data')
# Show full diff results, part of TestCase so does not follow our naming
# conventions.
maxDiff = None
def _GetAnalysisReportsFromQueue(self, analysis_report_queue_consumer):
"""Retrieves the analysis reports from the queue consumer.
Args:
analysis_report_queue_consumer: the analysis report queue consumer
object (instance of
TestAnalysisReportQueueConsumer).
Returns:
A list of analysis reports (instances of AnalysisReport).
"""
analysis_report_queue_consumer.ConsumeItems()
analysis_reports = []
for analysis_report in analysis_report_queue_consumer.analysis_reports:
self.assertIsInstance(analysis_report, event.AnalysisReport)
analysis_reports.append(analysis_report)
return analysis_reports
def _GetTestFilePath(self, path_segments):
"""Retrieves the path of a test file relative to the test data directory.
Args:
path_segments: the path segments inside the test data directory.
Returns:
A path of the test file.
"""
# Note that we need to pass the individual path segments to os.path.join
# and not a list.
return os.path.join(self._TEST_DATA_PATH, *path_segments)
def _ParseFile(self, parser_object, path, knowledge_base_object):
"""Parses a file using the parser object.
Args:
parser_object: the parser object.
path: the path of the file to parse.
knowledge_base_object: the knowledge base object (instance of
KnowledgeBase).
Returns:
An event object queue object (instance of Queue).
"""
event_queue = single_process.SingleProcessQueue()
event_queue_producer = queue.ItemQueueProducer(event_queue)
parse_error_queue = single_process.SingleProcessQueue()
parser_context = parsers_context.ParserContext(
event_queue_producer, parse_error_queue, knowledge_base_object)
path_spec = path_spec_factory.Factory.NewPathSpec(
definitions.TYPE_INDICATOR_OS, location=path)
file_entry = path_spec_resolver.Resolver.OpenFileEntry(path_spec)
parser_object.Parse(parser_context, file_entry)
event_queue.SignalEndOfInput()
return event_queue
def _RunAnalysisPlugin(self, analysis_plugin, knowledge_base_object):
"""Analyzes an event object queue using the plugin object.
Args:
analysis_plugin: the analysis plugin object (instance of AnalysisPlugin).
knowledge_base_object: the knowledge base object (instance of
KnowledgeBase).
Returns:
An event object queue object (instance of Queue).
"""
analysis_report_queue = single_process.SingleProcessQueue()
analysis_report_queue_consumer = TestAnalysisReportQueueConsumer(
analysis_report_queue)
analysis_report_queue_producer = queue.ItemQueueProducer(
analysis_report_queue)
analysis_context = context.AnalysisContext(
analysis_report_queue_producer, knowledge_base_object)
analysis_plugin.RunPlugin(analysis_context)
analysis_report_queue.SignalEndOfInput()
return analysis_report_queue_consumer
def _SetUpKnowledgeBase(self, knowledge_base_values=None):
"""Sets up a knowledge base.
Args:
knowledge_base_values: optional dict containing the knowledge base
values. The default is None.
Returns:
An knowledge base object (instance of KnowledgeBase).
"""
knowledge_base_object = knowledge_base.KnowledgeBase()
if knowledge_base_values:
for identifier, value in knowledge_base_values.iteritems():
knowledge_base_object.SetValue(identifier, value)
return knowledge_base_object

View File

@ -0,0 +1,267 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A plugin to enable quick triage of Windows Services."""
from plaso.analysis import interface
from plaso.lib import event
from plaso.winnt import human_readable_service_enums
# Moving this import to the bottom due to complaints from certain versions of
# linters.
import yaml
class WindowsService(yaml.YAMLObject):
"""Class to represent a Windows Service."""
# This is used for comparison operations and defines attributes that should
# not be used during evaluation of whether two services are the same.
COMPARE_EXCLUDE = frozenset(['sources'])
KEY_PATH_SEPARATOR = u'\\'
# YAML attributes
yaml_tag = u'!WindowsService'
yaml_loader = yaml.SafeLoader
yaml_dumper = yaml.SafeDumper
def __init__(self, name, service_type, image_path, start_type, object_name,
source, service_dll=None):
"""Initializes a new Windows service object.
Args:
name: The name of the service
service_type: The value of the Type value of the service key.
image_path: The value of the ImagePath value of the service key.
start_type: The value of the Start value of the service key.
object_name: The value of the ObjectName value of the service key.
source: A tuple of (pathspec, Registry key) describing where the
service was found
service_dll: Optional string value of the ServiceDll value in the
service's Parameters subkey. The default is None.
Raises:
TypeError: If a tuple with two elements is not passed as the 'source'
argument.
"""
self.name = name
self.service_type = service_type
self.image_path = image_path
self.start_type = start_type
self.service_dll = service_dll
self.object_name = object_name
if isinstance(source, tuple):
if len(source) != 2:
raise TypeError(u'Source arguments must be tuple of length 2.')
# A service may be found in multiple Control Sets or Registry hives,
# hence the list.
self.sources = [source]
else:
raise TypeError(u'Source argument must be a tuple.')
self.anomalies = []
@classmethod
def FromEvent(cls, service_event):
"""Creates a Service object from an plaso event.
Args:
service_event: The event object (instance of EventObject) to create a new
Service object from.
"""
_, _, name = service_event.keyname.rpartition(
WindowsService.KEY_PATH_SEPARATOR)
service_type = service_event.regvalue.get('Type')
image_path = service_event.regvalue.get('ImagePath')
start_type = service_event.regvalue.get('Start')
service_dll = service_event.regvalue.get('ServiceDll', u'')
object_name = service_event.regvalue.get('ObjectName', u'')
if service_event.pathspec:
source = (service_event.pathspec.location, service_event.keyname)
else:
source = (u'Unknown', u'Unknown')
return cls(
name=name, service_type=service_type, image_path=image_path,
start_type=start_type, object_name=object_name,
source=source, service_dll=service_dll)
def HumanReadableType(self):
"""Return a human readable string describing the type value."""
return human_readable_service_enums.SERVICE_ENUMS['Type'].get(
self.service_type, u'{0:d}'.format(self.service_type))
def HumanReadableStartType(self):
"""Return a human readable string describing the start_type value."""
return human_readable_service_enums.SERVICE_ENUMS['Start'].get(
self.start_type, u'{0:d}'.format(self.start_type))
def __eq__(self, other_service):
"""Custom equality method so that we match near-duplicates.
Compares two service objects together and evaluates if they are
the same or close enough to be considered to represent the same service.
For two service objects to be considered the same they need to
have the the same set of attributes and same values for all their
attributes, other than those enumerated as reserved in the
COMPARE_EXCLUDE constant.
Args:
other_service: The service (instance of WindowsService) we are testing
for equality.
Returns:
A boolean value to indicate whether the services are equal.
"""
if not isinstance(other_service, WindowsService):
return False
attributes = set(self.__dict__.keys())
other_attributes = set(self.__dict__.keys())
if attributes != other_attributes:
return False
# We compare the values for all attributes, other than those specifically
# enumerated as not relevant for equality comparisons.
for attribute in attributes.difference(self.COMPARE_EXCLUDE):
if getattr(self, attribute, None) != getattr(
other_service, attribute, None):
return False
return True
class WindowsServiceCollection(object):
"""Class to hold and de-duplicate Windows Services."""
def __init__(self):
"""Initialize a collection that holds Windows Service."""
self._services = []
def AddService(self, new_service):
"""Add a new service to the list of ones we know about.
Args:
new_service: The service (instance of WindowsService) to add.
"""
for service in self._services:
if new_service == service:
# If this service is the same as one we already know about, we
# just want to add where it came from.
service.sources.append(new_service.sources[0])
return
# We only add a new object to our list if we don't have
# an identical one already.
self._services.append(new_service)
@property
def services(self):
"""Get the services in this collection."""
return self._services
class AnalyzeWindowsServicesPlugin(interface.AnalysisPlugin):
"""Provides a single list of for Windows services found in the Registry."""
NAME = 'windows_services'
# Indicate that we can run this plugin during regular extraction.
ENABLE_IN_EXTRACTION = True
ARGUMENTS = [
('--windows-services-output', {
'dest': 'windows-services-output',
'type': unicode,
'help': 'Specify how the results should be displayed. Options are '
'text and yaml.',
'action': 'store',
'default': u'text',
'choices': [u'text', u'yaml']}),]
def __init__(self, incoming_queue, options=None):
"""Initializes the Windows Services plugin
Args:
incoming_queue: A queue to read events from.
options: Optional command line arguments (instance of
argparse.Namespace). The default is None.
"""
super(AnalyzeWindowsServicesPlugin, self).__init__(incoming_queue)
self._service_collection = WindowsServiceCollection()
self.plugin_type = interface.AnalysisPlugin.TYPE_REPORT
self._output_mode = getattr(options, 'windows-services-output', u'text')
def ExamineEvent(self, analysis_context, event_object, **kwargs):
"""Analyzes an event_object and creates Windows Services as required.
At present, this method only handles events extracted from the Registry.
Args:
analysis_context: The context object analysis plugins.
event_object: The event object (instance of EventObject) to examine.
"""
# TODO: Handle event log entries here also (ie, event id 4697).
if getattr(event_object, 'data_type', None) != 'windows:registry:service':
return
else:
# Create and store the service.
service = WindowsService.FromEvent(event_object)
self._service_collection.AddService(service)
def _FormatServiceText(self, service):
"""Produces a human readable multi-line string representing the service.
Args:
service: The service (instance of WindowsService) to format.
"""
string_segments = [
service.name,
u'\tImage Path = {0:s}'.format(service.image_path),
u'\tService Type = {0:s}'.format(service.HumanReadableType()),
u'\tStart Type = {0:s}'.format(service.HumanReadableStartType()),
u'\tService Dll = {0:s}'.format(service.service_dll),
u'\tObject Name = {0:s}'.format(service.object_name),
u'\tSources:']
for source in service.sources:
string_segments.append(u'\t\t{0:s}:{1:s}'.format(source[0], source[1]))
return u'\n'.join(string_segments)
def CompileReport(self):
"""Compiles a report of the analysis.
Returns:
The analysis report (instance of AnalysisReport).
"""
report = event.AnalysisReport()
if self._output_mode == 'yaml':
lines_of_text = []
lines_of_text.append(
yaml.safe_dump_all(self._service_collection.services))
else:
lines_of_text = ['Listing Windows Services']
for service in self._service_collection.services:
lines_of_text.append(self._FormatServiceText(service))
# Separate services with a blank line.
lines_of_text.append(u'')
report.SetText(lines_of_text)
return report

View File

@ -0,0 +1,192 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the windows services analysis plugin."""
import argparse
import unittest
from dfvfs.path import fake_path_spec
from plaso.analysis import test_lib
from plaso.analysis import windows_services
from plaso.engine import queue
from plaso.engine import single_process
from plaso.events import windows_events
from plaso.parsers import winreg
class WindowsServicesTest(test_lib.AnalysisPluginTestCase):
"""Tests for the Windows Services analysis plugin."""
SERVICE_EVENTS = [
{u'path': u'\\ControlSet001\\services\\TestbDriver',
u'text_dict': {u'ImagePath': u'C:\\Dell\\testdriver.sys', u'Type': 2,
u'Start': 2, u'ObjectName': u''},
u'timestamp': 1346145829002031},
# This is almost the same, but different timestamp and source, so that
# we can test the service de-duplication.
{u'path': u'\\ControlSet003\\services\\TestbDriver',
u'text_dict': {u'ImagePath': u'C:\\Dell\\testdriver.sys', u'Type': 2,
u'Start': 2, u'ObjectName': u''},
u'timestamp': 1346145839002031},
]
def _CreateAnalysisPlugin(self, input_queue, output_mode):
"""Create an analysis plugin to test with.
Args:
input_queue: A queue the plugin will read events from.
output_mode: The output format the plugin will use.
Valid options are 'text' and 'yaml'.
Returns:
An instance of AnalyzeWindowsServicesPlugin.
"""
argument_parser = argparse.ArgumentParser()
plugin_args = windows_services.AnalyzeWindowsServicesPlugin.ARGUMENTS
for parameter, config in plugin_args:
argument_parser.add_argument(parameter, **config)
arguments = ['--windows-services-output', output_mode]
options = argument_parser.parse_args(arguments)
analysis_plugin = windows_services.AnalyzeWindowsServicesPlugin(
input_queue, options)
return analysis_plugin
def _CreateTestEventObject(self, service_event):
"""Create a test event object with a particular path.
Args:
service_event: A hash containing attributes of an event to add to the
queue.
Returns:
An EventObject representing the service to be created.
"""
test_pathspec = fake_path_spec.FakePathSpec(
location=u'C:\\WINDOWS\\system32\\SYSTEM')
event_object = windows_events.WindowsRegistryServiceEvent(
service_event[u'timestamp'], service_event[u'path'],
service_event[u'text_dict'])
event_object.pathspec = test_pathspec
return event_object
def testSyntheticKeysText(self):
"""Test the plugin against mock events."""
event_queue = single_process.SingleProcessQueue()
# Fill the incoming queue with events.
test_queue_producer = queue.ItemQueueProducer(event_queue)
events = [self._CreateTestEventObject(service_event)
for service_event
in self.SERVICE_EVENTS]
test_queue_producer.ProduceItems(events)
test_queue_producer.SignalEndOfInput()
# Initialize plugin.
analysis_plugin = self._CreateAnalysisPlugin(event_queue, u'text')
# Run the analysis plugin.
knowledge_base = self._SetUpKnowledgeBase()
analysis_report_queue_consumer = self._RunAnalysisPlugin(
analysis_plugin, knowledge_base)
analysis_reports = self._GetAnalysisReportsFromQueue(
analysis_report_queue_consumer)
self.assertEquals(len(analysis_reports), 1)
analysis_report = analysis_reports[0]
expected_text = (
u'Listing Windows Services\n'
u'TestbDriver\n'
u'\tImage Path = C:\\Dell\\testdriver.sys\n'
u'\tService Type = File System Driver (0x2)\n'
u'\tStart Type = Auto Start (2)\n'
u'\tService Dll = \n'
u'\tObject Name = \n'
u'\tSources:\n'
u'\t\tC:\\WINDOWS\\system32\\SYSTEM:'
u'\\ControlSet001\\services\\TestbDriver\n'
u'\t\tC:\\WINDOWS\\system32\\SYSTEM:'
u'\\ControlSet003\\services\\TestbDriver\n\n')
self.assertEquals(expected_text, analysis_report.text)
self.assertEquals(analysis_report.plugin_name, 'windows_services')
def testRealEvents(self):
"""Test the plugin with text output against real events from the parser."""
parser = winreg.WinRegistryParser()
# We could remove the non-Services plugins, but testing shows that the
# performance gain is negligible.
knowledge_base = self._SetUpKnowledgeBase()
test_path = self._GetTestFilePath(['SYSTEM'])
event_queue = self._ParseFile(parser, test_path, knowledge_base)
# Run the analysis plugin.
analysis_plugin = self._CreateAnalysisPlugin(event_queue, u'text')
analysis_report_queue_consumer = self._RunAnalysisPlugin(
analysis_plugin, knowledge_base)
analysis_reports = self._GetAnalysisReportsFromQueue(
analysis_report_queue_consumer)
report = analysis_reports[0]
text = report.text
# We'll check that a few strings are in the report, like they're supposed
# to be, rather than checking for the exact content of the string,
# as that's dependent on the full path to the test files.
test_strings = [u'1394ohci', u'WwanSvc', u'Sources:', u'ControlSet001',
u'ControlSet002']
for string in test_strings:
self.assertTrue(string in text)
def testRealEventsYAML(self):
"""Test the plugin with YAML output against real events from the parser."""
parser = winreg.WinRegistryParser()
# We could remove the non-Services plugins, but testing shows that the
# performance gain is negligible.
knowledge_base = self._SetUpKnowledgeBase()
test_path = self._GetTestFilePath(['SYSTEM'])
event_queue = self._ParseFile(parser, test_path, knowledge_base)
# Run the analysis plugin.
analysis_plugin = self._CreateAnalysisPlugin(event_queue, 'yaml')
analysis_report_queue_consumer = self._RunAnalysisPlugin(
analysis_plugin, knowledge_base)
analysis_reports = self._GetAnalysisReportsFromQueue(
analysis_report_queue_consumer)
report = analysis_reports[0]
text = report.text
# We'll check that a few strings are in the report, like they're supposed
# to be, rather than checking for the exact content of the string,
# as that's dependent on the full path to the test files.
test_strings = [windows_services.WindowsService.yaml_tag, u'1394ohci',
u'WwanSvc', u'ControlSet001', u'ControlSet002']
for string in test_strings:
self.assertTrue(string in text, u'{0:s} not found in report text'.format(
string))
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,17 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@ -0,0 +1,137 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The artifact knowledge base object.
The knowledge base is filled by user provided input and the pre-processing
phase. It is intended to provide successive phases, like the parsing and
analysis phases, with essential information like e.g. the timezone and
codepage of the source data.
"""
from plaso.lib import event
import pytz
class KnowledgeBase(object):
"""Class that implements the artifact knowledge base."""
def __init__(self):
"""Initialize the knowledge base object."""
super(KnowledgeBase, self).__init__()
# TODO: the first versions of the knowledge base will wrap the pre-process
# object, but this should be replaced by an artifact style knowledge base
# or artifact cache.
self._pre_obj = event.PreprocessObject()
self._default_codepage = u'cp1252'
self._default_timezone = pytz.timezone('UTC')
@property
def pre_obj(self):
"""The pre-process object."""
return self._pre_obj
@property
def codepage(self):
"""The codepage."""
return getattr(self._pre_obj, 'codepage', self._default_codepage)
@property
def hostname(self):
"""The hostname."""
return getattr(self._pre_obj, 'hostname', u'')
@property
def platform(self):
"""The platform."""
return getattr(self._pre_obj, 'guessed_os', u'')
@platform.setter
def platform(self, value):
"""The platform."""
return setattr(self._pre_obj, 'guessed_os', value)
@property
def timezone(self):
"""The timezone object."""
return getattr(self._pre_obj, 'zone', self._default_timezone)
@property
def users(self):
"""The list of users."""
return getattr(self._pre_obj, 'users', [])
@property
def year(self):
"""The year."""
return getattr(self._pre_obj, 'year', 0)
def GetUsernameByIdentifier(self, identifier):
"""Retrieves the username based on an identifier.
Args:
identifier: the identifier, either a UID or SID.
Returns:
The username or - if not available.
"""
if not identifier:
return u'-'
return self._pre_obj.GetUsernameById(identifier)
def GetValue(self, identifier, default_value=None):
"""Retrieves a value by identifier.
Args:
identifier: the value identifier.
default_value: optional default value. The default is None.
Returns:
The value or None if not available.
"""
return getattr(self._pre_obj, identifier, default_value)
def SetDefaultCodepage(self, codepage):
"""Sets the default codepage.
Args:
codepage: the default codepage.
"""
# TODO: check if value is sane.
self._default_codepage = codepage
def SetDefaultTimezone(self, timezone):
"""Sets the default timezone.
Args:
timezone: the default timezone.
"""
# TODO: check if value is sane.
self._default_timezone = timezone
def SetValue(self, identifier, value):
"""Sets a value by identifier.
Args:
identifier: the value identifier.
value: the value.
"""
setattr(self._pre_obj, identifier, value)

View File

@ -0,0 +1,16 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@ -0,0 +1,184 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains the format classifier classes.
Plaso is a tool that extracts events from files on a file system.
For this it either reads files from a mounted file system or from an image.
It uses an exhaustive approach to determine parse events from a file, meaning
that it passes the file first to parser A and if that fails it continues with
parser B.
The classifier is designed to be able to more quickly determine the format of
a file and limit the number of parsers part of the exhaustive approach.
The current version of the classifier uses signatures to identify file formats.
Some signatures must always be defined at a specific offset, this is referred to
as an offset-bound signature or bound for short. Other signatures are commonly
found at a specific offset but not necessarily. The last form of signatures is
unbound, meaning that they don't have a fixed or common location where they can
be found.
A specification is a collection of signatures with additional metadata that
defines a specific file format. These specifications are grouped into a store
for ease of use, e.g. so that they can be read from a configuration file all
at once.
The classifier requires a scanner to analyze the data in a file. The scanner
uses the specifications in a store to scan for the signatures or a certain
format.
The classifier allows for multiple methods of scanning a file:
* full: the entire file is scanned. This is the default scanning method.
* head-tail: only the beginning (head) and the end (tail) of the file is
scanned. This approach is more efficient for larger files.
The buffer size is used as the size of the data that is scanned.
Smaller files are scanned entirely.
The classifier returns zero or more classifications which point to a format
specification and the scan results for the signatures defined by
the specification.
"""
import logging
class Classification(object):
"""This class represents a format classification.
The format classification consists of a format specification and
scan results.
"""
def __init__(self, specification, scan_matches):
"""Initializes the classification.
Args:
specification: the format specification (instance of Specification).
scan_matches: the list of scan matches (instances of _ScanMatch).
Raises:
TypeError: if the specification is not of type Specification.
"""
self._specification = specification
self.scan_matches = scan_matches
@property
def identifier(self):
"""The classification type."""
return self._specification.identifier
@property
def magic_types(self):
"""The magic types or an empty list if none."""
return self._specification.magic_types
@property
def mime_types(self):
"""The mime type or an empty list if none."""
return self._specification.mime_types
class Classifier(object):
"""Class for classifying formats in raw data.
The classifier is initialized with one or more specifications.
After which it can be used to classify data in files or file-like objects.
The actual scanning of the data is done by the scanner, these are separate
to allow for the scanner to easily be replaced for a more efficient
alternative if necessary.
For an example of how the classifier is to be used see: classify.py.
"""
BUFFER_SIZE = 16 * 1024 * 1024
def __init__(self, scanner):
"""Initializes the classifier and sets up the scanning related structures.
Args:
scanner: an instance of the signature scanner.
"""
self._scanner = scanner
def _GetClassifications(self, scan_results):
"""Retrieves the classifications based on the scan results.
Multiple scan results are combined into a single classification.
Args:
scan_results: a list containing instances of _ScanResult.
Returns:
a list of instances of Classification.
"""
classifications = {}
for scan_result in scan_results:
for scan_match in scan_result.scan_matches:
logging.debug(
u'scan match at offset: 0x{0:08x} specification: {1:s}'.format(
scan_match.total_data_offset, scan_result.identifier))
if scan_result.identifier not in classifications:
classifications[scan_result.identifier] = Classification(
scan_result.specification, scan_result.scan_matches)
return classifications.values()
def ClassifyBuffer(self, data, data_size):
"""Classifies the data in a buffer, assumes all necessary data is available.
Args:
data: a buffer containing raw data.
data_size: the size of the raw data in the buffer.
Returns:
a list of classifications or an empty list.
"""
scan_state = self._scanner.StartScan()
self._scanner.ScanBuffer(scan_state, data, data_size)
self._scanner.StopScan(scan_state)
return self._GetClassifications(scan_state.GetResults())
def ClassifyFileObject(self, file_object):
"""Classifies the data in a file-like object.
Args:
file_object: a file-like object.
Returns:
a list of classifier classifications or an empty list.
"""
scan_results = self._scanner.ScanFileObject(file_object)
return self._GetClassifications(scan_results)
def ClassifyFile(self, filename):
"""Classifies the data in a file.
Args:
filename: the name of the file.
Returns:
a list of classifier classifications or an empty list.
"""
classifications = []
with open(filename, 'rb') as file_object:
classifications = self.ClassifyFileObject(file_object)
return classifications

View File

@ -0,0 +1,72 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains tests for the format classifier classes."""
import os
import unittest
from plaso.classifier import classifier
from plaso.classifier import scanner
from plaso.classifier import test_lib
class ClassifierTest(unittest.TestCase):
"""Class to test Classifier."""
def setUp(self):
"""Function to test the initialize function."""
self._store = test_lib.CreateSpecificationStore()
self._test_file1 = os.path.join('test_data', 'NTUSER.DAT')
self._test_file2 = os.path.join('test_data', 'syslog.zip')
def testClassifyFileWithScanner(self):
"""Function to test the classify file function."""
test_scanner = scanner.Scanner(self._store)
test_classifier = classifier.Classifier(test_scanner)
classifications = test_classifier.ClassifyFile(self._test_file1)
self.assertEqual(len(classifications), 1)
# TODO: assert the contents of the classification.
test_classifier = classifier.Classifier(test_scanner)
classifications = test_classifier.ClassifyFile(self._test_file2)
self.assertEqual(len(classifications), 1)
# TODO: assert the contents of the classification.
def testClassifyFileWithOffsetBoundScanner(self):
"""Function to test the classify file function."""
test_scanner = scanner.OffsetBoundScanner(self._store)
test_classifier = classifier.Classifier(test_scanner)
classifications = test_classifier.ClassifyFile(self._test_file1)
self.assertEqual(len(classifications), 1)
# TODO: assert the contents of the classification.
test_classifier = classifier.Classifier(test_scanner)
classifications = test_classifier.ClassifyFile(self._test_file2)
self.assertEqual(len(classifications), 1)
# TODO: assert the contents of the classification.
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,78 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains a small classify test program."""
import argparse
import glob
import logging
from plaso.classifier import classifier
from plaso.classifier import scanner
from plaso.classifier import test_lib
def Main():
args_parser = argparse.ArgumentParser(
description='Classify test program.')
args_parser.add_argument(
'-t', '--type', type='choice', metavar='TYPE', action='store',
dest='scanner_type', choices=['scan-tree', 'scan_tree'],
default='scan-tree', help='The scanner type')
args_parser.add_argument(
'-v', '--verbose', action='store_true', dest='verbose', default=False,
help='Print verbose output')
args_parser.add_argument(
'filenames', nargs='+', action='store', metavar='FILENAMES',
default=None, help='The input filename(s) to classify.')
options = args_parser.parse_args()
if options.verbose:
logging.basicConfig(level=logging.DEBUG)
files_to_classify = []
for input_glob in options.filenames:
files_to_classify += glob.glob(input_glob)
store = test_lib.CreateSpecificationStore()
if options.scanner_type not in ['scan-tree', 'scan_tree']:
print u'Unsupported scanner type defaulting to: scan-tree'
scan = scanner.Scanner(store)
classify = classifier.Classifier(scan)
for input_filename in files_to_classify:
classifications = classify.ClassifyFile(input_filename)
print u'File: {0:s}'.format(input_filename)
if not classifications:
print u'No classifications found.'
else:
print u'Classifications:'
for classification in classifications:
print u'\tformat: {0:s}'.format(classification.identifier)
print u''
if __name__ == '__main__':
Main()

View File

@ -0,0 +1,308 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The patterns classes used by the scan tree-based format scanner."""
class _ByteValuePatterns(object):
"""Class that implements a mapping between byte value and patterns.
The byte value patterns are used in the scan tree-based format scanner
to map a byte value to one or more patterns.
"""
def __init__(self, byte_value):
"""Initializes the pattern table (entry) byte value.
Args:
byte_value: the byte value that maps the patterns in the table.
"""
super(_ByteValuePatterns, self).__init__()
self.byte_value = byte_value
self.patterns = {}
def __unicode__(self):
"""Retrieves a string representation of the byte value patterns."""
return u'0x{0:02x} {1!s}'.format(ord(self.byte_value), self.patterns)
def AddPattern(self, pattern):
"""Adds a pattern.
Args:
pattern: the pattern (instance of Pattern).
Raises:
ValueError: if the table entry already contains a pattern
with the same identifier.
"""
if pattern.identifier in self.patterns:
raise ValueError(u'Pattern {0:s} is already defined.'.format(
pattern.identifier))
self.patterns[pattern.identifier] = pattern
def ToDebugString(self, indentation_level=1):
"""Converts the byte value pattern into a debug string."""
indentation = u' ' * indentation_level
header = u'{0:s}byte value: 0x{1:02x}\n'.format(
indentation, ord(self.byte_value))
entries = u''.join([u'{0:s} patterns: {1:s}\n'.format(
indentation, identifier) for identifier in self.patterns])
return u''.join([header, entries, u'\n'])
class _SkipTable(object):
"""Class that implements a skip table.
The skip table is used in the scan tree-based format scanner to determine
the skip value for the BoyerMooreHorspool search.
"""
def __init__(self, skip_pattern_length):
"""Initializes the skip table.
Args:
skip_pattern_length: the (maximum) skip pattern length.
"""
super(_SkipTable, self).__init__()
self._skip_value_per_byte_value = {}
self.skip_pattern_length = skip_pattern_length
def __getitem__(self, key):
"""Retrieves a specific skip value.
Args:
key: the byte value within the skip table.
Returns:
the skip value for the key or the maximim skip value
if no corresponding key was found.
"""
if key in self._skip_value_per_byte_value:
return self._skip_value_per_byte_value[key]
return self.skip_pattern_length
def SetSkipValue(self, byte_value, skip_value):
"""Sets a skip value.
Args:
byte_value: the corresponding byte value.
skip_value: the number of bytes to skip.
Raises:
ValueError: if byte value or skip value is out of bounds.
"""
if byte_value < 0 or byte_value > 255:
raise ValueError(u'Invalid byte value, value out of bounds.')
if skip_value < 0 or skip_value >= self.skip_pattern_length:
raise ValueError(u'Invalid skip value, value out of bounds.')
if (not byte_value in self._skip_value_per_byte_value or
self._skip_value_per_byte_value[byte_value] > skip_value):
self._skip_value_per_byte_value[byte_value] = skip_value
def ToDebugString(self):
"""Converts the skip table into a debug string."""
header = u'Byte value\tSkip value\n'
entries = u''.join([u'0x{0:02x}\t{1:d}\n'.format(
byte_value, self._skip_value_per_byte_value[byte_value])
for byte_value in self._skip_value_per_byte_value])
default = u'Default\t{0:d}\n'.format(self.skip_pattern_length)
return u''.join([header, entries, default, u'\n'])
class Pattern(object):
"""Class that implements a pattern."""
def __init__(self, signature_index, signature, specification):
"""Initializes the pattern.
Args:
signature_index: the index of the signature within the specification.
signature: the signature (instance of Signature).
specification: the specification (instance of Specification) that
contains the signature.
"""
super(Pattern, self).__init__()
self._signature_index = signature_index
self.signature = signature
self.specification = specification
def __unicode__(self):
"""Retrieves a string representation."""
return self.identifier
@property
def expression(self):
"""The signature expression."""
return self.signature.expression
@property
def identifier(self):
"""The identifier."""
# Using _ here because some scanner implementation are limited to what
# characters can be used in the identifiers.
return u'{0:s}_{1:d}'.format(
self.specification.identifier, self._signature_index)
@property
def offset(self):
"""The signature offset."""
return self.signature.offset
@property
def is_bound(self):
"""Boolean value to indicate the signature is bound to an offset."""
return self.signature.is_bound
class PatternTable(object):
"""Class that implements a pattern table.
The pattern table is used in the the scan tree-based format scanner
to construct a scan tree. It contains either unbound patterns or
patterns bound to a specific offset.
"""
def __init__(self, patterns, ignore_list, is_bound=None):
"""Initializes and builds the patterns table from patterns.
Args:
patterns: a list of the patterns.
ignore_list: a list of pattern offsets to ignore.
is_bound: optional boolean value to indicate if the signatures are bound
to offsets. The default is None, which means the value should
be ignored and both bound and unbound patterns are considered
unbound.
Raises:
ValueError: if a signature pattern is too small to be useful (< 4).
"""
super(PatternTable, self).__init__()
self._byte_values_per_offset = {}
self.largest_pattern_length = 0
self.largest_pattern_offset = 0
self.patterns = []
self.smallest_pattern_length = 0
self.smallest_pattern_offset = 0
for pattern in patterns:
if is_bound is not None and pattern.signature.is_bound != is_bound:
continue
pattern_length = len(pattern.expression)
if pattern_length < 4:
raise ValueError(u'Pattern too small to be useful.')
self.smallest_pattern_length = min(
self.smallest_pattern_length, pattern_length)
self.largest_pattern_length = max(
self.largest_pattern_length, pattern_length)
self.patterns.append(pattern)
self._AddPattern(pattern, ignore_list, is_bound)
def _AddPattern(self, pattern, ignore_list, is_bound):
"""Adds the byte values per offset in the pattern to the table.
Args:
pattern: the pattern (instance of Pattern).
ignore_list: a list of pattern offsets to ignore.
is_bound: boolean value to indicate if the signatures are bound
to offsets. A value of None indicates that the value should
be ignored and both bound and unbound patterns are considered
unbound.
"""
pattern_offset = pattern.offset if is_bound else 0
self.smallest_pattern_offset = min(
self.smallest_pattern_offset, pattern_offset)
self.largest_pattern_offset = max(
self.largest_pattern_offset, pattern_offset)
for byte_value in pattern.expression:
if pattern_offset not in self._byte_values_per_offset:
self._byte_values_per_offset[pattern_offset] = {}
if pattern_offset not in ignore_list:
byte_values = self._byte_values_per_offset[pattern_offset]
if byte_value not in byte_values:
byte_values[byte_value] = _ByteValuePatterns(byte_value)
byte_value_patterns = byte_values[byte_value]
byte_value_patterns.AddPattern(pattern)
pattern_offset += 1
@property
def offsets(self):
"""The offsets."""
return self._byte_values_per_offset.keys()
def GetByteValues(self, pattern_offset):
"""Returns the bytes values for a specific pattern offset."""
return self._byte_values_per_offset[pattern_offset]
def GetSkipTable(self):
"""Retrieves the skip table for the patterns in the table.
Returns:
The skip table (instance of SkipTable).
"""
skip_table = _SkipTable(self.smallest_pattern_length)
for pattern in self.patterns:
if pattern.expression:
skip_value = self.smallest_pattern_length
for expression_index in range(0, self.smallest_pattern_length):
skip_value -= 1
skip_table.SetSkipValue(
ord(pattern.expression[expression_index]), skip_value)
return skip_table
def ToDebugString(self):
"""Converts the pattern table into a debug string."""
header = u'Pattern offset\tByte value(s)\n'
entries = u''
for pattern_offset in self._byte_values_per_offset:
entries += u'{0:d}'.format(pattern_offset)
byte_values = self._byte_values_per_offset[pattern_offset]
for byte_value in byte_values:
identifiers = u', '.join(
[identifier for identifier in byte_values[byte_value].patterns])
entries += u'\t0x{0:02x} ({1:s})'.format(ord(byte_value), identifiers)
entries += u'\n'
return u''.join([header, entries, u'\n'])

View File

@ -0,0 +1,156 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The range list data type."""
class Range(object):
"""Class that implements a range object."""
def __init__(self, range_offset, range_size):
"""Initializes the range object.
Args:
range_offset: the range offset.
range_size: the range size.
Raises:
ValueError: if the range offset or range size is not valid.
"""
if range_offset < 0:
raise ValueError(u'Invalid range offset value.')
if range_size < 0:
raise ValueError(u'Invalid range size value.')
super(Range, self).__init__()
self.start_offset = range_offset
self.size = range_size
self.end_offset = range_offset + range_size
class RangeList(object):
"""Class that implements a range list object."""
def __init__(self):
"""Initializes the range list object."""
super(RangeList, self).__init__()
self.ranges = []
@property
def number_of_ranges(self):
"""The number of ranges."""
return len(self.ranges)
def GetSpanningRange(self):
"""Retrieves the range spanning the entire range list."""
if self.number_of_ranges == 0:
return
first_range = self.ranges[0]
last_range = self.ranges[-1]
range_size = last_range.end_offset - first_range.start_offset
return Range(first_range.start_offset, range_size)
def Insert(self, range_offset, range_size):
"""Inserts the range defined by the offset and size in the list.
Note that overlapping ranges will be merged.
Args:
range_offset: the range offset.
range_size: the range size.
Raises:
RuntimeError: if the range cannot be inserted.
ValueError: if the range offset or range size is not valid.
"""
if range_offset < 0:
raise ValueError(u'Invalid range offset value.')
if range_size < 0:
raise ValueError(u'Invalid range size value.')
insert_index = None
merge_index = None
number_of_range_objects = len(self.ranges)
range_end_offset = range_offset + range_size
if number_of_range_objects == 0:
insert_index = 0
else:
range_object_index = 0
for range_object in self.ranges:
# Ignore negative ranges.
if range_object.start_offset < 0:
range_object_index += 1
continue
# Insert the range before an existing one.
if range_end_offset < range_object.start_offset:
insert_index = range_object_index
break
# Ignore the range since the existing one overlaps it.
if (range_offset >= range_object.start_offset and
range_end_offset <= range_object.end_offset):
break
# Merge the range since it overlaps the existing one at the end.
if (range_offset >= range_object.start_offset and
range_offset <= range_object.end_offset):
merge_index = range_object_index
break
# Merge the range since it overlaps the existing one at the start.
if (range_end_offset >= range_object.start_offset and
range_end_offset <= range_object.end_offset):
merge_index = range_object_index
break
# Merge the range since it overlaps the existing one.
if (range_offset <= range_object.start_offset and
range_end_offset >= range_object.end_offset):
merge_index = range_object_index
break
range_object_index += 1
# Insert the range after the last one.
if range_object_index >= number_of_range_objects:
insert_index = number_of_range_objects
if insert_index is not None and merge_index is not None:
raise RuntimeError(
u'Unable to insert the range both insert and merge specified.')
if insert_index is not None:
self.ranges.insert(insert_index, Range(range_offset, range_size))
elif merge_index is not None:
range_object = self.ranges[merge_index]
if range_offset < range_object.start_offset:
range_object.size += range_object.start_offset - range_offset
range_object.start_offset = range_offset
if range_end_offset > range_object.end_offset:
range_object.size += range_end_offset - range_object.end_offset
range_object.end_offset = range_end_offset

View File

@ -0,0 +1,113 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the range list."""
import unittest
from plaso.classifier import range_list
class RangeListTest(unittest.TestCase):
"""Class to test the range list."""
def testInsertPositiveRanges(self):
"""Function to test the insert function using positive ranges."""
range_list_object = range_list.RangeList()
# Test non-overlapping range.
range_list_object.Insert(500, 100)
self.assertEquals(range_list_object.number_of_ranges, 1)
range_object = range_list_object.ranges[0]
self.assertEquals(range_object.start_offset, 500)
self.assertEquals(range_object.end_offset, 600)
self.assertEquals(range_object.size, 100)
# Test non-overlapping range.
range_list_object.Insert(2000, 100)
self.assertEquals(range_list_object.number_of_ranges, 2)
range_object = range_list_object.ranges[1]
self.assertEquals(range_object.start_offset, 2000)
self.assertEquals(range_object.end_offset, 2100)
self.assertEquals(range_object.size, 100)
# Test range that overlaps with an existing range at the start.
range_list_object.Insert(1950, 100)
self.assertEquals(range_list_object.number_of_ranges, 2)
range_object = range_list_object.ranges[1]
self.assertEquals(range_object.start_offset, 1950)
self.assertEquals(range_object.end_offset, 2100)
self.assertEquals(range_object.size, 150)
# Test range that overlaps with an existing range at the end.
range_list_object.Insert(2050, 100)
self.assertEquals(range_list_object.number_of_ranges, 2)
range_object = range_list_object.ranges[1]
self.assertEquals(range_object.start_offset, 1950)
self.assertEquals(range_object.end_offset, 2150)
self.assertEquals(range_object.size, 200)
# Test non-overlapping range.
range_list_object.Insert(1000, 100)
self.assertEquals(range_list_object.number_of_ranges, 3)
range_object = range_list_object.ranges[1]
self.assertEquals(range_object.start_offset, 1000)
self.assertEquals(range_object.end_offset, 1100)
self.assertEquals(range_object.size, 100)
# Test range that aligns with an existing range at the end.
range_list_object.Insert(1100, 100)
self.assertEquals(range_list_object.number_of_ranges, 3)
range_object = range_list_object.ranges[1]
self.assertEquals(range_object.start_offset, 1000)
self.assertEquals(range_object.end_offset, 1200)
self.assertEquals(range_object.size, 200)
# Test range that aligns with an existing range at the start.
range_list_object.Insert(900, 100)
self.assertEquals(range_list_object.number_of_ranges, 3)
range_object = range_list_object.ranges[1]
self.assertEquals(range_object.start_offset, 900)
self.assertEquals(range_object.end_offset, 1200)
self.assertEquals(range_object.size, 300)
# Test non-overlapping range.
range_list_object.Insert(0, 100)
self.assertEquals(range_list_object.number_of_ranges, 4)
range_object = range_list_object.ranges[0]
self.assertEquals(range_object.start_offset, 0)
self.assertEquals(range_object.end_offset, 100)
self.assertEquals(range_object.size, 100)
# Test invalid ranges.
with self.assertRaises(ValueError):
range_list_object.Insert(-1, 100)
with self.assertRaises(ValueError):
range_list_object.Insert(3000, -100)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,744 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The scan tree classes used by the scan tree-based format scanner."""
import logging
from plaso.classifier import patterns
from plaso.classifier import range_list
class _PatternWeights(object):
"""Class that implements pattern weights."""
def __init__(self):
"""Initializes the pattern weights."""
super(_PatternWeights, self).__init__()
self._offsets_per_weight = {}
self._weight_per_offset = {}
def AddOffset(self, pattern_offset):
"""Adds a pattern offset and sets its weight to 0.
Args:
pattern_offset: the pattern offset to add to the pattern weights.
Raises:
ValueError: if the pattern weights already contains the pattern offset.
"""
if pattern_offset in self._weight_per_offset:
raise ValueError(u'Pattern offset already set.')
self._weight_per_offset[pattern_offset] = 0
def AddWeight(self, pattern_offset, weight):
"""Adds a weight for a specific pattern offset.
Args:
pattern_offset: the pattern offset to add to the pattern weights.
weight: the corresponding weight to add.
Raises:
ValueError: if the pattern weights does not contain the pattern offset.
"""
if pattern_offset not in self._weight_per_offset:
raise ValueError(u'Pattern offset not set.')
self._weight_per_offset[pattern_offset] += weight
if weight not in self._offsets_per_weight:
self._offsets_per_weight[weight] = []
self._offsets_per_weight[weight].append(pattern_offset)
def GetLargestWeight(self):
"""Retrieves the largest weight or 0 if none."""
if self._offsets_per_weight:
return max(self._offsets_per_weight)
return 0
def GetOffsetsForWeight(self, weight):
"""Retrieves the list of offsets for a specific weight."""
return self._offsets_per_weight[weight]
def GetWeightForOffset(self, pattern_offset):
"""Retrieves the weight for a specific pattern offset."""
return self._weight_per_offset[pattern_offset]
def ToDebugString(self):
"""Converts the pattern weights into a debug string."""
header1 = u'Pattern offset\tWeight\n'
entries1 = u''.join([u'{0:d}\t{1:d}\n'.format(
pattern_offset, self._weight_per_offset[pattern_offset])
for pattern_offset in self._weight_per_offset])
header2 = u'Weight\tPattern offset(s)\n'
entries2 = u''.join([u'{0:d}\t{1!s}\n'.format(
weight, self._offsets_per_weight[weight])
for weight in self._offsets_per_weight])
return u''.join([header1, entries1, u'\n', header2, entries2, u'\n'])
def SetWeight(self, pattern_offset, weight):
"""Sets a weight for a specific pattern offset.
Args:
pattern_offset: the pattern offset to set in the pattern weights.
weight: the corresponding weight to set.
Raises:
ValueError: if the pattern weights does not contain the pattern offset.
"""
if pattern_offset not in self._weight_per_offset:
raise ValueError(u'Pattern offset not set.')
self._weight_per_offset[pattern_offset] = weight
if weight not in self._offsets_per_weight:
self._offsets_per_weight[weight] = []
self._offsets_per_weight[weight].append(pattern_offset)
class ScanTree(object):
"""Class that implements a scan tree."""
_COMMON_BYTE_VALUES = frozenset(
'\x00\x01\xff\t\n\r 0123456789'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'abcdefghijklmnopqrstuvwxyz')
# The offset must be positive, negative offsets are ignored.
OFFSET_MODE_POSITIVE = 1
# The offset must be negative, positive offsets are ignored.
OFFSET_MODE_NEGATIVE = 2
# The offset must be positive, an error is raised for negative offsets.
OFFSET_MODE_POSITIVE_STRICT = 3
# The offset must be negative, an error is raised for positive offsets.
OFFSET_MODE_NEGATIVE_STRICT = 4
def __init__(
self, specification_store, is_bound,
offset_mode=OFFSET_MODE_POSITIVE_STRICT):
"""Initializes and builds the scan tree.
Args:
specification_store: the specification store (instance of
SpecificationStore) that contains the format
specifications.
is_bound: boolean value to indicate if the signatures are bound
to offsets. A value of None indicates that the value should
be ignored and both bound and unbound patterns are considered
unbound.
offset_mode: optional value to indicate how the signature offsets should
be handled. The default is that the offset must be positive
and an error is raised for negative offsets.
"""
super(ScanTree, self).__init__()
self.largest_length = 0
self.pattern_list = []
self.range_list = range_list.RangeList()
self.root_node = None
self.skip_table = None
# First determine all the patterns from the specification store.
self._BuildPatterns(specification_store, is_bound, offset_mode=offset_mode)
# Next create the scan tree starting with the root node.
ignore_list = []
pattern_table = patterns.PatternTable(
self.pattern_list, ignore_list, is_bound)
if pattern_table.patterns:
self.root_node = self._BuildScanTreeNode(
pattern_table, ignore_list, is_bound)
logging.debug(u'Scan tree:\n{0:s}'.format(
self.root_node.ToDebugString()))
# At the end the skip table is determined to provide for the
# BoyerMooreHorspool skip value.
self.skip_table = pattern_table.GetSkipTable()
logging.debug(u'Skip table:\n{0:s}'.format(
self.skip_table.ToDebugString()))
self.largest_length = pattern_table.largest_pattern_length
def _BuildPatterns(
self, specification_store, is_bound,
offset_mode=OFFSET_MODE_POSITIVE_STRICT):
"""Builds the list of patterns.
Args:
specification_store: the specification store (instance of
SpecificationStore) that contains the format
specifications.
is_bound: boolean value to indicate if the signatures are bound
to offsets. A value of None indicates that the value should
be ignored and both bound and unbound patterns are considered
unbound.
offset_mode: optional value to indicate how the signature offsets should
be handled. The default is that the offset must be positive
and an error is raised for negative offsets.
Raises:
ValueError: if a signature offset invalid according to specified offset
mode or a signature pattern is too small to be useful (< 4).
"""
self.pattern_list = []
for specification in specification_store.specifications:
signature_index = 0
for signature in specification.signatures:
if signature.expression:
signature_offset = signature.offset if is_bound else 0
signature_pattern_length = len(signature.expression)
# Make sure signature offset is numeric.
try:
signature_offset = int(signature_offset)
except (TypeError, ValueError):
signature_offset = 0
if signature_offset < 0:
if offset_mode == self.OFFSET_MODE_POSITIVE:
continue
elif offset_mode == self.OFFSET_MODE_POSITIVE_STRICT:
raise ValueError(u'Signature offset less than 0.')
# The range list does not allow offsets to be negative and thus
# the signature offset is turned into a positive equivalent.
signature_offset *= -1
# The signature size is substracted to make sure the spanning
# range will align with the original negative offset values.
signature_offset -= signature_pattern_length
elif signature_offset > 0:
if offset_mode == self.OFFSET_MODE_NEGATIVE:
continue
elif offset_mode == self.OFFSET_MODE_NEGATIVE_STRICT:
raise ValueError(u'Signature offset greater than 0.')
if signature_pattern_length < 4:
raise ValueError(u'Signature pattern smaller than 4.')
pattern = patterns.Pattern(
signature_index, signature, specification)
self.pattern_list.append(pattern)
self.range_list.Insert(signature_offset, signature_pattern_length)
signature_index += 1
def _BuildScanTreeNode(self, pattern_table, ignore_list, is_bound):
"""Builds a scan tree node.
Args:
pattern_table: a pattern table (instance of PatternTable).
ignore_list: a list of pattern offsets to ignore
is_bound: boolean value to indicate if the signatures are bound
to offsets. A value of None indicates that the value should
be ignored and both bound and unbound patterns are considered
unbound.
Raises:
ValueError: if number of byte value patterns value out of bounds.
Returns:
A scan tree node (instance of ScanTreeNode).
"""
# Make a copy of the lists because the function is going to alter them
# and the changes must remain in scope of the function.
pattern_list = list(pattern_table.patterns)
ignore_list = list(ignore_list)
similarity_weights = _PatternWeights()
occurrence_weights = _PatternWeights()
value_weights = _PatternWeights()
for pattern_offset in pattern_table.offsets:
similarity_weights.AddOffset(pattern_offset)
occurrence_weights.AddOffset(pattern_offset)
value_weights.AddOffset(pattern_offset)
byte_values = pattern_table.GetByteValues(pattern_offset)
number_of_byte_values = len(byte_values)
if number_of_byte_values > 1:
occurrence_weights.SetWeight(pattern_offset, number_of_byte_values)
for byte_value in byte_values:
byte_value_patterns = byte_values[byte_value]
byte_value_weight = len(byte_value_patterns.patterns)
if byte_value_weight > 1:
similarity_weights.AddWeight(pattern_offset, byte_value_weight)
if byte_value_weight not in self._COMMON_BYTE_VALUES:
value_weights.AddWeight(pattern_offset, 1)
logging.debug(u'Pattern table:\n{0:s}'.format(
pattern_table.ToDebugString()))
logging.debug(u'Similarity weights:\n{0:s}'.format(
similarity_weights.ToDebugString()))
logging.debug(u'Occurrence weights:\n{0:s}'.format(
occurrence_weights.ToDebugString()))
logging.debug(u'Value weights:\n{0:s}'.format(
value_weights.ToDebugString()))
pattern_offset = self._GetMostSignificantPatternOffset(
pattern_list, similarity_weights, occurrence_weights, value_weights)
ignore_list.append(pattern_offset)
# For the scan tree negative offsets are adjusted so that
# the smallest pattern offset is 0.
scan_tree_pattern_offset = pattern_offset
if scan_tree_pattern_offset < 0:
scan_tree_pattern_offset -= pattern_table.smallest_pattern_offset
scan_tree_node = ScanTreeNode(scan_tree_pattern_offset)
byte_values = pattern_table.GetByteValues(pattern_offset)
for byte_value in byte_values:
byte_value_patterns = byte_values[byte_value]
logging.debug(u'{0:s}'.format(byte_value_patterns.ToDebugString()))
number_of_byte_value_patterns = len(byte_value_patterns.patterns)
if number_of_byte_value_patterns <= 0:
raise ValueError(
u'Invalid number of byte value patterns value out of bounds.')
elif number_of_byte_value_patterns == 1:
for identifier in byte_value_patterns.patterns:
logging.debug(
u'Adding pattern: {0:s} for byte value: 0x{1:02x}.'.format(
identifier, ord(byte_value)))
scan_tree_node.AddByteValue(
byte_value, byte_value_patterns.patterns[identifier])
else:
pattern_table = patterns.PatternTable(
byte_value_patterns.patterns.itervalues(), ignore_list, is_bound)
scan_sub_node = self._BuildScanTreeNode(
pattern_table, ignore_list, is_bound)
logging.debug(
u'Adding scan node for byte value: 0x{0:02x}\n{1:s}'.format(
ord(byte_value), scan_sub_node.ToDebugString()))
scan_tree_node.AddByteValue(ord(byte_value), scan_sub_node)
for identifier in byte_value_patterns.patterns:
logging.debug(u'Removing pattern: {0:s} from:\n{1:s}'.format(
identifier, self._PatternsToDebugString(pattern_list)))
pattern_list.remove(byte_value_patterns.patterns[identifier])
logging.debug(u'Remaining patterns:\n{0:s}'.format(
self._PatternsToDebugString(pattern_list)))
number_of_patterns = len(pattern_list)
if number_of_patterns == 1:
logging.debug(u'Setting pattern: {0:s} for default value'.format(
pattern_list[0].identifier))
scan_tree_node.SetDefaultValue(pattern_list[0])
elif number_of_patterns > 1:
pattern_table = patterns.PatternTable(pattern_list, ignore_list, is_bound)
scan_sub_node = self._BuildScanTreeNode(
pattern_table, ignore_list, is_bound)
logging.debug(u'Setting scan node for default value:\n{0:s}'.format(
scan_sub_node.ToDebugString()))
scan_tree_node.SetDefaultValue(scan_sub_node)
return scan_tree_node
def _GetMostSignificantPatternOffset(
self, pattern_list, similarity_weights, occurrence_weights,
value_weights):
"""Returns the most significant pattern offset.
Args:
pattern_list: a list of patterns
similarity_weights: the similarity (pattern) weights.
occurrence_weights: the occurrence (pattern) weights.
value_weights: the value (pattern) weights.
Raises:
ValueError: when pattern is an empty list.
Returns:
a pattern offset.
"""
if not pattern_list:
raise ValueError(u'Missing pattern list.')
pattern_offset = None
number_of_patterns = len(pattern_list)
if number_of_patterns == 1:
pattern_offset = self._GetPatternOffsetForValueWeights(
value_weights)
elif number_of_patterns == 2:
pattern_offset = self._GetPatternOffsetForOccurrenceWeights(
occurrence_weights, value_weights)
elif number_of_patterns > 2:
pattern_offset = self._GetPatternOffsetForSimilarityWeights(
similarity_weights, occurrence_weights, value_weights)
logging.debug(u'Largest weight offset: {0:d}'.format(pattern_offset))
return pattern_offset
def _GetPatternOffsetForOccurrenceWeights(
self, occurrence_weights, value_weights):
"""Returns the most significant pattern offset based on the value weights.
Args:
occurrence_weights: the occurrence (pattern) weights.
value_weights: the value (pattern) weights.
Returns:
a pattern offset.
"""
debug_string = ""
pattern_offset = None
largest_weight = occurrence_weights.GetLargestWeight()
logging.debug(u'Largest occurrence weight: {0:d}'.format(largest_weight))
if largest_weight > 0:
occurrence_weight_offsets = occurrence_weights.GetOffsetsForWeight(
largest_weight)
number_of_occurrence_offsets = len(occurrence_weight_offsets)
else:
number_of_occurrence_offsets = 0
if number_of_occurrence_offsets == 0:
pattern_offset = self._GetPatternOffsetForValueWeights(
value_weights)
elif number_of_occurrence_offsets == 1:
pattern_offset = occurrence_weight_offsets[0]
else:
largest_weight = 0
largest_value_weight = 0
for occurrence_offset in occurrence_weight_offsets:
value_weight = value_weights.GetWeightForOffset(
occurrence_offset)
debug_string = (
u'Occurrence offset: {0:d} value weight: {1:d}').format(
occurrence_offset, value_weight)
if not pattern_offset or largest_weight < value_weight:
largest_weight = value_weight
pattern_offset = occurrence_offset
debug_string += u' largest value weight: {0:d}'.format(
largest_value_weight)
logging.debug(u'{0:s}'.format(debug_string))
return pattern_offset
def _GetPatternOffsetForSimilarityWeights(
self, similarity_weights, occurrence_weights, value_weights):
"""Returns the most significant pattern offset.
Args:
similarity_weights: the similarity (pattern) weights.
occurrence_weights: the occurrence (pattern) weights.
value_weights: the value (pattern) weights.
Returns:
a pattern offset.
"""
debug_string = ""
pattern_offset = None
largest_weight = similarity_weights.GetLargestWeight()
logging.debug(u'Largest similarity weight: {0:d}'.format(largest_weight))
if largest_weight > 0:
similarity_weight_offsets = similarity_weights.GetOffsetsForWeight(
largest_weight)
number_of_similarity_offsets = len(similarity_weight_offsets)
else:
number_of_similarity_offsets = 0
if number_of_similarity_offsets == 0:
pattern_offset = self._GetPatternOffsetForOccurrenceWeights(
occurrence_weights, value_weights)
elif number_of_similarity_offsets == 1:
pattern_offset = similarity_weight_offsets[0]
else:
largest_weight = 0
largest_value_weight = 0
for similarity_offset in similarity_weight_offsets:
occurrence_weight = occurrence_weights.GetWeightForOffset(
similarity_offset)
debug_string = (
u'Similarity offset: {0:d} occurrence weight: {1:d}').format(
similarity_offset, occurrence_weight)
if largest_weight > 0 and largest_weight == occurrence_weight:
value_weight = value_weights.GetWeightForOffset(
similarity_offset)
debug_string += u' value weight: {0:d}'.format(value_weight)
if largest_value_weight < value_weight:
largest_weight = 0
if not pattern_offset or largest_weight < occurrence_weight:
largest_weight = occurrence_weight
pattern_offset = similarity_offset
largest_value_weight = value_weights.GetWeightForOffset(
similarity_offset)
debug_string += u' largest value weight: {0:d}'.format(
largest_value_weight)
logging.debug(u'{0:s}'.format(debug_string))
return pattern_offset
def _GetPatternOffsetForValueWeights(
self, value_weights):
"""Returns the most significant pattern offset based on the value weights.
Args:
value_weights: the value (pattern) weights.
Raises:
RuntimeError: no value weight offset were found.
Returns:
a pattern offset.
"""
largest_weight = value_weights.GetLargestWeight()
logging.debug(u'Largest value weight: {0:d}'.format(largest_weight))
if largest_weight > 0:
value_weight_offsets = value_weights.GetOffsetsForWeight(largest_weight)
number_of_value_offsets = len(value_weight_offsets)
else:
number_of_value_offsets = 0
if number_of_value_offsets == 0:
raise RuntimeError(u'No value weight offsets found.')
return value_weight_offsets[0]
def _PatternsToDebugString(self, pattern_list):
"""Converts the list of patterns into a debug string."""
entries = u', '.join([u'{0:s}'.format(pattern) for pattern in pattern_list])
return u''.join([u'[', entries, u']'])
class ScanTreeNode(object):
"""Class that implements a scan tree node."""
def __init__(self, pattern_offset):
"""Initializes the scan tree node.
Args:
pattern_offset: the offset in the pattern to which the node
applies.
"""
super(ScanTreeNode, self).__init__()
self._byte_values = {}
self.default_value = None
self.parent = None
self.pattern_offset = pattern_offset
def AddByteValue(self, byte_value, scan_object):
"""Adds a byte value.
Args:
byte_value: the corresponding byte value.
scan_object: the scan object, either a scan sub node or a pattern.
Raises:
ValueError: if byte value is out of bounds or if the node already
contains a scan object for the byte value.
"""
if isinstance(byte_value, str):
byte_value = ord(byte_value)
if byte_value < 0 or byte_value > 255:
raise ValueError(u'Invalid byte value, value out of bounds.')
if byte_value in self._byte_values:
raise ValueError(u'Byte value already set.')
if isinstance(scan_object, ScanTreeNode):
scan_object.parent = self
self._byte_values[byte_value] = scan_object
def CompareByteValue(
self, data, data_offset, data_size, total_data_offset,
total_data_size=None):
"""Scans a buffer using the bounded scan tree.
This function will return partial matches on the ata block block
boundary as long as the total data size has not been reached.
Args:
data: a buffer containing raw data.
data_offset: the offset in the raw data in the buffer.
data_size: the size of the raw data in the buffer.
total_data_offset: the offset of the data relative to the start of
the total data scanned.
total_data_size: optional value to indicate the total data size.
The default is None.
Returns:
the resulting scan object which is either a ScanTreeNode or Pattern
or None.
Raises:
RuntimeError: if the data offset, total data offset, total data size
or pattern offset value is out of bounds.
"""
found_match = False
scan_tree_byte_value = 0
if data_offset < 0 or data_offset >= data_size:
raise RuntimeError(u'Invalid data offset, value out of bounds.')
if total_data_size is not None and total_data_size < 0:
raise RuntimeError(u'Invalid total data size, value out of bounds.')
if total_data_offset < 0 or (
total_data_size is not None and total_data_offset >= total_data_size):
raise RuntimeError(u'Invalid total data offset, value out of bounds.')
if (total_data_size is not None and
total_data_offset + data_size >= total_data_size):
match_on_boundary = True
else:
match_on_boundary = False
data_offset += self.pattern_offset
if not match_on_boundary and data_offset >= data_size:
raise RuntimeError(u'Invalid pattern offset value, out of bounds.')
if data_offset < data_size:
data_byte_value = ord(data[data_offset])
for scan_tree_byte_value in self._byte_values:
if data_byte_value == scan_tree_byte_value:
found_match = True
break
if found_match:
scan_object = self._byte_values[scan_tree_byte_value]
logging.debug(
u'Scan tree node match at data offset: 0x{0:08x}.'.format(data_offset)
)
else:
scan_object = self.default_value
if not scan_object:
scan_object = self.parent
while scan_object and not scan_object.default_value:
scan_object = scan_object.parent
if scan_object:
scan_object = scan_object.default_value
return scan_object
def SetDefaultValue(self, scan_object):
"""Sets the default (non-match) value.
Args:
scan_object: the scan object, either a scan sub node or a pattern.
Raises:
ValueError: if the default value is already set.
"""
if self.default_value:
raise ValueError(u'Default value already set.')
self.default_value = scan_object
def ToDebugString(self, indentation_level=1):
"""Converts the scan tree node into a debug string."""
indentation = u' ' * indentation_level
header = u'{0:s}pattern offset: {1:d}\n'.format(
indentation, self.pattern_offset)
entries = u''
for byte_value in self._byte_values:
entries += u'{0:s}byte value: 0x{1:02x}\n'.format(indentation, byte_value)
if isinstance(self._byte_values[byte_value], ScanTreeNode):
entries += u'{0:s}scan tree node:\n'.format(indentation)
entries += self._byte_values[byte_value].ToDebugString(
indentation_level + 1)
elif isinstance(self._byte_values[byte_value], patterns.Pattern):
entries += u'{0:s}pattern: {1:s}\n'.format(
indentation, self._byte_values[byte_value].identifier)
default = u'{0:s}default value:\n'.format(indentation)
if isinstance(self.default_value, ScanTreeNode):
default += u'{0:s}scan tree node:\n'.format(indentation)
default += self.default_value.ToDebugString(indentation_level + 1)
elif isinstance(self.default_value, patterns.Pattern):
default += u'{0:s}pattern: {1:s}\n'.format(
indentation, self.default_value.identifier)
return u''.join([header, entries, default, u'\n'])

View File

@ -0,0 +1,74 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains tests for the scan tree classes."""
import unittest
from plaso.classifier import patterns
from plaso.classifier import scan_tree
from plaso.classifier import specification
class ScanTreeNodeTest(unittest.TestCase):
"""Class to test the scan tree node."""
def testAddByteValueWithPattern(self):
"""Function to test the add byte value with pattern function."""
scan_node = scan_tree.ScanTreeNode(0)
format_regf = specification.Specification('REGF')
format_regf.AddNewSignature('regf', offset=0)
format_esedb = specification.Specification('ESEDB')
format_esedb.AddNewSignature('\xef\xcd\xab\x89', offset=4)
signature_esedb = specification.Signature('\xef\xcd\xab\x89', offset=4)
signature_regf = specification.Signature('regf', offset=0)
pattern_regf = patterns.Pattern(0, signature_regf, format_regf)
pattern_esedb = patterns.Pattern(0, signature_esedb, format_esedb)
scan_node.AddByteValue('r', pattern_regf)
scan_node.AddByteValue('\xef', pattern_esedb)
self.assertRaises(
ValueError, scan_node.AddByteValue, 'r', pattern_regf)
self.assertRaises(
ValueError, scan_node.AddByteValue, -1, pattern_regf)
self.assertRaises(
ValueError, scan_node.AddByteValue, 256, pattern_regf)
def testAddByteValueWithScanNode(self):
"""Function to test the add byte value with scan node function."""
scan_node = scan_tree.ScanTreeNode(0)
scan_sub_node_0x41 = scan_tree.ScanTreeNode(1)
scan_sub_node_0x80 = scan_tree.ScanTreeNode(1)
scan_node.AddByteValue(0x41, scan_sub_node_0x41)
scan_node.AddByteValue(0x80, scan_sub_node_0x80)
self.assertRaises(
ValueError, scan_node.AddByteValue, 0x80, scan_sub_node_0x80)
self.assertRaises(
ValueError, scan_node.AddByteValue, -1, scan_sub_node_0x80)
self.assertRaises(
ValueError, scan_node.AddByteValue, 256, scan_sub_node_0x80)
if __name__ == '__main__':
unittest.main()

749
plaso/classifier/scanner.py Normal file
View File

@ -0,0 +1,749 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains the classes for a scan tree-based format scanner."""
import logging
import os
from plaso.classifier import patterns
from plaso.classifier import range_list
from plaso.classifier import scan_tree
class _ScanMatch(object):
"""Class that implements a scan match."""
def __init__(self, total_data_offset, pattern):
"""Initializes the scan result.
Args:
total_data_offset: the offset of the resulting match relative
to the start of the total data scanned.
pattern: the pattern matched.
"""
super(_ScanMatch, self).__init__()
self.total_data_offset = total_data_offset
self.pattern = pattern
@property
def specification(self):
"""The specification."""
return self.pattern.specification
class _ScanResult(object):
"""Class that implements a scan result."""
def __init__(self, specification):
"""Initializes the scan result.
Args:
scan_tree_node: the corresponding scan tree node or None.
"""
super(_ScanResult, self).__init__()
self.specification = specification
self.scan_matches = []
@property
def identifier(self):
"""The specification identifier."""
return self.specification.identifier
class ScanState(object):
"""Class that implements a scan state."""
# The state definitions.
_SCAN_STATE_START = 1
_SCAN_STATE_SCANNING = 2
_SCAN_STATE_STOP = 3
def __init__(self, scan_tree_node, total_data_size=None):
"""Initializes the scan state.
Args:
scan_tree_node: the corresponding scan tree node or None.
total_data_size: optional value to indicate the total data size.
The default is None.
"""
super(ScanState, self).__init__()
self._matches = []
self.remaining_data = None
self.remaining_data_size = 0
self.scan_tree_node = scan_tree_node
self.state = self._SCAN_STATE_START
self.total_data_offset = 0
self.total_data_size = total_data_size
def AddMatch(self, total_data_offset, pattern):
"""Adds a result to the state to scanning.
Args:
total_data_offset: the offset of the resulting match relative
to the start total data scanned.
pattern: the pattern matched.
Raises:
RuntimeError: when a unsupported state is encountered.
"""
if (self.state != self._SCAN_STATE_START and
self.state != self._SCAN_STATE_SCANNING):
raise RuntimeError(u'Unsupported scan state.')
self._matches.append(_ScanMatch(total_data_offset, pattern))
def GetMatches(self):
"""Retrieves a list containing the results.
Returns:
A list of scan matches (instances of _ScanMatch).
Raises:
RuntimeError: when a unsupported state is encountered.
"""
if self.state != self._SCAN_STATE_STOP:
raise RuntimeError(u'Unsupported scan state.')
return self._matches
def Reset(self, scan_tree_node):
"""Resets the state to start.
This function will clear the remaining data.
Args:
scan_tree_node: the corresponding scan tree node or None.
Raises:
RuntimeError: when a unsupported state is encountered.
"""
if self.state != self._SCAN_STATE_STOP:
raise RuntimeError(u'Unsupported scan state.')
self.remaining_data = None
self.remaining_data_size = 0
self.scan_tree_node = scan_tree_node
self.state = self._SCAN_STATE_START
def Scanning(self, scan_tree_node, total_data_offset):
"""Sets the state to scanning.
Args:
scan_tree_node: the active scan tree node.
total_data_offset: the offset of the resulting match relative
to the start of the total data scanned.
Raises:
RuntimeError: when a unsupported state is encountered.
"""
if (self.state != self._SCAN_STATE_START and
self.state != self._SCAN_STATE_SCANNING):
raise RuntimeError(u'Unsupported scan state.')
self.scan_tree_node = scan_tree_node
self.state = self._SCAN_STATE_SCANNING
self.total_data_offset = total_data_offset
def Stop(self):
"""Sets the state to stop.
Raises:
RuntimeError: when a unsupported state is encountered.
"""
if (self.state != self._SCAN_STATE_START and
self.state != self._SCAN_STATE_SCANNING):
raise RuntimeError(u'Unsupported scan state.')
self.scan_tree_node = None
self.state = self._SCAN_STATE_STOP
class ScanTreeScannerBase(object):
"""Class that implements a scan tree-based scanner base."""
def __init__(self, specification_store):
"""Initializes the scanner.
Args:
specification_store: the specification store (instance of
SpecificationStore) that contains the format
specifications.
"""
super(ScanTreeScannerBase, self).__init__()
self._scan_tree = None
self._specification_store = specification_store
def _ScanBufferScanState(
self, scan_tree_object, scan_state, data, data_size, total_data_offset,
total_data_size=None):
"""Scans a buffer using the scan tree.
This function implements a BoyerMooreHorspool equivalent approach
in combination with the scan tree.
Args:
scan_tree_object: the scan tree (instance of ScanTree).
scan_state: the scan state (instance of ScanState).
data: a buffer containing raw data.
data_size: the size of the raw data in the buffer.
total_data_offset: the offset of the data relative to the start of
the total data scanned.
total_data_size: optional value to indicate the total data size.
The default is None.
Raises:
RuntimeError: if the total data offset, total data size or the last
pattern offset value is out of bounds
"""
if total_data_size is not None and total_data_size < 0:
raise RuntimeError(u'Invalid total data size, value out of bounds.')
if total_data_offset < 0 or (
total_data_size is not None and total_data_offset >= total_data_size):
raise RuntimeError(u'Invalid total data offset, value out of bounds.')
data_offset = 0
scan_tree_node = scan_state.scan_tree_node
if scan_state.remaining_data:
# str.join() should be more efficient then concatenation by +.
data = ''.join([scan_state.remaining_data, data])
data_size += scan_state.remaining_data_size
scan_state.remaining_data = None
scan_state.remaining_data_size = 0
if (total_data_size is not None and
total_data_offset + data_size >= total_data_size):
match_on_boundary = True
else:
match_on_boundary = False
while data_offset < data_size:
if (not match_on_boundary and
data_offset + scan_tree_object.largest_length >= data_size):
break
found_match = False
scan_done = False
while not scan_done:
scan_object = scan_tree_node.CompareByteValue(
data, data_offset, data_size, total_data_offset,
total_data_size=total_data_size)
if isinstance(scan_object, scan_tree.ScanTreeNode):
scan_tree_node = scan_object
else:
scan_done = True
if isinstance(scan_object, patterns.Pattern):
pattern_length = len(scan_object.signature.expression)
data_last_offset = data_offset + pattern_length
if cmp(scan_object.signature.expression,
data[data_offset:data_last_offset]) == 0:
if (not scan_object.signature.is_bound or
scan_object.signature.offset == data_offset):
found_match = True
logging.debug(
u'Signature match at data offset: 0x{0:08x}.'.format(
data_offset))
scan_state.AddMatch(total_data_offset + data_offset, scan_object)
if found_match:
skip_value = len(scan_object.signature.expression)
scan_tree_node = scan_tree_object.root_node
else:
last_pattern_offset = (
scan_tree_object.skip_table.skip_pattern_length - 1)
if data_offset + last_pattern_offset >= data_size:
raise RuntimeError(
u'Invalid last pattern offset, value out of bounds.')
skip_value = 0
while last_pattern_offset >= 0 and not skip_value:
last_data_offset = data_offset + last_pattern_offset
byte_value = ord(data[last_data_offset])
skip_value = scan_tree_object.skip_table[byte_value]
last_pattern_offset -= 1
if not skip_value:
skip_value = 1
scan_tree_node = scan_tree_object.root_node
data_offset += skip_value
if not match_on_boundary and data_offset < data_size:
scan_state.remaining_data = data[data_offset:data_size]
scan_state.remaining_data_size = data_size - data_offset
scan_state.Scanning(scan_tree_node, total_data_offset + data_offset)
def _ScanBufferScanStateFinal(self, scan_tree_object, scan_state):
"""Scans the remaining data in the scan state using the scan tree.
Args:
scan_tree_object: the scan tree (instance of ScanTree).
scan_state: the scan state (instance of ScanState).
"""
if scan_state.remaining_data:
data = scan_state.remaining_data
data_size = scan_state.remaining_data_size
scan_state.remaining_data = None
scan_state.remaining_data_size = 0
# Setting the total data size will make boundary matches are returned
# in this scanning pass.
total_data_size = scan_state.total_data_size
if total_data_size is None:
total_data_size = scan_state.total_data_offset + data_size
self._ScanBufferScanState(
scan_tree_object, scan_state, data, data_size,
scan_state.total_data_offset, total_data_size=total_data_size)
scan_state.Stop()
def GetScanResults(self, scan_state):
"""Retrieves the scan results.
Args:
scan_state: the scan state (instance of ScanState).
Return:
A list of scan results (instances of _ScanResult).
"""
scan_results = {}
for scan_match in scan_state.GetMatches():
specification = scan_match.specification
identifier = specification.identifier
logging.debug(
u'Scan match at offset: 0x{0:08x} specification: {1:s}'.format(
scan_match.total_data_offset, identifier))
if identifier not in scan_results:
scan_results[identifier] = _ScanResult(specification)
scan_results[identifier].scan_matches.append(scan_match)
return scan_results.values()
class Scanner(ScanTreeScannerBase):
"""Class that implements a scan tree-based scanner."""
_READ_BUFFER_SIZE = 512
def __init__(self, specification_store):
"""Initializes the scanner.
Args:
specification_store: the specification store (instance of
SpecificationStore) that contains the format
specifications.
"""
super(Scanner, self).__init__(specification_store)
def ScanBuffer(self, scan_state, data, data_size):
"""Scans a buffer.
Args:
scan_state: the scan state (instance of ScanState).
data: a buffer containing raw data.
data_size: the size of the raw data in the buffer.
"""
self._ScanBufferScanState(
self._scan_tree, scan_state, data, data_size,
scan_state.total_data_offset,
total_data_size=scan_state.total_data_size)
def ScanFileObject(self, file_object):
"""Scans a file-like object.
Args:
file_object: a file-like object.
Returns:
A list of scan results (instances of ScanResult).
"""
file_offset = 0
if hasattr(file_object, 'get_size'):
file_size = file_object.get_size()
else:
file_object.seek(0, os.SEEK_END)
file_size = file_object.tell()
scan_state = self.StartScan(total_data_size=file_size)
file_object.seek(file_offset, os.SEEK_SET)
while file_offset < file_size:
data = file_object.read(self._READ_BUFFER_SIZE)
data_size = len(data)
if data_size == 0:
break
self._ScanBufferScanState(
self._scan_tree, scan_state, data, data_size, file_offset,
total_data_size=file_size)
file_offset += data_size
self.StopScan(scan_state)
return self.GetScanResults(scan_state)
def StartScan(self, total_data_size=None):
"""Starts a scan.
The function sets up the scanning related structures if necessary.
Args:
total_data_size: optional value to indicate the total data size.
The default is None.
Returns:
A scan state (instance of ScanState).
Raises:
RuntimeError: when total data size is invalid.
"""
if total_data_size is not None and total_data_size < 0:
raise RuntimeError(u'Invalid total data size.')
if self._scan_tree is None:
self._scan_tree = scan_tree.ScanTree(
self._specification_store, None)
return ScanState(self._scan_tree.root_node, total_data_size=total_data_size)
def StopScan(self, scan_state):
"""Stops a scan.
Args:
scan_state: the scan state (instance of ScanState).
"""
self._ScanBufferScanStateFinal(self._scan_tree, scan_state)
class OffsetBoundScanner(ScanTreeScannerBase):
"""Class that implements an offset-bound scan tree-based scanner."""
_READ_BUFFER_SIZE = 512
def __init__(self, specification_store):
"""Initializes the scanner.
Args:
specification_store: the specification store (instance of
SpecificationStore) that contains the format
specifications.
"""
super(OffsetBoundScanner, self).__init__(specification_store)
self._footer_scan_tree = None
self._footer_spanning_range = None
self._header_scan_tree = None
self._header_spanning_range = None
def _GetFooterRange(self, total_data_size):
"""Retrieves the read buffer aligned footer range.
Args:
total_data_size: optional value to indicate the total data size.
The default is None.
Returns:
A range (instance of Range).
"""
# The actual footer range is in reverse since the spanning footer range
# is based on positive offsets, where 0 is the end of file.
if self._footer_spanning_range.end_offset < total_data_size:
footer_range_start_offset = (
total_data_size - self._footer_spanning_range.end_offset)
else:
footer_range_start_offset = 0
# Calculate the lower bound modulus of the footer range start offset
# in increments of the read buffer size.
footer_range_start_offset /= self._READ_BUFFER_SIZE
footer_range_start_offset *= self._READ_BUFFER_SIZE
# Calculate the upper bound modulus of the footer range size
# in increments of the read buffer size.
footer_range_size = self._footer_spanning_range.size
remainder = footer_range_size % self._READ_BUFFER_SIZE
footer_range_size /= self._READ_BUFFER_SIZE
if remainder > 0:
footer_range_size += 1
footer_range_size *= self._READ_BUFFER_SIZE
return range_list.Range(footer_range_start_offset, footer_range_size)
def _GetHeaderRange(self):
"""Retrieves the read buffer aligned header range.
Returns:
A range (instance of Range).
"""
# Calculate the lower bound modulus of the header range start offset
# in increments of the read buffer size.
header_range_start_offset = self._header_spanning_range.start_offset
header_range_start_offset /= self._READ_BUFFER_SIZE
header_range_start_offset *= self._READ_BUFFER_SIZE
# Calculate the upper bound modulus of the header range size
# in increments of the read buffer size.
header_range_size = self._header_spanning_range.size
remainder = header_range_size % self._READ_BUFFER_SIZE
header_range_size /= self._READ_BUFFER_SIZE
if remainder > 0:
header_range_size += 1
header_range_size *= self._READ_BUFFER_SIZE
return range_list.Range(header_range_start_offset, header_range_size)
def _ScanBufferScanState(
self, scan_tree_object, scan_state, data, data_size, total_data_offset,
total_data_size=None):
"""Scans a buffer using the scan tree.
This function implements a BoyerMooreHorspool equivalent approach
in combination with the scan tree.
Args:
scan_tree_object: the scan tree (instance of ScanTree).
scan_state: the scan state (instance of ScanState).
data: a buffer containing raw data.
data_size: the size of the raw data in the buffer.
total_data_offset: the offset of the data relative to the start of
the total data scanned.
total_data_size: optional value to indicate the total data size.
The default is None.
"""
scan_done = False
scan_tree_node = scan_tree_object.root_node
while not scan_done:
data_offset = 0
scan_object = scan_tree_node.CompareByteValue(
data, data_offset, data_size, total_data_offset,
total_data_size=total_data_size)
if isinstance(scan_object, scan_tree.ScanTreeNode):
scan_tree_node = scan_object
else:
scan_done = True
if isinstance(scan_object, patterns.Pattern):
pattern_length = len(scan_object.signature.expression)
pattern_start_offset = scan_object.signature.offset
pattern_end_offset = pattern_start_offset + pattern_length
if cmp(scan_object.signature.expression,
data[pattern_start_offset:pattern_end_offset]) == 0:
scan_state.AddMatch(
total_data_offset + scan_object.signature.offset, scan_object)
logging.debug(
u'Signature match at data offset: 0x{0:08x}.'.format(data_offset))
# TODO: implement.
# def ScanBuffer(self, scan_state, data, data_size):
# """Scans a buffer.
# Args:
# scan_state: the scan state (instance of ScanState).
# data: a buffer containing raw data.
# data_size: the size of the raw data in the buffer.
# """
# # TODO: fix footer scanning logic.
# # need to know the file size here for the footers.
# # TODO: check for clashing ranges?
# header_range = self._GetHeaderRange()
# footer_range = self._GetFooterRange(scan_state.total_data_size)
# if self._scan_tree == self._header_scan_tree:
# if (scan_state.total_data_offset >= header_range.start_offset and
# scan_state.total_data_offset < header_range.end_offset):
# self._ScanBufferScanState(
# self._scan_tree, scan_state, data, data_size,
# scan_state.total_data_offset,
# total_data_size=scan_state.total_data_size)
# elif scan_state.total_data_offset > header_range.end_offset:
# # TODO: implement.
# pass
# if self._scan_tree == self._footer_scan_tree:
# if (scan_state.total_data_offset >= footer_range.start_offset and
# scan_state.total_data_offset < footer_range.end_offset):
# self._ScanBufferScanState(
# self._scan_tree, scan_state, data, data_size,
# scan_state.total_data_offset,
# total_data_size=scan_state.total_data_size)
def ScanFileObject(self, file_object):
"""Scans a file-like object.
Args:
file_object: a file-like object.
Returns:
A scan state (instance of ScanState).
"""
# TODO: add support for fixed size block-based reads.
if hasattr(file_object, 'get_size'):
file_size = file_object.get_size()
else:
file_object.seek(0, os.SEEK_END)
file_size = file_object.tell()
file_offset = 0
scan_state = self.StartScan(total_data_size=file_size)
if self._header_scan_tree.root_node is not None:
header_range = self._GetHeaderRange()
# TODO: optimize the read by supporting fixed size block-based reads.
# if file_offset < header_range.start_offset:
# file_offset = header_range.start_offset
file_object.seek(file_offset, os.SEEK_SET)
# TODO: optimize the read by supporting fixed size block-based reads.
# data = file_object.read(header_range.size)
data = file_object.read(header_range.end_offset)
data_size = len(data)
if data_size > 0:
self._ScanBufferScanState(
self._scan_tree, scan_state, data, data_size, file_offset,
total_data_size=file_size)
file_offset += data_size
if self._footer_scan_tree.root_node is not None:
self.StopScan(scan_state)
self._scan_tree = self._footer_scan_tree
scan_state.Reset(self._scan_tree.root_node)
if self._footer_scan_tree.root_node is not None:
footer_range = self._GetFooterRange(file_size)
# Note that the offset in the footer scan tree start with 0. Make sure
# the data offset of the data being scanned is aligned with the offset
# in the scan tree.
if footer_range.start_offset < self._footer_spanning_range.end_offset:
data_offset = (
self._footer_spanning_range.end_offset - footer_range.start_offset)
else:
data_offset = 0
if file_offset < footer_range.start_offset:
file_offset = footer_range.start_offset
file_object.seek(file_offset, os.SEEK_SET)
data = file_object.read(self._READ_BUFFER_SIZE)
data_size = len(data)
if data_size > 0:
self._ScanBufferScanState(
self._scan_tree, scan_state, data[data_offset:],
data_size - data_offset, file_offset + data_offset,
total_data_size=file_size)
self.StopScan(scan_state)
return self.GetScanResults(scan_state)
def StartScan(self, total_data_size=None):
"""Starts a scan.
The function sets up the scanning related structures if necessary.
Args:
total_data_size: optional value to indicate the total data size.
The default is None.
Returns:
A list of scan results (instances of ScanResult).
Raises:
RuntimeError: when total data size is invalid.
"""
if total_data_size is None or total_data_size < 0:
raise RuntimeError(u'Invalid total data size.')
if self._header_scan_tree is None:
self._header_scan_tree = scan_tree.ScanTree(
self._specification_store, True,
offset_mode=scan_tree.ScanTree.OFFSET_MODE_POSITIVE)
if self._header_spanning_range is None:
spanning_range = self._header_scan_tree.range_list.GetSpanningRange()
self._header_spanning_range = spanning_range
if self._footer_scan_tree is None:
self._footer_scan_tree = scan_tree.ScanTree(
self._specification_store, True,
offset_mode=scan_tree.ScanTree.OFFSET_MODE_NEGATIVE)
if self._footer_spanning_range is None:
spanning_range = self._footer_scan_tree.range_list.GetSpanningRange()
self._footer_spanning_range = spanning_range
if self._header_scan_tree.root_node is not None:
self._scan_tree = self._header_scan_tree
elif self._footer_scan_tree.root_node is not None:
self._scan_tree = self._footer_scan_tree
else:
self._scan_tree = None
if self._scan_tree is not None:
root_node = self._scan_tree.root_node
else:
root_node = None
return ScanState(root_node, total_data_size=total_data_size)
def StopScan(self, scan_state):
"""Stops a scan.
Args:
scan_state: the scan state (instance of ScanState).
"""
self._ScanBufferScanStateFinal(self._scan_tree, scan_state)
self._scan_tree = None

View File

@ -0,0 +1,119 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains tests for the format scanner classes."""
import unittest
from plaso.classifier import scanner
from plaso.classifier import test_lib
class ScannerTest(unittest.TestCase):
"""Class to test the scanner."""
def testInitialize(self):
"""Function to test the initialize function."""
store = test_lib.CreateSpecificationStore()
# Signature for LNK
data1 = ('\x4c\x00\x00\x00\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00'
'\x00\x00\x00\x46')
# Signature for REGF
data2 = 'regf'
# Random data
data3 = '\x01\xfa\xe0\xbe\x99\x8e\xdb\x70\xea\xcc\x6b\xae\x2f\xf5\xa2\xe4'
# Boundary scan test
data4a = ('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00PK')
data4b = ('\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z')
# Large buffer test
data5_size = 1024 * 1024
data5 = '\x00' * (data5_size - 4)
data5 += 'PK\x07\x08'
test_scanner = scanner.Scanner(store)
total_data_size = len(data1)
scan_state = test_scanner.StartScan(total_data_size=total_data_size)
test_scanner.ScanBuffer(scan_state, data1, len(data1))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 1)
scan_state = test_scanner.StartScan(total_data_size=None)
test_scanner.ScanBuffer(scan_state, data1, len(data1))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 1)
total_data_size = len(data2)
scan_state = test_scanner.StartScan(total_data_size=total_data_size)
test_scanner.ScanBuffer(scan_state, data2, len(data2))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 1)
scan_state = test_scanner.StartScan(total_data_size=None)
test_scanner.ScanBuffer(scan_state, data2, len(data2))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 1)
total_data_size = len(data3)
scan_state = test_scanner.StartScan(total_data_size=total_data_size)
test_scanner.ScanBuffer(scan_state, data3, len(data3))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 0)
scan_state = test_scanner.StartScan(total_data_size=None)
test_scanner.ScanBuffer(scan_state, data3, len(data3))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 0)
total_data_size = len(data4a) + len(data4b)
scan_state = test_scanner.StartScan(total_data_size=total_data_size)
test_scanner.ScanBuffer(scan_state, data4a, len(data4a))
test_scanner.ScanBuffer(scan_state, data4b, len(data4b))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 1)
scan_state = test_scanner.StartScan(total_data_size=None)
test_scanner.ScanBuffer(scan_state, data4a, len(data4a))
test_scanner.ScanBuffer(scan_state, data4b, len(data4b))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 1)
total_data_size = len(data5)
scan_state = test_scanner.StartScan(total_data_size=total_data_size)
test_scanner.ScanBuffer(scan_state, data5, len(data5))
test_scanner.StopScan(scan_state)
self.assertEqual(len(scan_state.GetMatches()), 1)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,156 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The format specification classes."""
class Signature(object):
"""Class that defines a signature of a format specification.
The signature consists of a byte string expression, an optional
offset relative to the start of the data, and a value to indidate
if the expression is bound to the offset.
"""
def __init__(self, expression, offset=None, is_bound=False):
"""Initializes the signature.
Args:
expression: string containing the expression of the signature.
The expression consists of a byte string at the moment
regular expression (regexp) are not supported.
offset: the offset of the signature or None by default. None is used
to indicate the signature has no offset. A positive offset
is relative from the start of the data a negative offset
is relative from the end of the data.
is_bound: boolean value to indicate the signature must be bound to
the offset or False by default.
"""
self.expression = expression
self.offset = offset
self.is_bound = is_bound
class Specification(object):
"""Class that contains a format specification."""
def __init__(self, identifier):
"""Initializes the specification.
Args:
identifier: string containing a unique name for the format.
"""
self.identifier = identifier
self.mime_types = []
self.signatures = []
self.universal_type_identifiers = []
def AddMimeType(self, mime_type):
"""Adds a MIME type."""
self.mime_types.append(mime_type)
def AddNewSignature(self, expression, offset=None, is_bound=False):
"""Adds a signature.
Args:
expression: string containing the expression of the signature.
offset: the offset of the signature or None by default. None is used
to indicate the signature has no offset. A positive offset
is relative from the start of the data a negative offset
is relative from the end of the data.
is_bound: boolean value to indicate the signature must be bound to
the offset or False by default.
"""
self.signatures.append(
Signature(expression, offset=offset, is_bound=is_bound))
def AddUniversalTypeIdentifier(self, universal_type_identifiers):
"""Adds a Universal Type Identifier (UTI)."""
self.universal_type_identifiers.append(universal_type_identifiers)
class SpecificationStore(object):
"""Class that servers as a store for specifications."""
def __init__(self):
"""Initializes the specification store."""
self._format_specifications = {}
@property
def specifications(self):
"""A specifications iterator object."""
return self._format_specifications.itervalues()
def AddNewSpecification(self, identifier):
"""Adds a new specification.
Args:
identifier: a string containing the format identifier,
which should be unique for the store.
Returns:
a instance of Specification.
Raises:
ValueError: if the store already contains a specification with
the same identifier.
"""
if identifier in self._format_specifications:
raise ValueError("specification {0:s} is already defined in "
"store.".format(identifier))
self._format_specifications[identifier] = Specification(identifier)
return self._format_specifications[identifier]
def AddSpecification(self, specification):
"""Adds a specification.
Args:
specification: the specification (instance of Specification).
Raises:
KeyError: if the store already contains a specification with
the same identifier.
"""
if specification.identifier in self._format_specifications:
raise KeyError(
u'Specification {0:s} is already defined in store.'.format(
specification.identifier))
self._format_specifications[specification.identifier] = specification
def ReadFromFileObject(self, unused_file_object):
"""Reads the specification store from a file-like object.
Args:
unused_file_object: A file-like object.
Raises:
RuntimeError: because functionality is not implemented yet.
"""
# TODO: implement this function.
raise RuntimeError(u'Function not implemented.')
def ReadFromFile(self, filename):
"""Reads the specification store from a file.
Args:
filename: The name of the file.
"""
file_object = open(filename, 'r')
self.ReadFromFileObject(file_object)
file_object.close()

View File

@ -0,0 +1,46 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the format specification classes."""
import unittest
from plaso.classifier import specification
class SpecificationStoreTest(unittest.TestCase):
"""Class to test the specification store."""
def testAddSpecification(self):
"""Function to test the add specification function."""
store = specification.SpecificationStore()
format_regf = specification.Specification('REGF')
format_regf.AddNewSignature('regf', offset=0)
format_esedb = specification.Specification('ESEDB')
format_esedb.AddNewSignature('\xef\xcd\xab\x89', offset=4)
store.AddSpecification(format_regf)
store.AddSpecification(format_esedb)
with self.assertRaises(KeyError):
store.AddSpecification(format_regf)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,113 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Shared test cases."""
from plaso.classifier import specification
def CreateSpecificationStore():
"""Creates a format specification store for testing purposes.
Returns:
A format specification store (instance of SpecificationStore).
"""
store = specification.SpecificationStore()
test_specification = store.AddNewSpecification('7zip')
test_specification.AddMimeType('application/x-7z-compressed')
test_specification.AddUniversalTypeIdentifier('org.7-zip.7-zip-archive')
test_specification.AddNewSignature('7z\xbc\xaf\x27\x1c', offset=0)
test_specification = store.AddNewSpecification('esedb')
test_specification.AddNewSignature(
'\xef\xcd\xab\x89', offset=4, is_bound=True)
test_specification = store.AddNewSpecification('evt')
test_specification.AddNewSignature(
'\x30\x00\x00\x00LfLe\x01\x00\x00\x00\x01\x00\x00\x00', offset=0,
is_bound=True)
test_specification = store.AddNewSpecification('evtx')
test_specification.AddNewSignature('ElfFile\x00', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('ewf')
test_specification.AddNewSignature(
'EVF\x09\x0d\x0a\xff\x00', offset=0, is_bound=True)
test_specification = specification.Specification('ewf_logical')
test_specification.AddNewSignature(
'LVF\x09\x0d\x0a\xff\x00', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('lnk')
test_specification.AddNewSignature(
'\x4c\x00\x00\x00\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00'
'\x00\x00\x00\x46', offset=0)
test_specification = store.AddNewSpecification('msiecf_index_dat')
test_specification.AddNewSignature(
'Client UrlCache MMF Ver ', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('nk2')
test_specification.AddNewSignature(
'\x0d\xf0\xad\xba\xa0\x00\x00\x00\x01\x00\x00\x00', offset=0,
is_bound=True)
test_specification = store.AddNewSpecification('olecf')
test_specification.AddNewSignature(
'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1', offset=0, is_bound=True)
test_specification.AddNewSignature(
'\x0e\x11\xfc\x0d\xd0\xcf\x11\x0e', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('pff')
test_specification.AddNewSignature('!BDN', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('qcow')
test_specification.AddNewSignature('QFI\xfb', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('rar')
test_specification.AddMimeType('application/x-rar-compressed')
test_specification.AddUniversalTypeIdentifier('com.rarlab.rar-archive')
test_specification.AddNewSignature(
'Rar!\x1a\x07\x00', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('regf')
test_specification.AddNewSignature('regf', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('thumbache_db_cache')
test_specification.AddNewSignature('CMMM', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('thumbache_db_index')
test_specification.AddNewSignature('IMMM', offset=0, is_bound=True)
test_specification = store.AddNewSpecification('zip')
test_specification.AddMimeType('application/zip')
test_specification.AddUniversalTypeIdentifier('com.pkware.zip-archive')
# WinZip 8 signature.
test_specification.AddNewSignature('PK00', offset=0, is_bound=True)
test_specification.AddNewSignature('PK\x01\x02')
test_specification.AddNewSignature('PK\x03\x04', offset=0)
test_specification.AddNewSignature('PK\x05\x05')
# Will be at offset 0 when the archive is empty.
test_specification.AddNewSignature('PK\x05\x06', offset=-22, is_bound=True)
test_specification.AddNewSignature('PK\x06\x06')
test_specification.AddNewSignature('PK\x06\x07')
test_specification.AddNewSignature('PK\x06\x08')
# Will be at offset 0 when this is spanned archive.
test_specification.AddNewSignature('PK\x07\x08')
return store

17
plaso/engine/__init__.py Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

202
plaso/engine/classifier.py Normal file
View File

@ -0,0 +1,202 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The file format classifier."""
# TODO: rewrite most of the classifier in C and integrate with the code in:
# plaso/classifier
import gzip
import logging
import os
import tarfile
import zipfile
import zlib
from dfvfs.lib import definitions
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import resolver as path_spec_resolver
from plaso.lib import errors
class Classifier(object):
"""Class that defines the file format classifier."""
_MAGIC_VALUES = {
'ZIP': {'length': 4, 'offset': 0, 'values': ['P', 'K', '\x03', '\x04']},
'TAR': {'length': 5, 'offset': 257, 'values': ['u', 's', 't', 'a', 'r']},
'GZ': {'length': 2, 'offset': 0, 'values': ['\x1f', '\x8b']},
}
# TODO: Remove this logic when the classifier is ready.
# This is only used temporary until files can be classified.
magic_max_length = 0
# Defines the maximum depth into a file (for SmartOpenFiles).
MAX_FILE_DEPTH = 3
@classmethod
def _SmartOpenFile(cls, file_entry):
"""Return a generator for all pathspec protobufs extracted from a file.
If the file is compressed then extract all members and include
them into the processing queue.
Args:
file_entry: The file entry object.
Yields:
A path specification (instance of dfvfs.PathSpec) of embedded file
entries.
"""
file_object = file_entry.GetFileObject()
# TODO: Remove when classifier gets deployed. Then we
# call the classifier here and use that for definition (and
# then we forward the classifier definition in the pathspec
# protobuf.
file_object.seek(0, os.SEEK_SET)
if not cls.magic_max_length:
for magic_value in cls._MAGIC_VALUES.values():
cls.magic_max_length = max(
cls.magic_max_length,
magic_value['length'] + magic_value['offset'])
header = file_object.read(cls.magic_max_length)
file_classification = ''
# Go over each and every magic value defined and compare
# each read byte (according to original offset and current one)
# If all match, then we have a particular file format and we
# can move on.
for m_value, m_dict in cls._MAGIC_VALUES.items():
length = m_dict['length'] + m_dict['offset']
if len(header) < length:
continue
offset = m_dict['offset']
magic = m_dict['values']
if header[offset:offset + len(magic)] == ''.join(magic):
file_classification = m_value
break
# TODO: refactor the file type specific code into sub functions.
if file_classification == 'ZIP':
try:
file_object.seek(0, os.SEEK_SET)
zip_file = zipfile.ZipFile(file_object, 'r')
# TODO: Make this is a more "sane" check, and perhaps
# not entirely skip the file if it has this particular
# ending, but for now, this both slows the tool down
# considerably and makes it also more unstable.
_, _, filename_extension = file_entry.name.rpartition(u'.')
if filename_extension in [u'.jar', u'.sym', u'.xpi']:
file_object.close()
logging.debug(
u'Unsupported ZIP sub type: {0:s} detected in file: {1:s}'.format(
filename_extension, file_entry.path_spec.comparable))
return
for info in zip_file.infolist():
if info.file_size > 0:
logging.debug(
u'Including: {0:s} from ZIP into process queue.'.format(
info.filename))
yield path_spec_factory.Factory.NewPathSpec(
definitions.TYPE_INDICATOR_ZIP, location=info.filename,
parent=file_entry.path_spec)
except zipfile.BadZipfile:
pass
elif file_classification == 'GZ':
try:
type_indicator = file_entry.path_spec.type_indicator
if type_indicator == definitions.TYPE_INDICATOR_GZIP:
raise errors.SameFileType
file_object.seek(0, os.SEEK_SET)
gzip_file = gzip.GzipFile(fileobj=file_object, mode='rb')
_ = gzip_file.read(4)
gzip_file.close()
logging.debug((
u'Including: {0:s} as GZIP compressed stream into process '
u'queue.').format(file_entry.name))
yield path_spec_factory.Factory.NewPathSpec(
definitions.TYPE_INDICATOR_GZIP, parent=file_entry.path_spec)
except (IOError, zlib.error, errors.SameFileType):
pass
# TODO: Add BZ2 support.
elif file_classification == 'TAR':
try:
file_object.seek(0, os.SEEK_SET)
tar_file = tarfile.open(fileobj=file_object, mode='r')
for name_info in tar_file.getmembers():
if not name_info.isfile():
continue
name = name_info.path
logging.debug(
u'Including: {0:s} from TAR into process queue.'.format(name))
yield path_spec_factory.Factory.NewPathSpec(
definitions.TYPE_INDICATOR_TAR, location=name,
parent=file_entry.path_spec)
except tarfile.ReadError:
pass
file_object.close()
@classmethod
def SmartOpenFiles(cls, file_entry, depth=0):
"""Generate a list of all available PathSpecs extracted from a file.
Args:
file_entry: A file entry object.
depth: Incrementing number that defines the current depth into
a file (file inside a ZIP file is depth 1, file inside a tar.gz
would be of depth 2).
Yields:
A file entry object (instance of dfvfs.FileEntry).
"""
if depth >= cls.MAX_FILE_DEPTH:
return
for path_spec in cls._SmartOpenFile(file_entry):
sub_file_entry = path_spec_resolver.Resolver.OpenFileEntry(path_spec)
if sub_file_entry is None:
logging.debug(
u'Unable to open file: {0:s}'.format(path_spec.comparable))
continue
yield sub_file_entry
depth += 1
for sub_file_entry in cls.SmartOpenFiles(sub_file_entry, depth=depth):
yield sub_file_entry

421
plaso/engine/collector.py Normal file
View File

@ -0,0 +1,421 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generic collector that supports both file system and image files."""
import hashlib
import logging
import os
from dfvfs.helpers import file_system_searcher
from dfvfs.lib import definitions as dfvfs_definitions
from dfvfs.lib import errors as dfvfs_errors
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import resolver as path_spec_resolver
from plaso.engine import queue
from plaso.lib import errors
class Collector(queue.ItemQueueProducer):
"""Class that implements a collector object."""
def __init__(
self, process_queue, source_path, source_path_spec,
resolver_context=None):
"""Initializes the collector object.
The collector discovers all the files that need to be processed by
the workers. Once a file is discovered it is added to the process queue
as a path specification (instance of dfvfs.PathSpec).
Args:
process_queue: The process queue (instance of Queue). This queue contains
the file entries that need to be processed.
source_path: Path of the source file or directory.
source_path_spec: The source path specification (instance of
dfvfs.PathSpec) as determined by the file system
scanner. The default is None.
resolver_context: Optional resolver context (instance of dfvfs.Context).
The default is None.
"""
super(Collector, self).__init__(process_queue)
self._filter_find_specs = None
self._fs_collector = FileSystemCollector(process_queue)
self._resolver_context = resolver_context
# TODO: remove the need to pass source_path
self._source_path = os.path.abspath(source_path)
self._source_path_spec = source_path_spec
self._vss_stores = None
def __enter__(self):
"""Enters a with statement."""
return self
def __exit__(self, unused_type, unused_value, unused_traceback):
"""Exits a with statement."""
return
def _ProcessImage(self, volume_path_spec, find_specs=None):
"""Processes a volume within a storage media image.
Args:
volume_path_spec: The path specification of the volume containing
the file system.
find_specs: Optional list of find specifications (instances of
dfvfs.FindSpec). The default is None.
"""
if find_specs:
logging.debug(u'Collecting from image file: {0:s} with filter'.format(
self._source_path))
else:
logging.debug(u'Collecting from image file: {0:s}'.format(
self._source_path))
path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_TSK, location=u'/',
parent=volume_path_spec)
try:
file_system = path_spec_resolver.Resolver.OpenFileSystem(
path_spec, resolver_context=self._resolver_context)
except IOError as exception:
logging.error(
u'Unable to open file system with error: {0:s}'.format(exception))
return
try:
self._fs_collector.Collect(
file_system, path_spec, find_specs=find_specs)
except (dfvfs_errors.AccessError, dfvfs_errors.BackEndError) as exception:
logging.warning(u'{0:s}'.format(exception))
if find_specs:
logging.debug(u'Collection from image with filter FAILED.')
else:
logging.debug(u'Collection from image FAILED.')
return
if self._abort:
return
if self._vss_stores:
self._ProcessVSS(volume_path_spec, find_specs=find_specs)
if find_specs:
logging.debug(u'Collection from image with filter COMPLETED.')
else:
logging.debug(u'Collection from image COMPLETED.')
def _ProcessVSS(self, volume_path_spec, find_specs=None):
"""Processes a VSS volume within a storage media image.
Args:
volume_path_spec: The path specification of the volume containing
the file system.
find_specs: Optional list of find specifications (instances of
dfvfs.FindSpec). The default is None.
"""
logging.info(u'Processing VSS.')
vss_path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_VSHADOW, location=u'/',
parent=volume_path_spec)
vss_file_entry = path_spec_resolver.Resolver.OpenFileEntry(
vss_path_spec, resolver_context=self._resolver_context)
number_of_vss = vss_file_entry.number_of_sub_file_entries
# In plaso 1 represents the first store index in dfvfs and pyvshadow 0
# represents the first store index so 1 is subtracted.
vss_store_range = [store_nr - 1 for store_nr in self._vss_stores]
for store_index in vss_store_range:
if self._abort:
return
if find_specs:
logging.info((
u'Collecting from VSS volume: {0:d} out of: {1:d} '
u'with filter').format(store_index + 1, number_of_vss))
else:
logging.info(u'Collecting from VSS volume: {0:d} out of: {1:d}'.format(
store_index + 1, number_of_vss))
vss_path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_VSHADOW, store_index=store_index,
parent=volume_path_spec)
path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_TSK, location=u'/',
parent=vss_path_spec)
file_system = path_spec_resolver.Resolver.OpenFileSystem(
path_spec, resolver_context=self._resolver_context)
try:
self._fs_collector.Collect(
file_system, path_spec, find_specs=find_specs)
except (dfvfs_errors.AccessError, dfvfs_errors.BackEndError) as exception:
logging.warning(u'{0:s}'.format(exception))
if find_specs:
logging.debug(
u'Collection from VSS store: {0:d} with filter FAILED.'.format(
store_index + 1))
else:
logging.debug(u'Collection from VSS store: {0:d} FAILED.'.format(
store_index + 1))
return
if find_specs:
logging.debug(
u'Collection from VSS store: {0:d} with filter COMPLETED.'.format(
store_index + 1))
else:
logging.debug(u'Collection from VSS store: {0:d} COMPLETED.'.format(
store_index + 1))
def Collect(self):
"""Collects files from the source."""
source_file_entry = path_spec_resolver.Resolver.OpenFileEntry(
self._source_path_spec, resolver_context=self._resolver_context)
if not source_file_entry:
logging.warning(u'No files to collect.')
self.SignalEndOfInput()
return
if (not source_file_entry.IsDirectory() and
not source_file_entry.IsFile() and
not source_file_entry.IsDevice()):
raise errors.CollectorError(
u'Source path: {0:s} not a device, file or directory.'.format(
self._source_path))
type_indicator = self._source_path_spec.type_indicator
if type_indicator == dfvfs_definitions.TYPE_INDICATOR_OS:
if source_file_entry.IsFile():
self.ProduceItem(self._source_path_spec)
else:
file_system = path_spec_resolver.Resolver.OpenFileSystem(
self._source_path_spec, resolver_context=self._resolver_context)
try:
self._fs_collector.Collect(
file_system, self._source_path_spec,
find_specs=self._filter_find_specs)
except (dfvfs_errors.AccessError,
dfvfs_errors.BackEndError) as exception:
logging.warning(u'{0:s}'.format(exception))
else:
self._ProcessImage(
self._source_path_spec.parent, find_specs=self._filter_find_specs)
self.SignalEndOfInput()
def SetCollectDirectoryMetadata(self, collect_directory_metadata):
"""Sets the collect directory metadata flag.
Args:
collect_directory_metadata: Boolean value to indicate to collect
directory metadata.
"""
self._fs_collector.SetCollectDirectoryMetadata(collect_directory_metadata)
def SetFilter(self, filter_find_specs):
"""Sets the collection filter find specifications.
Args:
filter_find_specs: List of filter find specifications (instances of
dfvfs.FindSpec).
"""
self._filter_find_specs = filter_find_specs
def SetVssInformation(self, vss_stores):
"""Sets the Volume Shadow Snapshots (VSS) information.
This function will enable VSS collection.
Args:
vss_stores: The range of VSS stores to include in the collection,
where 1 represents the first store.
"""
self._vss_stores = vss_stores
def SignalAbort(self):
"""Signals the producer to abort."""
super(Collector, self).SignalAbort()
self._fs_collector.SignalAbort()
class FileSystemCollector(queue.ItemQueueProducer):
"""Class that implements a file system collector object."""
def __init__(self, process_queue):
"""Initializes the collector object.
The collector discovers all the files that need to be processed by
the workers. Once a file is discovered it is added to the process queue
as a path specification (instance of dfvfs.PathSpec).
Args:
process_queue: The process queue (instance of Queue). This queue contains
the file entries that need to be processed.
"""
super(FileSystemCollector, self).__init__(process_queue)
self._collect_directory_metadata = True
self._duplicate_file_check = False
self._hashlist = {}
self.number_of_file_entries = 0
def __enter__(self):
"""Enters a with statement."""
return self
def __exit__(self, unused_type, unused_value, unused_traceback):
"""Exits a with statement."""
return
def _CalculateNTFSTimeHash(self, file_entry):
"""Return a hash value calculated from a NTFS file's metadata.
Args:
file_entry: The file entry (instance of TSKFileEntry).
Returns:
A hash value (string) that can be used to determine if a file's timestamp
value has changed.
"""
stat_object = file_entry.GetStat()
ret_hash = hashlib.md5()
ret_hash.update('atime:{0:d}.{1:d}'.format(
getattr(stat_object, 'atime', 0),
getattr(stat_object, 'atime_nano', 0)))
ret_hash.update('crtime:{0:d}.{1:d}'.format(
getattr(stat_object, 'crtime', 0),
getattr(stat_object, 'crtime_nano', 0)))
ret_hash.update('mtime:{0:d}.{1:d}'.format(
getattr(stat_object, 'mtime', 0),
getattr(stat_object, 'mtime_nano', 0)))
ret_hash.update('ctime:{0:d}.{1:d}'.format(
getattr(stat_object, 'ctime', 0),
getattr(stat_object, 'ctime_nano', 0)))
return ret_hash.hexdigest()
def _ProcessDirectory(self, file_entry):
"""Processes a directory and extract its metadata if necessary."""
# Need to do a breadth-first search otherwise we'll hit the Python
# maximum recursion depth.
sub_directories = []
for sub_file_entry in file_entry.sub_file_entries:
if self._abort:
return
try:
if not sub_file_entry.IsAllocated() or sub_file_entry.IsLink():
continue
except dfvfs_errors.BackEndError as exception:
logging.warning(
u'Unable to process file: {0:s} with error: {1:s}'.format(
sub_file_entry.path_spec.comparable.replace(
u'\n', u';'), exception))
continue
# For TSK-based file entries only, ignore the virtual /$OrphanFiles
# directory.
if sub_file_entry.type_indicator == dfvfs_definitions.TYPE_INDICATOR_TSK:
if file_entry.IsRoot() and sub_file_entry.name == u'$OrphanFiles':
continue
if sub_file_entry.IsDirectory():
# This check is here to improve performance by not producing
# path specifications that don't get processed.
if self._collect_directory_metadata:
self.ProduceItem(sub_file_entry.path_spec)
self.number_of_file_entries += 1
sub_directories.append(sub_file_entry)
elif sub_file_entry.IsFile():
# If we are dealing with a VSS we want to calculate a hash
# value based on available timestamps and compare that to previously
# calculated hash values, and only include the file into the queue if
# the hash does not match.
if self._duplicate_file_check:
hash_value = self._CalculateNTFSTimeHash(sub_file_entry)
inode = getattr(sub_file_entry.path_spec, 'inode', 0)
if inode in self._hashlist:
if hash_value in self._hashlist[inode]:
continue
self._hashlist.setdefault(inode, []).append(hash_value)
self.ProduceItem(sub_file_entry.path_spec)
self.number_of_file_entries += 1
for sub_file_entry in sub_directories:
if self._abort:
return
try:
self._ProcessDirectory(sub_file_entry)
except (dfvfs_errors.AccessError, dfvfs_errors.BackEndError) as exception:
logging.warning(u'{0:s}'.format(exception))
def Collect(self, file_system, path_spec, find_specs=None):
"""Collects files from the file system.
Args:
file_system: The file system (instance of dfvfs.FileSystem).
path_spec: The path specification (instance of dfvfs.PathSpec).
find_specs: Optional list of find specifications (instances of
dfvfs.FindSpec). The default is None.
"""
if find_specs:
searcher = file_system_searcher.FileSystemSearcher(file_system, path_spec)
for path_spec in searcher.Find(find_specs=find_specs):
if self._abort:
return
self.ProduceItem(path_spec)
self.number_of_file_entries += 1
else:
file_entry = file_system.GetFileEntryByPathSpec(path_spec)
self._ProcessDirectory(file_entry)
def SetCollectDirectoryMetadata(self, collect_directory_metadata):
"""Sets the collect directory metadata flag.
Args:
collect_directory_metadata: Boolean value to indicate to collect
directory metadata.
"""
self._collect_directory_metadata = collect_directory_metadata

View File

@ -0,0 +1,354 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The unit tests for the generic collector object."""
import logging
import os
import shutil
import tempfile
import unittest
from dfvfs.helpers import file_system_searcher
from dfvfs.lib import definitions as dfvfs_definitions
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import context
from dfvfs.resolver import resolver as path_spec_resolver
from plaso.engine import collector
from plaso.engine import queue
from plaso.engine import single_process
from plaso.engine import utils as engine_utils
class TempDirectory(object):
"""A self cleaning temporary directory."""
def __init__(self):
"""Initializes the temporary directory."""
super(TempDirectory, self).__init__()
self.name = u''
def __enter__(self):
"""Make this work with the 'with' statement."""
self.name = tempfile.mkdtemp()
return self.name
def __exit__(self, unused_type, unused_value, unused_traceback):
"""Make this work with the 'with' statement."""
shutil.rmtree(self.name, True)
class TestCollectorQueueConsumer(queue.ItemQueueConsumer):
"""Class that implements a test collector queue consumer."""
def __init__(self, queue_object):
"""Initializes the queue consumer.
Args:
queue_object: the queue object (instance of Queue).
"""
super(TestCollectorQueueConsumer, self).__init__(queue_object)
self.path_specs = []
def _ConsumeItem(self, path_spec):
"""Consumes an item callback for ConsumeItems.
Args:
path_spec: a path specification (instance of dfvfs.PathSpec).
"""
self.path_specs.append(path_spec)
@property
def number_of_path_specs(self):
"""The number of path specifications."""
return len(self.path_specs)
def GetFilePaths(self):
"""Retrieves a list of file paths from the path specifications."""
file_paths = []
for path_spec in self.path_specs:
location = getattr(path_spec, 'location', None)
if location is not None:
file_paths.append(location)
return file_paths
class CollectorTestCase(unittest.TestCase):
"""The collector test case."""
_TEST_DATA_PATH = os.path.join(os.getcwd(), u'test_data')
# Show full diff results, part of TestCase so does not follow our naming
# conventions.
maxDiff = None
def _GetTestFilePath(self, path_segments):
"""Retrieves the path of a test file relative to the test data directory.
Args:
path_segments: the path segments inside the test data directory.
Returns:
A path of the test file.
"""
# Note that we need to pass the individual path segments to os.path.join
# and not a list.
return os.path.join(self._TEST_DATA_PATH, *path_segments)
class CollectorTest(CollectorTestCase):
"""Tests for the collector."""
def testFileSystemCollection(self):
"""Test collection on the file system."""
test_files = [
self._GetTestFilePath([u'syslog.tgz']),
self._GetTestFilePath([u'syslog.zip']),
self._GetTestFilePath([u'syslog.bz2']),
self._GetTestFilePath([u'wtmp.1'])]
with TempDirectory() as dirname:
for a_file in test_files:
shutil.copy(a_file, dirname)
path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_OS, location=dirname)
test_collection_queue = single_process.SingleProcessQueue()
resolver_context = context.Context()
test_collector = collector.Collector(
test_collection_queue, dirname, path_spec,
resolver_context=resolver_context)
test_collector.Collect()
test_collector_queue_consumer = TestCollectorQueueConsumer(
test_collection_queue)
test_collector_queue_consumer.ConsumeItems()
self.assertEquals(test_collector_queue_consumer.number_of_path_specs, 4)
def testFileSystemWithFilterCollection(self):
"""Test collection on the file system with a filter."""
dirname = u'.'
path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_OS, location=dirname)
filter_name = ''
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
filter_name = temp_file.name
temp_file.write('/test_data/testdir/filter_.+.txt\n')
temp_file.write('/test_data/.+evtx\n')
temp_file.write('/AUTHORS\n')
temp_file.write('/does_not_exist/some_file_[0-9]+txt\n')
test_collection_queue = single_process.SingleProcessQueue()
resolver_context = context.Context()
test_collector = collector.Collector(
test_collection_queue, dirname, path_spec,
resolver_context=resolver_context)
find_specs = engine_utils.BuildFindSpecsFromFile(filter_name)
test_collector.SetFilter(find_specs)
test_collector.Collect()
test_collector_queue_consumer = TestCollectorQueueConsumer(
test_collection_queue)
test_collector_queue_consumer.ConsumeItems()
try:
os.remove(filter_name)
except (OSError, IOError) as exception:
logging.warning((
u'Unable to remove temporary file: {0:s} with error: {1:s}').format(
filter_name, exception))
# Two files with test_data/testdir/filter_*.txt, AUTHORS
# and test_data/System.evtx.
self.assertEquals(test_collector_queue_consumer.number_of_path_specs, 4)
paths = test_collector_queue_consumer.GetFilePaths()
current_directory = os.getcwd()
expected_path = os.path.join(
current_directory, u'test_data', u'testdir', u'filter_1.txt')
self.assertTrue(expected_path in paths)
expected_path = os.path.join(
current_directory, u'test_data', u'testdir', u'filter_2.txt')
self.assertFalse(expected_path in paths)
expected_path = os.path.join(
current_directory, u'test_data', u'testdir', u'filter_3.txt')
self.assertTrue(expected_path in paths)
expected_path = os.path.join(
current_directory, u'AUTHORS')
self.assertTrue(expected_path in paths)
def testImageCollection(self):
"""Test collection on a storage media image file.
This images has two files:
+ logs/hidden.zip
+ logs/sys.tgz
The hidden.zip file contains one file, syslog, which is the
same for sys.tgz.
The end results should therefore be:
+ logs/hidden.zip (unchanged)
+ logs/hidden.zip:syslog (the text file extracted out)
+ logs/sys.tgz (unchanged)
+ logs/sys.tgz (read as a GZIP file, so not compressed)
+ logs/sys.tgz:syslog.gz (A GZIP file from the TAR container)
+ logs/sys.tgz:syslog.gz:syslog (the extracted syslog file)
This means that the collection script should collect 6 files in total.
"""
test_file = self._GetTestFilePath([u'syslog_image.dd'])
volume_path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_OS, location=test_file)
path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_TSK, location=u'/',
parent=volume_path_spec)
test_collection_queue = single_process.SingleProcessQueue()
resolver_context = context.Context()
test_collector = collector.Collector(
test_collection_queue, test_file, path_spec,
resolver_context=resolver_context)
test_collector.Collect()
test_collector_queue_consumer = TestCollectorQueueConsumer(
test_collection_queue)
test_collector_queue_consumer.ConsumeItems()
self.assertEquals(test_collector_queue_consumer.number_of_path_specs, 3)
def testImageWithFilterCollection(self):
"""Test collection on a storage media image file with a filter."""
test_file = self._GetTestFilePath([u'ímynd.dd'])
volume_path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_OS, location=test_file)
path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_TSK, location=u'/',
parent=volume_path_spec)
filter_name = ''
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
filter_name = temp_file.name
temp_file.write('/a_directory/.+zip\n')
temp_file.write('/a_directory/another.+\n')
temp_file.write('/passwords.txt\n')
test_collection_queue = single_process.SingleProcessQueue()
resolver_context = context.Context()
test_collector = collector.Collector(
test_collection_queue, test_file, path_spec,
resolver_context=resolver_context)
find_specs = engine_utils.BuildFindSpecsFromFile(filter_name)
test_collector.SetFilter(find_specs)
test_collector.Collect()
test_collector_queue_consumer = TestCollectorQueueConsumer(
test_collection_queue)
test_collector_queue_consumer.ConsumeItems()
try:
os.remove(filter_name)
except (OSError, IOError) as exception:
logging.warning((
u'Unable to remove temporary file: {0:s} with error: {1:s}').format(
filter_name, exception))
self.assertEquals(test_collector_queue_consumer.number_of_path_specs, 2)
paths = test_collector_queue_consumer.GetFilePaths()
# path_specs[0]
# type: TSK
# file_path: '/a_directory/another_file'
# container_path: 'test_data/ímynd.dd'
# image_offset: 0
self.assertEquals(paths[0], u'/a_directory/another_file')
# path_specs[1]
# type: TSK
# file_path: '/passwords.txt'
# container_path: 'test_data/ímynd.dd'
# image_offset: 0
self.assertEquals(paths[1], u'/passwords.txt')
class BuildFindSpecsFromFileTest(unittest.TestCase):
"""Tests for the BuildFindSpecsFromFile function."""
def testBuildFindSpecsFromFile(self):
"""Tests the BuildFindSpecsFromFile function."""
filter_name = ''
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
filter_name = temp_file.name
# 2 hits.
temp_file.write('/test_data/testdir/filter_.+.txt\n')
# A single hit.
temp_file.write('/test_data/.+evtx\n')
# A single hit.
temp_file.write('/AUTHORS\n')
temp_file.write('/does_not_exist/some_file_[0-9]+txt\n')
# This should not compile properly, missing file information.
temp_file.write('failing/\n')
# This should not fail during initial loading, but fail later on.
temp_file.write('bad re (no close on that parenthesis/file\n')
find_specs = engine_utils.BuildFindSpecsFromFile(filter_name)
try:
os.remove(filter_name)
except (OSError, IOError) as exception:
logging.warning(
u'Unable to remove temporary file: {0:s} with error: {1:s}'.format(
filter_name, exception))
self.assertEquals(len(find_specs), 4)
dirname = u'.'
path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_OS, location=dirname)
file_system = path_spec_resolver.Resolver.OpenFileSystem(path_spec)
searcher = file_system_searcher.FileSystemSearcher(
file_system, path_spec)
path_spec_generator = searcher.Find(find_specs=find_specs)
self.assertNotEquals(path_spec_generator, None)
path_specs = list(path_spec_generator)
# One evtx, one AUTHORS, two filter_*.txt files, total 4 files.
self.assertEquals(len(path_specs), 4)
with self.assertRaises(IOError):
_ = engine_utils.BuildFindSpecsFromFile('thisfiledoesnotexist')
if __name__ == '__main__':
unittest.main()

319
plaso/engine/engine.py Normal file
View File

@ -0,0 +1,319 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2012 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The processing engine."""
import abc
import logging
from dfvfs.helpers import file_system_searcher
from dfvfs.lib import definitions as dfvfs_definitions
from dfvfs.resolver import resolver as path_spec_resolver
from plaso.artifacts import knowledge_base
from plaso.engine import collector
from plaso.engine import queue
from plaso.lib import errors
from plaso.preprocessors import interface as preprocess_interface
from plaso.preprocessors import manager as preprocess_manager
class BaseEngine(object):
"""Class that defines the processing engine base."""
def __init__(self, collection_queue, storage_queue, parse_error_queue):
"""Initialize the engine object.
Args:
collection_queue: the collection queue object (instance of Queue).
storage_queue: the storage queue object (instance of Queue).
parse_error_queue: the parser error queue object (instance of Queue).
"""
self._collection_queue = collection_queue
self._enable_debug_output = False
self._enable_profiling = False
self._event_queue_producer = queue.ItemQueueProducer(storage_queue)
self._filter_object = None
self._mount_path = None
self._open_files = False
self._parse_error_queue = parse_error_queue
self._parse_error_queue_producer = queue.ItemQueueProducer(
parse_error_queue)
self._profiling_sample_rate = 1000
self._source = None
self._source_path_spec = None
self._source_file_entry = None
self._text_prepend = None
self.knowledge_base = knowledge_base.KnowledgeBase()
self.storage_queue = storage_queue
def CreateCollector(
self, include_directory_stat, vss_stores=None, filter_find_specs=None,
resolver_context=None):
"""Creates a collector object.
The collector discovers all the files that need to be processed by
the workers. Once a file is discovered it is added to the process queue
as a path specification (instance of dfvfs.PathSpec).
Args:
include_directory_stat: Boolean value to indicate whether directory
stat information should be collected.
vss_stores: Optional list of VSS stores to include in the collection,
where 1 represents the first store. Set to None if no
VSS stores should be processed. The default is None.
filter_find_specs: Optional list of filter find specifications (instances
of dfvfs.FindSpec). The default is None.
resolver_context: Optional resolver context (instance of dfvfs.Context).
The default is None. Note that every thread or process
must have its own resolver context.
Returns:
A collector object (instance of Collector).
Raises:
RuntimeError: if source path specification is not set.
"""
if not self._source_path_spec:
raise RuntimeError(u'Missing source.')
collector_object = collector.Collector(
self._collection_queue, self._source, self._source_path_spec,
resolver_context=resolver_context)
collector_object.SetCollectDirectoryMetadata(include_directory_stat)
if vss_stores:
collector_object.SetVssInformation(vss_stores)
if filter_find_specs:
collector_object.SetFilter(filter_find_specs)
return collector_object
@abc.abstractmethod
def CreateExtractionWorker(self, worker_number):
"""Creates an extraction worker object.
Args:
worker_number: A number that identifies the worker.
Returns:
An extraction worker (instance of worker.ExtractionWorker).
"""
def GetSourceFileSystemSearcher(self, resolver_context=None):
"""Retrieves the file system searcher of the source.
Args:
resolver_context: Optional resolver context (instance of dfvfs.Context).
The default is None. Note that every thread or process
must have its own resolver context.
Returns:
The file system searcher object (instance of dfvfs.FileSystemSearcher).
Raises:
RuntimeError: if source path specification is not set.
"""
if not self._source_path_spec:
raise RuntimeError(u'Missing source.')
file_system = path_spec_resolver.Resolver.OpenFileSystem(
self._source_path_spec, resolver_context=resolver_context)
type_indicator = self._source_path_spec.type_indicator
if type_indicator == dfvfs_definitions.TYPE_INDICATOR_OS:
mount_point = self._source_path_spec
else:
mount_point = self._source_path_spec.parent
return file_system_searcher.FileSystemSearcher(file_system, mount_point)
def PreprocessSource(self, platform, resolver_context=None):
"""Preprocesses the source and fills the preprocessing object.
Args:
platform: string that indicates the platform (operating system).
resolver_context: Optional resolver context (instance of dfvfs.Context).
The default is None. Note that every thread or process
must have its own resolver context.
"""
searcher = self.GetSourceFileSystemSearcher(
resolver_context=resolver_context)
if not platform:
platform = preprocess_interface.GuessOS(searcher)
self.knowledge_base.platform = platform
preprocess_manager.PreprocessPluginsManager.RunPlugins(
platform, searcher, self.knowledge_base)
def SetEnableDebugOutput(self, enable_debug_output):
"""Enables or disables debug output.
Args:
enable_debug_output: boolean value to indicate if the debug output
should be enabled.
"""
self._enable_debug_output = enable_debug_output
def SetEnableProfiling(self, enable_profiling, profiling_sample_rate=1000):
"""Enables or disables profiling.
Args:
enable_debug_output: boolean value to indicate if the profiling
should be enabled.
profiling_sample_rate: optional integer indicating the profiling sample
rate. The value contains the number of files
processed. The default value is 1000.
"""
self._enable_profiling = enable_profiling
self._profiling_sample_rate = profiling_sample_rate
def SetFilterObject(self, filter_object):
"""Sets the filter object.
Args:
filter_object: the filter object (instance of objectfilter.Filter).
"""
self._filter_object = filter_object
def SetMountPath(self, mount_path):
"""Sets the mount path.
Args:
mount_path: string containing the mount path.
"""
self._mount_path = mount_path
# TODO: rename this mode.
def SetOpenFiles(self, open_files):
"""Sets the open files mode.
Args:
open_files: boolean value to indicate if the worker should scan for
file entries inside files.
"""
self._open_files = open_files
def SetSource(self, source_path_spec, resolver_context=None):
"""Sets the source.
Args:
source_path_spec: The source path specification (instance of
dfvfs.PathSpec) as determined by the file system
scanner. The default is None.
resolver_context: Optional resolver context (instance of dfvfs.Context).
The default is None. Note that every thread or process
must have its own resolver context.
Raises:
BadConfigOption: if source cannot be set.
"""
path_spec = source_path_spec
while path_spec.parent:
path_spec = path_spec.parent
# Note that source should be used for output purposes only.
self._source = getattr(path_spec, 'location', u'')
self._source_path_spec = source_path_spec
self._source_file_entry = path_spec_resolver.Resolver.OpenFileEntry(
self._source_path_spec, resolver_context=resolver_context)
if not self._source_file_entry:
raise errors.BadConfigOption(
u'No such device, file or directory: {0:s}.'.format(self._source))
if (not self._source_file_entry.IsDirectory() and
not self._source_file_entry.IsFile() and
not self._source_file_entry.IsDevice()):
raise errors.CollectorError(
u'Source path: {0:s} not a device, file or directory.'.format(
self._source))
if self._source_path_spec.type_indicator in [
dfvfs_definitions.TYPE_INDICATOR_OS,
dfvfs_definitions.TYPE_INDICATOR_FAKE]:
if self._source_file_entry.IsFile():
logging.debug(u'Starting a collection on a single file.')
# No need for multiple workers when parsing a single file.
elif not self._source_file_entry.IsDirectory():
raise errors.BadConfigOption(
u'Source: {0:s} has to be a file or directory.'.format(
self._source))
# TODO: remove this functionality.
def SetTextPrepend(self, text_prepend):
"""Sets the text prepend.
Args:
text_prepend: string that contains the text to prepend to every
event object.
"""
self._text_prepend = text_prepend
def SignalAbort(self):
"""Signals the engine to abort."""
logging.warning(u'Signalled abort.')
self._event_queue_producer.SignalEndOfInput()
self._parse_error_queue_producer.SignalEndOfInput()
def SignalEndOfInputStorageQueue(self):
"""Signals the storage queue no input remains."""
self._event_queue_producer.SignalEndOfInput()
self._parse_error_queue_producer.SignalEndOfInput()
def SourceIsDirectory(self):
"""Determines if the source is a directory.
Raises:
RuntimeError: if source path specification is not set.
"""
if not self._source_file_entry:
raise RuntimeError(u'Missing source.')
return (not self.SourceIsStorageMediaImage() and
self._source_file_entry.IsDirectory())
def SourceIsFile(self):
"""Determines if the source is a file.
Raises:
RuntimeError: if source path specification is not set.
"""
if not self._source_file_entry:
raise RuntimeError(u'Missing source.')
return (not self.SourceIsStorageMediaImage() and
self._source_file_entry.IsFile())
def SourceIsStorageMediaImage(self):
"""Determines if the source is storage media image file or device.
Raises:
RuntimeError: if source path specification is not set.
"""
if not self._source_path_spec:
raise RuntimeError(u'Missing source.')
return self._source_path_spec.type_indicator not in [
dfvfs_definitions.TYPE_INDICATOR_OS,
dfvfs_definitions.TYPE_INDICATOR_FAKE]

204
plaso/engine/queue.py Normal file
View File

@ -0,0 +1,204 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2012 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Queue management implementation for Plaso.
This file contains an implementation of a queue used by plaso for
queue management.
The queue has been abstracted in order to provide support for different
implementations of the queueing mechanism, to support multi processing and
scalability.
"""
import abc
from plaso.lib import errors
class QueueEndOfInput(object):
"""Class that implements a queue end of input."""
class Queue(object):
"""Class that implements the queue interface."""
@abc.abstractmethod
def __len__(self):
"""Returns the estimated current number of items in the queue."""
@abc.abstractmethod
def IsEmpty(self):
"""Determines if the queue is empty."""
@abc.abstractmethod
def PushItem(self, item):
"""Pushes an item onto the queue."""
@abc.abstractmethod
def PopItem(self):
"""Pops an item off the queue."""
def SignalEndOfInput(self):
"""Signals the queue no input remains."""
self.PushItem(QueueEndOfInput())
class QueueConsumer(object):
"""Class that implements the queue consumer interface.
The consumer subscribes to updates on the queue.
"""
def __init__(self, queue_object):
"""Initializes the queue consumer.
Args:
queue_object: the queue object (instance of Queue).
"""
super(QueueConsumer, self).__init__()
self._abort = False
self._queue = queue_object
def SignalAbort(self):
"""Signals the consumer to abort."""
self._abort = True
class QueueProducer(object):
"""Class that implements the queue producer interface.
The producer generates updates on the queue.
"""
def __init__(self, queue_object):
"""Initializes the queue producer.
Args:
queue_object: the queue object (instance of Queue).
"""
super(QueueProducer, self).__init__()
self._abort = False
self._queue = queue_object
def SignalAbort(self):
"""Signals the producer to abort."""
self._abort = True
def SignalEndOfInput(self):
"""Signals the queue no input remains."""
self._queue.SignalEndOfInput()
class EventObjectQueueConsumer(QueueConsumer):
"""Class that implements the event object queue consumer.
The consumer subscribes to updates on the queue.
"""
@abc.abstractmethod
def _ConsumeEventObject(self, event_object, **kwargs):
"""Consumes an event object callback for ConsumeEventObjects."""
def ConsumeEventObjects(self, **kwargs):
"""Consumes the event object that are pushed on the queue.
This function will issue a callback to _ConsumeEventObject for every
event object (instance of EventObject) consumed from the queue.
Args:
kwargs: keyword arguments to pass to the _ConsumeEventObject callback.
"""
while not self._abort:
try:
item = self._queue.PopItem()
except errors.QueueEmpty:
break
if isinstance(item, QueueEndOfInput):
# Push the item back onto the queue to make sure all
# queue consumers are stopped.
self._queue.PushItem(item)
break
self._ConsumeEventObject(item, **kwargs)
self._abort = False
class ItemQueueConsumer(QueueConsumer):
"""Class that implements an item queue consumer.
The consumer subscribes to updates on the queue.
"""
@abc.abstractmethod
def _ConsumeItem(self, item):
"""Consumes an item callback for ConsumeItems.
Args:
item: the item object.
"""
def ConsumeItems(self):
"""Consumes the items that are pushed on the queue."""
while not self._abort:
try:
item = self._queue.PopItem()
except errors.QueueEmpty:
break
if isinstance(item, QueueEndOfInput):
# Push the item back onto the queue to make sure all
# queue consumers are stopped.
self._queue.PushItem(item)
break
self._ConsumeItem(item)
self._abort = False
class ItemQueueProducer(QueueProducer):
"""Class that implements an item queue producer.
The producer generates updates on the queue.
"""
def _FlushQueue(self):
"""Flushes the queue callback for the QueueFull exception."""
return
def ProduceItem(self, item):
"""Produces an item onto the queue.
Args:
item: the item object.
"""
try:
self._queue.PushItem(item)
except errors.QueueFull:
self._FlushQueue()
def ProduceItems(self, items):
"""Produces items onto the queue.
Args:
items: a list or generator of item objects.
"""
for item in items:
self.ProduceItem(item)

View File

@ -0,0 +1,366 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The single process processing engine."""
import collections
import logging
import pdb
from plaso.engine import collector
from plaso.engine import engine
from plaso.engine import queue
from plaso.engine import worker
from plaso.lib import errors
from plaso.parsers import context as parsers_context
class SingleProcessCollector(collector.Collector):
"""Class that implements a single process collector object."""
def __init__(
self, process_queue, source_path, source_path_spec,
resolver_context=None):
"""Initializes the collector object.
The collector discovers all the files that need to be processed by
the workers. Once a file is discovered it is added to the process queue
as a path specification (instance of dfvfs.PathSpec).
Args:
process_queue: The process queue (instance of Queue). This queue contains
the file entries that need to be processed.
source_path: Path of the source file or directory.
source_path_spec: The source path specification (instance of
dfvfs.PathSpec) as determined by the file system
scanner. The default is None.
resolver_context: Optional resolver context (instance of dfvfs.Context).
The default is None.
"""
super(SingleProcessCollector, self).__init__(
process_queue, source_path, source_path_spec,
resolver_context=resolver_context)
self._extraction_worker = None
self._fs_collector = SingleProcessFileSystemCollector(process_queue)
def _FlushQueue(self):
"""Flushes the queue callback for the QueueFull exception."""
while not self._queue.IsEmpty():
logging.debug(u'Extraction worker started.')
self._extraction_worker.Run()
logging.debug(u'Extraction worker stopped.')
def SetExtractionWorker(self, extraction_worker):
"""Sets the extraction worker.
Args:
extraction_worker: the extraction worker object (instance of
EventExtractionWorker).
"""
self._extraction_worker = extraction_worker
self._fs_collector.SetExtractionWorker(extraction_worker)
class SingleProcessEngine(engine.BaseEngine):
"""Class that defines the single process engine."""
def __init__(self, maximum_number_of_queued_items=0):
"""Initialize the single process engine object.
Args:
maximum_number_of_queued_items: The maximum number of queued items.
The default is 0, which represents
no limit.
"""
collection_queue = SingleProcessQueue(
maximum_number_of_queued_items=maximum_number_of_queued_items)
storage_queue = SingleProcessQueue(
maximum_number_of_queued_items=maximum_number_of_queued_items)
parse_error_queue = SingleProcessQueue(
maximum_number_of_queued_items=maximum_number_of_queued_items)
super(SingleProcessEngine, self).__init__(
collection_queue, storage_queue, parse_error_queue)
self._event_queue_producer = SingleProcessItemQueueProducer(storage_queue)
self._parse_error_queue_producer = SingleProcessItemQueueProducer(
parse_error_queue)
def CreateCollector(
self, include_directory_stat, vss_stores=None, filter_find_specs=None,
resolver_context=None):
"""Creates a collector object.
The collector discovers all the files that need to be processed by
the workers. Once a file is discovered it is added to the process queue
as a path specification (instance of dfvfs.PathSpec).
Args:
include_directory_stat: Boolean value to indicate whether directory
stat information should be collected.
vss_stores: Optional list of VSS stores to include in the collection,
where 1 represents the first store. Set to None if no
VSS stores should be processed. The default is None.
filter_find_specs: Optional list of filter find specifications (instances
of dfvfs.FindSpec). The default is None.
resolver_context: Optional resolver context (instance of dfvfs.Context).
The default is None. Note that every thread or process
must have its own resolver context.
Returns:
A collector object (instance of Collector).
Raises:
RuntimeError: if source path specification is not set.
"""
if not self._source_path_spec:
raise RuntimeError(u'Missing source.')
collector_object = SingleProcessCollector(
self._collection_queue, self._source, self._source_path_spec,
resolver_context=resolver_context)
collector_object.SetCollectDirectoryMetadata(include_directory_stat)
if vss_stores:
collector_object.SetVssInformation(vss_stores)
if filter_find_specs:
collector_object.SetFilter(filter_find_specs)
return collector_object
def CreateExtractionWorker(self, worker_number):
"""Creates an extraction worker object.
Args:
worker_number: A number that identifies the worker.
Returns:
An extraction worker (instance of worker.ExtractionWorker).
"""
parser_context = parsers_context.ParserContext(
self._event_queue_producer, self._parse_error_queue_producer,
self.knowledge_base)
extraction_worker = SingleProcessEventExtractionWorker(
worker_number, self._collection_queue, self._event_queue_producer,
self._parse_error_queue_producer, parser_context)
extraction_worker.SetEnableDebugOutput(self._enable_debug_output)
# TODO: move profiler in separate object.
extraction_worker.SetEnableProfiling(
self._enable_profiling,
profiling_sample_rate=self._profiling_sample_rate)
if self._open_files:
extraction_worker.SetOpenFiles(self._open_files)
if self._filter_object:
extraction_worker.SetFilterObject(self._filter_object)
if self._mount_path:
extraction_worker.SetMountPath(self._mount_path)
if self._text_prepend:
extraction_worker.SetTextPrepend(self._text_prepend)
return extraction_worker
def ProcessSource(
self, collector_object, storage_writer, parser_filter_string=None):
"""Processes the source and extracts event objects.
Args:
collector_object: A collector object (instance of Collector).
storage_writer: A storage writer object (instance of BaseStorageWriter).
parser_filter_string: Optional parser filter string. The default is None.
"""
extraction_worker = self.CreateExtractionWorker(0)
extraction_worker.InitalizeParserObjects(
parser_filter_string=parser_filter_string)
# Set the extraction worker and storage writer values so that they
# can be accessed if the QueueFull exception is raised. This is
# needed in single process mode to prevent the queue consuming too
# much memory.
collector_object.SetExtractionWorker(extraction_worker)
self._event_queue_producer.SetStorageWriter(storage_writer)
self._parse_error_queue_producer.SetStorageWriter(storage_writer)
logging.debug(u'Processing started.')
logging.debug(u'Collection started.')
collector_object.Collect()
logging.debug(u'Collection stopped.')
logging.debug(u'Extraction worker started.')
extraction_worker.Run()
logging.debug(u'Extraction worker stopped.')
self._event_queue_producer.SignalEndOfInput()
logging.debug(u'Storage writer started.')
storage_writer.WriteEventObjects()
logging.debug(u'Storage writer stopped.')
# Reset the extraction worker and storage writer values to return
# the objects in their original state. This will prevent access
# to the extraction worker outside this function and allow it
# to be garbage collected.
self._event_queue_producer.SetStorageWriter(None)
self._parse_error_queue_producer.SetStorageWriter(None)
collector_object.SetExtractionWorker(None)
logging.debug(u'Processing completed.')
class SingleProcessEventExtractionWorker(worker.BaseEventExtractionWorker):
"""Class that defines the single process event extraction worker."""
def _DebugParseFileEntry(self):
"""Callback for debugging file entry parsing failures."""
pdb.post_mortem()
class SingleProcessFileSystemCollector(collector.FileSystemCollector):
"""Class that implements a single process file system collector object."""
def __init__(self, process_queue):
"""Initializes the collector object.
The collector discovers all the files that need to be processed by
the workers. Once a file is discovered it is added to the process queue
as a path specification (instance of dfvfs.PathSpec).
Args:
process_queue: The process queue (instance of Queue). This queue contains
the file entries that need to be processed.
"""
super(SingleProcessFileSystemCollector, self).__init__(process_queue)
self._extraction_worker = None
def _FlushQueue(self):
"""Flushes the queue callback for the QueueFull exception."""
while not self._queue.IsEmpty():
logging.debug(u'Extraction worker started.')
self._extraction_worker.Run()
logging.debug(u'Extraction worker stopped.')
def SetExtractionWorker(self, extraction_worker):
"""Sets the extraction worker.
Args:
extraction_worker: the extraction worker object (instance of
EventExtractionWorker).
"""
self._extraction_worker = extraction_worker
class SingleProcessItemQueueProducer(queue.ItemQueueProducer):
"""Class that implements a single process item queue producer."""
def __init__(self, queue_object):
"""Initializes the queue producer.
Args:
queue_object: the queue object (instance of Queue).
"""
super(SingleProcessItemQueueProducer, self).__init__(queue_object)
self._storage_writer = None
def _FlushQueue(self):
"""Flushes the queue callback for the QueueFull exception."""
logging.debug(u'Storage writer started.')
self._storage_writer.WriteEventObjects()
logging.debug(u'Storage writer stopped.')
def SetStorageWriter(self, storage_writer):
"""Sets the storage writer.
Args:
storage_writer: the storage writer object (instance of
BaseStorageWriter).
"""
self._storage_writer = storage_writer
class SingleProcessQueue(queue.Queue):
"""Single process queue."""
def __init__(self, maximum_number_of_queued_items=0):
"""Initializes a single process queue object.
Args:
maximum_number_of_queued_items: The maximum number of queued items.
The default is 0, which represents
no limit.
"""
super(SingleProcessQueue, self).__init__()
# The Queue interface defines the maximum number of queued items to be
# 0 if unlimited as does the multi processing queue, but deque uses
# None to indicate no limit.
if maximum_number_of_queued_items == 0:
maximum_number_of_queued_items = None
# maxlen contains the maximum number of items allowed to be queued,
# where None represents unlimited.
self._queue = collections.deque(
maxlen=maximum_number_of_queued_items)
def __len__(self):
"""Returns the estimated current number of items in the queue."""
return len(self._queue)
def IsEmpty(self):
"""Determines if the queue is empty."""
return len(self._queue) == 0
def PushItem(self, item):
"""Pushes an item onto the queue.
Raises:
QueueFull: when the queue is full.
"""
number_of_items = len(self._queue)
# Deque will drop the first item in the queue when maxlen is exceeded.
if not self._queue.maxlen or number_of_items < self._queue.maxlen:
self._queue.append(item)
number_of_items += 1
if self._queue.maxlen and number_of_items == self._queue.maxlen:
raise errors.QueueFull
def PopItem(self):
"""Pops an item off the queue.
Raises:
QueueEmpty: when the queue is empty.
"""
try:
# Using popleft to have FIFO behavior.
return self._queue.popleft()
except IndexError:
raise errors.QueueEmpty

View File

@ -0,0 +1,133 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests the single process processing engine."""
import os
import unittest
from dfvfs.lib import definitions as dfvfs_definitions
from dfvfs.helpers import file_system_searcher
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import context
from plaso.engine import single_process
from plaso.engine import test_lib
from plaso.lib import errors
class SingleProcessQueueTest(unittest.TestCase):
"""Tests the single process queue."""
_ITEMS = frozenset(['item1', 'item2', 'item3', 'item4'])
def testPushPopItem(self):
"""Tests the PushItem and PopItem functions."""
test_queue = single_process.SingleProcessQueue()
for item in self._ITEMS:
test_queue.PushItem(item)
self.assertEquals(len(test_queue), len(self._ITEMS))
test_queue.SignalEndOfInput()
test_queue_consumer = test_lib.TestQueueConsumer(test_queue)
test_queue_consumer.ConsumeItems()
expected_number_of_items = len(self._ITEMS)
self.assertEquals(
test_queue_consumer.number_of_items, expected_number_of_items)
def testQueueEmpty(self):
"""Tests the queue raises the QueueEmpty exception."""
test_queue = single_process.SingleProcessQueue()
with self.assertRaises(errors.QueueEmpty):
test_queue.PopItem()
def testQueueFull(self):
"""Tests the queue raises the QueueFull exception."""
test_queue = single_process.SingleProcessQueue(
maximum_number_of_queued_items=5)
for item in self._ITEMS:
test_queue.PushItem(item)
with self.assertRaises(errors.QueueFull):
test_queue.PushItem('item5')
with self.assertRaises(errors.QueueFull):
test_queue.PushItem('item6')
test_queue_consumer = test_lib.TestQueueConsumer(test_queue)
test_queue_consumer.ConsumeItems()
expected_number_of_items = len(self._ITEMS)
self.assertEquals(
test_queue_consumer.number_of_items, expected_number_of_items + 1)
class SingleProcessEngineTest(unittest.TestCase):
"""Tests for the engine object."""
_TEST_DATA_PATH = os.path.join(os.getcwd(), u'test_data')
def testEngine(self):
"""Test the engine functionality."""
resolver_context = context.Context()
test_engine = single_process.SingleProcessEngine(
maximum_number_of_queued_items=25000)
self.assertNotEquals(test_engine, None)
source_path = os.path.join(self._TEST_DATA_PATH, u'ímynd.dd')
os_path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_OS, location=source_path)
source_path_spec = path_spec_factory.Factory.NewPathSpec(
dfvfs_definitions.TYPE_INDICATOR_TSK, location=u'/',
parent=os_path_spec)
test_engine.SetSource(source_path_spec, resolver_context=resolver_context)
self.assertFalse(test_engine.SourceIsDirectory())
self.assertFalse(test_engine.SourceIsFile())
self.assertTrue(test_engine.SourceIsStorageMediaImage())
test_searcher = test_engine.GetSourceFileSystemSearcher(
resolver_context=resolver_context)
self.assertNotEquals(test_searcher, None)
self.assertIsInstance(
test_searcher, file_system_searcher.FileSystemSearcher)
test_engine.PreprocessSource('Windows')
test_collector = test_engine.CreateCollector(
False, vss_stores=None, filter_find_specs=None,
resolver_context=resolver_context)
self.assertNotEquals(test_collector, None)
self.assertIsInstance(
test_collector, single_process.SingleProcessCollector)
test_extraction_worker = test_engine.CreateExtractionWorker(0)
self.assertNotEquals(test_extraction_worker, None)
self.assertIsInstance(
test_extraction_worker,
single_process.SingleProcessEventExtractionWorker)
if __name__ == '__main__':
unittest.main()

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