pax_global_header00006660000000000000000000000064132056261100014506gustar00rootroot0000000000000052 comment=d14c91314a1e2dcbb1d9934d7f13230f31240487 apt-transport-s3-1.3.0/000077500000000000000000000000001320562611000146505ustar00rootroot00000000000000apt-transport-s3-1.3.0/CHANGELOG000066400000000000000000000011561320562611000160650ustar00rootroot000000000000002015-09-23 Marcin Kulisz * Fixing new line issue in Authorization header caused by more restrictive urllib in python 2.7.10, thx to jensschroer (https://github.com/jensschroer) * Added sha512 handling for checksums, thx to Frank Zwart for supplied patch 2015-01-09 Marcin Kulisz * Fixing '+~ ' handling and making http errors more readable, thx for the patches to Shyamal Prasad 2014-08-06 Marcin Kulisz * Initial release * Operational s3 transport with IAM Roles present on the server apt-transport-s3-1.3.0/COPYING000066400000000000000000000432541320562611000157130ustar00rootroot00000000000000 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 Lesser 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 How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. apt-transport-s3-1.3.0/README.md000066400000000000000000000061261320562611000161340ustar00rootroot00000000000000[License and Copyright]: #license--copyright [Requirements]: #requirements [Configuration]: #configuration [Usage]: #usage [Contribution]: #contribution # apt-transport-s3 ### Table of Contents 1. [License & Copyright][License and Copyright] 2. [Requirements][Requirements] 3. [Configuration][Contribution] 4. [Usage][Usage] 5. [Contribution][Contribution] ## apt-transport-s3 Allow to have a privately hosted apt repository on S3. Access keys are read from `/etc/apt/s3auth.conf` file or IAM role if machine is hosted on AWS or has access to AWS metadata server on 169.254.169.254. They are also taken from the usual environment variables. ## License & Copyright # Copyright (C) 2014 Bashton Ltd. # # This program is free software; you can redistribute it and/or modify # it 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. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ## Requirements ### Additional package dependencies (except installed by default in Debian) 1. python-configobj ## Configuration /etc/apt/s3auth.conf or IAM role can provide credentials required for using private apt repositories. NOTE: Region MUST match the region the buckets are stored in and if not defined defaults to us-east-1. Example of s3auth.conf file: ``` AccessKeyId = myaccesskey SecretAccessKey = mysecretaccesskey Region = 'us-east-1' ``` ## Usage Install the .deb package from the releases page. The bucket repo should be specified using an s3:// prefix, for example: `deb s3://aptbucketname/repo/ trusty main contrib non-free` if you need to use a proxy to connect to the internet you can specify this as an APT configuration directive (for example in /etc/apt/apt.conf.d/90apt-transport-s3) `Acquire::http::Proxy "http://myproxy:3128/";` ## Testing The module will run in interactive mode. It accepts on `stdin` and outputs on `stdout`. The messages it accepts on stdin are in the following format and [documented here](http://www.fifi.org/doc/libapt-pkg-doc/method.html/index.html#abstract). ``` 600 URI Acquire URI:s3://my-s3-repository/project-a/dists/trusty/main/binary-amd64/Packages Filename:Packages.downloaded Fail-Ignore:true Index-File:true ``` This message will trigger an s3 get from the above bucket and key and save it to Filename. It needs a blank line after the message to trigger the processing by the s3 method. ## Contribution If you want to contribute a patch via PR please create it against development branch. Patches via email are welcome as well. apt-transport-s3-1.3.0/debian/000077500000000000000000000000001320562611000160725ustar00rootroot00000000000000apt-transport-s3-1.3.0/debian/README.source000066400000000000000000000024741320562611000202600ustar00rootroot00000000000000apt-transport-s3 for Debian ----------------------- The apt-transport-s3 source is obtained from by the release tag. The Debian packaging tracks the latest tarball from the above url. The apt-transport-s3 package source is maintained within above github repository on Debian branch. * 'master' branch is where we're keeping source code of apt-transport-s3 * The 'debian/*' branchs are for keeping Debian package specific files (per suit) and merging in (with --no-ff) from 'master' branch to build packages. ** There are no Debian specific patches as package mainainters are also the upstream * We carry upstream's tags in 'debian' branch prefixed with 'upstream/' applied on master merge into debian baranch (with --no-ff) ex.: upstream/1.0.1 * We prefix our tags with 'debian/' e.g. debian/1.0.1-1 ** experimental releases are prefixed 'debian/experimental' e.g. debian/experimental/4.0-1 ** Debian tagging should be done after package had been successfully uploaded to Debian repository (to avoid having tags for debs which doesn't exist in the archive) Information how to use gbp work flow following liks may be useful: https://honk.sigxcpu.org/piki/development/debian_packages_in_git/ https://wiki.debian.org/PackagingWithGit apt-transport-s3-1.3.0/debian/apt-transport-s3.8000066400000000000000000000020531320562611000213240ustar00rootroot00000000000000.\" (C) Copyright 2014 Marcin Kulisz (kuLa) , .TH APT-TRANSPORT-S3 8 "August 14, 2014" .SH NAME .SH DESCRIPTION apt-transport-s3 \- it's a package which contains apt transport ('plugin') allowing apt to fetch files stored in private repositories held on AWS S3. .SH AWS Credentials To access repositories held on S3 it is compulsory to have correct permissions into the bucket where repository is located and those permissions have to be reflected in at least one of below two places. .B IAM Roles default place where S3 transport is looking for credentials allowing for fetching files from S3 bucket .B /etc/apt/s3auth.conf credentials configuration file in ini format without section headers .SH URI format URI format is in standard apt format only difference with S3 transport is that instead of HTTP(s), cdrom or FTP protocol .B s3 should be used .br ex. .IR "deb s3://bucket_name.s3.amazonaws.com/ testing main contrib non-free" .PP .SH EXAMPLE /etc/apt/s3auth.conf AccessKeyId = myaccesskey SecretAccessKey = mysecrectkey Token = '' apt-transport-s3-1.3.0/debian/changelog000066400000000000000000000020501320562611000177410ustar00rootroot00000000000000apt-transport-s3 (1.3.0-1) UNRELEASED; urgency=medium * Added build-dep on dh-python and bumping up std-ver to 4.0.0 * d/copyright update -- Marcin Kulisz (kuLa) Sun, 20 Aug 2017 10:52:24 +0100 apt-transport-s3 (1.2.1-1) unstable; urgency=medium * fixing signature handling in d/wach * fixing Vcs-Git url * new upstream v1.2.1 -- Marcin Kulisz (kuLa) Thu, 08 Oct 2015 18:19:59 +0100 apt-transport-s3 (1.2.0-1) unstable; urgency=medium * added missing (from binary) manpage * bumping up standards-verion to 3.9.6 * pointing VCS fields in d/control to the packaging branch for d/sid * new upstream with patches for handling '+~ ' chars and modified error handling for problematic URLs * fixing dch * fixed d/watch and added gpg sign handling -- Marcin Kulisz (kuLa) Sun, 30 Aug 2015 13:44:09 +0100 apt-transport-s3 (1.1.0-2) unstable; urgency=low * Initial release (Closes: #756022) -- Marcin Kulisz (kuLa) Thu, 14 Aug 2014 08:43:59 +0100 apt-transport-s3-1.3.0/debian/compat000066400000000000000000000000021320562611000172700ustar00rootroot000000000000009 apt-transport-s3-1.3.0/debian/control000066400000000000000000000020401320562611000174710ustar00rootroot00000000000000Source: apt-transport-s3 Section: admin Priority: optional Maintainer: Marcin Kulisz (kuLa) Uploaders: David Watson Build-Depends: python (>= 2.6.6-3), debhelper (>= 9), dh-python Standards-Version: 4.0.0 X-Python-Version: >= 2.6 Homepage: https://github.com/BashtonLtd/apt-transport-s3 Vcs-Git: https://github.com/BashtonLtd/apt-transport-s3.git Vcs-Browser: https://github.com/BashtonLtd/apt-transport-s3/tree/debian/sid Package: apt-transport-s3 Architecture: all Depends: ${misc:Depends}, ${python:Depends}, apt, python-configobj Description: APT transport for privately held AWS S3 repositories This package contains the APT AWS S3 transport. It makes possible to fetch files from repositories privately held on AWS S3. . To start using S3 based repo it's enough to have IAM role on the server and to add line similar to the below to apt sources.list (more information in 'man apt-transport-s3'): deb s3://s3.amazonaws.com/BUCKETNAME wheezy main apt-transport-s3-1.3.0/debian/copyright000066400000000000000000000021251320562611000200250ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: apt-transport-s3 Source: https://github.com/BashtonLtd/apt-transport-s3 Files: * Copyright: 2017 Marcin Kulisz 2014-2017 David Watson 2014-2017 Marcin Kulisz License: GPL-2+ This package is free software; you can redistribute it and/or modify it 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. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". apt-transport-s3-1.3.0/debian/gbp.conf000066400000000000000000000001001320562611000175000ustar00rootroot00000000000000[DEFAULT] upstream-branch = master debian-branch = debian/sid apt-transport-s3-1.3.0/debian/install000066400000000000000000000000311320562611000174550ustar00rootroot00000000000000s3 /usr/lib/apt/methods/ apt-transport-s3-1.3.0/debian/manpages000066400000000000000000000000321320562611000176030ustar00rootroot00000000000000debian/apt-transport-s3.8 apt-transport-s3-1.3.0/debian/rules000077500000000000000000000003571320562611000171570ustar00rootroot00000000000000#!/usr/bin/make -f #DH_VERBOSE = 1 DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/default.mk %: dh $@ --with python2 override_dh_installchangelogs: dh_installchangelogs CHANGELOG override_dh_python2: dh_python2 --depends=python apt-transport-s3-1.3.0/debian/source/000077500000000000000000000000001320562611000173725ustar00rootroot00000000000000apt-transport-s3-1.3.0/debian/source/format000066400000000000000000000000141320562611000206000ustar00rootroot000000000000003.0 (quilt) apt-transport-s3-1.3.0/debian/upstream/000077500000000000000000000000001320562611000177325ustar00rootroot00000000000000apt-transport-s3-1.3.0/debian/upstream/signing-key.asc000066400000000000000000001453551320562611000226630ustar00rootroot00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBE5x98YBEADTTQ+N8ub+Q7DnK9A+n8gsRWOguTVt1ldDY/JEH8/bh70jhb4J FwtXNSKNGos+Yyxd9OzKQCaLHwO581YpceP/nebfW4mfz2eEZ3QGWVRWHukiXpK+ SxWeBYMhnZNFjvR8p8mpxnFAyACUYGEKS0qoBQQiOCMrPOSe/SerJjFu8jtGLzkT V089N95jB3w4VH1457EtPdWxV01KYyMBI4SRQfmkwLd6YowW2JEP1hSzbtpYRnhg uIvPCxHLQoj/qEQrIAv+IXcZMoafQNRS5Jkhya2Sq/0Cr0Dh9oiFqJl+Ri79a1d6 gh0WurZw4mBOhfJI6eNX3qndLcJnBGQvquDx1bQT1XJlxDBjTwHLINN4QzOE8/p0 S0e0DUf1tvUntEfT3TCduGWj1nxx6DJo/JbaRXV32+H4lnmmMIfONTcjMF9OvHsd wF25lqbxVUJVIugUZjXrkA2avMK3hMvJ23ufElAAr8FFglbyU1zHOCeMnE/vYpjY RDEFLMHrdwCA4Q/Cg+3n5oci+VJcTHDzbUMgxaYhOF3ESX4oKnAq+CqW8+CWuXsi boWa9WvAq9sZfVDyvfl4xBJEeKpSkKX0p4u7yW2r+MnJ+Y/Nn5fcFIdTJ/o+qT85 XKxkTypCg1f/Z8i46F+pHjXlOPhxgGQKJG/mjYIK6Ib+xwOXFfh1j8nAhQARAQAB tChNYXJjaW4gS3VsaXN6IChrdUxhKSA8ZGViaWFuQGt1bGlzei5uZXQ+iQI4BBMB AgAiBQJOcffGAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRBoaTDdWMM4 s179D/9leAQv1ri8SbKmdgZHcKb4bq7qcIBFdorm2c+aYVUogOUJ1j9qxG8ai7wT 8vexcj4gI2WbMWCKLVX6GdrwHi7skYrXfF3jIbic4rYKYSDLa4pAQUwcswLimbJQ i4lAVJP/C/siMbSvrWuERXfxtzMyNzz2clwXxO6liF2H715e7JO1d0FKdg75uW6G yf+rcuEatniIqmlCCKjlho4pb0m1BXGBRe3sYUPuVBKO98sCprSbv8UMrF9zz/n8 83dzBgJyxuGotgg/IxYRFgJRcxB17oof/x5zRGrBrCq2PoYgxlqE9uygpbG7JzUw znLYB6t2gAWedalwHv7mrtCT6IUpwl++y1iOVYFyRBVyKXD/NAA2Hu72gZoP0RBI njkFZ9X7UAgSLSLD4wI9TCYNfEJidPUBfW+4e2CbY5leEAn10BfBJbYYBRuD55sG NgJoWOnpjQgC14nu/tlTWVcOZzWEIyoI55i8n2H+fTIXQrE500AR+n7Ym1fxm/5f dB/5e3ZUjaAgd6th8X0+JCqQP6bzUZuY76HH1nQd6X9Dt8ax/uD63IPS2zwOlT4+ 3bxgeTd9ku7akB8XapCOOs+wO3AzGjPPcFJsLDp8r3isJBdJZfi7daKK0JXtVj+0 L/npLt6cK+pqVCy24eerg2/fX3pAXlpnA/9k4SPUo2fxAKyzWokDMwQSAQgBHQUC T4VECTcUgAAAAAAfAA9kc2lsdmVycyt3aGVuQGRpZ2l0YWwtc2N1cmYub3JnUGVy c29uYWwgY2hlY2tzwB0aaHR0cDovL3d3dy5kaWdpdGFsLXNjdXJmLm9yZy9maWxl cy9ncGcvY2VydC1wb2xpY3kvM0NDRUJBQkUyMDZDM0I2OS8yMDA5MDgyMjE3NDFa P3NoYTUxMnN1bT1kYWJmYTQ2OWZlNzU4OWFkNmRkMDQ5OGYxNDk4OTFhMTNmODA3 ZGE0NWQ0ZWQ2MDZhZjkyNGIzNTM4MjllYWFiZmFmZDBhNDc4NjM1YmViNTU2ZDE2 OGFjNWJmMzhjOWI1YmI2ZTAzNmE1NzAxMTQ4OGYzOTc2NThlMjlhMjNkZQAKCRA8 zrq+IGw7aU4iD/4yBHWrgabjI/7FDxzGOfCfaK2a8nK/9kkL4stNnvvROMhRNHHj FkBB2mlM/gfhM4nKtCs0czVGP1hGu9EMgq2NukpDDx9DxO90gN64zY3zioPrN4nI N11nPq0+6oAGq6YKwPlw3Rw+02QxJHqmRnTfeSfGeiGw3kev2avkJNbk4TgZsAyn gYSj2Qk7+/l+epXmgrCUQea2zi98g4UiG5iGoXzmlM8pI4dCZixTQIAm7zpZrrIT SAJn0qMR/i8rf9xCnze9n/SvQ1H1Yq7kZEVbKIFDpvhWi3js3S0s1U4qfduhQ2EH A7ls8VpCba6Z7WUDkfhmWZoxwTIQN04Jdg4/pPDvgzEO+N04g+kgaSXdasRnai54 L1N4hCCaAXbJeTCPQCBTuQBRhs38o5Toi/wH2U5XpN7h2dFqTmIysZf4nvlQd3+h GmWXkdX9/D89WFhO7GkwJacZr3xn1Z5SH3dQBq4z5saLcn8363LIV49f1TfztMoS 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 rKNTUsNEJZVrYCSjSGC4WmLO9h2sf49SQe1jCgvraQyJiQI4BBMBAgAiBQJPDYlw AhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRBoaTDdWMM4s5S+EAC6mXW9 RsjnoAUz2uG9XYBn7zgB7n08akjsXI3qYh1FYv2lt+QX/b/yl01PQrVQadkr5vAX OFapkq00SA1BNRJJsFydUgWnN9FGm2L+2wmY7IsOxF0aKRkvnxIkJBu4xfPrJkmB hZEcICM/cNmg0JZ+l/AIPtIq6OAFCVjSvP2J+NlSwYrD08wWaEbogzg3L13M9pzc WAZo97+/cKr7htn5he4H8/ZXo0Q9xpu39cF4lWsi3GZRVSQWmtkgrOHOdu1uyWhv /i0UCPTPNt8t4O0LbL+Lw26d1Lrd4U0bL6jGkGwXvCzQmi3KpCmYMh7l0u5wnaQq eirUfwzcYDkbCx6xRsQHTmzbZDT1hSeVgXrhGYGEPHDnXHIkkCrzzZN789WYd9y2 Tke9lp+j1JmNmzqkvGeSmURG3aetxxz3IeFV6Ou+f525MolJIxUnbSDxChL28WVp zOAoGs+TJ/3160iWranppl0JNt5cnH9XVF/r1g+NlYMASosOaFMJwf+XQNvFTpDs z5wBxOGc0jvWuDFiLD3yN9fswoFOF2nqI+GNMPJl31C8NEy/QZiS8sDUHEVRhthy aiYk5iGw6W2/6fVEvJlFB+XTLNknp3CGy7bM/jXTtg9qiLNqTXxHbXQtiNc6pA0Y dljrgOkbFGYgbPk9YSFTvXiUVpK6viakERZJuokDMwQSAQgBHQUCT4VECTcUgAAA AAAfAA9kc2lsdmVycyt3aGVuQGRpZ2l0YWwtc2N1cmYub3JnUGVyc29uYWwgY2hl Y2tzwB0aaHR0cDovL3d3dy5kaWdpdGFsLXNjdXJmLm9yZy9maWxlcy9ncGcvY2Vy dC1wb2xpY3kvM0NDRUJBQkUyMDZDM0I2OS8yMDA5MDgyMjE3NDFaP3NoYTUxMnN1 bT1kYWJmYTQ2OWZlNzU4OWFkNmRkMDQ5OGYxNDk4OTFhMTNmODA3ZGE0NWQ0ZWQ2 MDZhZjkyNGIzNTM4MjllYWFiZmFmZDBhNDc4NjM1YmViNTU2ZDE2OGFjNWJmMzhj OWI1YmI2ZTAzNmE1NzAxMTQ4OGYzOTc2NThlMjlhMjNkZQAKCRA8zrq+IGw7abHp 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 5YjbMie2Jvg1H/jqfjOBN5mEbV2uq+JeAmm32RkAsu6kLMIvOrhGdJO248MB77tZ DKAi4si3EsBFxgwiyU7X4KyJAzMEEgEIAR0FAk+FRAg3FIAAAAAAHwAPZHNpbHZl cnMrd2hlbkBkaWdpdGFsLXNjdXJmLm9yZ1BlcnNvbmFsIGNoZWNrc8AdGmh0dHA6 Ly93d3cuZGlnaXRhbC1zY3VyZi5vcmcvZmlsZXMvZ3BnL2NlcnQtcG9saWN5LzND Q0VCQUJFMjA2QzNCNjkvMjAwOTA4MjIxNzQxWj9zaGE1MTJzdW09ZGFiZmE0Njlm ZTc1ODlhZDZkZDA0OThmMTQ5ODkxYTEzZjgwN2RhNDVkNGVkNjA2YWY5MjRiMzUz ODI5ZWFhYmZhZmQwYTQ3ODYzNWJlYjU1NmQxNjhhYzViZjM4YzliNWJiNmUwMzZh NTcwMTE0ODhmMzk3NjU4ZTI5YTIzZGUACgkQPM66viBsO2k1+g//S6HjKxdyd0QO JkKY7W8hB4qMnwkzPSpDCjvbzQi4LEBi/aiLSteOFg3H4Lr9mxKllGi6j9ST3q9F vadoBZ3ZqEwgbtZRPYB/GeUBfaI3Y1tQXYwm6wbc6zjtLDEbw0s0SddDlh38wkac +cH+SMWx7GwxGONHBB9YO0CtjDJ4C8L4xd6qmqY+4iiPxM3u+AFzty7occkgKGqG saH2yLo7GW7LhcKF1rhWbM0zTo1CW9jDcJtdegzpIW3XkibtKhB8Uph7QoxBk1AS N615jySqzhMjMr/Yp945pGo251qazQvCOAF9l1zGxUhLpCiLq6aM+2RkhMa/sKCL A0s8z1OIDALh1CrqvyLb34yzzCi9ba/NdgDs4DdAzN6rHPb1WsSL1rLu8tbxGOhm 3TvXxeMwEIHLO1rjL79yiIyVXlzGRwVnilO1/rOleRataDsCV2HUjjtv4M57gFfM 3PvD4qXP4shady9PrIN9hJ8WQo/c03O7vhfHJBzOn8YBgB4DliBkr+WXMTf977dK u8NCK0BEPBBmGGVeBjbMVaCpwjZQp3uK1Xr1el/tPC08VpEli/Y07iPm0AYemr1W QnsMaf1wsvOeFpaO8Iz+slGc8RnYFZxiGCOc/AUdwn3E6zPbj20pFol8jNmJh6UJ X70fKHnV48cDA489K54bbL+bWqCxvDeJAhwEEAEIAAYFAlIJJA8ACgkQR3EhcfLt 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 =VDCi -----END PGP PUBLIC KEY BLOCK----- apt-transport-s3-1.3.0/debian/watch000066400000000000000000000003441320562611000171240ustar00rootroot00000000000000version=3 opts="filenamemangle=s/(?:.*)?v?(\d[\d\.]*)\.tar\.gz/apt-transport-s3-$1.tar.gz/,pgpsigurlmangle=s/$/.asc/" \ https://github.com/BashtonLtd/apt-transport-s3/releases .*/v\d\S*/apt-transport-s3-?(\d[\d\.]*)\.tar\.gz apt-transport-s3-1.3.0/s3000077500000000000000000000451341320562611000151320ustar00rootroot00000000000000#!/usr/bin/python -u # Copyright (C) 2014 Bashton Ltd # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # https://github.com/BashtonLtd/apt-transport-s3 import urllib2 import urlparse import time import hashlib import hmac import json import sys import os import datetime import xml.etree.ElementTree as ET import socket import ssl from configobj import ConfigObj RETRIES = 5 def wait_time(c): return pow(2, c) - 1 RETRIES = 5 def wait_time(c): return pow(2, c) - 1 class AWSCredentials(object): """ Class for dealing with IAM role credentials from meta-data server and later on to deal with boto/aws config provided keys """ def __init__(self, config_file=None): self.conf_file = config_file host = 'http://169.254.169.254' path = '/latest/meta-data/iam/security-credentials/' self.meta_data_uri = urlparse.urljoin(host, path) def __get_role(self): # Read IAM role from AWS metadata store request = urllib2.Request(self.meta_data_uri) response = None for i in range(0, RETRIES): try: response = urllib2.urlopen(request, None, 10) self.iamrole = response.read() break except ssl.SSLError as e: if 'timed out' in e.message: time.sleep(wait_time(i + 1)) else: raise e except socket.timeout: time.sleep(wait_time(i + 1)) except urllib2.URLError as e: if hasattr(e, 'reason'): raise Exception("URL error reason: %s, probable cause is that\ you don't have IAM role on this machine" % e.reason) elif hasattr(e, 'code'): raise Exception("Server error code: %s" % e.code) finally: if response: response.close() else: raise Exception("GetRole request timed out") def __load_config(self): """ Loading config file from predefined location. Example config file content: AccessKeyId = mykey SecretAccessKey = mysecretkey Token = '' # this can/have to be empty """ # Checking if 'file' exists, if it does read it if os.path.isfile(os.path.expanduser(self.conf_file)): config = ConfigObj(os.path.expanduser(self.conf_file)) return config else: raise Exception("Config file: %s doesn't exist" % self.conf_file) def get_credentials(self): """ Read IAM credentials from AWS metadata store. Note: This method should be explicitly called after constructing new object, as in 'explicit is better than implicit'. """ data = {} try: data = self.__load_config() except: pass self.region = data.get('Region', 'us-east-1') if self.region is None or self.region == '': raise Exception("Region required") sys.stderr.write("Region: {}\n".format(self.region)) if data.get("AccessKeyId") is not None: sys.stderr.write("Using config file for credentials\n") if data.get("AccessKeyId") is None: data['AccessKeyId'] = os.environ.get("AWS_ACCESS_KEY_ID", None) data['SecretAccessKey'] = os.environ.get("AWS_SECRET_ACCESS_KEY", None) data['Token'] = os.environ.get("AWS_SESSION_TOKEN", None) if data.get("AccessKeyId") is not None: sys.stderr.write("Using environment variables for credentials\n") if data.get("AccessKeyId") is None: self.__get_role() request = urllib2.Request( urlparse.urljoin(self.meta_data_uri, self.iamrole) ) response = None for i in range(0, RETRIES): try: response = urllib2.urlopen(request, None, 30) data = json.loads(response.read()) break except ssl.SSLError as e: if 'timed out' in e.message: time.sleep(wait_time(i + 1)) else: raise e except socket.timeout: time.sleep(wait_time(i + 1)) except urllib2.URLError as e: if hasattr(e, 'reason'): raise Exception("URL error reason: %s" % e.reason) elif hasattr(e, 'code'): raise Exception("Server error code: %s" % e.code) finally: if response: response.close() else: raise Exception("GetCredentials request timed out") self.access_key = data['AccessKeyId'] if self.access_key is None or self.access_key == '': raise Exception("AccessKeyId required") self.secret_key = data['SecretAccessKey'] if self.secret_key is None or self.secret_key == '': raise Exception("SecretAccessKey required") self.token = data['Token'] def v4Sign(self, key, msg): return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest() def getSignatureKey(self, dateStamp, serviceName): kDate = self.v4Sign(('AWS4' + self.secret_key).encode('utf-8'), dateStamp) kRegion = self.v4Sign(kDate, self.region) kService = self.v4Sign(kRegion, serviceName) kSigning = self.v4Sign(kService, 'aws4_request') return kSigning def uriopen(self, uri): """uriopen(uri) open the remote file and return a file object.""" try: return urllib2.urlopen(self._request(uri), None, 30) except urllib2.HTTPError as e: # HTTPError is a "file like object" similar to what # urllib2.urlopen returns, so return it and let caller # deal with the error code if e.code == 400: # token errors are buried in 400 messages so expose xmlResponse = ET.fromstring(e.read()) if xmlResponse is not None: e.msg = "{} - {}".format(e, xmlResponse.find("Message").text) if e.code == 301: e.msg = "{} - Set s3auth.conf region to match bucket 'Region': bucket may not be in {}".format(e, self.region) return e # For other errors, throw an exception directly except urllib2.URLError as e: if hasattr(e, 'reason'): raise Exception("URL error reason: %s" % e.reason) elif hasattr(e, 'code'): raise Exception("Server error code: %s" % e.code) except urllib2.socket.timeout: raise Exception("Socket timeout") def _request(self, uri): uri_parsed = urlparse.urlparse(uri) if '.' in uri_parsed.netloc: raise Exception("uri should not include fully qualified domain name for bucket") # quote path for +, ~, and spaces # see bugs.launchpad.net #1003633 and #1086997 scheme = 'https' host = 's3.{}.amazonaws.com'.format(self.region) bucket = uri_parsed.netloc path = '/{}{}'.format(bucket, self._quote(uri_parsed.path, '+~ ')) s3url = urlparse.urlunparse( ( scheme, host, path, '', '', '' ) ) request = urllib2.Request(s3url) request.add_header('x-amz-content-sha256', self._payload_hash(request)) # Create a date for headers and the credential string amzdate = datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ') request.add_header('x-amz-date', amzdate) if self.token is not None and self.token != '': request.add_header('x-amz-security-token', self.token) canonical_request = self._canonical_request(request, host, amzdate) authorization_header = self._authorization_header(canonical_request, amzdate) request.add_header('Authorization', authorization_header) return request def _authorization_header(self, canonical_request, amzdate): datestamp = amzdate.split('T')[0] algorithm = 'AWS4-HMAC-SHA256' credential_scope = datestamp + '/' + self.region + '/s3/aws4_request' string_to_sign = algorithm + '\n' \ + amzdate + '\n' \ + credential_scope + '\n' \ + canonical_request signing_key = self.getSignatureKey(datestamp, 's3') signature = hmac.new(signing_key, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest() authorization_header = "{} Credential={}/{}, SignedHeaders={}, Signature={}".format( algorithm, self.access_key, credential_scope, self._signed_headers(), signature ) return authorization_header def _canonical_request(self, request, host, amzdate): canonical_uri = urlparse.unquote(request.get_selector()) canonical_uri = self._quote(canonical_uri, '+') canonical_querystring = '' canonical_headers = 'host:' + host + '\n' \ + 'x-amz-content-sha256:' + self._payload_hash(request) + '\n' \ + 'x-amz-date:' + amzdate + '\n' if self.token is not None and self.token != '': canonical_headers += 'x-amz-security-token:' + self.token + '\n' canonical_request = request.get_method() + '\n' \ + canonical_uri + '\n' \ + canonical_querystring + '\n' \ + canonical_headers + '\n' \ + self._signed_headers() + '\n' \ + self._payload_hash(request) return hashlib.sha256(canonical_request).hexdigest() def _signed_headers(self): signed_headers = 'host;x-amz-content-sha256;x-amz-date' if self.token is not None and self.token != '': signed_headers += ';x-amz-security-token' return signed_headers def _payload_hash(self, request): payload = request.get_data() if payload is None: payload = '' return hashlib.sha256(payload).hexdigest() # We need to be able to quote specific characters to support S3 # lookups, something urllib and friends don't do easily def _quote(self, s, unsafe): res = list(s) for i in range(len(res)): c = res[i] if c in unsafe: res[i] = '%%%02X' % ord(c) return ''.join(res) class APTMessage(object): MESSAGE_CODES = { 100: 'Capabilities', 102: 'Status', 200: 'URI Start', 201: 'URI Done', 400: 'URI Failure', 600: 'URI Acquire', 601: 'Configuration', } def __init__(self, code, headers): self.code = code self.headers = headers def process(self, lines): status_line = lines.pop(0) self.code = int(status_line.split()[0]) self.headers = [] for line in lines: line = line.strip() if not line: continue parts = [p.strip() for p in line.split(':', 1)] if len(parts) != 2: continue self.headers.append(parts) return self(code, headers) def encode(self): result = '{0} {1}\n'.format(self.code, self.MESSAGE_CODES[self.code]) for item in self.headers.keys(): if self.headers[item] is not None: result += '{0}: {1}\n'.format(item, self.headers[item]) return result + '\n' class S3_method(object): __eof = False def __init__(self, config_file='/etc/apt/s3auth.conf'): self.iam = AWSCredentials(config_file) self.iam.get_credentials() self.send_capabilities() def fail(self, message='Failed'): self.send_uri_failure({'URI': self.uri, 'Message': message}) def _read_message(self): """ Apt uses for communication with its methods the text protocol similar to http. This function parses the protocol messages from stdin. """ if self.__eof: return None result = {} line = sys.stdin.readline() while line == '\n': line = sys.stdin.readline() if not line: self.__eof = True return None s = line.split(" ", 1) result['_number'] = int(s[0]) result['_text'] = s[1].strip() while not self.__eof: line = sys.stdin.readline() if not line: self.__eof = True return result if line == '\n': return result (item, value) = line.split(":", 1) if not result.get(item): result[item] = [] result[item].append(value.strip()) return result def send(self, code, headers): message = APTMessage(code, headers) sys.stdout.write(message.encode()) def send_capabilities(self): self.send(100, { 'Version': '1.1', 'Single-Instance': 'true', 'Send-Config': 'true'}) def send_status(self, headers): self.send(102, headers) def send_uri_start(self, headers): self.send(200, headers) def send_uri_done(self, headers): self.send(201, headers) def send_uri_failure(self, headers): self.send(400, headers) def run(self): """Loop through requests on stdin""" while True: message = self._read_message() if message is None: return 0 if message['_number'] == 601: try: self.configure(message) except Exception, e: self.fail(e.__class__.__name__ + ": " + str(e)) elif message['_number'] == 600: try: self.fetch(message) except Exception, e: self.fail(e.__class__.__name__ + ": " + str(e)) else: return 100 # configure def configure(self, message): for item in message['Config-Item']: if item.startswith('Acquire::http::Proxy'): (key, value) = item.split('=',1) if key == 'Acquire::http::Proxy': os.environ['http_proxy'] = value os.environ['https_proxy'] = value # We need to be able to quote specific characters to support S3 # lookups, something urllib and friends don't do easily def quote(self, s, unsafe): res = list(s) for i in range(len(res)): c = res[i] if c in unsafe: res[i] = '%%%02X' % ord(c) return ''.join(res) def fetch(self, msg): self.uri = msg['URI'][0] self.filename = msg['Filename'][0] self.send_status({'URI': self.uri, 'Message': 'Waiting for headers'}) for i in range(0, RETRIES): try: response = self.iam.uriopen(self.uri) except ssl.SSLError as e: if 'timed out' in e.message: time.sleep(wait_time(i + 1)) continue else: raise e except socket.timeout: time.sleep(wait_time(i + 1)) continue self.send_status({'URI': self.uri, 'Message': 'Waiting for headers'}) if response.code != 200: self.send_uri_failure({ 'URI': self.uri, 'Message': str(response.code) + ' ' + response.msg, 'FailReason': 'HttpError' + str(response.code)}) try: while True: data = response.read(4096) if not len(data): break except ssl.SSLError as e: if 'timed out' in e.message: pass else: raise e except socket.timeout: pass finally: response.close() return self.send_uri_start({ 'URI': self.uri, 'Size': response.headers.getheader('content-length'), 'Last-Modified': response.headers.getheader('last-modified')}) f = open(self.filename, "w") hash_sha256 = hashlib.sha256() hash_sha512 = hashlib.sha512() hash_md5 = hashlib.md5() try: while True: data = response.read(4096) if not len(data): break hash_sha256.update(data) hash_sha512.update(data) hash_md5.update(data) f.write(data) break except ssl.SSLError as e: if 'timed out' in e.message: time.sleep(wait_time(i + 1)) else: raise e except socket.timeout: time.sleep(wait_time(i + 1)) finally: response.close() f.close() else: raise Exception("Fetch request timed out") self.send_uri_done({ 'URI': self.uri, 'Filename': self.filename, 'Size': response.headers.getheader('content-length'), 'Last-Modified': response.headers.getheader('last-modified'), 'MD5-Hash': hash_md5.hexdigest(), 'MD5Sum-Hash': hash_md5.hexdigest(), 'SHA256-Hash': hash_sha256.hexdigest(), 'SHA512-Hash': hash_sha512.hexdigest()}) if __name__ == '__main__': try: config = '/etc/apt/s3auth.conf' if len(sys.argv) == 2 and os.path.isfile(sys.argv[1]): config = sys.argv[1] method = S3_method(config) ret = method.run() sys.exit(ret) except KeyboardInterrupt: pass apt-transport-s3-1.3.0/s3auth.conf000066400000000000000000000000221320562611000167200ustar00rootroot00000000000000Region='eu-west-2'